LoginSignup
5
5

More than 5 years have passed since last update.

「第24回オフラインリアルタイムどう書く」を Haskell で。

Last updated at Posted at 2014-08-08

「第24回オフラインリアルタイムどう書く」の問題を Haskell で解いてみました。

「平方数」と[立法数」は Haskell の得意な「無限数列」を作って、必要な分だけ使い回せるようにしました。
"format" 関数は kei_q さんの投稿に使われていたものを、そのまま使わせてもらいました。

offLine24.hs
import Data.Char
import Data.List

-- 平方数
squareNumber :: [Int]
squareNumber = [x ^ 2 | x <- [1 ..]]

-- 立方数
cubicNumber :: [Int]
cubicNumber = [x ^ 3 | x <- [1 ..]]

-- 倍数番目を撤去 (先頭が1番目であることに注意)
delNth :: Int -> [Int] -> [Int]
delNth n xs = init as ++ delNth n bs
  where (as, bs) = splitAt n xs

-- 直前を撤去
delBefore :: [Int] -> [Int] -> [Int]
delBefore (x : xs) ys
  | null as      =            delBefore xs bs
  | head bs == x = init as ++ delBefore xs bs
  | otherwise    = as      ++ delBefore xs bs
  where (as, bs) = span (< x) ys

-- 直後を撤去
delAfter :: [Int] -> [Int] -> [Int]
delAfter (x : xs) ys
  | null as      =       delAfter    xs bs
  | last as == x = as ++ delIfNextEq xs bs
  | otherwise    = as ++ delAfter    xs bs
  where
    (as, bs) = span (<= x) ys
    delIfNextEq (x : xs) (y : ys)
      | x == y    = delIfNextEq xs ys
      | otherwise = delAfter (x : xs) ys

solve :: String -> String
solve cs = format $ take 10 $ foldl f [1 ..] cs
  where
    format = intercalate "," . map show
    f ns 'S' = delAfter  squareNumber ns
    f ns 's' = delBefore squareNumber ns
    f ns 'C' = delAfter  cubicNumber  ns
    f ns 'c' = delBefore cubicNumber  ns
    f ns 'h' = drop 100 ns
    f ns c   = delNth (digitToInt c) ns


-- << Test >> --------------------------------------------------------

testData :: [(Int, String, String)]
testData =
  [(0, "ss6cc24S", "1,9,21,30,33,37,42,44,49,56"),
   (1, "h",        "101,102,103,104,105,106,107,108,109,110"),
   (2, "hh",       "201,202,203,204,205,206,207,208,209,210"),
   (3, "hhh",      "301,302,303,304,305,306,307,308,309,310"),
   (4, "2",        "1,3,5,7,9,11,13,15,17,19"),
   (5, "22",       "1,5,9,13,17,21,25,29,33,37"),
   (6, "222",      "1,9,17,25,33,41,49,57,65,73"),
   (7, "3",        "1,2,4,5,7,8,10,11,13,14"),
   (8, "33",       "1,2,5,7,10,11,14,16,19,20"),
   (9, "333",      "1,2,7,10,14,16,20,23,28,29"),
   (10, "s",       "1,2,4,5,6,7,9,10,11,12"),
   (11, "ss",      "1,4,5,6,9,10,11,12,13,16"),
   (12, "sss",     "4,5,9,10,11,12,16,17,18,19"),
   (13, "S",       "1,3,4,6,7,8,9,11,12,13"),
   (14, "SS",      "1,4,7,8,9,12,13,14,15,16"),
   (15, "SSS",     "1,8,9,13,14,15,16,20,21,22"),
   (16, "c",       "1,2,3,4,5,6,8,9,10,11"),
   (17, "cc",      "1,2,3,4,5,8,9,10,11,12"),
   (18, "ccc",     "1,2,3,4,8,9,10,11,12,13"),
   (19, "C",       "1,3,4,5,6,7,8,10,11,12"),
   (20, "CC",      "1,4,5,6,7,8,11,12,13,14"),
   (21, "CCC",     "1,5,6,7,8,12,13,14,15,16"),
   (22, "23",      "1,3,7,9,13,15,19,21,25,27"),
   (23, "32",      "1,4,7,10,13,16,19,22,25,28"),
   (24, "2h",      "201,203,205,207,209,211,213,215,217,219"),
   (25, "h2",      "101,103,105,107,109,111,113,115,117,119"),
   (26, "sC",      "1,4,5,6,7,9,10,11,12,13"),
   (27, "Cs",      "1,4,5,6,7,8,10,11,12,13"),
   (28, "s468",    "1,2,4,6,7,11,12,16,17,20"),
   (29, "S468",    "1,3,4,7,8,12,13,16,18,21"),
   (30, "cc579",   "1,2,3,4,8,9,11,13,15,16"),
   (31, "CC579",   "1,4,5,6,8,11,13,15,17,18"),
   (32, "85",      "1,2,3,4,6,7,9,10,12,13"),
   (33, "sh",      "110,111,112,113,114,115,116,117,118,119"),
   (34, "94h",     "150,151,154,155,156,158,159,160,163,164"),
   (35, "h9c8",    "101,102,103,104,105,106,107,110,111,112"),
   (36, "Cc3s",    "1,3,5,6,10,11,13,16,17,19"),
   (37, "cs4h6",   "149,150,152,153,154,157,158,160,161,162"),
   (38, "84523c",  "1,3,11,15,23,26,34,38,46,49"),
   (39, "54C78hS", "228,231,232,233,236,241,242,243,246,247"),
   (40, "65h7ccs", "151,152,153,154,157,158,160,163,164,165"),
   (41, "c95hSc2C",     "145,147,151,153,156,159,162,164,168,171"),
   (42, "c5h3Ss794",    "130,131,133,137,138,142,148,150,152,157"),
   (43, "7ShscC846",    "129,130,131,134,135,139,141,142,146,148"),
   (44, "cshSCCS7ch",   "253,254,256,259,260,261,263,264,265,266"),
   (45, "hhC7849Ss6C",  "201,202,203,205,206,211,212,216,220,225"),
   (46, "hhsc3C987Ccs", "201,202,204,205,207,208,214,217,218,220"),
   (47, "SC7S8hc59ss2", "162,169,174,178,182,185,188,194,199,203"),
   (48, "s7S6c35C9CShc",  "367,371,377,379,380,385,387,388,392,395"),
   (49, "4scC3hh982Cc5s", "422,426,430,434,447,451,459,463,471,479"),
   (50, "23h465Ssc9CchC", "1027,1033,1045,1047,1057,1069,1071,1075,1081,1093")]

test :: [(Int, Bool)]
test = map f testData
  where
    f (a, b, c) = (a, solve b == c)
5
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
5