How to resolve the algorithm Esthetic numbers step by step in the Haskell programming language
How to resolve the algorithm Esthetic numbers step by step in the Haskell programming language
Table of Contents
Problem Statement
An esthetic number is a positive integer where every adjacent digit differs from its neighbour by 1.
These examples are nominally in base 10 but the concept extends easily to numbers in other bases. Traditionally, single digit numbers are included in esthetic numbers; zero may or may not be. For our purposes, for this task, do not include zero (0) as an esthetic number. Do not include numbers with leading zeros. Esthetic numbers are also sometimes referred to as stepping numbers.
Let's start with the solution:
Step by Step solution about How to resolve the algorithm Esthetic numbers step by step in the Haskell programming language
The provided Haskell code implements functions for generating and working with esthetic numbers in various bases. An esthetic number is a number where the absolute difference between consecutive digits is always 1.
1. Esthetic Numbers:
- The program defines the
isEsthetic
function, which checks if a given number (represented as a list of digits) in a specified base is esthetic. It does this by calculating the differences between consecutive digits and checking if all differences are equal to 1.
2. Monadic Solution (esthetics_m):
- The
esthetics_m
function uses the monadic approach to generate esthetic numbers. It generates a list of differences for various lengths (using thereplicateM
function) and combines them with a starting digit to create potential esthetic numbers. However, this approach can be inefficient, especially for larger bases.
3. Iterative Solution (esthetics):
- The
esthetics
function is a more efficient iterative approach that generates esthetic numbers. It uses a loop (implemented usingiterate
andstep
) to incrementally build up esthetic numbers by considering new digits that maintain the esthetic property.
4. Base Conversion:
- The code includes functions for converting numbers between different bases:
fromBase b
takes a number in base 10 and converts it to the specified baseb
.toBase b
converts a number from baseb
to base 10.
5. Display Functions:
showInBase b
takes a number in base 10 and converts it to the specified baseb
, then displays it as a string of digits.
Overall:
This code provides various functions for working with esthetic numbers, including generating them in different bases and verifying if a given number is esthetic. The iterative approach (esthetics
) is more efficient for generating large numbers of esthetic numbers.
Source code in the haskell programming language
import Data.List (unfoldr, genericIndex)
import Control.Monad (replicateM, foldM, mzero)
-- a predicate for esthetic numbers
isEsthetic b = all ((== 1) . abs) . differences . toBase b
where
differences lst = zipWith (-) lst (tail lst)
-- Monadic solution, inefficient for small bases.
esthetics_m b =
do differences <- (\n -> replicateM n [-1, 1]) <$> [0..]
firstDigit <- [1..b-1]
differences >>= fromBase b <$> scanl (+) firstDigit
-- Much more efficient iterative solution (translation from Python).
-- Uses simple list as an ersatz queue.
esthetics b = tail $ fst <$> iterate step (undefined, q)
where
q = [(d, d) | d <- [1..b-1]]
step (_, queue) =
let (num, lsd) = head queue
new_lsds = [d | d <- [lsd-1, lsd+1], d < b, d >= 0]
in (num, tail queue ++ [(num*b + d, d) | d <- new_lsds])
-- representation of numbers as digits
fromBase b = foldM f 0
where f r d | d < 0 || d >= b = mzero
| otherwise = pure (r*b + d)
toBase b = reverse . unfoldr f
where
f 0 = Nothing
f n = let (q, r) = divMod n b in Just (r, q)
showInBase b = foldMap (pure . digit) . toBase b
where digit = genericIndex (['0'..'9'] <> ['a'..'z'])
You may also check:How to resolve the algorithm Constrained random points on a circle step by step in the C++ programming language
You may also check:How to resolve the algorithm Loops/Break step by step in the Avail programming language
You may also check:How to resolve the algorithm Minimum positive multiple in base 10 using only 0 and 1 step by step in the Tcl programming language
You may also check:How to resolve the algorithm Atomic updates step by step in the PARI/GP programming language
You may also check:How to resolve the algorithm Reverse words in a string step by step in the ALGOL 68 programming language