aoc2020/day5.ml

48 lines
1.6 KiB
OCaml
Raw Permalink Normal View History

2020-12-06 01:05:21 +01:00
let add_t (a, b) (c, d) = (a + c, b + d)
let two_to_pov x = int_of_float (2. ** (float_of_int x))
let seat_of_ticket ticket =
let len = (String.length ticket) - 1 in
let rec aux idx res s =
let current = abs (len - idx - 3) in
if idx < 0 then res
else match s.[idx] with
| 'B' -> aux (idx - 1) (add_t res (two_to_pov current, 0)) s
| 'R' -> aux (idx - 1) (add_t res (0, two_to_pov (3 - current))) s
| _ -> aux (idx - 1) res s in
let (row, col) = aux len (0, 0) ticket in
(row * 8) + col
let try_read f =
try Some (input_line f)
with End_of_file -> None
let part1 filename =
let f = open_in filename in
let rec loop max =
match try_read f with
| Some t -> let seat_id = seat_of_ticket t in
if seat_id > max then loop seat_id else loop max
| None -> close_in f; max in
loop 0
let part2 filename =
let f = open_in filename in
let rec read_file_to_list l =
match try_read f with
| Some s -> read_file_to_list ((seat_of_ticket s) :: l)
| None -> close_in f; l in
let find (prev_id, bingo) seat_id =
(seat_id,
Option.fold ~none:(if seat_id = prev_id + 2 then Some (seat_id - 1) else None)
~some:(fun x -> Some x) bingo) in
let (_, ticket_id) = read_file_to_list []
|> List.sort compare
|> List.fold_left (find) (-1, None) in
Option.get ticket_id
let () = print_endline (string_of_int (part1 "day5.input"))
let () = print_endline (string_of_int (part2 "day5.input"))