Skip to content

Instantly share code, notes, and snippets.

@jasonaowen
Created January 10, 2017 23:11
Show Gist options
  • Save jasonaowen/4dd4ef5e93bd78cb42554ac4b13e4980 to your computer and use it in GitHub Desktop.
Save jasonaowen/4dd4ef5e93bd78cb42554ac4b13e4980 to your computer and use it in GitHub Desktop.
A (failed) attempt at generating Hamming numbers (aka regular numbers) for Code Dojo
hamming :: (Int, Int, Int) -> Int
hamming (two, three, five) = 2^two * 3^three * 5^five
nextHammingCoefficient (x, y, z)
| minimum [nextX, nextY, nextZ] == nextX = (x + 1, y, z)
| minimum [nextX, nextY, nextZ] == nextY = (x, y + 1, z)
| minimum [nextX, nextY, nextZ] == nextZ = (x, y, z + 1)
where nextX = hamming (x + 1, y, z)
nextY = hamming (x, y + 1, z)
nextZ = hamming (x, y, z + 1)
hammingCoefficients = iterate nextHammingCoefficient (0, 0, 0)
hammingNumbers = take 10 hammingCoefficients
@atungare
Copy link

Here is a working implementation based on the solution at rosettacode -- the recursion going on here is pretty trippy!

hamming :: [Int]
hamming = 1:(minMerge (map (*2) hamming) (minMerge (map (*3) hamming) (map (*5) hamming)))

minMerge :: Ord a => [a] -> [a] -> [a]
minMerge (x:xs) (y:ys)
  | x < y     = x:(minMerge xs (y:ys))
  | y < x     = y:(minMerge (x:xs) ys)
  | otherwise = x:(minMerge xs ys)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment