type choice = Rock | Paper | Scissors let int_of_choice = function | Rock -> 1 | Paper -> 2 | Scissors -> 3 let choice_of_string = function | "A" | "X" -> Rock | "B" | "Y" -> Paper | "C" | "Z" -> Scissors | _ -> failwith "invalid choice" ;; type outcome = Draw | Win | Lose let int_of_outcome = function | Lose -> 0 | Draw -> 3 | Win -> 6 let outcome_of_string = function | "X" -> Lose | "Y" -> Draw | "Z" -> Win | _ -> failwith "invalid choice" let choice_of_outcome oponent = function | Win -> if oponent = Rock then Paper else if oponent = Paper then Scissors else Rock | Lose -> if oponent = Rock then Scissors else if oponent = Paper then Rock else Paper | Draw -> if oponent = Rock then Rock else if oponent = Paper then Paper else Scissors let outcome me oponent = match int_of_choice me - int_of_choice oponent with | -1 | 2 -> Lose | 1 | -2 -> Win | _ -> Draw open Utils let solve f l = l |> List.map (fun line -> line |> String.split_on_char ' ' |> pair_of_list |> f |> (fun (oponent, me) -> ((outcome me oponent) |> int_of_outcome) + int_of_choice me)) |> List.fold_left (+) 0 let d2_1 = solve (fun (oponent_s, me_s) -> (choice_of_string oponent_s, choice_of_string me_s)) let d2_2 = solve (fun (oponent_s, outcome_s) -> (choice_of_string oponent_s, outcome_of_string outcome_s) |> (fun (oponent, outcome) -> (oponent, (choice_of_outcome oponent outcome)))) let _ = "\n1: " ^ (string_of_int (read_file "bin/d2/input.txt" |> d2_1)) ^ "\n2: " ^ (string_of_int (read_file "bin/d2/input.txt" |> d2_2)) |> print_endline