Posted at

第9回オフラインリアルタイムどう書くの参考問題をHaskellで書いた

More than 5 years have passed since last update.

第9回オフラインリアルタイムどう書くの参考問題をHaskellで書きました。

オフラインリアルタイムどう書くの過去問でHaskellスキルアップを目指します。


makeNumber.hs

import Data.List

import Control.Applicative
import Text.Regex

--先頭が0でない長さ4の順列
permutations' :: [Int] -> [[Int]]
permutations' ns = nub $ filter (\x -> head x /= 0) $ map (take 4) $ permutations ns

--6を9に変換する
convert6To9 :: [Int] -> [[Int]]
convert6To9 [] = [[]]
convert6To9 (n:ns) | n /= 6 = map (n:) $ convert6To9 ns
| otherwise = [(n:), (9:)] <*> convert6To9 ns

make4DigitsNumber :: [Int] -> [[Int]]
make4DigitsNumber ns = sort $ concatMap convert6To9 $ permutations' ns

listToString :: [Int] -> String
listToString [] = ""
listToString (n:ns) = show n ++ listToString ns

solve :: Int -> [Int] -> String
solve n ns = let list = make4DigitsNumber ns in
if length list >= n
then listToString $ list !! (n - 1)
else "-"

parseTestData :: String -> [(Int, [Int], String)]
parseTestData str = map parseLine $ lines str
where
parseLine :: String -> (Int, [Int], String)
parseLine line = let [input, output] = words line
(index, numList) = parseInput input
in (index, numList, output)
parseInput :: String -> (Int, [Int])
parseInput input = let [index, numList] = splitRegex (mkRegex ":") input
in (read index :: Int, parseNumList numList)
parseNumList :: String -> [Int]
parseNumList [] = []
parseNumList (n:ns) = (read (n:[]) :: Int):(parseNumList ns)

main = do
testData <- parseTestData <$> getContents
mapM (\(index, numList, output) -> print $ (solve index numList) == output) testData