メリークリスマス! 1日1個 @nabetani さんの作った問題を解くAdventCalendarの最終目です。最後なので2つ解いちゃいましょう!
一問目は http://qiita.com/Nabetani/items/cbc3af152ee3f50a822f です。今日はピックアップされている中で一番古い問題に挑戦します。
module Doukaku.Poker (solve) where
import Data.List.Split (splitWhen)
import Data.List (sort, group)
solve :: String -> String
solve = decide . sort . map length . group . sort . parse
where
decide [1,4] = "4K"
decide [2,3] = "FH"
decide [1,1,3] = "3K"
decide [1,2,2] = "2P"
decide [1,1,1,2] = "1P"
decide _ = "--"
parse :: String -> [String]
parse = tail . splitWhen (`elem` "SHDC")
スートは無視してオッケーなので、簡単ですね。group
関数を使ったお陰で大変シンプルになりました。スートはパース時に捨てています。
そして、二問目は http://qiita.com/Nabetani/items/d819d1e5f2378317511e です。一問目の続編です。
module Doukaku.Poker2013 (solve) where
import Data.List (sort, group, tails)
import Data.Char (intToDigit)
solve :: String -> String
solve input
| 'T' `elem` (map fst cards) && 'A' `elem` (map fst cards) &&
samesuit cards == 5 && ordered cards == 5 = "RF"
| samesuit cards == 5 && ordered cards == 5 = "SF"
| samesuit cards == 5 = "FL"
| ordered cards == 5 = "ST"
| any (\cs -> samesuit cs == 4 && ordered cs == 4) card4s = "4SF"
| samesuit cards == 4 = "4F"
| ordered cards == 4 = "4S"
| otherwise = "-"
where
card4s = map (\c -> filter (/= c) cards) cards
cards = parse input
samesuit, ordered :: [(Char, Char)] -> Int
samesuit = maximum . map length . group . sort . map snd
ordered hs = maximum . map (contains (map fst hs)) . tails $ numberorder
contains _ [] = 0
contains hs (x:xs)
| x `elem` hs = 1 + contains hs xs
| otherwise = 0
parse :: String -> [(Char, Char)]
parse ('1':'0':s:cs) = ('T', s) : parse cs
parse (n:s:cs) = (n, s) : parse cs
parse _ = []
numberorder :: [Char]
numberorder = 'A' : map intToDigit [2 .. 9] ++ "TJQKA"
連番とスートを判定しなければいけないため。一問目とは全く趣が異なる問題に仕上がっています。ordered
とsamesuite
で
連番とスートの枚数を判定し、これを使って判断する戦略を取りました。が、これだと"4SF"
だけうまく判断できません。
連番の4枚と同じスートの4枚が別の組かもしれないためです。なので、急遽card4s
を用意することになり、旨みがなくなってしまいました。
このAdvent Calendarで作ったソースコードは、すべて https://github.com/hiratara/doukaku-past-questions-advent-2013 にアップしてあります。
Travis CIでのテストは https://travis-ci.org/hiratara/doukaku-past-questions-advent-2013 に。
今回は試しに detailed-0.9
でテストを書いてみてハマった点もあったのですが、その話はまたの機会に。