fork download
  1. module Main (main) where
  2.  
  3. import Data.List (group, nub, sort)
  4.  
  5. main :: IO ()
  6. main = do
  7. input <- getLine
  8. if isValid input then
  9. mapM_ putStrLn (takeMachi input)
  10. else if isExitCall input then
  11. putStrLn "bye"
  12. else
  13. putStrLn "invalid" >> main
  14.  
  15. isValid :: String -> Bool
  16. isValid s = length s == 13
  17. && all (\c -> '1' <= c && c <= '9') s
  18. && all (\g -> length g <= 4) (group (sort s))
  19.  
  20. isExitCall :: String -> Bool
  21. isExitCall s = s == "exit"
  22.  
  23. atamaList,
  24. atamaMachiList,
  25. juntsuList,
  26. juntsuMachiList,
  27. koutsuList,
  28. koutsuMachiList,
  29. mentsuList,
  30. mentsuMachiList
  31. :: [[Int]]
  32.  
  33. atamaList = [[n, n] | n <- [1 .. 9]]
  34.  
  35. atamaMachiList = [[n, -n] | n <- [1 .. 9]]
  36.  
  37. juntsuList = [[n, n+1, n+2] | n <- [1 .. 7]]
  38.  
  39. juntsuMachiList = [[-n, n+1, n+2] | n <- [1 .. 7]]
  40. ++ [[n, -(n+1), n+2] | n <- [1 .. 7]]
  41. ++ [[n, n+1, -(n+2)] | n <- [1 .. 7]]
  42.  
  43. koutsuList = [[n, n, n] | n <- [1 .. 9]]
  44.  
  45. koutsuMachiList = [[n, n, -n] | n <- [1 .. 9]]
  46.  
  47. mentsuList = juntsuList ++ koutsuList
  48.  
  49. mentsuMachiList = juntsuMachiList ++ koutsuMachiList
  50.  
  51. isValidMachi :: [[Int]] -> Bool
  52. isValidMachi m = all (\g -> length g <= 4) (group (sort (map abs (concat m))))
  53.  
  54. machiList :: [[[Int]]]
  55. machiList = [[atama, mentsu1, mentsu2, mentsu3, mentsu4]
  56. | atama <- atamaMachiList
  57. , mentsu1 <- mentsuList
  58. , mentsu2 <- mentsuList
  59. , mentsu3 <- mentsuList
  60. , mentsu4 <- mentsuList]
  61. ++ [[atama, mentsu1, mentsu2, mentsu3, mentsu4]
  62. | atama <- atamaList
  63. , mentsu1 <- mentsuMachiList
  64. , mentsu2 <- mentsuList
  65. , mentsu3 <- mentsuList
  66. , mentsu4 <- mentsuList]
  67.  
  68. isMatchMachi :: String -> [[Int]] -> Bool
  69. isMatchMachi s m = sort s
  70. == concat (map show (sort (filter (\n -> n > 0) (concat m))))
  71.  
  72. takeMachi :: String -> [String]
  73. takeMachi s = nub (map (\m -> concat (sort (map machiToString m))) (filter isValidMachi (filter (\m -> isMatchMachi s m) machiList)))
  74.  
  75. machiToString :: [Int] -> String
  76. machiToString m =
  77. if any (\n -> n < 0) m then
  78. "[" ++ concat (map show (filter (\n -> n > 0) m)) ++ "]"
  79. else
  80. "(" ++ concat (map show m) ++ ")"
  81.  
Success #stdin #stdout 1.12s 4648KB
stdin
1112345678999
stdout
(111)(345)(678)(999)[2]
(111)(234)(678)(999)[5]
(111)(234)(567)(999)[8]
(11)(123)(678)(999)[45]
(11)(123)(456)(999)[78]
(11)(345)(678)(999)[12]
(11)(123)(456)(789)[99]
(111)(456)(789)(99)[23]
(111)(234)(789)(99)[56]
(111)(234)(567)(99)[89]
(123)(456)(789)(99)[11]