やたーDiceをOCamlで書いたよー
長年JOIer達の間で「どうやればきれいに解けるのか」「無理」という会話がなされてきたDiceをOCamlで解いた。
よっしゃ結構きれいや!と思ってドヤ顔をしつつ他のC++のソースとか参照してたら別にきれいでもない上にこっちのほうが長かったので死にたい。
でもすごく短かいソースは「これ書いててバグらなかったんですね…(困惑)」みたいな感じなのでべつにいいです。
実際書いてる途中で何度も型検査に助けられたので、一発で通る率は圧倒的にC++とかよりOCamlのほうが高いと思います。
問題文はこちら。
AIZU ONLINE JUDGE
AOJはOCamlに対応しろ!
type direction = North | East | South | West | Right | Left;; type dice = { top:int; east:int; north:int; west:int; south:int; bottom:int; };; let solve n = let rec read n l = if n > 0 then let convert = function | "North" -> North | "East" -> East | "South" -> South | "West" -> West | "Right" -> Right | "Left" -> Left | _ -> raise Not_found in read (n - 1) ((Scanf.scanf "%s\n" convert)::l) else l and make_dice () = { top = 1; bottom = 6; east = 3; west = 4; south = 2; north = 5;} in let solve_impl n = let turn_dice d dir = match dir with | North -> {d with top = d.south; south = d.bottom; bottom = d.north; north = d.top;} | East -> {d with top = d.west; west = d.bottom; bottom = d.east; east = d.top;} | West -> {d with top = d.east; east = d.bottom; bottom = d.west; west = d.top;} | South -> {d with top = d.north; north = d.bottom; bottom = d.south; south = d.top;} | Right -> {d with east = d.north; north = d.west; west = d.south; south = d.east;} | Left -> {d with east = d.south; south = d.west; west = d.north; north = d.east;} in let directions = read n [] and f dir (dic, score) = let next_dice = (turn_dice dic dir) in (next_dice, score + next_dice.top) in snd (List.fold_right f directions ((make_dice ()), 1)) in Printf.printf "%d\n" (solve_impl n) in let rec next () = Scanf.scanf "%d\n" (fun n -> if n > 0 then (solve n(*; next ()*))) in next ();;