-- | Determines whether it is numberwang. module Acme.Colosson ( numberwang ) where import System.Random import System.IO.Unsafe data Wanger = Numb Bool Wanger Wanger simon :: Wanger -> Integer -> Bool simon (Numb b _ _) 0 = b simon (Numb _ x y) n = case divMod n 2 of (m, 0) -> simon x m (m, _) -> simon y m julie :: StdGen -> Wanger julie g0 = let (b, g1) = random g0 (g2, g3) = split g1 in Numb b (julie g2) (julie g3) colosson :: IO (Integer -> Bool) colosson = do nt <- julie `fmap` newStdGen pt <- julie `fmap` newStdGen let f n | n < 0 = simon nt (-n) | otherwise = simon pt n return f -- | Is it numberwang? numberwang :: Integer -> Bool numberwang = unsafePerformIO colosson {-# NOINLINE numberwang #-}