48 lines
1.6 KiB
OCaml
48 lines
1.6 KiB
OCaml
|
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"))
|