第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