~turminal/aoc2022

3e32b533168acbc73071ecf4680b4832a5569292 — Bor Grošelj Simić 1 year, 10 months ago 316c9e8
day 2
3 files changed, 101 insertions(+), 0 deletions(-)

A 2/lex.mll
A 2/t1.ml
A 2/t2.ml
A 2/lex.mll => 2/lex.mll +11 -0
@@ 0,0 1,11 @@
{
type token =
	| Line of char * char
	| Eof
}

rule token = parse
	| ['A'-'C'] ' ' ['X'-'Z'] '\n' as line {
		Line (line.[0], line.[2])
	}
	| eof { Eof }

A 2/t1.ml => 2/t1.ml +36 -0
@@ 0,0 1,36 @@
open Lex

type shape = Rock | Paper | Scissors

let shape_of_char = function
	| 'A' | 'X' -> Rock
	| 'B' | 'Y' -> Paper
	| 'C' | 'Z' -> Scissors
	| _ -> invalid_arg "shape_of_char"

let rec f lexbuf =
	match Lex.token lexbuf with
	| Eof -> []
	| Line (l, r) -> (shape_of_char l, shape_of_char r) :: f lexbuf

let shape_score = function
	| _, Rock -> 1
	| _, Paper -> 2
	| _, Scissors -> 3

let outcome_score = function
	| a, b when a = b -> 3
	| Rock, Paper -> 6
	| Scissors, Rock -> 6
	| Paper, Scissors -> 6
	| _ -> 0

let score s = shape_score s + outcome_score s

let () =
	stdin
		|> Lexing.from_channel
		|> f
		|> List.map score
		|> List.fold_left (+) 0
		|> Printf.printf "%d\n"

A 2/t2.ml => 2/t2.ml +54 -0
@@ 0,0 1,54 @@
open Lex

type shape = Rock | Paper | Scissors
type outcome = Win | Draw | Lose

let shape_of_char = function
	| 'A' -> Rock
	| 'B' -> Paper
	| 'C' -> Scissors
	| _ -> invalid_arg "shape_of_char"

let outcome_of_char = function
	| 'X' -> Lose
	| 'Y' -> Draw
	| 'Z' -> Win
	| _ -> invalid_arg "outcome_of_char"

let rec f lexbuf =
	match Lex.token lexbuf with
	| Eof -> []
	| Line (l, r) -> (shape_of_char l,  outcome_of_char r) :: f lexbuf

let shape_score = function
	| Rock -> 1
	| Paper -> 2
	| Scissors -> 3

let outcome_score = function
	| Win -> 6
	| Draw -> 3
	| Lose -> 0

let find_match = function
	| a, Draw -> a
	| a, Win ->
			(match a with
			| Rock -> Paper
			| Paper -> Scissors
			| Scissors -> Rock)
	| a, Lose ->
			(match a with
			| Paper -> Rock
			| Scissors -> Paper
			| Rock -> Scissors)

let score (s, o) = shape_score (find_match (s, o)) + outcome_score o

let () =
	stdin
		|> Lexing.from_channel
		|> f
		|> List.map score
		|> List.fold_left (+) 0
		|> Printf.printf "%d\n"