Day 10 in OCaml
This commit is contained in:
parent
12d25e7b7d
commit
254e5861f5
|
@ -0,0 +1 @@
|
|||
(lang dune 2.9)
|
|
@ -0,0 +1,10 @@
|
|||
[({(<(())[]>[[{[]{<()<>>
|
||||
[(()[<>])]({[<{<<[]>>(
|
||||
{([(<{}[<>[]}>{[]{[(<()>
|
||||
(((({<>}<{<{<>}{[]{[]{}
|
||||
[[<[([]))<([[{}[[()]]]
|
||||
[{[{({}]{}}([{[{{{}}([]
|
||||
{<[[]]>}<{[{[{[]{()[[[]
|
||||
[<(<(<(<{}))><([]([]()
|
||||
<{([([[(<>()){}]>(<<{{
|
||||
<{([{{}}[<[[[<>{}]]]>[]]
|
|
@ -0,0 +1,73 @@
|
|||
open Core
|
||||
|
||||
let read_lines path =
|
||||
In_channel.read_lines path
|
||||
|
||||
let opening = function
|
||||
| '(' | '[' | '<' | '{' -> true
|
||||
| _ -> false
|
||||
|
||||
let matching = function
|
||||
| '(' -> ')'
|
||||
| '[' -> ']'
|
||||
| '{' -> '}'
|
||||
| '<' -> '>'
|
||||
| _ -> assert false
|
||||
|
||||
let illegal_character_score = function
|
||||
| ')' -> 3
|
||||
| ']' -> 57
|
||||
| '}' -> 1197
|
||||
| '>' -> 25137
|
||||
| _ -> assert false
|
||||
|
||||
type line_state =
|
||||
| Valid
|
||||
| Incomplete of char list
|
||||
| Invalid of int
|
||||
|
||||
let line_score (line : string) =
|
||||
String.fold_until ~init:[]
|
||||
~f: (fun stack character ->
|
||||
match stack, character with
|
||||
| x, c when opening c -> Continue (matching c :: x)
|
||||
| x :: xs, c when Stdlib.(x = c) -> Continue xs
|
||||
| _, c -> Stop (Invalid (illegal_character_score c))
|
||||
)
|
||||
~finish: (fun stack ->
|
||||
if List.is_empty stack
|
||||
then Valid
|
||||
else Incomplete stack
|
||||
)
|
||||
line
|
||||
|
||||
let part1 lines =
|
||||
lines
|
||||
|> List.map ~f:(function Invalid x -> x | _ -> 0)
|
||||
|> List.fold_left ~f:(+) ~init:0
|
||||
|
||||
let part2_character_score = function
|
||||
| ')' -> 1
|
||||
| ']' -> 2
|
||||
| '}' -> 3
|
||||
| '>' -> 4
|
||||
| _ -> assert false
|
||||
|
||||
let score_incomplete stack =
|
||||
List.fold_left ~init:0
|
||||
~f:(fun acc current -> acc * 5 + part2_character_score current)
|
||||
stack
|
||||
|
||||
let part2 lines =
|
||||
let filtered = List.filter lines ~f:(function Incomplete _ -> true | _ -> false) in
|
||||
let sorted_scores = filtered
|
||||
|> List.map ~f:(function Incomplete x -> x | _ -> assert false)
|
||||
|> List.map ~f:score_incomplete
|
||||
|> List.sort ~compare:compare
|
||||
in List.nth_exn sorted_scores ((List.length filtered) / 2)
|
||||
|
||||
let input = read_lines (Sys.get_argv ()).(1)
|
||||
let preprocessed_lines = List.map ~f:line_score input
|
||||
|
||||
let () = Printf.printf "Part 1: %d\n" (part1 preprocessed_lines)
|
||||
let () = Printf.printf "Part 2: %d\n" (part2 preprocessed_lines)
|
Reference in New Issue