-- http://www.codewars.com/kata/526d84b98f428f14a60008da
module Hamming where

position :: Int -> Int
position n = sum [floor (1 + (logn - fi x * log 2 - fi y * log 3 ) / log 5) | x <- xs, y <- ys x] where
  fi   = fromIntegral
  logn = log (fi n + 0.5)
  xs   = [0 .. floor $ logn / log 2]
  ys x = [0 .. floor $ (logn - fi x * log 2) / log 3]


hamming  :: Int -> Int
hamming n = head $ filter ((==n) . position) [pow2 * pow3 * pow5 |
  pow2 <- pows 1 2, pow3 <- pows pow2 3, pow5 <- pows (pow2 * pow3) 5] where
    pows m b = takeWhile ((<=n) . position . (*m)) $ map (b^) [0..]
