Skip to content

Instantly share code, notes, and snippets.

@choplin
Created May 16, 2012 11:06
Show Gist options
  • Save choplin/2709561 to your computer and use it in GitHub Desktop.
Save choplin/2709561 to your computer and use it in GitHub Desktop.
Inverse FizzBuzz implementation of Haskell
module Main where
data FizzBuzz = Fizz | Buzz | FizzBuzz deriving (Eq, Show)
type Pattern = (Int,[FizzBuzz])
patterns :: [Pattern]
patterns = [
(6,[Fizz,Fizz])
,(3,[Fizz,Buzz,Fizz,Fizz])
,(9,[Fizz,Buzz,Fizz,FizzBuzz])
,(12,[Fizz,FizzBuzz])
,(5,[Buzz,Fizz,Fizz])
,(10,[Buzz,Fizz,FizzBuzz])
,(15,[FizzBuzz])
]
same :: Eq a => (a,a) -> Bool
same (x,y) = x == y
sameHeads :: Eq a => [a] -> [a] -> Bool
sameHeads xs ys = same $ unzip $ zip xs ys
fit :: [FizzBuzz] -> Pattern -> Bool
fit inp (n,pat) = sameHeads inp pat
searchStart :: [FizzBuzz] -> [Pattern] -> [Int]
searchStart inp pats = map fst $ filter (fit inp) pats
isFizzBuzz :: Int -> Bool
isFizzBuzz x = x `mod` 5 == 0 || x `mod` 3 == 0
fizzbuzz :: Int -> [(Int,FizzBuzz)]
fizzbuzz start = zip fbseq $ map convert fbseq
where
fbseq = filter isFizzBuzz [start..]
convert x
| x `mod` 15 == 0 = FizzBuzz
| x `mod` 5 == 0 = Buzz
| otherwise = Fizz
searchSeq :: Int -> [FizzBuzz] -> [Int]
searchSeq start inp = case isValid of
True -> [start..(maximum $ map fst fbseq)]
False -> []
where
fbseq = take (length inp) $ fizzbuzz start
isValid = all same $ zip inp $ map snd fbseq
inverseFizzBuzz :: [FizzBuzz] -> [Pattern] -> [Int]
inverseFizzBuzz inp pats = case startNums of
[] -> []
xs -> searchSeq (minimum xs) inp
where
startNums = searchStart inp pats
main = print $ inverseFizzBuzz [Fizz, Buzz, Fizz, Fizz, Buzz, Fizz] patterns
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment