HaskellでAOJ ITP1_6_B不足しているカードの発見
なくなったカードの発見 | プログラミング入門 | Aizu Online Judge
nput
最初の行に太郎が持っているカードの枚数 n (n ≤ 52)が与えられます。
続いて n 組のカードがそれぞれ1行に与えられます。各組は1つの空白で区切られた文字と整数です。文字はカードの絵柄を表し、スペードが'S'、ハートが'H'、クラブが'C'、ダイヤが'D'で表されています。整数はそのカードのランク(1 ~ 13)を表しています。
Output
足りないカードをそれぞれ1行に出力して下さい。各カードは入力と同様に1つの空白で区切られた文字と整数です。出力するカードの順番は以下のとおりとします:
絵柄がスペード、ハート、クラブ、ダイヤの順番で優先的に出力する。
絵柄が同じ場合は、ランクが小さい順に出力する。
初見での方針は
全カードのリストを作って
そこと与えられたカードとの差分を取る事。
ところが全カードのリストを作るスマートな方法が分からない。
["S","H","C","D"] と[1..13]を組み合わせたいがググって方法を探る。
日本語でググってもあまり情報が出て来ないので
hackageのData.Listと睨めっこする事にした。
しかしそんな都合のいい操作は見当たらず・・・
allcards = zip (repeat "H") [1..13] ++ zip (repeat "D") [1..13] ++ zip (repeat "S") [1..13] ++ zip (repeat "C") [1..13]
仕方なく作ったのが上の関数。
・・・いくら何でもダサすぎる。
多少格好をつける為にも共通部分をくくる事にした。
allcards = cards "H" ++ cards "D" ++ cards "S" ++ cards "C" where cards s = zip (repeat s) [1..13]
まだくくれる。
allcards = concat $ map cards ["H","D","S","C"] where cards s = zip (repeat s) [1..13]
なんとかそれっぽくなって一安心。
扱いにくいので
タプルをリストにする関数も作成。
tupleToList :: (String, Integer) -> [String] tupleToList (s,n) = [s, show n] allcardsList :: [[String]] allcardsList = map tupleToList allcards
ここで
["D","13"]のようなリストよりも
"D 13"のような一つのStringにした方が更に扱いやすい事に気付く。
という訳でtoupleToListを改造。
tupleToString :: ([Char], Integer) -> String tupleToString (s,n) = s ++ " " ++ show n allcardsList :: [String] allcardsList = map tupleToString allcards
こういった方針転換を簡単に出来るのがHaskellの良さだ。
出力では順番にとなっているので
最初に全カードを作る時の関数を順番通りになるように変更。
import Data.List ((\\)) allcards :: [([Char], Integer)] allcards = concat $ map cards ["S","H","C","D"] where cards s = zip (repeat s) [1..13] tupleToString :: ([Char], Integer) -> String tupleToString (s,n) = s ++ " " ++ show n allcardsList :: [String] allcardsList = map tupleToString allcards main = do s' <- getContents let s = tail $ lines s' putStr $ unlines $ allcardsList \\ s
最終的に上記のコードで通ったので
答え合わせに達人達のコードを拝見
r = [x | x <- [(s : ' ' : (show n)) | s <- "SHCD", n <- [1..13]]
http://judge.u-aizu.ac.jp/onlinejudge/review.jsp?rid=1716949#1
リスト内包表記でスマートに書けたようだ。
Prelude> [x | x <- [(s : ' ' : (show n)) | s <- "SHCD", n <- [1..13]]] ["S 1","S 2","S 3","S 4","S 5","S 6","S 7","S 8","S 9","S 10","S 11","S 12","S 13","H 1","H 2","H 3","H 4","H 5","H 6","H 7","H 8","H 9","H 10","H 11","H 12","H 13","C 1","C 2","C 3","C 4","C 5","C 6","C 7","C 8","C 9","C 10","C 11","C 12","C 13","D 1","D 2","D 3","D 4","D 5","D 6","D 7","D 8","D 9","D 10","D 11","D 12","D 13"]
う〜む、これは美しい。勉強になった。