LoginSignup
1
1

More than 5 years have passed since last update.

ポーカー、ポーカーの残り+(2012.6.22、2013.4.19の過去問)

Posted at

メリークリスマス! 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"

連番とスートを判定しなければいけないため。一問目とは全く趣が異なる問題に仕上がっています。orderedsamesuite
連番とスートの枚数を判定し、これを使って判断する戦略を取りました。が、これだと"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 でテストを書いてみてハマった点もあったのですが、その話はまたの機会に。

1
1
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
1
1