interview question
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

62 lines
1.5KB

  1. import System.IO
  2. data Incarnation = S Bool Bool Int (Int,Int) Int Int
  3. seed :: Int -> Int
  4. seed n = 1 + (h * (n+1))
  5. where h = (div n 2)
  6. lineage :: Int -> [Int]
  7. lineage n = take (n*n) $ futures (atom n)
  8. atom :: Int -> Incarnation
  9. atom n = S False True 1 (1,0) (seed n) n
  10. xor :: Bool -> Bool -> Bool
  11. xor a b = (a || b) && (not (a && b))
  12. futures :: Incarnation -> [Int]
  13. futures self@(S _ _ _ _ l _) =
  14. (l:(futures (evolve self)))
  15. divine :: Incarnation -> Int
  16. divine (S v s _ _ l n) = l `sign` val
  17. where
  18. sign = if s then (+) else (-)
  19. val = if v then n else 1
  20. evolve :: Incarnation -> Incarnation
  21. evolve i@(S v s cd (so,sn) _ b)
  22. | cd > 1 = (S v s (cd-1) (so,sn) (divine i) b)
  23. | otherwise =
  24. (S (not v) (s `xor` v) (cs ns) ns (divine i) b)
  25. where
  26. ns = (intuit v (so,sn))
  27. cs = (if v then fst else snd)
  28. intuit :: Bool -> (Int,Int) -> (Int,Int)
  29. intuit True (a,b) = ((a+1),b)
  30. intuit _ (a,b) = (a,(b+1))
  31. -- blurgh io
  32. -- bloating the program making me import stuff >:(
  33. main :: IO ()
  34. main = do
  35. putStr "destinies to observe: "
  36. hFlush stdout
  37. args <- getLine
  38. mapM_ putStrLn
  39. $ map (\n -> ("n=" ++ (show n) ++ " ~ ")
  40. ++ (if (aura n)
  41. then (show (lineage (read n)))
  42. else "[ soul contains invalid aura ]"))
  43. (words args)
  44. aura :: String -> Bool
  45. aura s = if (foldr (&&) True (map (`elem` ['0'..'9']) s))
  46. then ((mod rs 2) == 1)
  47. else False
  48. where
  49. rs = (read s)::Int