Skip to content

Instantly share code, notes, and snippets.

@notogawa
Created May 16, 2012 13:53
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save notogawa/2710503 to your computer and use it in GitHub Desktop.
Save notogawa/2710503 to your computer and use it in GitHub Desktop.
Inverse Fizzbuzz
module Main where
import Data.List(sortBy)
import Data.Ord(comparing)
main :: IO ()
main = interact $ unlines . take 1 . map (show . uncurry enumFromTo) . zzubzzif . lines
zzubzzif :: [String] -> [(Int,Int)]
zzubzzif [] = []
zzubzzif (fb:fbs) = foldl (#) [ (a, a) | a <- [1..15], fizzbuzz a == fb ] fbs
(#) :: [(Int,Int)] -> String -> [(Int,Int)]
rs # fb = sortBy (comparing $ uncurry $ flip(-)) [ (a, b') |
(a, b) <- rs,
let b':_ = [ n | n <- [b+1..], 1 < gcd 15 n ],
fizzbuzz b' == fb ]
fizzbuzz :: Int -> String
fizzbuzz n | 0 == mod n 15 = "FizzBuzz"
| 0 == mod n 5 = "Buzz"
| 0 == mod n 3 = "Fizz"
| otherwise = show n
{-# Language TemplateHaskell, QuasiQuotes, FlexibleContexts #-}
module Main where
import Data.Ord
import Data.List
import Text.Peggy
[peggy|
f3 :: [Int] = fizz b5? !. { carry 3 $ maybe [] id $2 }
b5 :: [Int] = buzz f6? !. { carry 5 $ maybe [] id $2 }
f6 :: [Int] = fizz f9? !. { carry 6 $ maybe [] id $2 }
f9 :: [Int] = fizz b10? !. { carry 9 $ maybe [] id $2 }
b10 :: [Int] = buzz f12? !. { carry 10 $ maybe [] id $2 }
f12 :: [Int] = fizz fb15? !. { carry 12 $ maybe [] id $2 }
fb15 :: [Int] = fizzbuzz f3? !. { carry 15 $ maybe [] id $2 }
fizz ::: String = "Fizz" { "Fizz" }
buzz ::: String = "Buzz" { "Buzz" }
fizzbuzz ::: String = "FizzBuzz" { "FizzBuzz" }
|]
main :: IO ()
main = do
fizzbuzz <- getLine
let candidates = [ [head ls..last ls] |
Right ls <- [parseString f3 "<stdin>" fizzbuzz,
parseString b5 "<stdin>" fizzbuzz,
parseString f6 "<stdin>" fizzbuzz,
parseString f9 "<stdin>" fizzbuzz,
parseString b10 "<stdin>" fizzbuzz,
parseString f12 "<stdin>" fizzbuzz,
parseString fb15 "<stdin>" fizzbuzz] ]
if null candidates
then putStrLn "Invalid"
else putStrLn . unwords . map show $ minimumBy (comparing length) candidates
carry x [] = [x]
carry x xs | any (<= x) xs = x : map (15+) xs
| otherwise = x : xs
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment