Compare commits

...

10 commits

Author SHA1 Message Date
e7a329d126 day19 2020-12-20 01:29:58 -05:00
01d387264c day18 2020-12-20 01:29:41 -05:00
5bab305b71 day 17 yo 2020-12-18 14:22:49 -05:00
731d7aff61 day16 2020-12-17 00:01:24 -05:00
787610c66b day15 2020-12-16 15:43:45 -05:00
fab8323597 Adding data too 2020-12-16 00:05:05 -05:00
bda3cae3aa day 14. still not done with 13.. 2020-12-16 00:01:35 -05:00
c334cf3795 day 12 2020-12-12 18:21:03 -05:00
4b612ac95d didn't know you could just use = to check equality of 2 nested lists.. 2020-12-11 23:26:07 -05:00
81aade09dd day 11 2020-12-11 17:55:00 -05:00
19 changed files with 3742 additions and 0 deletions

95
day11.ml Normal file
View file

@ -0,0 +1,95 @@
(* Common util. Should probably put this in a module or something.. *)
let get_one_line file =
try Some (input_line file) with
End_of_file -> None
let get_lines file =
let rec input lines =
match get_one_line file with
Some line -> input (line :: lines)
| None -> List.rev lines
in input []
let read_file file =
let channel = open_in(file) in
get_lines channel
let explode s = (* convert a string to a list of chars *)
let rec exp i l =
if i < 0 then l else exp (i - 1) (s.[i] :: l) in
exp (String.length s - 1) [];;
let print_grid l =
print_newline ();
List.iter (fun line ->
List.iter (Printf.printf "%c") line;
Printf.printf "\n") l
let (<<) f g x = f(g(x))
(* --- *)
let get_value l (x, y) = (* if in bounds, Some of the value, else None *)
try let row = List.nth l x in
Some (List.nth row y)
with
| Failure _ -> None
| Invalid_argument _ -> None
let dirs = [(-1, -1); (-1, 0); (-1, 1); (0, -1); (0, 1); (1, -1); (1, 0); (1, 1)]
let get_neighbors (x, y) l = (* returns list of Options. None means off the grid *)
let coords = List.map (fun (dx, dy) -> (x + dx, y + dy)) dirs in
List.map (get_value l) coords
let rec walk (x, y) l (dx, dy) = (* walk from (x, y) in direction (dx, dy) until you hit something or fall off *)
let coord = (x + dx, y + dy) in
match get_value l coord with
| Some '.' -> walk coord l (dx, dy)
| a -> a
let get_far_neighbors (x, y) l = (* returns list of Options. None means off the grid *)
List.map (walk (x, y) l) dirs
let num_occupied = (* count the number of # in a List of char options *)
List.length << List.filter (function
| None -> false
| Some v -> Char.equal v '#')
let change_seat is_far (x, y) l = (* is_far is for the 2nd problem *)
let neighbors_fun = if is_far then get_far_neighbors else get_neighbors in
let max_neighbors = if is_far then 5 else 4 in
let neighbors = neighbors_fun (x, y) l in (* make a list of all neighbors, either near or far *)
match get_value l (x, y) with
| None -> '?' (* eh? *)
| Some 'L' -> if num_occupied neighbors = 0 then '#' else 'L'
| Some '#' -> if num_occupied neighbors >= max_neighbors then 'L' else '#'
| Some s -> s
let change_seats is_far l =
List.mapi (fun x ->
List.mapi (fun y _ ->
change_seat is_far (x, y) l
)
) l
let rec start is_far grid = (* keep changing seats until the grid stops changing *)
(* print_grid grid; *)
let grid' = change_seats is_far grid in
if grid = grid'
then grid'
else start is_far grid'
let () =
let grid = read_file "day11.txt" |> List.map explode in
start false grid (* false means near-neighbors *)
|> List.flatten
|> List.filter (Char.equal '#') |> List.length (* count occupied seats *)
|> Printf.printf "near-neighbor count %i\n";
start true grid
|> List.flatten
|> List.filter (Char.equal '#') |> List.length
|> Printf.printf "far-neighbor count %i\n";

97
day11.txt Normal file
View file

@ -0,0 +1,97 @@
LLLLLLLLLLLLLLLLLLLLLLLLL.LLLLL..LLLLLLLLLLLL.LLL..LLLLLLLLLLLLLL.LL.LLLLL.LLLLLLLLL.LLLLLLLLLLLLL
LLLLLLL.LLLLLLL.LLLLLLLLL.LLLLL.LLLL.LLLLLLLL.LLLLLLLLL.LLLL.LLLLLLLLLLLLLLLLLLLLLL..LLLLLLL..LLLL
LLLLLL.LLLLLLLLLLLLLLLLLL.LLLLL.LLLLLLLLL.LLL.LLLLLLLLLLLLLL.LLLLLLL..LLLLLLLLLLLLLLLLLLLLLL.LLLLL
LLLLLLL.LLLLLLLLLLLLLLLLLLLLLLL.LLLL.LLLLLLLLLLLLLLLLLLLL.LLLLLLLLLLLLLLL..LLLLLLLLL.LLLLLLL..LLLL
.LLL.LL.LLLLLLL.LLLLLLLLL.LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL.LLLLLLL.LLLLL.LLLLLLLLL.LLLLLLLLLLLLL
LL.LLLL.LLLLLLLLLLLLLLLLL.LLLLL.LLLL.LLLLLLLLLLLLL.LLL.LLLLLLLLLLLLL.LLLLLLLLLLLLLLL.LLLLLLL.LLLLL
......L........LLL....L.L......L.LL...L.....L.LL..L..L..L..LLL..LL......L...L.LL.L.L....L.........
LLLLLLL.LLLLLLL.LLLLLLLLL.LLLLLLLLLL.LLLLLLLLL.LLL.LLLLLLLLL.L.LLLLL.LLLLL.LLLLLLLLL.LLLLLLL.LLLLL
LLLLLLLLLLLLLLL.LLLLLLLLL.LLLLL.LLLL.LLLLLLLLLLLLLLLLLLLLLLL.LLLLLLL.LLLLL.LLLLLLLLLLLLLLLLL.LLLLL
LLLLLLL.LLLLLLL.LLLLLLLLL.LLLLL.LLLL.LLLLLLLL.LLLL.LLLLLL.LL.LLLLLLL.LLLLLLLLLLLLLLL.LLLLLLL.LLLLL
LLLLLLLLLLLLLLL.LLLLLLLLL.LLLLL.LLLL..LLLLLLL.LLLLLLLLLLLLLL.LLL.LLL..LLLL.LLLLLLLLL.LLLLLLL.LLLLL
LLLLLLL.LLL.LLLLLLL.LLLLL.LLLLL.LLLL.LLLLLLLL.LLLL.LLLLLLLLLLLL.LLLL.L.LLL.LLLLLLLLLLLLLLLLL.LLLLL
LLLLL.L.LLLLLLL.LLLLLL.LL.LLLLL.LLLL.LLLLLLLL.LLLL.LLLLLLLLL.L.L..LLLLLLL.LLLLLLLLLL.LLLLLLLLLLLLL
.L....LLLL.LL.LL..L.L.L.L.LL..L..L.LLLLLL.L.LLLL.L.L..LL...L..L..LLL.....L........LL.L..L..L..L..L
LLLLLLL.LLLLLLL.LLLLL.LLL.LLLLLLLLLL.LLLLL.LLLLLLL.LLLLLLLLLLLLLLLLLLLLLLL.LLLLLLLLL.LLLLLLLLLLLLL
LLLLLLLLLLLLLLLLLL.LLLLLLLLLLLL..LLLLLLLLLLLL.LLLL.LLLLLLLLL.LLLLLLL.LLLLLLLLLLLLLLLLLLLLLLL.LLLLL
LLLLLLL.LL.LLLL.LLLLLLLLLLLLLL.LLLLLLLL.LLLLLLLLLLLLLLLLLLLL.LLLLLLL.LLLLLLLLLLLLLLLLLLLLLLL.LLLLL
LLLLLLL.LLLLLLL.LLLLLLLLL.LLLLL.LLLLLLLLLLLLL.LLLLLLLLLLLLLLLLLLLLLL.LLLLL.LLLLLLLLL.LLLLLLL.LLL.L
LLLLLLLLLLLLLLL.LLLLLLLLL.LLLLLLLLLL.LLLLLLLLLLLLL.LLLLLLLLL.LLLLLLL.LLLLLLLL.LLLLLLLLLLL.LL.LLLLL
.....L..L...L.L.L..........L..LLLL....L..L.L..LLLL...L..L....L.LL.L....L.L.L....LL.L..L......LLL.L
LLLLLLL.LLLLLLL.LLLLLLLLLLLLLLLLLLLL.LLLLLLLLLLLLL.LLLLLLLLLLLLLLLLL.LLLLL.LL.LLLLLL.LL.LLLL.LLLLL
LLLLLLL.L.LLLLLLLLLL.LLLL.L.LLLLLLLLLLLLLLLLLLLLLL.LLLLLLLLL.LLLLLLLLL.LLLLLLLLLLLLL.LLLLLLLLLLLLL
LLLLLLL.LLLLLLL.LLLLLLLLL.LLLLL.LLLLLLLLLLLLL.LLLL.LLLLLLLLLLLLLLLLL.LLLLLLLLLLLL.LLLLLLLLLL.LLLLL
LLLLLLL.LLLLLLLLLLLLLLLLL.LLLLL.L.LL.LLLLLLLLLLLLL.LLLLLLLLL.LLLL.LLLLLLLLLLLLLLL.L..LLLLLLLLLLL.L
LLLLLLL.LLLLLLLLLLLLLLLLL.LLLLLLLLLL.LLLLLL.L.LLLL.L.LLLLLLLLLLLLLLL.LLLLLLLLLLLLL.L.LLLLLLLLLLLLL
LLLLLLLLLLLLLLL.LLLLLL.LL.LLLLL.LLLLLLLLLLLLLLLLLLLLLLLLLLLL.LLLLLLL.LLLLL.LLLLLLLLL.LLLLLLL.LLLLL
LLLLLLL.LL.LLLLLLLL.LLLLL.LLLLL.LLLL.LLLLLLLL.LLLLLLLLLLLLLL.LLLLLLL.LLLLL.LLLLLLL.L.LLLLLLL.LLLLL
L.LLLLL.LLLLLLL.LLLLLLLLL.LLLLL.LLLLLLLLLLLLL.LLLLLLLLLLLLLL.LLLLLLL.LLLLLLLLLLLLLLL.LLLLLLLLLLLLL
LLLLLLLLLLLLLLLLLLLLLLLLL.LLLLL.LLLLLLLLLLLLLLLLLL.LLLL.LLLL.LLLLLLL.LLLLLLLLLLLLLLLLLLLLLLLL.LLLL
..L...L...L......L.LLLL.....LLL.L.LLLLLL.L.L.L..L.L.......L.L..L...L.L.L....LL...L.LL......LL.L.L.
LLLLLLL.LLLLLLL.L.LLLLLLL.LLLLL.LLL.LLLLLLLLL.LLLLLLLLLLLLLL.LLLLLLL.LLLLL.LLLLLLLLL.LLLLLLL.LLLLL
LLLLLLL.LLLLLLL.LLLLLLLLLLLLLLL.LLLLLLLLLLLLL..LLL.LLLLLLLLLLLLLLLLL.LLLLL.LLLLLLLLL.LLLLLLL.LLLLL
LLLLLLL.LLLLLLLLLLLLLLLLL.LLLLL.LLLLLLLLLLLLLLLLLL.LLLLLLLLL.LLLLLLL.LLL.L.LLLLL.LLLLLLLLLLL.LLLLL
LLLLLLL.LLLLLLL.LL.LLLLLL..LLLL.LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL.LLLLL..LLLLLLLL.LLLL.LL.LLLLL
LL.LLLL.LLLLLLLLL.LLLLLLL.LLLLLLLLLLLLLLLLLLLLLLLL.L.LLLLL.LLLLLLLLLLLLLLLLLLLLLLL.L.LLLLLLL.LLLLL
LLLLLLL.LLLLLLL.LLLLLLLLL.LLLLL.LLLL.LLLLLLLL.LLLL.LLLLLL.LL.LLLLL.L.LLLLL.LLLLLLLLLLLLLLLLLLLLLLL
LLLLLLL.LLL.LLL.LLLLLLLLLLLLLLL.LLLL.LLLLLLLL.LLLLLLLLLLLL.LLLLLLLLLLLLLLL.LLLLLLLLL.LLLLLLL.LLLLL
L.L.......L.L....LL......LL.LL...LL..L...........L.....LLL....L..LL.LL.L.L.LL.......L.L...L....L..
LLLLLLL.LLLLLLLLLLLLLLLLL.LLLLL.LLLL.LLLLLLLLLLLLL.LLLLLLLLL.LLLLLLL.LL.LL.LLLLLLLLLLLLLLLLL.LLL.L
LLLLLLL.LLLLLLLLLLLLLLLLLLLLLLL.LLLL.LL.LLLLLLLLLL.LL.LLLLLL.LLLLLLLLLLLLL.LLLLLLLLLLLLLLLLLLLLLLL
LLLLLLL.LLLLLLL.LLLLLLLLL.LLLLL.LLLL..LLLLLLLLLLLL.LLLLLLLLLLLLLLLLL.L..LL.LLL.LLLLLLLLLLLLLLLLLLL
LLLLLLLLLL.LLLLLLLLLLLLLLLLLLLL.LLLL.LLLLLLLLLLLLL.LLLLLLLLLLLLLLLLLLLLLLL.LLLLLLLLL.LLLLLLL.LLLLL
LLLLLLLLLL.LLLL.LLLLLLL.LLL.LLLLLLLL.LLLLLLLLLLLLL.LLLLLLLLL.LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL.LLLLL
L.LLLLLLLLLLLLL.LL.LLLLLL.LLLLL.LLLL.LLLLLLLL.LLLLLLLLLLL.LL.LLLL.LLLLLLLLLL.LLLLLLL.LLLLLLL.LLLLL
...LL.L..LL...L.......L.LL.......LL.LLL.L.LLL...L..LLL.L...L.......LL.LL.LL.L..LL........L.......L
LLLLLLL.LLLLLLL.LLLLLLLLL.LLLLL.LLLL.LLLLLLLL.LLLLLLLLLLLLLL.LLLLLLL.LLLLL.LLLLLLLLLLLLLLLLL.LLLLL
LLLLLLL.LLLLLLL.LLLLLLLLLLLLLLL.LLLL.LLLLLLLL.LLLLLLLLL.LLLL.LLLLLLL.LLLLL.LLLLLLLLLLLLLLLLLLLLLLL
LLLLLLL.LLLLLLLLLLLLLLLLL.LLLLL.LLLLLLLLLLLLL.LLLL.LLLLLLLLL.LLLLL.L..LLLL.LLLLLLLLL.LLLL.LLLLLLLL
LLLLLLLLLLLLLLL.LLLLLLLLLLLLLLL.LLLL.LLLLLLLL.LLLL..LLLLLLLLLLLLLLL..LL.LL.L.LLL.LLL.LLLLLLL.LLLLL
LLLLL..LLLL.LLLLLLLLLLLLL.LLLLLLLL.L.LLLLLLLL.LLLL.LLLLLLLLL.L.LLL.LLLLLLL.LLLLLLLLL.LLLLLLLLLLLLL
LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL.LLLL.LLLLLLLL.LLLL.LLLLLLLLLLLLLLLLLLLLL.L.LLLLLLLLL.LLLLL.L.LLLLL
.LLLLLL.LLLLLLL..LLLLLLLL.LLLLLLLLLLLLLLLLLLL.LLLLLLLLLLLLLLLLLLLLLLLLLLLL.LLLLLLLLL.LLLLLLL.LLLLL
LLLLLLL.LLLLLLLLLLL.LLLLLLLLLLLLLLL.LLLLLLLLLLLLLLLLLLLLLLLL.LLLLLLL.LLLLLLLLLLLLLLLLLLLLLLL.LLLLL
..LL....L..........LL..L....L.LL...L.L...L.L...LLL..LL....LL.L.L.LLLL...L.L.......L.....LL........
LLLLLLL.LLLLLLL.LLLLLLLLLLLLLLLLLLLL.LLLLLLLL.LLLLLLLLLLLLLL.LLLLLLLLLLLLLLLLLLLLLLL.LLLLLLL.LL.L.
LLLLLLL.LLLL.LL.LLL.LLLLL.LLLLL.LLLL.LLLLLLL.LLLLL.LLLLLLLLLLLLLLLLL.LLLLLLLLLLLLLLL.LL.LLLLLLL.LL
LL.LLLLLLLLLL.LLLLLLLLLLL.LLLLL.LLLL.LLLLLLLL.LLLL.LLLLLLLLL.LLL.LLL.LLLLL.LLLLLLLLL.LLLLLLL.LLLLL
LLLLLLLLLLLLLLLL.LLLLLLLLLLLLLL.LLLL.LLLLLLLL.LLLLLLLLLLLLLL.LLLLLLL.LLLLL.LLLLLLLLL.LLLLLLL.LLLL.
LLLLLLLLLLLLLLL.LLLLLLLL.LLLLLL.LLLL.LLLLLLLLLLLLL.LLLLLLLLL.LLL.LLL.L.LLLLLLLLLLLLLLLLLLLLL.LLLLL
LLLLLLL.LLLLLLL.LLLLLLL.L.LLLLL.LLLL.LLLL.LLL.LLLLLLLLLL.LLLLLLLLLLL.LLLLL.LLLLLLLLL.LLLLLLL.LLL.L
LLLLLLL.LLLLLLL.LLLLLLLLLLLLLLL.LLLL.L.LLLLLLLLLLL.LLLLLLLLL.LL.LLLL.LLLLLLLLLLLLLLL.LLLLLLLLLLLLL
LLL.LLL.L.LLLLL.LLLLLLLLL.LLLLL.LLLL.LLLLLLLL.LLLL.LLLLLLL.L.LLLLLLLLL.LLL.LLLLLLLLLLLLLLLLLLLLLLL
..LLL.LL.....LL...LL..L..LLL...........LL...........L.....L.......L..LLLLL......L......LL..L...L.L
LLLLLLL.LLLLLLL.L.LLLLLLLLLL.LL.LLLL.LLLLLLLLLLLLL.LLLLLLL.L.LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL.LLLLL
LLLLLLLLLLLLLLL.LL..LL.LLLLLLLL.LLLL.LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL.LLLLL.LLLLLLLLL.LLL.LLL.LLLLL
LLLLLLL.LLLLLLL.LLLLLLLLL.LLLLL.LLLLLLLLLLLLL.LLLL.LLLLLLLLL.LLLLLLL..LLLL.LLLLLLLLLLLLLLLLLLLLLLL
LLLLLLLLLLLL.LLLLLLLLLLLLLLLLLL.LLLLLLLLLLLLL.LLLL.LLLLLLLLL.LLLLLLLLL.LLLLLLLLLLLLLLLLLLLLL.LLLLL
LLLLLLLLLLLLLLL.LLLLLLLLL.LLLLL.LLLLLLLLLLLLL.LLLLLLLLL.LLLL.LLLLLLL.LLLLLLLLLLLLLLL.LLLLLLLLLLLLL
LLLLLLL.LLLLLLL.LLLLLLLLL.LLLLL.LLLL.LL.LLLLL.LLLL.LLLLLLLLL.LLLLLL.LLLLLL.LLLLLLLLL.LLLLLLL.L.LLL
LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL.LLLLLLLL.LLL..LLLLLLLLL.LLLLLLL.LLLLL.LLLLLLLLL.LLLLLLL..LLLL
LLLLLLL.LLLLLLLLL.LLLLLLLLLLLLL.LLLL.LLLLLLLLLLLLL.LLLLLLLLL.LLLLLLLLLLLLL.LLLLLLL.LL.LLLLLLLLLLLL
LLLLLLLLLLLLLLL.LLLLLLLLLLLLLLL.LLLL.LLLLLLLL.LLLL.LLLLLLLLL.LLLLLLL.LLLL..LLLLLLLLLLLLLLLLL.LLLLL
.......L...LLL.L....L.LL......L.L...L...LL.LL...L...L..L.L.LL.........L.L..L.L.L.......L..L.....L.
LLLLLLLLLLLLLLL.LLLLLLLLL.LLLLLLLLLL.LLLLLLL..LLLLLLLLLLLLL..LLLLL.LLLLLLL.LLLLLLLLL.LLLLLLLLLLLLL
LLLLLLLLLLLLLLL.LLLLLLLLL.LLLLL.LLLL.LLLLLLLLLLLLL.LLLLLLLLL.LL.LLLLLLLLLL.LLLLLLLLLLLLLLLLL.LLLLL
LLLLLLL.LLLLLLL.LLLLLLLLLLLLLLLLLLLLLLLLLLLLL.LL.LLLLLLLLLLLLLLLLL.L.LLLLL.LLLLLLLLL.LLLLLLL.LLLLL
LLLLLLL.LLLLLLL.LLLLLLLLL.LLLLL.LLLLLLLLLLLLLLLLLL.LLLLL.LLL.LLLLLLLLLLLLL.L.LLLLLLL.LLLLLLLLLLLLL
LLLLLLL.LLL.LLL.LLLLLLLLL.LLLLL.LLLLLLLLLLLLL.LLLL.LLLLLLLLL.LLLLLLL.LLLLL.LLLLLLLLLLLLLLLLL.LLLLL
LLLLLL..LL.LLLLL.LLLLLLLL.L.LLL.LLLL.LLLLLLLLLLLLLLLL..LLLLL.LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL
.LLLL.L.LLLLLLL.LLLLLLLLL.LLLLLLLLLL..LLL.LLL.LLLL.LLLLLLLLL.LLLL.LL.LLLLL.LLLLLLLLL.LLLLLLL..L.LL
LLLLLLL.LLLLLLLLLLLLLLLLLLLLLLLLLLL..LL.LLLLLLLLLL.LL.LLLLLL.LLLLL.L.LLLLL.LLLLLL..LLLLLLLLL.LLLLL
..L...L..L..L.L..LL.L.LLL.LLL.L....L..LL.....L....LL...L.L.L.L...L.L.....LLL......L...LL.L.......L
LLLLLLLLLLLLLLL.LLLLLLLLL.LLLL.LLLLL.LLLLLLL.LLLLL..LLLLLLLLLLL.L.LL.LLLLLLLLLLLL.LL.LLL.LLL.LLLLL
LLLLLLL.LLLLLL..LLLLLLLLL.LLLLLLLLLL.LLLLLLLL.LLLL.LLLLLLLLL.LLLLLLL.LLLLLLLLLLLLLLL.LLLLLLL.LLLLL
LLLLLLL..LLLLLL.LLLLLLLLLLLLLLL.LLLL.LLLLLLLL.LLLL.LLLLLLLLL.LLLLLLL.LLLLL.LLLLLLLLLLLLLLLLLLLLLLL
LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL.LLLL.LLLLLLLL.LLLL.LLLLLLLLLL.LLLLLL.LLLLLLLLLLLLLLL.LLLLLLL.L.LLL
LLLLLLL.LLLLLLLLLLLLLLLLL.LLLLL.LLLL.LLLLLLLL.LLLL.LLLLLLLLLLLLLLLLL.LLLLLLLLLLLLLLL.LLLL.LL.LLLLL
..L..LL.L.L...LL...L.LL.LL....L.L.L.LLL...LL.LL...L...L...LLLLLL.LLL...L.L.LL................LL.L.
LLLLLLLLLLL.LLL.LLLLLLLLL.LLLLL.LLLLLLLLLLLLL.LLL.LLLLLLLLLL.LLLLLLL.LLLLLLLLLL.LLLL.LLLLLLLLLLLLL
LLLLLLL.LLLLLLLLLLLLLLLLL.LLLLLLLLLL.LLLLLLLLLLLLL.LLLLLLLLL.LLLLLLL.LLLLL.LLLLLLLLL.LLLLLLLLLLLLL
LLLLLLL.LLLLL.L.LLL.LLLLLLLLLLLLLLLLLLLL.LLLLLLLLL.LLLLLLLLL.LLL.LLL.LLLLL.LLLLLLLLLLLLLLLLLLLLLLL
LLLLLLL.LLLLLLL.LLLLLLLLL.L.LLL.LL.LLLLLLLL.L.LLLL.LLLLLLLLL.LLLLLLLLLLLLLLLLLLLLLLL.LLLLLLLLLLLLL
.LL.LLL.LLLLLLL.LLLLLLLLL.LLLLL.LLLLLLLLLLLLL.LLLL.LLLLLLLLL.LLLLLLLLLLL.L.LLLLLLLLLLLLLLLLL.LLLLL
LLLLLLL.LLLLLLLLLLLLLLLLL.LLLLLLLLLL.LLLLLLLL.LL.LLLL.LLLLLL.LLLLLLLLLLLLLLLLLLLLLLL.LLLLLLLLLLLLL
LLLL.LL.LLLLLLL.LLLLLLLLL.LLLLL.LLLLLLLLLLLLLLLLLL.LLLLLLLLLLLLLLLLL.LLLLLLLLLLLLLLL.LLLLLLL.LLLLL
LLLLLLLLLLLLLLLLLLLLLLLLL.LLLLL.LL.LLLLLLLLLL.LLLL.LLLLLLLLL.LLLLLLL.LLLLL.LLLLLLL.LLLLLLLLL.LLLLL
LLLLLLL.LLLLLLL..LLLLLLLLLLLLLLLLLLL.LLLLLLLLLLLLL.LLLLLLLLL.LL.LLLL.LLLLL.LLLLLLLLL.LLLLLLL.LLLLL

91
day12.1.ml Normal file
View file

@ -0,0 +1,91 @@
(* Common util. Should probably put this in a module or something.. *)
let get_one_line file =
try Some (input_line file) with
End_of_file -> None
let get_lines file =
let rec input lines =
match get_one_line file with
Some line -> input (line :: lines)
| None -> List.rev lines
in input []
let read_file file =
let channel = open_in(file) in
get_lines channel
let explode s = (* convert a string to a list of chars *)
let rec exp i l =
if i < 0 then l else exp (i - 1) (s.[i] :: l) in
exp (String.length s - 1) [];;
let implode l = String.of_seq (List.to_seq l)
let (<<) f g x = f(g(x))
let (>>) f g x = g(f(x))
let rec find_idx x = function (* find index of x *)
| [] -> raise (Failure "Not Found")
| h :: t -> if x = h then 0 else 1 + find_idx x t
let abs x = if x < 0 then -x else x
(* --- *)
(*
type dir = North | Eath | South | West
let string_of_dir = function | North -> 'N' | Eeast -> 'E' | South -> 'S' | West -> 'W'
type action = N | E | S | W | L | R | F
let action_of_char = function | 'N' -> N | 'E' -> E | 'S' -> S | 'W' -> W | 'L' -> L | 'R' -> R | 'F' -> F
type position = int * int
type bearing = { position: position; heading: char }
(* nah fuck all that *)
*)
type instruction = { action: char; value: int }
let dirs = [('N', (0, 1)); ('E', (1, 0)); ('S', (0, -1)); ('W', (-1, 0))]
let dir_list = ['N'; 'E'; 'S'; 'W']
let parse_line = (* from string to instruction *)
explode >> function | action :: value -> { action; value = int_of_string @@ implode value }
let rec turn direction heading = function (* returns new heading, matching on degrees *)
| 0 -> heading (* doing this 90 degrees at a time *)
| d -> (* rotate through our dir_list *)
let old_idx = find_idx heading dir_list in
let idx_dx = match direction with | 'L' -> -1 | 'R' -> 1 in
let new_idx = (old_idx + 4 + idx_dx) mod 4 in (* if we fall off the dir_list in either way, wrap around with mod *)
let new_heading = List.nth dir_list new_idx in
(* Printf.printf "turning! old_idx %i idx_dx %i new_idx %i new_heading %c" old_idx idx_dx new_idx new_heading; *)
turn direction new_heading (d - 90)
let move { action; value } (x, y) heading = (* returns (new location, new heading) *)
Printf.printf "@ (%i, %i) facing %c. moving %c %i\n" x y heading action value;
match action with
| 'L' -> ((x, y), turn 'L' heading value)
| 'R' -> ((x, y), turn 'R' heading value)
| 'F' ->
let (dx, dy) = List.assoc heading dirs in
((x + (dx * value), y + (dy * value)), heading)
| dir -> (* Either N, E, S, or W. Find the (dx, dy) and apply it *)
let (dx, dy) = List.assoc dir dirs in
((x + (dx * value), y + (dy * value)), heading)
let rec travel (x, y) heading map =
match map with
| [] -> (x, y)
| line :: rest ->
let (new_position, new_heading) = move line (x, y) heading in
travel new_position new_heading rest
let manhattan (x, y) = (abs x) + abs y
let () =
let map = read_file "day12.txt" |> List.map parse_line in
let (x, y) = map |> travel (0, 0) 'E' in
Printf.printf "ending location (%i, %i). manhattan distance: %i\n" x y (manhattan (x, y));

74
day12.2.ml Normal file
View file

@ -0,0 +1,74 @@
(* Common util. Should probably put this in a module or something.. *)
let get_one_line file =
try Some (input_line file) with
End_of_file -> None
let get_lines file =
let rec input lines =
match get_one_line file with
Some line -> input (line :: lines)
| None -> List.rev lines
in input []
let read_file file =
let channel = open_in(file) in
get_lines channel
let explode s = (* convert a string to a list of chars *)
let rec exp i l =
if i < 0 then l else exp (i - 1) (s.[i] :: l) in
exp (String.length s - 1) [];;
let implode l = String.of_seq (List.to_seq l)
let (<<) f g x = f(g(x))
let (>>) f g x = g(f(x))
let rec find_idx x = function (* find index of x *)
| [] -> raise (Failure "Not Found")
| h :: t -> if x = h then 0 else 1 + find_idx x t
let abs x = if x < 0 then -x else x
(* --- *)
type instruction = { action: char; value: int }
let dirs = [('N', (0, 1)); ('E', (1, 0)); ('S', (0, -1)); ('W', (-1, 0))]
let dir_list = ['N'; 'E'; 'S'; 'W']
let parse_line = (* from string to instruction *)
explode >> function | action :: value -> { action; value = int_of_string @@ implode value }
let rec turn direction (wx, wy) = function (* returns new waypoint location *)
| 0 -> (wx, wy) (* doing this 90 degrees at a time *)
| degrees ->
let new_position = match direction with
| 'L' -> (-1 * wy, wx)
| 'R' -> (wy, -1 * wx)
in turn direction new_position (degrees - 90)
let move { action; value } (x, y) (wx, wy) = (* returns (new ship location, new waypoint location) *)
Printf.printf "@ (%i, %i). moving %c %i\n" x y action value;
match action with
| 'L' -> ((x, y), turn 'L' (wx, wy) value)
| 'R' -> ((x, y), turn 'R' (wx, wy) value)
| 'F' -> ((x + (wx * value), y + (wy * value)), (wx, wy))
| dir -> (* Either N, E, S, or W. Find the (dx, dy) and apply it *)
let (dx, dy) = List.assoc dir dirs in
((x, y), (wx + (dx * value), wy + (dy * value)))
let rec travel (x, y) (wx, wy) map =
match map with
| [] -> (x, y)
| line :: rest ->
let (new_position, waypoint_position) = move line (x, y) (wx, wy) in
travel new_position waypoint_position rest
let manhattan (x, y) = (abs x) + abs y
let () =
let map = read_file "day12.txt" |> List.map parse_line in
let (x, y) = map |> travel (0, 0) (10, 1) in
Printf.printf "ending location (%i, %i). manhattan distance: %i\n" x y (manhattan (x, y));

760
day12.txt Normal file
View file

@ -0,0 +1,760 @@
F35
L90
S5
F4
R90
F46
W3
N1
L90
F13
S5
E5
R180
S1
F39
N2
R90
S1
F94
R90
F55
L90
S2
R90
W3
S5
E3
R180
S4
L90
F40
N5
W5
N3
F88
L90
W3
F12
W1
N1
F65
L90
E1
N1
L270
E3
F67
R90
R180
N3
W5
N4
R90
F48
R180
F50
E3
S4
F50
N4
L90
N5
F26
L90
F21
N5
L90
R90
F13
R90
S2
E4
F33
N5
R90
F78
L180
N3
E5
N4
L180
N3
F12
E4
L90
N2
F32
L270
F13
L90
S5
F100
N4
W4
L270
N1
L90
E5
F30
W3
S3
E4
F38
E3
E2
L90
N1
L180
F89
E1
R90
F51
R90
F12
E5
L90
S3
E3
S3
L180
F66
L180
N3
F26
W4
E2
N4
F90
S4
R90
W4
F79
R90
F38
W3
F10
R90
W1
L180
F34
E5
N4
F30
S4
W1
L180
N2
W1
F76
S5
L270
N5
W1
L90
F4
N1
R90
F86
N1
L90
N1
F75
S4
F85
N3
L270
N5
F85
S4
F84
R180
W2
F10
R90
F72
L90
F90
W4
L90
F94
R90
E4
R90
S2
L90
W3
F89
W3
S2
R90
E1
S1
E5
N1
F77
L90
N2
F52
S1
W1
N5
R90
S2
L90
F97
N1
F54
L90
F3
S2
W5
F71
W2
F86
E5
N1
F32
R270
F1
E4
F18
R180
R90
E1
S5
S3
W2
F75
W4
N1
F3
E1
F46
R90
N4
W5
L90
F76
W2
F62
N2
F29
E2
N4
F60
L90
N2
L90
F31
R270
F97
S4
F75
L90
S4
F51
L90
W5
L90
F53
R270
N1
L90
E3
R90
W1
F44
N1
F97
R90
N2
W4
F27
L90
F91
E1
S5
R180
W5
N2
L90
E2
N5
F34
F26
R90
N2
E4
S5
F58
W1
F3
N5
E3
S2
W4
N2
W5
F19
L180
W4
F68
L90
N5
R90
F65
S4
R180
S4
L90
F59
R90
E3
R90
F44
L90
E5
F19
W5
N4
F10
N4
L90
S4
L90
W3
F75
R180
E5
F97
E3
F63
S3
F53
W2
F53
N1
L90
F14
S3
E5
L90
N5
F28
L90
F3
L90
S2
F52
S2
F99
S5
W2
L90
S1
W5
L90
S1
F11
R90
W4
R90
F11
N3
W3
N5
F39
W1
F50
N2
L90
W4
F88
S5
W4
R270
W4
F55
R90
E3
R180
S1
E3
F100
E3
F38
N3
F28
E5
R90
F94
R180
F95
R90
W4
R180
F40
N4
R90
S5
F69
E2
F2
N5
W2
F16
S2
F71
W2
N3
L90
F36
W1
F90
N5
R90
F93
E2
F23
N1
L90
F22
R90
L90
N4
L180
F7
L90
W2
F29
N2
L90
E4
R90
N5
F13
R180
F87
L90
S1
L90
E2
R90
F19
S4
F100
L270
W1
L180
F87
N1
F100
R90
S3
L90
W1
N1
L90
W2
F98
L180
S1
W4
S5
F45
S4
L90
E1
S4
F31
E1
S1
E2
R90
S5
L90
F12
R180
W1
L90
N1
L90
F23
E4
S2
L90
E5
S4
F21
N3
R90
W4
E5
F32
S1
E2
L90
F45
L90
W3
L180
F100
S5
F88
S5
F29
E1
L180
F12
S5
F52
N2
F31
R90
E1
L90
F64
W3
L90
N1
R90
F60
E2
F4
S1
F97
F62
L180
F66
R90
E1
S5
R90
S3
F96
W1
N2
F95
R90
E3
R90
E2
S2
E4
F42
S4
E4
L90
E1
F73
L90
N3
L90
F82
S3
R270
S5
W1
R90
W2
S1
S3
L90
F74
S3
F13
R180
F32
E2
S2
F93
N1
R270
F4
E5
F63
W2
L180
F26
E3
N5
R90
N3
L270
F22
N1
W5
F29
S5
R90
S1
F3
N4
R90
E3
R90
N2
L90
N3
F42
W4
F37
L90
F15
W3
N5
F25
E2
F33
E2
S1
L90
F55
E4
L90
W1
N1
F30
E2
R90
E2
F80
L90
W2
S1
F9
L270
W2
F82
L90
F94
N5
F16
W5
F74
R180
N3
F58
W5
F95
R270
S4
F55
L90
N1
L180
F85
N2
R90
E1
L90
F57
S2
L90
F31
L180
S3
L90
F58
N3
L270
N3
R270
F15
L180
N4
L90
N5
R180
E1
S4
F11
L90
E5
N4
E3
L90
E4
F71
R90
S2
E3
L90
S3
F90
W4
F8
R180
N3
W4
S4
F58
N4
E1
L180
S4
W1
R180
F47
S1
L90
R90
N1
E1
N4
R180
N2
E1
R90
E3
L90
F67
N3
F51
N1
F41
L180
R90
F5
E2
S5
W1
F51
R180
N1
E1
F91
R90
N2
L90
F66
L90
S3
L90
F52
E2
S1
F66
R180
F18
W5
L90
W1
F88
S1
R180
F92
L90
S5
F19
L90
E3
S3
E3
N5
W3
F8
E2
S4
F3

7
day13.txt Normal file
View file

@ -0,0 +1,7 @@
1009310
19,x,x,x,x,x,x,x,x,x,x,x,x,37,x,x,x,x,x,599,x,29,x,x,x,x,x,x,x,x,x,x,x,x,x,x,17,x,x,x,x,x,23,x,x,x,x,x,x,x,761,x,x,x,x,x,x,x,x,x,41,x,x,13
7,13,x,x,59,x,31,19
67,7,x,59,61
1789,37,47,1889
100000000000000

119
day14.ml Normal file
View file

@ -0,0 +1,119 @@
(* Common util. Should probably put this in a module or something.. *)
let get_one_line file =
try Some (input_line file) with
End_of_file -> None
let get_lines file =
let rec input lines =
match get_one_line file with
Some line -> input (line :: lines)
| None -> List.rev lines
in input []
let read_file file =
let channel = open_in(file) in
get_lines channel
let explode s = (* convert a string to a list of chars *)
let rec exp i l =
if i < 0 then l else exp (i - 1) (s.[i] :: l) in
exp (String.length s - 1) [];;
let implode l = String.of_seq (List.to_seq l)
let (<<) f g x = f(g(x))
let (>>) f g x = g(f(x))
let abs x = if x < 0 then -x else x
(* --- *)
type instruction = Mask of string | Mem of int * int (* Mem (addr, value) *)
let parse_instruction : string -> instruction =
String.split_on_char '='
>> List.map String.trim
>> fun [left; right] ->
if left = "mask"
then Mask right
else
let len = String.length left in
let addr = String.sub left 4 (len - 5) in
Mem (int_of_string addr, int_of_string right)
let rec pow a = function
| 0 -> 1
| 1 -> a
| n ->
let b = pow a (n / 2) in
b * b * (if n mod 2 = 0 then 1 else a)
let bin2dec =
List.rev
>> List.mapi (fun i d -> if d = 1 then pow 2 i else 0)
>> List.fold_left (+) 0
let int_of_char = String.make 1 >> int_of_string
let run_mask mask num = (* 'and' the 0s and 'or' the 1s *)
let l = explode mask in
let ones = List.map (fun c -> if c = '1' then '1' else '0') l (* copy the mask but just the ones *)
|> List.map int_of_char |> bin2dec in (* convert from char list to int list to decimal int *)
let zeros = List.map (fun c -> if c = '0' then '1' else '0') l (* same for zeros but make all the zeros 1s *)
|> List.map int_of_char |> bin2dec in
(num lor ones) - (num land zeros) (* subtract! *)
let change_bit number position new_value =
let mask = 1 lsl position in
(number land (lnot mask)) lor ((new_value lsl position) land mask)
let rec find_addrs mask addr = (* return a list of all addresses after applying mask with floaty bit *)
let mask' = List.rev @@ explode mask in
Printf.printf "\nnew mask! %s\n" mask;
let rec go addr' idx =
if idx = List.length mask'
then [addr']
else
let cur = List.nth mask' idx in
if cur = '0'
then go addr' (idx + 1)
else
if cur = '1'
then go (change_bit addr' idx 1) (idx + 1)
else (* X *)
let addr0 = (change_bit addr' idx 0) in
let addr1 = (change_bit addr' idx 1) in
List.concat [go addr0 (idx + 1); go addr1 (idx + 1)]
in go addr 0
let hash = Hashtbl.create 1000
let hash' = Hashtbl.create 1000
let rec walk mask = function
| [] -> ()
| x :: xs ->
match x with
| Mask m -> walk m xs (* update the mask and recurse *)
| Mem (addr, value) ->
(* problem 1 *)
run_mask mask value
|> Hashtbl.replace hash addr;
(* problem 2 *)
find_addrs mask addr
|> List.iter (fun addr' -> Hashtbl.replace hash' addr' value;);
walk mask xs (* recurse *)
let () =
let lines = read_file "day14.txt" |> List.map parse_instruction in
walk "" lines;
let sum = Hashtbl.fold (fun k v acc -> acc + v) hash 0 in
Printf.printf "sum: %i\n" sum;
let sum' = Hashtbl.fold (fun k v acc -> acc + v) hash' 0 in
Printf.printf "sum': %i\n" sum';

586
day14.txt Normal file
View file

@ -0,0 +1,586 @@
mask = X1011100000X111X01001000001110X00000
mem[4616] = 8311689
mem[8936] = 240
mem[58007] = 369724
mask = 10X0111X01X0XX110X10100X1001X000010X
mem[41137] = 232605
mem[33757] = 1437435
mask = X0011110100X011X01000X1000X1000X0100
mem[12518] = 27521105
mem[25203] = 3177
mem[33089] = 636515
mem[39100] = 494341
mem[59321] = 16252
mem[55061] = 1075
mask = 1000X11X01X0X01111XX10110001X1110111
mem[16129] = 15646
mem[35714] = 30634
mem[14485] = 6847
mask = 10011110110000X10X0X1010XX1010100X00
mem[2308] = 704945037
mem[41472] = 19000
mem[34542] = 334200
mask = 11011X00X000001X0X00XX000011X001000X
mem[49552] = 397346
mem[52482] = 244619
mem[40387] = 339372
mem[24387] = 1184014
mask = 1000101XXXX100X1X1X10001X01000111101
mem[42901] = 58252697
mem[3604] = 2970
mem[38806] = 78120216
mask = 1XX01X1111000010011101001X1110XXXX11
mem[16713] = 3710
mem[47208] = 490
mem[2864] = 835240
mem[30001] = 92649470
mask = 1X1101XX0XX1X011010X1000100011010X01
mem[12306] = 9094
mem[50276] = 737
mem[44950] = 312069
mask = 100X11101X00001X010X11XX00011010011X
mem[9068] = 2331
mem[34800] = 29860461
mem[18114] = 4912
mem[38010] = 2912
mem[59634] = 2460
mem[18826] = 3632988
mem[24839] = 87354329
mask = 0100X1101X01001101010X11000XX01000X0
mem[45994] = 1032
mem[15104] = 353
mem[43012] = 3302
mem[3101] = 3195
mem[58848] = 504541
mem[48036] = 3990
mask = 101011111100X010010X0X0X110111X10110
mem[55860] = 425881800
mem[49212] = 127188344
mem[16320] = 45285651
mask = 10X01110010X000X11000001000X0010X100
mem[10403] = 4668
mem[64] = 79964
mem[52226] = 263
mask = 1001X110110X0011010110001X01X0X01100
mem[13086] = 15318901
mem[14412] = 75226298
mask = XX0011XX010000X11100000100010X1X0100
mem[23984] = 1042686
mem[43191] = 960403
mem[304] = 17453
mem[43446] = 312310
mem[3612] = 7039
mem[24387] = 1076710
mem[35072] = 35503
mask = 10001X10110X0XXX01010101X00110000X0X
mem[40240] = 74221428
mem[19881] = 1055
mem[61105] = 2705392
mem[36207] = 117170
mem[34315] = 1069384
mem[24067] = 9021444
mask = 100X1X1111000001X0010XX11X01101001X0
mem[33794] = 809
mem[62607] = 265070
mem[59634] = 49282
mem[61442] = 364
mem[37003] = 628813
mem[7946] = 644992
mask = 1101X1000X0X001111X00111000100101001
mem[31631] = 5264178
mem[54754] = 1554399
mem[23468] = 4729
mask = 000111XX10X0001101X0X1001010X1XXX110
mem[50043] = 4139464
mem[49775] = 61509506
mem[53862] = 156448
mem[13334] = 87
mem[18854] = 9282
mem[34330] = 30468246
mask = 00011110100X00X1X1X000X11001101001X0
mem[31487] = 906990
mem[52518] = 305801
mem[49859] = 295219
mem[31776] = 1816407
mem[1947] = 7357561
mem[46508] = 4130
mem[17050] = 30862
mask = 10001110110X000X0X01X10X00111000101X
mem[9293] = 1384
mem[38283] = 2143609
mem[34969] = 5179
mem[63542] = 11640
mem[27523] = 1345
mask = 100111X0000000X1X10000100010100000X0
mem[10736] = 216826655
mem[45201] = 17886838
mem[10901] = 638
mem[32804] = 195074
mask = 1101X1X0XX00111101X0000111111X110001
mem[39181] = 416963
mem[9249] = 23378
mem[31817] = 28320828
mem[2935] = 456520
mem[13116] = 502217
mem[43105] = 1629110
mask = 1XXX111X1100X01X010110001X01101X1100
mem[50732] = 3451
mem[15501] = 841008
mem[17518] = 59713011
mem[20719] = 597200
mem[304] = 4690251
mem[54185] = 1478
mem[64845] = 15752175
mask = 110111000000X0X00X001X111000X1100010
mem[8552] = 30412318
mem[13116] = 1108685
mem[6392] = 779855579
mem[37617] = 3473324
mem[51729] = 51848
mem[57424] = 23802
mem[15479] = 17
mask = X00111101XX001111010011110X001000X01
mem[25195] = 129734
mem[11914] = 2701
mem[2864] = 25833
mask = 1001111X11X10XXX0X00101010110X00X001
mem[41424] = 106207900
mem[48133] = 43924223
mem[49702] = 179742
mask = 10011X111101000X00XX1X0X101110001001
mem[34101] = 640437195
mem[41745] = 203723
mask = 110111X011011011X100101X10100100000X
mem[348] = 627305
mem[12497] = 7501
mem[805] = 3988
mem[60636] = 184971943
mask = 100111001000001X0100X10011X00001XXX0
mem[50944] = 202043
mem[34140] = 15663180
mem[2200] = 1479
mem[27465] = 82898391
mask = 000X11111X10001101X00X01101X0001011X
mem[37944] = 6895727
mem[61573] = 409349871
mem[50342] = 61513
mem[13583] = 22407
mem[59968] = 102419
mem[2136] = 114207754
mem[30421] = 997
mask = 100111101X0X0011010X1XX01XX1X010010X
mem[13083] = 207
mem[10383] = 31056
mem[59321] = 402034
mem[22966] = 20228
mem[23372] = 779
mem[25895] = 1614
mem[11288] = 3047
mask = 1101110000000001XX0X111X1001XXX1110X
mem[31200] = 6875882
mem[26216] = 947
mem[5932] = 72207364
mem[64126] = 1260
mem[24890] = 3898
mem[61396] = 2240803
mask = 10001X101X0XX0110X01010011011X001110
mem[27866] = 740
mem[19123] = 32418
mem[23286] = 13542
mem[50342] = 34812801
mem[19362] = 12615968
mem[23756] = 107442819
mask = 100X111X1100X11X0X0X000X1X1001110110
mem[2772] = 3055
mem[8755] = 581
mem[60512] = 906058
mem[22390] = 3925820
mem[15876] = 280704
mem[40784] = 1550
mask = X000101X1100001011X10001000110010X00
mem[182] = 466813
mem[15844] = 21827
mem[4813] = 19124
mem[49362] = 2261
mask = 11011X00110X1X10010X0X110111101010XX
mem[37402] = 839
mem[35835] = 3289
mem[21867] = 10856
mem[32498] = 1600115
mem[35408] = 547736
mask = 1111110000010X1X11X00100X0X110101X01
mem[1140] = 1767723
mem[18180] = 11108349
mem[19129] = 115
mem[7955] = 103275871
mask = 1000101X1X00000X0XX1100001X11X1100X0
mem[39668] = 7209001
mem[57657] = 873105
mem[21665] = 441551
mem[20895] = 390
mem[42377] = 98696816
mem[38513] = 18489
mask = 1001101X110X000XX001110X10011X10110X
mem[63570] = 15065690
mem[3660] = 49298
mem[27417] = 427585
mem[37005] = 58080842
mem[21145] = 45587769
mem[59405] = 235561467
mask = 1XX100000000X001010X0001010X00010010
mem[61696] = 13179282
mem[60388] = 14504403
mem[54528] = 139910709
mem[10543] = 2877271
mem[44950] = 1250
mask = 100111100X000111110000X0000X00X001X1
mem[34901] = 4089
mem[7491] = 4875619
mem[30899] = 358791983
mem[63542] = 48357
mem[55865] = 289
mask = XX0X1110100100X10100010010XX00100100
mem[1939] = 9240
mem[13700] = 884
mem[56638] = 5690182
mem[38174] = 2173
mem[52518] = 54887
mask = 1X001X111100X0X10X01XX001X11101X1100
mem[13834] = 15183481
mem[65481] = 29968
mem[23863] = 467501
mem[19360] = 167115
mem[7268] = 8208487
mem[14485] = 158
mask = 100111101100001XX1011000001X0X100000
mem[8868] = 484089989
mem[53350] = 4089002
mem[57545] = 6025444
mem[28491] = 45516050
mask = 1000111XX10000X00111X101X0X010101XXX
mem[39822] = 451680949
mem[57061] = 370534242
mask = 10001X10110X0010X111XX0100X11010X11X
mem[16975] = 239223476
mem[21172] = 15004
mem[14883] = 71129165
mask = 10X0X1111100X0100111010101X110000110
mem[20805] = 1015445496
mem[14229] = 217524
mem[40036] = 2501
mem[41119] = 17208160
mem[56826] = 349928
mem[57555] = 884
mask = 000X11101000001101XX1000000000100X00
mem[35523] = 32624
mem[36012] = 9499537
mem[38756] = 421
mem[14024] = 190459520
mem[13308] = 1286846
mem[37150] = 4205580
mask = 1X01111011000X1X0100100X011001110100
mem[40710] = 2279
mem[34963] = 2267645
mem[12759] = 643
mem[17704] = 5597582
mem[30411] = 351996998
mem[16505] = 272444
mask = 10X111101X010X1X0X0010011001000X0110
mem[39356] = 22255
mem[48815] = 1638
mem[34690] = 420690
mem[16320] = 104253
mem[53422] = 477
mask = 100011X0XX01XX10111111010X0010011111
mem[54065] = 24449
mem[10993] = 12705817
mem[47121] = 284443
mem[36383] = 512188
mem[18814] = 159439379
mem[17770] = 99104
mask = 110111000X000X010101X11X101X00000X11
mem[51615] = 735360
mem[62469] = 15939
mask = 100X1110XX000X11X100100X00000X00X10X
mem[14772] = 38635
mem[29236] = 13420
mem[62613] = 47790
mem[39212] = 167702
mem[8936] = 106407539
mem[38934] = 332
mask = 0X00111010010011X10X0X0XX001X010000X
mem[63621] = 996
mem[56538] = 52673058
mem[37764] = 995346
mem[32132] = 103636989
mem[15733] = 13086
mem[44188] = 194198
mask = 0101010010000011X11010011X1X0X101X01
mem[46447] = 784
mem[13324] = 3401
mem[22200] = 165702
mem[7955] = 649
mem[15844] = 2690647
mem[64010] = 1096
mask = 11X1X1X001X11X11010XX01000X011010010
mem[24806] = 1221
mem[53291] = 1348383
mem[55875] = 25945782
mem[4492] = 1904
mem[59333] = 2401690
mem[47121] = 1839078
mask = 10011110X10100X1X10X0010110010110110
mem[40541] = 11787096
mem[62086] = 2967
mem[28799] = 4008988
mem[64917] = 268674
mem[18114] = 2655847
mem[45757] = 57333538
mem[44645] = 644597
mask = X000111000000X1111XX10X1000X0111X100
mem[10448] = 1060
mem[31631] = 77787880
mem[42148] = 6070584
mem[57082] = 485245396
mem[52482] = 21478
mask = 100XX11011000X11010X0010X00X10X0110X
mem[2017] = 14320
mem[3101] = 714880
mem[33316] = 105398
mem[28361] = 127078137
mem[23616] = 10309
mem[16594] = 13326311
mask = X001111001X0XX1101X01011X0110X1X1100
mem[43153] = 29487947
mem[46646] = 3335247
mem[17123] = 27270587
mem[5225] = 16921674
mem[30789] = 418871729
mask = 110X011010001111011000X111011XXX0100
mem[10985] = 214477
mem[13116] = 27310
mem[5115] = 1416
mem[12596] = 453023
mem[11737] = 24916
mem[14311] = 6470
mem[10361] = 300
mask = 000X11XX100000110110111110100X1101XX
mem[22040] = 1941817
mem[38002] = 7734399
mem[48736] = 31798852
mem[47426] = 204659941
mem[11288] = 15341
mask = 10X10X000001001X1100X010X011100X1001
mem[42377] = 129247876
mem[27828] = 50890049
mask = 10001110010000X1110010101011X101X01X
mem[57528] = 3471
mem[23114] = 96086679
mem[8446] = 38698
mem[14844] = 792092
mem[42506] = 31779
mem[64009] = 10029
mem[42731] = 172808
mask = 1101XX000000X0X1010010000001000X00XX
mem[426] = 11039
mem[23258] = 556641472
mem[51919] = 15137974
mem[21761] = 530
mem[21377] = 850024656
mem[59501] = 531065557
mask = 10001X10010X0X1101X00010100X1011X001
mem[43269] = 9515743
mem[426] = 5602
mem[2308] = 381075
mem[57933] = 56242190
mem[48133] = 597263
mask = 10X111X010X10011X1011000100100111100
mem[53350] = 383807
mem[37410] = 1044
mem[62086] = 14451
mask = X001111010XXX01101001001XX1001101000
mem[12756] = 551
mem[1027] = 656489115
mem[60702] = 336416
mem[42396] = 60622
mem[3436] = 1377859
mem[17518] = 1451
mask = 10011110100X00110100100X000XX00001XX
mem[42037] = 79130078
mem[34850] = 3303
mask = XX011X1010010011010110000X0100100X1X
mem[30581] = 949124
mem[18437] = 1990679
mem[2340] = 174075070
mem[46975] = 5827
mem[9421] = 107926
mem[28836] = 6636869
mask = 1X01X100X00X001XX1000X0X000110X00001
mem[53904] = 2238757
mem[22157] = 13388
mem[59321] = 31451373
mem[31277] = 110705865
mask = 100X1111X100001101X1X11100X010101101
mem[64929] = 5596232
mem[42822] = 12360220
mem[49391] = 650
mem[527] = 1337719
mem[56173] = 44948559
mem[64845] = 51705729
mask = 100X11X0X10X0XX101000000101X0010X11X
mem[63581] = 62572875
mem[52795] = 23120259
mem[38228] = 737964538
mem[45105] = 480
mem[33059] = 273619504
mem[60636] = 73
mask = 1X0111X01100001101001X00X00000100110
mem[2592] = 114883
mem[61691] = 2066
mem[51873] = 208
mask = 110X100X110X10XX1100101XX01X10111X01
mem[28341] = 144281151
mem[36729] = 56472321
mem[63409] = 10778
mem[21172] = 63301
mem[1101] = 3785
mask = 100111100X00001101X01X00001110X01XX1
mem[36813] = 990295316
mem[44821] = 179862368
mem[45561] = 12722
mem[54859] = 19017266
mem[50564] = 167811030
mem[43704] = 126046154
mask = 10001X10X1000011X1000X00100100110010
mem[42747] = 1659054
mem[10403] = 568236
mem[45045] = 43419
mem[31809] = 59431
mem[49382] = 16398
mem[56638] = 387921470
mask = 11X1X1000001X01011X0X1X0XX1010001001
mem[15844] = 133202
mem[59321] = 81765
mem[19566] = 8456988
mem[51120] = 1362
mask = 1001X11XX0000011X10011100X0010000001
mem[49173] = 1284
mem[3884] = 8094
mem[32207] = 12943
mem[32916] = 43847
mem[45] = 78615226
mem[47659] = 4559
mask = 10011X101X000111X0X000101010001X0X01
mem[47504] = 3997682
mem[630] = 49259614
mem[23114] = 688
mem[62188] = 12822166
mem[65077] = 459034
mask = X101010XX000X01101X010X0011100101000
mem[26001] = 1543
mem[48133] = 288946
mem[53422] = 18943982
mask = 1X00XXX1110X00110101X0111100X010000X
mem[33738] = 196926637
mem[37664] = 623
mem[48029] = 5133
mem[23732] = 23735
mem[30329] = 212916554
mem[8552] = 119946627
mem[6631] = 1907
mask = 1XX11100X000001X01X01100X10X000100X0
mem[1703] = 775689020
mem[2780] = 3545
mem[2818] = 234302
mask = 1001X1XX100000110100000001X0001X0101
mem[61417] = 120523
mem[13083] = 2308
mem[32789] = 3997976
mem[50116] = 778868811
mem[8936] = 61495467
mem[12206] = 208
mask = 100111X0X00000X1010000100000001011XX
mem[9421] = 2972812
mem[34256] = 2423170
mem[36762] = 36668
mem[19241] = 64537
mem[31618] = 1055988588
mask = X00X101111000X0100010XX0X111X01010X0
mem[49552] = 27782759
mem[9251] = 4816
mem[14980] = 3017
mask = X0X10000X000X00X01X1010111111X11X110
mem[40421] = 51130
mem[60996] = 34278
mem[64961] = 414
mask = 1000111X1100001001X1X10XX0010X0XXX00
mem[52359] = 763212311
mem[44171] = 9117448
mem[49702] = 8926626
mem[2466] = 2011885
mem[10736] = 383225
mem[38555] = 14408818
mem[19362] = 677100
mask = 100011X1110XX010011X1100X001X001X11X
mem[60702] = 1681285
mem[33941] = 249
mem[33060] = 48065
mem[6660] = 11635
mask = 10X1111X1X000011010X1X0XX10000110X00
mem[33592] = 7818
mem[20643] = 5562857
mem[61417] = 482
mem[25002] = 18611
mask = 1X011000110010X0X100101XX111X1X100X1
mem[15042] = 1048663
mem[46450] = 906445926
mem[65481] = 325
mem[8090] = 145570
mem[46447] = 2513
mask = 11X101X01X00XX11X10000000X11X00X0000
mem[9686] = 6175651
mem[55574] = 42723
mem[37505] = 2089
mem[64151] = 6581
mem[24387] = 3109
mem[56931] = 0
mask = 11011100XX0X1X1X010010010X1X10X000X0
mem[42506] = 1351
mem[15066] = 30271
mem[426] = 4269668
mem[20864] = 120804232
mem[14675] = 1430376
mask = X00X111X110000110100X000101100101000
mem[16379] = 14955
mem[63542] = 294779946
mem[43782] = 14023312
mem[50116] = 68098604
mem[6346] = 2828888
mask = 1XX0X1100110XX11X0101011100000100100
mem[27465] = 802232
mem[46780] = 18542342
mem[19044] = 4213
mem[39202] = 76554568
mem[33173] = 68587
mask = 10X1111111110101X100001010X1000001X1
mem[57043] = 971606118
mem[46661] = 8089
mem[38403] = 32188546
mem[18704] = 630312774
mem[16594] = 54138487
mask = 1XX1100X00X0001001000000000X000100X1
mem[33536] = 5526445
mem[3755] = 929
mem[5733] = 77809
mem[14065] = 15212249
mem[34315] = 1058941
mask = X00111101X000011010XX0X110100X01X00X
mem[33910] = 15336
mem[29561] = 16371540
mem[10901] = 273
mask = 100011X101000001110X01001X0011X001X0
mem[23567] = 675387
mem[7604] = 2997382
mem[16594] = 858806
mem[47216] = 549
mem[15386] = 126092

85
day15.ml Normal file
View file

@ -0,0 +1,85 @@
(* Common util. Should probably put this in a module or something.. *)
let get_one_line file =
try Some (input_line file) with
End_of_file -> None
let get_lines file =
let rec input lines =
match get_one_line file with
Some line -> input (line :: lines)
| None -> List.rev lines
in input []
let read_file file =
let channel = open_in(file) in
get_lines channel
let explode s = (* convert a string to a list of chars *)
let rec exp i l =
if i < 0 then l else exp (i - 1) (s.[i] :: l) in
exp (String.length s - 1) [];;
let implode l = String.of_seq (List.to_seq l)
let (<<) f g x = f(g(x))
let (>>) f g x = g(f(x))
let flip f x y = f y x
(* --- *)
let rec find_idx x = function (* find index of x *)
| [] -> raise (Failure "Not Found")
| h :: t -> if x = h then 0 else 1 + find_idx x t
let rec last = function
| [] -> raise (Failure "Empty List")
| x :: [] -> x
| x :: xs -> last xs
let hash = Hashtbl.create 1000
let rec go idx last num =
(* Printf.printf "\nidx: %i. last num: %i\n" idx num; *)
if idx = last - 1
then num
else
let next =
try
let idx' = Hashtbl.find hash num in
let new_num = idx - idx' in
new_num
with Not_found _ -> 0
in
let _ = Hashtbl.replace hash num idx in
go (idx+1) last next
let () =
let nums = read_file "day15.txt"
|> flip List.nth 0 (* grab the first line *)
|> String.split_on_char ','
|> List.map int_of_string
in
List.iter (Printf.printf "%i ") nums;
print_newline ();
(* pluck out the last number to start things off *)
let rev = List.rev nums in
let x :: xs = rev in
let nums' = List.rev xs in
let starting_idx = List.length xs in
(* Add the initial list to our hash *)
List.iteri (fun i x -> Hashtbl.add hash x i;) nums';
let final = go starting_idx 2020 x in
Printf.printf "after 2020: %i\n" final;
Hashtbl.clear hash;
List.iteri (fun i x -> Hashtbl.add hash x i;) nums';
let final' = go starting_idx 30000000 x in
Printf.printf "after 30000000: %i\n" final';

3
day15.txt Normal file
View file

@ -0,0 +1,3 @@
2,0,6,12,1,3
3,2,1
0,3,6

180
day16.ml Normal file
View file

@ -0,0 +1,180 @@
(* Common util. Should probably put this in a module or something.. *)
let get_one_line file =
try Some (input_line file) with
End_of_file -> None
let get_lines file =
let rec input lines =
match get_one_line file with
Some line -> input (line :: lines)
| None -> List.rev lines
in input []
let read_file file =
let channel = open_in(file) in
get_lines channel
let explode s = (* convert a string to a list of chars *)
let rec exp i l =
if i < 0 then l else exp (i - 1) (s.[i] :: l) in
exp (String.length s - 1) []
let implode l = String.of_seq (List.to_seq l)
let (<<) f g x = f(g(x))
let (>>) f g x = g(f(x))
let rec find_idx nth x = function (* find nth index of x in a list *)
| [] -> raise (Failure "Not Found")
| h :: t ->
if x = h
then if nth = 0 then 0 else 1 + find_idx (nth-1) x t
else 1 + find_idx nth x t
let rec take n l = (* take the first n elements *)
match n with
| 0 -> []
| n ->
match l with
| [] -> []
| x :: xs -> x :: (take (n-1) xs)
let rec drop n l = (* drop the first n elemnts *)
match n with
| 0 -> l
| n -> drop (n-1) @@ List.tl l
let sub_list start length = (* sub list from start *)
drop start >> take length
let range start len = (* makes a new list from start with length len *)
List.init len (fun x -> x + 0) |> List.map (fun x -> x + start)
(* --- *)
type rule = { name: string; ranges: (int * int) list }
(* type ordering = string * (int list) (* rule name and it's possible positinos *) *)
let parse_range r =
let [l; r] = String.split_on_char '-' r in
(int_of_string l, int_of_string r)
let parse_rules line = (* from "class: 1-6 or 5-7" to a rule *)
let [name; range_strings] = String.split_on_char ':' line in
let [rs1; _; rs2] = String.split_on_char ' ' (String.trim range_strings) in
{ name; ranges = [parse_range rs1; parse_range rs2] }
let read_chunks lines =
let blank1 = find_idx 0 "" lines in
let blank2 = find_idx 1 "" lines in
let rule_lines = sub_list 0 blank1 lines in
let rules = List.map parse_rules rule_lines in
let your_ticket = List.nth lines (blank2 - 1)
|> String.split_on_char ','
|> List.map int_of_string
in
let nearby_tickets = sub_list (blank2 + 2) (List.length lines - blank2 - 2) lines
|> List.map @@ String.split_on_char ','
|> List.map @@ List.map int_of_string
in
(rules, your_ticket, nearby_tickets)
(* Part 1 stuff *)
let is_value_valid rules value = (* given a list of rules and a value, is this value good *)
List.exists (fun { name; ranges } ->
List.exists (fun (l, r) ->
(value >= l) && (value <= r)
) ranges
) rules
let find_invalid_values rules tickets = (* given a list of rules and a list of tickets, find all invalid values within the tickets *)
List.map (fun ticket ->
List.filter (fun value -> not @@ is_value_valid rules value) ticket
) tickets
|> List.concat
(* Part 2 stuff *)
let find_valid_tickets rules =
List.filter (fun ticket ->
List.for_all (fun value -> is_value_valid rules value) ticket
)
let is_position_valid rule tickets position =
let values = List.map (fun t -> List.nth t position) tickets in
List.for_all (fun value ->
is_value_valid [rule] value
) values
let find_positions rule tickets =
let len = List.length (List.nth tickets 0) in
let all_positions = range 0 len in
let good_positions = List.filter (is_position_valid rule tickets) all_positions in
Printf.printf "Found good positions for rule %s: " rule.name;
List.iter (Printf.printf "%i ") good_positions;
print_newline ();
good_positions
let find_all_orderings rules tickets =
List.map (fun rule ->
let positions = find_positions rule tickets in
(rule.name, positions)
) rules
let remove_found_from_ordering found (name, positions) =
let new_pos_list = List.filter (fun p -> not @@ List.mem_assoc p found) positions in
(name, new_pos_list)
let find_ordering orderings =
print_newline ();
let rec go ords found =
if List.length orderings = List.length found
then found
else
let ords' = List.map (remove_found_from_ordering found) ords in
(* any of these only have 1 possibility? *)
let has_one = List.find (fun o -> List.length (snd o) = 1) ords' in
let uniq_pos = List.nth (snd has_one) 0 in
Printf.printf "found %s position: %i \n" (fst has_one) uniq_pos;
go ords' ((uniq_pos, fst has_one) :: found)
in
go orderings []
let find_departure_positions ords =
List.filter (fun (pos, name) ->
try String.sub name 0 9 = "departure"
with Invalid_argument _ -> false
) ords
|> List.map (fun (pos, name) -> (name, pos))
let values_at_positions positions ticket =
List.map (fun (name, pos) -> List.nth ticket pos) positions
let () =
let (rules, my_ticket, nearby) = read_file "day16.txt" |> read_chunks in
(* Part 1 *)
let invalid_nums = find_invalid_values rules nearby in
let invalid_sum = List.fold_left (+) 0 invalid_nums in
Printf.printf "invalid sum: %i\n" invalid_sum;
(* Part 2 *)
let valid_tickets = find_valid_tickets rules nearby in
let all_orderings = find_all_orderings rules valid_tickets in
let ordering = find_ordering all_orderings in
let departure_positions = find_departure_positions ordering in
print_newline ();
List.iter (fun (a, b) -> Printf.printf "%s %i\n" a b) departure_positions;
let departure_values = values_at_positions departure_positions my_ticket in
print_newline ();
List.iter (fun x -> Printf.printf "departure value %i\n" x) departure_values;
let prod = List.fold_left ( * ) 1 departure_values in
Printf.printf "\nproduct: %i" prod;

266
day16.txt Normal file
View file

@ -0,0 +1,266 @@
departure location: 43-237 or 251-961
departure station: 27-579 or 586-953
departure platform: 31-587 or 608-967
departure track: 26-773 or 784-973
departure date: 41-532 or 552-956
departure time: 33-322 or 333-972
arrival location: 30-165 or 178-965
arrival station: 31-565 or 571-968
arrival platform: 36-453 or 473-963
arrival track: 35-912 or 924-951
class: 39-376 or 396-968
duration: 31-686 or 697-974
price: 28-78 or 96-971
route: 32-929 or 943-955
row: 40-885 or 896-968
seat: 26-744 or 765-967
train: 46-721 or 741-969
type: 30-626 or 641-965
wagon: 48-488 or 513-971
zone: 34-354 or 361-973
your ticket:
151,71,67,113,127,163,131,59,137,103,73,139,107,101,97,149,157,53,109,61
nearby tickets:
680,418,202,55,792,800,896,801,312,252,721,702,24,112,608,837,98,222,797,364
876,910,289,816,873,280,791,313,641,15,719,587,353,366,617,710,565,419,339,621
869,683,645,185,121,51,670,401,308,213,54,150,813,264,330,50,444,825,837,368
244,131,561,851,165,270,78,573,818,869,946,370,527,866,655,816,146,792,431,431
626,744,334,482,185,797,770,723,532,475,441,62,837,657,412,106,404,433,577,439
610,514,611,681,156,854,838,126,524,710,518,193,744,857,258,642,12,273,192,221
215,408,404,344,319,720,403,434,885,248,707,195,672,312,809,855,118,529,673,439
103,402,226,678,711,212,843,806,358,436,342,257,98,401,527,831,524,401,275,709
429,906,336,77,146,122,179,295,251,529,487,858,901,71,417,477,458,474,154,786
903,313,919,564,904,853,673,373,209,408,825,516,441,818,474,773,556,848,151,229
96,861,791,620,929,256,587,211,250,684,420,258,365,96,104,653,368,528,784,817
898,866,669,867,901,618,575,210,498,265,413,556,190,376,624,818,295,294,431,649
50,346,807,717,850,820,791,561,486,752,414,669,927,72,205,117,137,564,744,799
600,109,553,712,141,649,929,799,204,788,310,71,926,197,348,293,103,667,67,907
369,60,369,443,209,220,453,853,525,231,155,412,4,161,576,852,856,898,119,829
420,272,878,835,449,359,678,236,664,579,158,908,264,620,286,699,838,354,519,906
331,716,527,851,431,297,57,70,109,102,195,346,901,372,818,210,223,554,800,50
912,715,194,876,927,96,827,943,445,438,79,799,885,563,904,142,254,519,883,815
858,554,559,194,840,867,434,825,946,443,663,654,258,924,617,412,916,263,269,619
412,808,836,128,67,928,985,742,827,199,800,924,277,281,52,769,707,784,518,345
398,408,187,164,438,720,813,366,345,449,979,266,902,376,905,259,428,74,53,56
308,520,425,339,430,279,847,417,308,118,772,1,659,302,305,612,522,623,209,52
680,205,199,842,309,563,520,340,609,787,118,140,827,418,149,485,795,22,531,225
521,862,352,410,674,317,59,222,529,586,838,979,876,96,946,810,792,436,224,811
112,306,194,802,319,339,659,137,312,234,294,701,288,130,847,397,22,715,576,70
225,68,221,56,844,179,854,181,310,620,71,208,850,585,417,254,876,830,908,98
435,929,398,830,283,925,749,178,204,58,650,144,707,876,352,372,126,370,803,844
182,842,804,858,354,823,684,22,76,617,396,73,835,521,149,203,851,853,215,716
233,178,770,847,440,336,520,816,873,818,588,835,251,882,698,397,310,270,133,872
509,221,402,766,801,837,485,900,672,652,647,311,292,773,856,430,185,183,407,927
124,870,133,420,865,338,196,318,119,742,430,102,555,915,815,154,835,807,180,803
368,259,784,111,226,117,835,150,354,69,340,676,767,141,537,445,134,164,571,790
879,616,419,449,261,78,522,265,348,832,393,264,704,806,902,838,811,651,680,125
406,396,161,517,900,261,803,63,339,60,906,62,842,785,121,861,262,867,700,242
898,641,654,560,859,231,397,252,477,157,681,186,477,194,420,282,153,914,611,866
813,20,771,655,408,864,851,260,874,949,431,901,143,251,879,449,718,515,435,852
710,56,218,785,211,713,711,438,626,64,583,215,741,165,315,911,191,297,333,686
431,218,299,274,773,201,405,907,673,287,930,911,315,103,481,488,677,808,276,193
662,907,796,401,409,812,182,485,854,477,702,831,262,855,999,527,212,318,854,681
213,653,734,363,615,453,218,906,405,770,199,191,221,681,767,272,210,682,200,179
375,832,786,316,452,809,908,218,488,875,190,712,482,678,66,726,424,948,75,363
575,831,402,860,333,315,524,587,402,531,714,520,57,568,430,103,828,800,313,179
810,101,209,741,837,818,56,915,292,947,943,318,165,701,788,851,366,55,622,418
914,834,72,372,879,352,142,708,834,667,191,609,117,162,268,481,576,836,346,188
667,620,767,269,311,884,275,332,56,155,901,797,798,642,907,482,61,612,366,906
853,944,802,987,337,136,664,795,562,56,587,475,349,407,785,833,272,197,658,76
181,180,56,265,561,333,235,161,361,704,612,623,703,748,525,702,622,564,855,109
865,160,289,530,805,821,515,799,265,224,262,677,904,858,811,22,217,699,614,804
787,299,882,294,989,444,284,401,717,102,398,432,433,285,342,488,699,741,662,845
274,556,342,270,616,114,214,586,62,435,552,718,813,194,721,686,15,912,821,310
833,97,123,151,203,234,436,264,125,329,787,481,342,435,622,855,833,312,798,714
219,475,819,115,265,269,431,138,452,149,625,433,300,553,105,218,907,347,856,596
429,658,114,274,789,849,212,7,304,281,744,60,614,906,366,189,653,448,164,291
58,766,409,707,659,68,182,861,597,370,671,407,57,615,787,642,128,376,555,290
662,432,146,300,228,561,819,539,677,369,348,680,363,208,720,587,336,157,841,397
870,150,556,206,442,199,980,299,527,449,437,216,52,577,210,181,119,844,113,800
293,299,816,96,949,215,724,333,165,896,298,649,564,552,190,860,836,312,829,474
104,226,201,482,713,681,141,925,741,201,450,274,718,877,915,56,230,786,787,475
134,134,477,369,354,665,164,258,949,111,523,869,481,636,928,209,851,430,527,702
826,73,74,732,74,863,488,237,96,683,334,212,873,873,670,624,879,845,301,354
784,228,566,101,899,474,400,232,795,676,216,837,452,744,340,876,361,706,60,805
650,872,275,642,371,676,841,683,619,620,625,683,123,767,202,441,274,416,445,940
279,136,878,619,838,416,319,102,420,253,112,142,223,336,927,403,945,443,624,358
271,622,97,865,517,202,908,178,570,448,52,284,649,260,270,427,372,62,798,769
356,69,74,480,59,884,744,523,555,720,574,483,131,211,409,194,401,153,682,767
929,184,710,772,909,818,267,677,513,222,513,563,72,530,371,4,810,403,68,264
789,446,418,843,184,657,325,903,553,117,857,118,290,773,320,516,828,251,905,122
420,832,526,401,204,483,300,422,837,550,361,452,855,259,717,149,896,335,259,618
412,178,129,624,60,929,310,530,295,354,275,353,114,927,254,4,160,451,668,835
226,831,110,76,573,201,655,609,21,656,64,614,154,273,898,315,618,183,513,315
161,842,295,823,835,207,99,147,528,98,830,928,410,368,269,360,818,210,844,299
59,900,515,246,487,844,703,122,909,821,190,275,271,653,577,144,165,345,131,144
864,437,115,567,120,671,99,51,875,875,404,552,817,613,857,572,650,50,270,183
526,233,771,563,802,766,220,553,684,60,344,814,560,826,148,570,400,52,422,187
338,948,443,144,705,126,874,438,412,478,636,73,102,698,412,820,218,681,345,311
448,336,136,785,298,153,99,113,365,311,881,861,278,190,314,811,213,726,854,478
341,402,719,812,647,679,610,446,164,858,370,436,608,219,263,7,74,719,134,575
108,815,307,658,845,144,855,308,20,708,336,785,815,433,220,434,704,884,236,123
283,416,97,846,163,769,339,164,54,77,820,768,75,219,148,859,770,943,731,107
477,879,632,682,376,703,307,427,269,71,766,480,945,403,53,255,907,264,119,449
932,375,479,905,155,672,182,848,477,479,484,236,375,338,150,709,698,375,186,794
849,141,709,158,161,342,564,847,262,623,665,147,213,198,759,621,744,823,853,709
727,788,294,826,182,189,421,793,642,345,235,292,137,703,901,425,309,334,834,410
157,122,524,524,673,656,858,129,668,308,421,854,848,806,477,616,556,359,844,478
798,672,806,530,408,793,281,901,300,812,432,573,138,20,98,346,133,274,408,794
124,209,55,561,260,620,617,777,668,124,414,658,659,348,877,842,75,197,430,863
211,922,946,486,292,879,678,162,267,403,156,744,766,430,310,849,303,479,709,865
316,368,668,254,514,209,443,150,128,421,183,479,62,909,730,126,372,289,130,608
197,237,824,844,514,428,828,221,206,578,311,434,702,279,153,338,854,113,879,751
794,766,838,417,198,148,558,532,302,664,519,483,828,294,578,931,426,121,528,165
676,664,712,257,743,670,703,264,115,842,857,163,611,798,221,408,573,525,462,909
644,708,620,878,843,280,841,847,839,824,376,609,556,811,316,548,486,414,898,657
530,253,787,302,516,202,117,259,69,618,450,233,944,900,528,453,723,697,432,641
519,413,683,475,708,345,612,572,269,57,685,199,666,320,147,770,263,186,357,133
186,441,66,283,227,344,349,874,855,137,210,224,422,77,939,705,403,904,790,524
152,303,611,665,103,614,181,827,867,131,488,866,770,514,340,372,882,288,835,776
181,743,361,201,513,107,427,181,573,568,427,288,827,477,418,809,148,374,429,430
72,737,201,333,865,846,405,284,526,448,791,142,448,59,624,705,646,484,713,403
290,121,812,103,232,708,374,473,60,640,322,415,669,712,58,304,117,702,363,849
656,336,613,838,404,820,944,232,315,643,557,625,54,623,415,897,426,868,916,126
133,110,102,949,561,146,937,481,678,884,187,769,198,741,906,204,680,899,801,482
397,707,194,998,226,789,612,255,375,882,354,399,478,765,125,840,679,825,587,316
218,839,664,903,900,863,354,800,529,931,319,183,202,836,773,56,432,516,587,644
398,578,100,532,56,446,704,297,182,134,853,160,319,161,634,881,657,669,619,876
321,227,434,711,420,115,847,608,868,848,478,853,487,550,576,519,586,320,104,270
436,530,862,518,826,301,609,804,401,106,532,104,210,255,812,229,237,648,569,743
217,472,946,912,293,869,65,788,661,898,823,673,654,486,162,231,815,310,513,841
298,426,880,336,586,405,314,866,677,653,460,233,78,135,425,710,269,179,427,344
874,404,98,564,435,665,720,103,945,870,990,741,125,265,553,197,773,571,165,846
659,808,652,697,134,641,340,192,450,580,837,575,643,115,876,710,165,863,339,820
610,713,107,195,553,72,465,407,410,296,257,868,275,213,643,445,435,785,345,159
475,418,927,316,430,842,874,764,63,861,337,412,823,213,587,154,350,216,139,417
532,479,525,407,624,117,699,334,272,183,348,162,191,742,303,152,96,288,810,545
150,152,156,743,451,699,587,290,182,361,263,308,348,455,682,160,803,97,225,868
229,764,307,792,883,905,698,716,65,872,621,317,701,851,904,401,184,826,530,824
447,822,133,345,644,299,819,269,806,181,244,613,813,579,704,152,161,806,844,312
622,312,742,222,875,835,520,883,920,899,702,793,716,519,652,449,803,621,369,337
235,614,850,211,416,217,103,744,825,185,886,808,553,252,770,116,252,220,429,787
944,869,293,576,825,58,22,859,162,266,342,562,525,74,902,527,153,475,361,926
654,826,576,292,468,872,222,286,196,220,252,349,99,766,54,720,903,124,618,480
219,76,254,642,127,292,56,475,934,928,181,162,427,451,348,60,815,152,697,925
428,885,473,878,625,299,824,835,787,115,57,927,461,180,236,865,653,225,704,364
399,322,987,482,316,825,113,473,875,885,642,441,869,149,565,719,929,912,440,860
421,58,122,522,520,435,344,614,68,2,154,861,406,127,682,684,261,400,348,800
111,798,528,439,560,683,203,704,644,290,909,645,668,443,128,528,313,641,932,519
106,113,437,863,925,674,477,857,423,945,528,345,162,312,676,469,273,906,478,514
446,360,787,364,51,252,104,406,577,529,373,852,436,801,189,297,662,811,124,226
187,185,872,680,420,368,810,608,100,906,787,565,684,936,484,320,611,665,117,794
891,617,124,145,819,475,410,409,819,310,612,798,336,702,859,901,864,336,66,903
270,103,307,665,643,348,154,823,816,108,193,145,715,274,576,320,762,113,303,134
476,717,419,62,73,851,658,369,230,871,254,882,667,884,513,665,402,213,189,923
72,211,288,579,871,465,62,558,674,809,106,519,199,320,147,278,217,108,808,99
863,265,214,53,710,50,859,677,697,277,782,435,686,257,337,661,845,274,906,309
806,56,911,936,74,76,185,112,874,335,710,766,397,768,75,376,76,513,833,51
311,626,356,140,654,522,823,61,668,398,523,370,279,65,132,897,859,697,148,809
305,149,664,340,909,858,291,448,273,469,808,341,267,707,877,406,648,523,649,436
429,62,300,616,884,515,292,448,406,361,872,204,641,250,403,424,435,284,858,228
156,297,209,830,125,129,206,150,134,443,509,429,896,404,882,613,770,155,418,122
868,336,877,702,117,917,114,563,298,318,812,259,721,451,416,574,285,527,418,520
717,443,59,528,272,902,126,646,806,698,662,123,305,671,147,224,52,181,785,580
407,236,621,443,198,230,355,295,578,586,864,562,527,335,840,451,900,838,657,531
659,147,608,768,372,865,78,618,868,835,915,374,785,371,296,101,224,293,97,312
949,318,301,873,407,125,864,356,279,660,292,71,715,902,255,854,876,354,901,209
708,107,773,829,228,765,179,676,685,359,409,473,101,217,288,842,576,266,575,233
822,660,911,870,442,108,558,511,76,375,713,159,666,283,271,851,619,683,110,474
312,524,711,340,704,620,789,409,403,146,736,905,282,577,320,475,340,440,650,309
534,871,709,148,274,903,476,230,786,556,157,101,798,288,51,744,362,362,415,524
673,423,146,771,844,911,568,833,189,397,207,63,769,835,852,220,216,220,307,860
401,871,484,143,713,812,349,716,431,219,765,338,525,826,792,104,451,78,757,649
280,101,563,356,128,532,789,666,515,529,766,374,183,224,721,902,794,857,262,787
133,617,573,140,103,50,847,227,910,990,681,233,559,441,641,905,799,150,909,867
168,200,839,361,202,146,680,257,475,552,927,307,515,203,832,74,216,552,192,343
478,622,664,671,338,697,473,232,222,372,876,99,868,360,625,831,428,420,280,340
55,907,345,864,433,430,155,312,864,397,411,426,52,261,487,673,561,477,138,568
855,366,57,473,102,300,451,265,880,905,173,300,341,480,352,947,911,139,617,879
309,433,651,526,411,702,73,701,300,313,402,307,481,796,578,309,113,299,624,469
802,310,461,138,862,337,370,117,857,422,823,346,100,609,617,529,705,151,198,668
881,484,521,520,623,112,254,883,754,517,608,927,804,299,73,368,316,700,160,879
949,810,744,335,414,683,52,891,179,307,680,806,674,255,662,122,768,661,899,487
135,623,482,52,335,486,116,592,833,901,444,140,310,108,256,102,848,148,474,451
796,194,433,545,477,710,108,139,426,712,713,222,398,808,54,281,675,306,911,140
834,769,761,203,62,870,212,104,398,771,150,397,817,870,418,270,618,698,525,373
339,814,257,721,335,786,348,61,879,363,263,289,515,840,288,865,282,770,97,630
333,234,118,259,267,120,443,134,664,222,62,12,199,436,877,624,300,294,943,804
277,308,809,363,303,119,919,354,139,858,425,669,119,70,403,182,678,410,72,196
519,195,252,179,656,182,398,262,679,565,3,522,272,903,928,525,116,614,255,56
859,67,102,75,51,852,68,526,889,877,202,876,340,57,414,844,372,666,878,281
193,697,835,116,312,626,660,333,72,312,56,642,259,196,73,163,77,529,630,218
828,948,404,78,127,422,435,408,846,767,787,145,453,331,214,641,528,872,522,661
77,414,578,468,285,269,255,291,867,424,660,704,655,232,187,675,670,253,575,56
520,528,564,58,14,222,280,288,650,256,698,613,138,713,363,59,354,853,526,336
290,902,236,483,52,158,636,796,571,948,700,924,223,55,421,217,296,308,343,318
809,905,373,340,530,646,344,71,67,517,357,430,341,337,796,98,115,366,817,523
215,806,313,293,357,348,76,334,345,878,562,827,908,573,788,289,236,53,433,207
776,608,561,428,827,319,621,553,199,284,412,658,335,440,571,147,302,621,54,884
53,710,578,642,624,579,321,474,436,211,304,57,850,267,472,227,785,795,876,574
151,556,909,619,320,847,451,624,978,529,370,315,254,195,137,907,420,428,948,819
411,706,399,183,411,262,53,721,271,443,678,677,872,251,221,58,311,664,320,722
134,119,187,527,69,517,201,371,346,832,664,208,151,884,358,307,668,651,114,296
577,567,449,401,879,372,523,710,863,310,802,182,708,527,518,701,421,821,162,440
587,824,442,426,791,553,677,682,265,805,865,718,837,811,569,253,179,398,900,720
681,844,482,885,352,262,713,578,627,841,473,794,108,154,215,409,446,96,835,479
752,477,196,792,302,429,441,906,62,299,419,232,829,703,396,278,791,670,396,289
614,51,252,701,118,178,56,163,432,920,237,374,518,268,791,259,344,237,255,518
585,481,949,572,904,833,153,337,75,944,476,70,850,898,699,624,838,61,403,118
314,882,524,926,148,127,265,293,556,781,660,484,420,668,311,473,124,255,652,160
445,5,260,142,557,258,263,100,110,284,715,878,443,555,853,423,608,398,117,200
877,806,946,868,208,529,487,230,125,253,127,814,367,740,408,449,814,182,790,841
819,925,211,815,192,685,136,706,558,141,148,903,178,3,68,615,362,61,625,707
185,69,518,336,304,716,449,165,80,116,318,805,103,282,70,372,699,114,113,672
851,704,309,678,98,563,807,57,133,134,828,138,282,62,348,763,861,340,561,283
862,883,123,867,616,192,772,932,72,207,276,527,621,258,337,515,947,667,339,432
901,868,825,614,106,865,479,227,433,269,198,375,861,182,51,247,473,697,526,532
285,705,266,479,646,296,287,633,302,710,153,408,165,158,576,54,75,191,515,351
849,685,101,180,75,786,55,156,370,151,347,702,903,55,843,583,554,217,298,433
344,586,262,228,766,709,348,643,699,518,443,626,417,614,837,23,114,203,787,488
57,259,788,341,230,273,197,581,608,134,514,528,107,102,214,347,621,680,609,446
103,284,195,634,855,113,652,315,279,98,101,50,312,642,125,525,447,319,681,293
847,445,531,292,347,60,677,159,196,839,746,56,220,441,851,158,573,280,652,908
404,205,271,50,532,801,879,246,218,119,906,827,253,475,516,114,828,843,422,133
279,876,997,859,124,52,673,831,345,483,579,478,306,869,790,707,104,849,97,877
518,623,801,923,204,698,850,333,532,287,414,126,821,196,298,785,765,949,204,525
943,875,711,365,559,75,448,814,813,420,681,841,669,781,521,294,611,793,908,199
564,75,442,146,10,646,322,881,897,707,120,808,147,474,795,701,50,647,367,578
162,76,846,72,203,287,209,205,782,441,135,296,285,574,66,105,528,744,198,202
657,558,230,159,118,800,647,295,836,908,144,280,232,13,440,72,868,855,205,365
334,773,656,648,806,808,649,287,133,432,332,797,717,282,220,822,798,104,641,475
150,287,401,157,146,788,376,648,339,261,527,212,668,660,267,877,356,352,195,819
809,112,104,289,829,109,843,352,283,506,96,679,424,677,713,852,514,678,52,708
929,645,186,104,805,414,908,646,584,647,224,438,303,143,664,619,812,705,284,519
630,350,191,341,350,108,767,208,399,685,185,480,268,791,654,649,219,909,795,268
871,812,400,748,205,515,209,849,707,836,838,318,207,206,71,435,648,647,474,557
118,865,294,189,948,284,479,429,542,110,612,837,190,54,706,145,433,609,256,678
184,836,486,441,137,867,658,710,768,373,786,662,903,370,154,300,120,742,296,983
288,482,319,371,829,291,283,826,118,477,216,928,226,652,829,291,796,574,134,332
265,279,445,165,704,525,349,64,207,125,548,437,273,257,773,226,224,770,714,162
697,815,292,708,13,558,418,437,262,139,288,710,796,561,99,199,711,373,808,669
909,662,834,530,644,436,181,297,128,600,288,322,614,478,300,367,303,810,119,313
703,925,810,100,788,316,946,97,652,231,570,152,101,163,274,486,414,656,677,793
885,346,322,679,256,853,929,803,154,179,163,369,641,898,611,7,805,130,129,424
568,669,424,924,947,157,792,682,413,819,449,129,530,284,320,50,280,574,72,438
107,834,68,576,304,284,224,996,910,425,115,276,441,160,260,271,518,825,234,421
142,646,789,187,451,120,840,219,109,734,305,767,711,525,822,432,833,284,188,720
314,744,103,131,520,703,829,147,439,187,880,882,532,857,100,211,576,619,206,12
796,852,844,203,787,815,301,134,732,310,142,840,948,826,867,852,815,625,57,811
868,273,164,612,572,563,257,795,288,305,662,155,686,183,671,995,563,717,261,334
667,118,65,201,428,309,803,664,443,574,849,429,804,341,424,327,74,720,370,514
56,259,742,438,683,317,481,460,441,819,165,133,100,882,578,946,676,113,139,448
616,112,878,830,225,158,70,207,457,790,625,741,672,572,305,310,226,125,611,254
83,282,198,859,813,817,267,254,353,709,614,317,53,51,422,860,520,111,232,318
63,146,666,194,834,277,366,531,623,230,998,310,184,198,651,269,421,564,431,339
467,202,347,652,473,279,685,572,133,520,302,142,235,484,528,900,164,643,803,286
819,196,653,118,616,193,192,765,652,608,707,234,864,608,4,876,523,870,513,716
156,743,21,370,304,576,425,259,268,430,305,717,370,410,617,233,646,259,615,871
452,620,51,132,648,430,902,906,261,924,559,318,258,126,203,635,189,145,697,769
697,846,130,325,555,233,127,820,137,844,856,669,810,268,826,74,814,677,681,843
439,827,68,69,439,560,830,568,185,621,854,429,278,416,261,841,903,116,478,189
924,810,909,425,251,617,425,644,135,231,129,159,851,402,522,918,205,586,97,52
111,142,149,419,437,450,372,446,217,440,660,686,851,202,648,991,840,269,206,700
303,822,146,474,112,75,712,321,712,626,720,220,334,63,947,645,624,467,812,446
196,409,771,530,96,51,221,885,330,867,815,949,826,338,485,791,58,370,853,199

94
day17.1.ml Normal file
View file

@ -0,0 +1,94 @@
(* Common util. Should probably put this in a module or something.. *)
let explode s = (* convert a string to a list of chars *)
let rec exp i l =
if i < 0 then l else exp (i - 1) (s.[i] :: l) in
exp (String.length s - 1) []
let implode l = String.of_seq (List.to_seq l)
let (<<) f g x = f(g(x))
let (>>) f g x = g(f(x))
let rec uniq = function (* dedups a list *)
| [] -> []
| x :: xs ->
if List.mem x xs
then uniq xs
else x :: (uniq xs)
(* --- *)
let string_of_cube (x, y, z) = Printf.sprintf "(%i, %i, %i) " x y z
let print_cube = print_string << string_of_cube
let print_cubes cubes = (List.map print_cube cubes; print_newline ())
let read_grid lines = (* string list to active cube list *)
List.mapi (fun x line ->
List.mapi (fun y cell ->
if cell = '#' then Some (x, y, 0) else None
) (explode line)
) lines
|> List.concat
|> List.filter Option.is_some
|> List.map Option.get
let neighbor_d = [-1; 0; 1]
let find_neighbors (x, y, z) = (* find all of the neighboring cubes *)
List.map (fun dx ->
List.map (fun dy ->
List.map (fun dz ->
(x + dx, y + dy, z + dz)
) neighbor_d
) neighbor_d
) neighbor_d
|> List.concat |> List.concat (* flatten *)
|> List.filter (fun (x', y', z') -> not (x = x' && y = y' && z = z')) (* remove the point itself *)
let update position cubes = (* returns true if this position should be active *)
let neighbors = find_neighbors position in
let active_neighbors = List.filter (fun x -> List.mem x cubes) neighbors in
let num_active_neighbors = List.length active_neighbors in
let active = List.mem position cubes in
let active' = num_active_neighbors = 3 || (active && num_active_neighbors = 2) in
num_active_neighbors = 3 || (active && num_active_neighbors = 2)
let cycle cubes =
let neighbors = List.map find_neighbors cubes |> List.concat in
let uniq_neighbors = uniq neighbors in
let cubes' = List.map (fun n -> (n, update n cubes)) uniq_neighbors in
(* List.filter (fun (c, active) -> active) cubes' (* only return the active ones *) *)
List.filter_map (fun (c, active) -> if active then Some c else None) cubes' (* only return the active ones *)
let rec go cubes = function (* cycle n times *)
| 0 -> cubes
| n -> go (cycle cubes) (n - 1)
let () =
let test = [
".#.";
"..#";
"###";
] in
let start = [
"...###.#";
"#.#.##..";
".##.##..";
"..##...#";
".###.##.";
".#..##..";
".....###";
".####..#";
] in
let cubes = read_grid start in
print_string "starting coordinates\n";
print_cubes cubes;
print_newline ();
let n = 6 in
let cubes' = go cubes n in
Printf.printf "after %i cycle(s)\n" n;
print_cubes cubes';
Printf.printf "count: %i\n" (List.length cubes');

99
day17.2.ml Normal file
View file

@ -0,0 +1,99 @@
(* Common util. Should probably put this in a module or something.. *)
let explode s = (* convert a string to a list of chars *)
let rec exp i l =
if i < 0 then l else exp (i - 1) (s.[i] :: l) in
exp (String.length s - 1) []
let implode l = String.of_seq (List.to_seq l)
let (<<) f g x = f(g(x))
let (>>) f g x = g(f(x))
let rec uniq = function (* dedups a list *)
| [] -> []
| x :: xs ->
if List.mem x xs
then uniq xs
else x :: (uniq xs)
(* --- *)
let string_of_cube (x, y, z, w) = Printf.sprintf "(%i, %i, %i, %i) " x y z w
let print_cube = print_string << string_of_cube
let print_cubes cubes = (List.map print_cube cubes; print_newline ())
let read_grid lines = (* string list to active cube list *)
List.mapi (fun x line ->
List.mapi (fun y cell ->
if cell = '#' then Some (x, y, 0, 0) else None
) (explode line)
) lines
|> List.concat
|> List.filter Option.is_some
|> List.map Option.get
let neighbor_d = [-1; 0; 1]
(* donno how to do this nicely.. *)
let find_neighbors (x, y, z, w) = (* find all of the neighboring cubes *)
List.map (fun dx ->
List.map (fun dy ->
List.map (fun dz ->
List.map (fun dw ->
(x + dx, y + dy, z + dz, w + dw)
) neighbor_d
) neighbor_d
) neighbor_d
) neighbor_d
|> List.concat |> List.concat |> List.concat (* flatten *)
|> List.filter (fun (x', y', z', w') -> not (x = x' && y = y' && z = z' && w = w')) (* remove the point itself *)
let update position cubes = (* returns true if this position should be active *)
let neighbors = find_neighbors position in
let active_neighbors = List.filter (fun x -> List.mem x cubes) neighbors in
let num_active_neighbors = List.length active_neighbors in
let active = List.mem position cubes in
let active' = num_active_neighbors = 3 || (active && num_active_neighbors = 2) in
num_active_neighbors = 3 || (active && num_active_neighbors = 2)
let cycle cubes =
let neighbors = List.map find_neighbors cubes |> List.concat in
let uniq_neighbors = uniq neighbors in
let cubes' = List.map (fun n -> (n, update n cubes)) uniq_neighbors in
List.filter_map (fun (c, active) -> if active then Some c else None) cubes' (* only return the active ones *)
let rec go cubes n = (* cycle n times *)
Printf.printf "GO! %i\n" n;
match n with
| 0 -> cubes
| n -> go (cycle cubes) (n - 1)
let () =
let test = [
".#.";
"..#";
"###";
] in
let start = [
"...###.#";
"#.#.##..";
".##.##..";
"..##...#";
".###.##.";
".#..##..";
".....###";
".####..#";
] in
let cubes = read_grid start in
print_string "starting coordinates\n";
print_cubes cubes;
print_newline ();
let n = 6 in
let cubes' = go cubes n in
Printf.printf "after %i cycle(s)\n" n;
print_cubes cubes';
let count = List.length cubes' in
Printf.printf "count: %i\n" count;

90
day18.1.ml Normal file
View file

@ -0,0 +1,90 @@
(* Common util. Should probably put this in a module or something.. *)
let get_one_line file =
try Some (input_line file) with
End_of_file -> None
let get_lines file =
let rec input lines =
match get_one_line file with
Some line -> input (line :: lines)
| None -> List.rev lines
in input []
let read_file file =
let channel = open_in(file) in
get_lines channel
let explode s = (* convert a string to a list of chars *)
let rec exp i l =
if i < 0 then l else exp (i - 1) (s.[i] :: l) in
exp (String.length s - 1) []
let (<<) f g x = f(g(x))
let (>>) f g x = g(f(x))
let rec take n l = (* take the first n elements *)
match n with
| 0 -> []
| n ->
match l with
| [] -> []
| x :: xs -> x :: (take (n-1) xs)
let rec drop n l = (* drop the first n elemnts *)
match n with
| 0 -> l
| n -> drop (n-1) @@ List.tl l
let c2i = String.make 1 >> int_of_string
(* --- *)
type exp = Add of exp * exp | Mul of exp * exp | Num of int
let rec string_of_exp = function
| Num x -> string_of_int x
| Mul (a, b) -> Printf.sprintf "(%s * %s)" (string_of_exp a) (string_of_exp b)
| Add (a, b) -> Printf.sprintf "(%s + %s)" (string_of_exp a) (string_of_exp b)
let print_exp = print_string << string_of_exp
let print_exps = List.iter print_exp
let rec find_matching_paren count (x::xs) =
match x with
| '(' -> if count = 0 then 0 else 1 + find_matching_paren (count-1) xs
| ')' -> 1 + find_matching_paren (count+1) xs
| n -> 1 + find_matching_paren count xs
let read_exp line =
let line' = line
|> explode
|> List.filter (fun x -> x != ' ')
|> List.rev
in
let rec go stack = function
| [] -> List.hd stack
| '+' :: xs -> Add (List.hd stack, (go (List.tl stack) xs))
| '*' :: xs -> Mul (List.hd stack, (go (List.tl stack) xs))
| ')' :: xs ->
let matching = 1 + find_matching_paren 0 xs in
let sub = take matching xs in
let rest = drop matching xs in
go ((go [] sub)::stack) rest
| '(' :: xs -> List.hd stack
| num :: xs -> go ((Num (c2i num)) :: stack) xs
in
go [] line'
let rec eval = function
| Num a -> a
| Add (a, b) -> (eval a) + (eval b)
| Mul (a, b) -> (eval a) * (eval b)
let () =
let exps = read_file "day18.txt" |> List.map read_exp in
let values = List.map eval exps in
let sum = List.fold_left (+) 0 values in
print_int sum;

106
day18.2.ml Normal file
View file

@ -0,0 +1,106 @@
(* Common util. Should probably put this in a module or something.. *)
let get_one_line file =
try Some (input_line file) with
End_of_file -> None
let get_lines file =
let rec input lines =
match get_one_line file with
Some line -> input (line :: lines)
| None -> List.rev lines
in input []
let read_file file =
let channel = open_in(file) in
get_lines channel
let explode s = (* convert a string to a list of chars *)
let rec exp i l =
if i < 0 then l else exp (i - 1) (s.[i] :: l) in
exp (String.length s - 1) []
let implode l = String.of_seq (List.to_seq l)
let (<<) f g x = f(g(x))
let (>>) f g x = g(f(x))
let rec take n l = (* take the first n elements *)
match n with
| 0 -> []
| n ->
match l with
| [] -> []
| x :: xs -> x :: (take (n-1) xs)
let rec drop n l = (* drop the first n elemnts *)
match n with
| 0 -> l
| n -> drop (n-1) @@ List.tl l
let c2i = String.make 1 >> int_of_string
(* --- *)
type exp = Add of exp * exp | Mul of exp * exp | Num of int
type op = Plus | Mult
let rec string_of_exp = function
| Num x -> string_of_int x
| Mul (a, b) -> Printf.sprintf "(%s * %s)" (string_of_exp a) (string_of_exp b)
| Add (a, b) -> Printf.sprintf "(%s + %s)" (string_of_exp a) (string_of_exp b)
let print_exp = print_string << string_of_exp
let print_exps = List.iter print_exp
let string_of_op = function | Plus -> "Plus" | Mult -> "Mult"
let print_op = print_string << string_of_op
let print_ops = List.iter print_op
let rec find_matching_paren count (x::xs) = (* find matching closing paren *)
match x with
| ')' -> if count = 0 then 0 else 1 + find_matching_paren (count-1) xs
| '(' -> 1 + find_matching_paren (count+1) xs
| n -> 1 + find_matching_paren count xs
let rec run_stack exps ops =
if List.length exps = 1
then List.hd exps
else
let (l :: r :: exps') = exps in
let (op :: ops') = ops in
match op with
| Plus -> run_stack ((Add (l, r)) :: exps') ops'
| Mult -> run_stack ((Mul (l, r)) :: exps') ops'
let read_exp line =
let line' = line
|> explode
|> List.filter (fun x -> x != ' ')
in
let rec go exps ops = function
| [] -> run_stack exps ops (* end of our string *)
| '*' :: xs -> Mul (run_stack exps ops, go [] [] xs) (* "split" on Mul *)
| '+' :: xs -> go exps (Plus :: ops) xs
| '(' :: xs ->
let matching = 1 + find_matching_paren 0 xs in
let sub = take matching xs in
let rest = drop matching xs in
go ((go [] [] sub)::exps) ops rest
| ')' :: xs -> go exps ops xs
| num :: xs -> go ((Num (c2i num)) :: exps) ops xs
in
go [] [] line'
let rec eval = function
| Num a -> a
| Add (a, b) -> (eval a) + (eval b)
| Mul (a, b) -> (eval a) * (eval b)
let () =
let exps = read_file "day18.txt" |> List.map read_exp in
let values = List.map eval exps in
let sum = List.fold_left (+) 0 values in
print_int sum;

373
day18.txt Normal file
View file

@ -0,0 +1,373 @@
(4 + (2 * 7) * 4) + (6 * 9 + 8 * 4 + 7 * 3) * 3 * 5
5 * 9 + (5 * 9) * (6 + 2) + 3 + 7
8 + 5 * 9 * 9 + 9 + 5
(7 + 9 * 8 + 4 * 6) + 6 * ((9 + 9 + 5 * 7 + 4) * 8 * 2 + 5 * 6 + 2) + 2 * 6
(6 * (5 + 8 * 7 * 8 + 4) * (7 + 7 * 3 * 5)) + 5 * (8 + (8 + 3 + 5 + 5) + (3 + 2 + 7 * 2 * 9) + 6 * 5 + (2 * 6)) * ((4 * 3) + 3) + 9 * (3 + 6 * 2 + 3 * 8)
2 * 9 + (6 * 2 + 6 + (9 + 6 + 8 + 5 + 5) + (8 + 7 * 4 + 3) + 8) * (4 + 4 * 2 + 6)
5 + 4 + 5 + (7 + (9 + 7 + 4 + 4 + 4 + 5) + 2 * 4) + 4 * 9
9 + (7 * 8 + (6 + 3 + 4)) + (5 * 9)
2 * 4 + 8 + (5 + 8) * 9 * (9 + (5 + 3) + 3)
8 * 6 * 5 + 8 + (8 * (2 + 8 * 7 * 5 + 3 + 5)) * 2
6 * ((3 + 4 * 3 * 7 * 8) * 8 + (9 + 5 + 2 * 3) * 3 * 2) + 7 + 8 * 8 + 4
9 + 3 + 7 * 8
(9 + (4 + 9 + 3 + 5 * 5 + 5) * 5 + 9 * 6) * 3 * 2 * 6 * 5
7 * 9 * 6
(5 + 2 * 8) * 8 + 3 + 8
9 * 5 * (5 + (5 * 4 + 8 + 6 * 5) * (9 * 7 + 5)) * 3 * 9
(6 * (8 * 3 * 7 + 2) * (3 + 9 + 5 + 5) + 3) + 7 * 3
7 + 9 + (4 + 9 * (4 * 6 + 3 * 8 * 5) + 8 + 9 + 3) + 6 * (6 + 8 + 7 * 9 * 6 + 6) + 7
2 * (5 * 5 + 6 + (5 + 5 * 5 + 6)) * 4 + 5 + 2
8 + 2 * (8 * 7 * 4 + 8) * 9
9 + 5 * (4 * 8 + 9 * 6 + (3 * 3) + 2) + 5 + (4 * 5 + 2 * 2)
(5 * 7 + 2) + 3 + 9
7 * 9 + 8
3 * 7 * (7 + 5 + 8 * 5 * 8)
(7 + (3 * 6 + 6 * 9 + 2) * 8 * 6 + 6 + 2) * 6
4 * (7 * 5 * (6 + 8) * 7 * (5 * 3 * 2 * 9 + 2 * 4) * 6) * 2 + 2 * 5
((3 * 3 * 9 + 8) + 2 + 5 + 8) + 6 * (6 + 9 * 2) + 7 * 9 * ((9 + 4 + 4) * 4 + 4 + 9)
7 * (4 * 2 + 3 + 7 + 5) * (8 + 2 + (5 * 9) * 2 + 3 * 5)
7 + (8 + 3 + 8 * 4 * 2 * 2) + 7 * 2 + ((3 + 5 * 3 + 5) * 8 + 3) + 8
7 + 2 + 9 * 9 + 5
((6 + 4 + 2) * 2 + 9) + 3 * 6 * (6 + 4 + 9 + 2 + 6) * 9
6 + 6 * (9 * 9 + 6 + 6) + 2 * 6
2 + 5 * ((4 * 4) * 6) + (3 * 3 + 2) * 9 + 5
9 * 4 + 8 * 5 * ((6 * 5 * 4) + (3 + 8 * 7 + 6 * 7) * (6 * 6 + 7) * 8 + 4 + 7)
3 * 8 + (4 + (7 * 7 + 9 * 8 * 6 + 7) * (8 * 4 + 4 * 6 * 4 + 4) + 2 * 9)
3 + 6 * 2 * 3 * (4 + 7 + (3 * 6 + 7 * 8) * 7 + 9 * 8)
2 + 8 + (5 * 4 * 2 * 5 + 5) * 4 + 3 * 4
6 + 4 + (5 + 5)
6 * 3 + 8 + (8 + 2 + 9 * 3) * ((6 * 8 + 6) + 6 + (7 * 4 * 3) * 4 + 9 + 3)
((9 + 7 + 9 + 2 * 7 * 7) + 8 * 6) + 2 + 7
6 * (6 + 9 * 2 + 4 * 7 + 8) + 5 * 9
((2 + 5 + 6 * 3) + 7 + (7 * 6 * 8 * 3 + 8 * 3)) + (8 * 6 * 8 * 9 * 5)
6 * 7 * 5 + 5 * (2 * 9) * 4
(8 * 7) * (2 * (7 + 3) + 3) + 8
(7 * 9 + 7 + 7 + 7 + 7) + (7 * 5 * 8 + 4 * 5) + 6
5 * (6 * 7 * 8 * 5) * 6
5 * (2 + (6 * 7) * 8 * 3 + 6 * 2) + 2 * 4 + 8 + 3
3 * 5 + 6 + 6
((9 * 9) * 6) + (4 + 9 * 6 + 4 * 9 + 7)
(3 + 9 + 2) * (3 * 7 * 7 * 7 * (8 * 8 * 4 + 3 + 8)) + 2
6 * 6 + 8
((9 + 5 + 8) + 9) + 7 + ((9 * 5) * 3 * (3 * 4 * 4 + 3) * 7) + ((5 + 6 + 2) * (7 * 2 * 9 * 8) * 5)
6 + (8 * 7 * 6 + 5) + 9 * 7 * 7 * 7
2 + (4 * 9 * 3 * 9 + 8) + 2 * 7 * 3 + 4
7 + 3 + (5 + 7 * (4 + 4 * 8) + 2 + 8 * 6) * 2
(2 * 5 * (4 * 7) * 9 * (3 + 7)) + 3 * 4 * (2 * 3 * 8 * 4) * ((6 + 2 * 2) + (6 * 5 * 7 * 6) + 9 * (8 + 4))
((9 + 3 + 5) + 8) * 2
2 + 4 + 7 + 5 * (6 * 7 + 8 * (4 * 3 + 6 * 4 + 7) * (7 + 3 + 7 + 3 * 2) + 8)
5 + (9 * 8 + 5)
(2 + (9 + 7 * 8) + (6 + 7) + 6) * 5 + 3 * 2
7 + (9 + (8 * 7 * 9)) * 8 + 3
9 * (9 + 4 * 2 * 3 + (6 + 7 * 8 + 9)) + 6 * ((7 * 4 + 7 * 4) + 2 * 6 * 5 + 6 * 6)
((3 * 3 + 4 * 9) + 7 + 7 + 3) * 8
9 + 8 * (2 + 6 + 8 * 6 + 3 + (8 * 6 * 6 * 4 * 6))
3 * (9 + 2 * (9 + 2 * 8) + 3 + 8 * 5) + (9 + 8 + (6 * 9 + 2 + 8 * 5 + 7) * 7) * 2
((2 + 9) + 3) * 6 * 2 * 2 * 4 + 7
2 * 3 + 4 + (7 + (7 * 5 * 5 + 5) * 9 + (3 + 3 * 5) + 3 * 8)
4 * (8 + 2 + (3 * 7 + 4 + 2 * 6 + 2) * 8 + 7)
4 + (5 * 9 * (8 + 3 * 9 + 9 + 5) * (3 * 8 + 9 * 8)) * 8 + 9
4 * 5 * (2 + 2 + 7 + (3 * 7 * 4 * 2) + 3) * 6
((8 * 8 * 4 + 4 + 5) + 6) + 9 * (3 * 3) * 4
9 * (8 + (6 + 2 * 7 + 3 + 8 * 8) * 3 * (9 + 3) * (3 + 7 * 3) + 5)
9 * 3
6 * (7 + 8 * 8 * 4) * 6 * 9 + (4 * 7) * 4
4 * (3 * (4 * 9 * 6) + 5 + 5) * 4 * 6 * 6 * ((9 + 3 * 6 + 5 + 8) + 4)
5 * 2 * (4 * 3 + (8 * 4 + 2 + 2) * 6 * (8 * 8 * 2 + 7 + 9) + 3) * 5 + (4 + 6)
3 + (5 + 6 * 5 * 9) * 9 + 7
((3 + 6 + 8) * 7 * 3 + 4 + 4 * 8) * 2 * 2
2 + ((9 + 9 * 4 + 2 + 3) * 4 + 9 + 5 + (7 + 3 * 9)) + 8 + 7 * 3
5 * 5 * (5 * 6 * 6 + (3 + 4 * 8 + 7) * 2) * 6 + 4 + 3
4 + 3 * (5 + (6 * 5 + 6 * 2) * 4) + 9 + 7 * (5 * 5 + 9 * 5)
2 + (6 * 7) + 7 + 3 * 7
5 * 7 * (6 + (9 * 5)) * 4 + 2
((7 * 7 * 3) + 2 + 2 + (9 + 8 + 3)) * (3 * 8 + 6) + ((6 + 2 * 6) * (2 * 4 + 3 + 8 + 2)) * 8
((8 + 3 + 8 + 5 + 8 * 3) * 2 + 4 * (6 + 4)) * 8 * 2 * 5 + 9
7 + 6 * 3 + 3 + (5 * 7 + 3 + 3 + 8) * 6
8 + 7 + ((5 * 9 * 3 + 3 + 4 + 6) + (6 * 6 + 2 + 6) + 8)
5 + 5
6 + (6 * 5 * 7 + 8)
(8 + (9 + 2 + 8 + 2 + 2) * 4 + 7 * 6) * 9 * 6 * (6 * 6 * 5 + 5 * 4) + 7 + 9
3 + 8 + (3 + (6 * 9 + 9 * 2 * 3 * 4) * 3 + 9 * (4 * 2) + (3 * 2 * 9 + 2))
(5 * 8 + 7 * 8 + (2 + 3 * 8) * (8 + 4 * 7)) * 3
8 + 2 * (2 + (6 * 6 + 9 * 3 + 6) + (9 * 2 * 4) + 6 * 4 * (6 * 3 + 2 + 6 + 3 + 5)) + 8 + 4 * 9
8 + 8 + (4 * 9 + 9)
5 + 5 * (5 + 8 + (3 * 9 * 9 + 8 + 8 * 2) * 5) * (8 + 7 + 7 + 8 + (2 + 7 * 4 * 8))
6 * 3 + 6 + ((9 * 5 * 4 + 6 + 5 + 5) * 6) * 2 + (6 * 5 + 5 * 7 * 8 * (3 + 7 * 7 * 9))
4 + (3 + 4 + 5 * (4 * 2 + 7 * 9 + 6 + 6)) + (7 + 7)
2 * (6 + 2 + 6 * 3 + 4) + (6 + 5 * 4 * 8 + 3 + 7) + 8 + 3 * 5
((5 + 3 + 7 * 2 + 9 * 5) + 7 * 7 * (4 + 7 + 9) + 8 + 6) + 3
((9 * 9 + 2 * 7 * 5 * 6) + 8 * 7 * 4 * 2 + 6) * 5 * 9
((3 * 3 * 2 + 5 + 6) * 7 + (3 * 6 * 2) * 3 + 3) + 9 * 7 + 5
(7 + (4 + 7 + 6 * 8 + 9 * 9) + 7 * 2 * 2) * 7
(9 * 3 * 9) + ((2 * 6 * 6 + 9 * 7) * 3) + 3 + 8 + 8
2 + (3 * 5) * (2 + 8 + 8 * 3 * 6 + 6) * 6 * 9
(4 * 7 * 7 + 3 + 4) * 3 * 9 + 6 * (2 + 5 * 4)
(8 * 4 + 3 * 8) * 4 * 5
(7 + 5 + (4 + 2) + 4) + (2 * 5 * 9 * 2 * 6)
9 * 4 + 3 + 8 * (2 * 4 + 7 * 2 * 2) * (2 + 6 + 5 + 9 + 5)
8 + 3 * (6 * 8) + (2 * 4 + 7 * 8)
(9 + 6 + 3) * 5 + (9 * 8) * 5 + 6 * 5
((6 * 2 + 6 * 2) + 3 + 7 + 5 * 8) * 2 + 2
2 + (9 * 3 * 9) * (4 + (6 + 4 + 7) + 5) + 9
(3 + 4) + 5 + 7 + 7
9 + 8 + 8 + 7 + 5 + ((2 + 7 * 9 * 7 * 6 * 9) * 8 * 8 + 7 * 3 + 9)
(8 * 7 * (8 * 7)) * 9 + (4 * (4 + 9) * (7 * 9 + 9 + 6 * 5 + 5) + 7)
(6 + 7 * 9 + 5 + 5) * 5 * (2 + 6 + (3 * 6) + (7 + 3 + 5 * 5) + 9)
2 + ((7 + 8 * 2 + 8) * 4 + 2) * 9 * 9 + 8
8 * 8 * 7 * 2 + 2
7 * 2 + 9 + ((5 * 2 + 6 * 9 + 8 + 7) + 6 * 2 + 8 + 4 * (3 * 2 * 3 * 2))
5 * (7 * 5 + (7 * 9) * 4 * 6 * (8 + 7 + 3 + 9 + 9)) * 4
8 * ((3 + 7 + 5) + 7) + 5 + (6 + 4 + 6 + 4 * 4) + ((2 * 6) * 3) + 9
3 * 3
4 * (5 + 5 + 6 + 2 + 7) + 7 * 6
(7 + 4 + 5 * 9 + 5 + 8) * 8 * (7 * 9 * 9) + 4
3 + (9 * (7 * 7 + 3 * 4 + 8 + 5) * 7 * (2 * 4) + 9 + 5) * (4 + 7)
6 * (5 * (6 * 2) + 6 + (4 * 8 + 9) + 3 * (2 * 4 + 4)) * 6 * 5 + 6 + 3
(9 * 3 * 9) * 8 * 5 * (8 + 3 + 2 + 9)
(8 + 8 * (8 * 9) + 2 + 7) + 8 * (5 * 7 + 6 + 2 * 4 * 2) + 6 * (3 * 8 + 6) * 2
2 * (8 * 5 + 7) * 8 + 7 * 9
4 * 4 * (5 + (5 * 4 + 2 * 9 + 5 + 7)) * 8 * ((4 * 9 + 4) + 6 * (7 + 2 + 4 * 8 * 9))
4 * 6 + (4 * 8 * 3 * (9 + 8) * 7 * 9)
(6 + 9 + 3 * 2 + 8 * 8) * 6
(8 + (3 + 3 + 2 * 3) + (6 + 7 * 6) + 7 * 4 + (9 * 5 * 4 * 6 + 2)) * 2 + 5
4 * 6 + 2 * 5 * 2 + (5 + 3 + 2 + (5 * 3 * 3 + 7 * 6 + 2) + 8)
9 + 2 + (7 * 7 + 7 + 9)
5 + 8 + (8 + (5 + 9 + 6 * 2 * 4 * 4)) * 9
(2 + 4 + 8 + 7 * 8 * 5) + 3 + 3 + (9 + 9 + (9 * 2 + 6 + 4 + 4) + 6 * 2) + 2
7 + (6 + 5 * 2 * 9 + 7 + (9 + 7)) * (3 + 6 + 2 * 5 * 3)
8 + (9 + (4 * 3 * 7 * 7) * 7) + 9 * 6
6 * 9 * ((8 + 5) + 9) * 7 * 8
(2 * 9 + 2) + (6 * 3 * 3 + 6 * 7 + 9)
7 * 5 * (4 * 4 + 7 * 4 + 8 + 3)
3 * (6 + (5 + 3) + 5) * 3
(7 * (9 * 5 * 9 + 2 + 4) + 3 * 8 + (9 + 7) + (2 * 9 + 5)) * (6 + 3 * 9 + 3 + (7 + 4 * 9 + 5) + 9) * (8 * 2 + (2 * 9 + 7 + 5 * 4) * 4)
4 + 7 + 5 + 6 * 8
5 + 4 + 3
9 * (6 * 2 + 7 + 5) * 3 * 2 * 2
7 * 4 + ((6 * 7 * 6 * 8 + 6 * 9) * 7 * 3) + 8
9 * 5 + 4 + 8 + 8 * 8
(3 + 6) * 2 * 7 * (2 * 7 + 2 + 6 + 3)
5 * 2 + 8 * 7 + (4 + 8 + (3 * 6 + 7 * 2 + 4 + 7))
6 + (8 + 6 * (9 * 7 + 2 + 2 + 3 + 4) * (4 * 7 + 2 + 4 * 3) * 3)
(8 + 5 * 2) * (9 * 4) + 5
3 * (4 * 5 * (4 + 3 + 4) + 5 * (3 + 6 + 3 * 7 * 7)) * 3
2 + 7 + (8 + 3) + 8
8 * (9 * 8 * 3) + 4
(2 * 6) * 3
((9 * 6 + 3 + 3 * 9 + 7) + 2 * (2 + 9 * 8 + 2 * 4) + 9 * 8 + 6) + (5 * 9 * (2 + 7) + 7 * 9) + 7
4 + 7 * ((3 * 7 + 2) * 9 * 7 * 2 + 4 + 3) * 4 * (3 + 8 * 9) + 6
9 * (9 + (9 * 6 + 2 * 7 + 6) + 7 * 2 + 2)
(9 * 2 + 4 + 8 + 6 * 8) * (4 + 8 + 7) * 5 + (4 * 2 + 2) * ((4 * 5) * 8) * 2
(5 * 9 + 9 + 2) * 3 + ((7 * 5 + 9 * 3) + 2 + 3 + 6 + 7) + 4 * 6 * 6
9 * 8 + 3 * 4 * (9 + 5 + 7 + 5) * (6 * (7 + 4 * 6 * 7) + 6 * (6 * 5 * 3 + 9 + 4) + (2 * 3 + 3 + 6))
7 * 6 * 2 + (8 * 9 + (6 * 7 * 8 + 6 + 9 * 8) * 3 + 6)
5 + 7 * 8 + 2 + ((2 + 4) * 7)
2 * 5 + 6 * 6 * (3 * 6)
6 * 6 * 6 * (6 * (4 * 4 + 5) * 4 + 3 + 9) + 4
((3 * 4 * 7) * 5 * 9 + 7 * 6 + 5) + 2 * 2 * 6 + 4 * 8
7 * 2 * (3 + (6 * 9 * 9) * 4) * (5 * 8 * 7 * 6 + 2 * 9) * 7
9 + (6 + 6 + (8 + 8 * 3 + 6 + 6))
5 * 2 + 7 + 3 * (9 + 9 * 9 * 9 * (4 * 4)) * 2
4 + 6 + 3 + (2 + 2 * 7 * 2) + 5 + 7
7 * 9 * 9 * 2 * 4 + 7
6 + (6 + 5 + 5) + 7 + 4
9 + (9 * (7 * 3 + 9 + 7 + 8 * 8) * 6 * 5) + 2 * 5
8 + 6 * 8
8 * (9 * 6 + 4 + 8 + 8)
((8 + 3) + 8 * 2) + (3 * 6 * 7 + 7 + 4 + 2) * 9 * 5
6 * (4 * 5 + 6 * 7 * 4) + (2 * 8 + 4 + 7 + 7 + 6) + 9 + 5
9 * 8 * (2 + 7 + 9 + 4 + 5) + (8 * (3 * 8 + 3 * 6)) + ((7 * 2) * 7) + 2
9 + 4 + 9 * 2 * (5 * 2 + 6 + (9 * 5 + 8 + 2 * 5) + 6 + 6) + 7
9 + 9 * ((3 * 6) + (5 + 5 + 7 * 9 * 4 + 9) + 2 * 6 * 6) * 5
(9 * (3 * 2) + 8 * 2) * (6 * (8 + 3 * 8 + 5 * 5 * 9) + 4 + 9 * 6) * 5 + 9 * 6
7 * 9 * (2 * 9 + 4 * (3 * 2 * 6 * 9 + 5 + 6) + 2) + 7 * 6 + 3
9 + (5 * (3 * 9) + 4 * 6 + 6) + 9 + 8 * 5
8 + 8 * 8 + (9 + 4 * (5 + 3 * 8 * 3 * 4 * 4) + 2 * 8 * (9 * 6 * 4 * 6 + 9))
(6 + 6 * 3 + (5 + 8 * 4 + 4) + 3) * (3 + 7) * (6 + 5 * 4 * 6 + 6 + (5 * 7))
(9 + 7 + 6 + (8 * 8) * 4 * 6) + 3 * 5
5 * 2 * 3 + (3 + (6 + 9 * 2) * 3 * 3)
2 + (8 * 7 * (4 * 8 * 2 + 6 * 7)) * 5 + 5 + (8 * 5)
9 * 6 * 4 * 2 * ((6 * 3 + 9 * 8) * 5) * 3
((8 + 6) + 6 * (8 * 5 * 5 * 7) + (2 + 9 + 6 * 7) * 7 * (2 + 9 * 7 * 3)) * ((7 * 5 + 2 * 5) + (8 * 7))
(7 + 8) * 6 * 9 + 6 + 6 * 8
7 * 8 + (8 * 2) * 7 * 8 * 9
9 * ((8 + 6 * 9 + 2 + 3 * 2) * 2 + 4 + 3 + 7) * 2 * 6
2 + (8 + (2 + 9) * 7 * 4 + (8 * 6 + 8 * 6 * 4 + 5) + 6) + 4 * (9 + (3 + 4) * (3 * 9 * 7 * 6 + 9 + 7) + 9 * 6 * 3)
2 + (8 + (8 * 2 + 3 * 8 * 4 + 2)) + 3 * 6
(5 * 5 + (3 + 5 * 6 * 9 + 4 * 4)) * 8 * (7 * 7 + 3 * 7)
9 + 6 * (9 * 2 + 2 * (9 + 6 * 8 + 5 + 3))
5 * 5 + 5 * (7 * 3 * 3 * 5) + 6
7 * 5 * 7 * ((6 * 3 + 5 * 8 * 6) * 7 + 4 * 5) + 7
(5 * 4 + 8) * 3 + 6 + 9 + 6
(7 + 7 + 4 + 8) * (2 * 7 + 9) * 2 * 4
2 + ((7 + 2 + 9 * 4 + 2) * 6 + 9)
9 + 2 + (7 + 6 + 4) * 3 * 8
5 + 7 * 2 + 2 * (3 * 4 + 4 * 6) + 2
2 + (7 + 2 + (9 * 3 * 5 + 7 + 7) + 5 * (7 + 7 * 2 * 4 * 7 * 4) + 5) * (6 + 2 * 5 + (4 * 6 + 4 * 8 * 4) + 7) * 2 * 5
((5 * 9) * 9) * 2 + 4 + ((3 + 6) + (9 + 3 + 6 + 3) * 3 * 5 + (9 + 9 + 6 * 7) + 7) * 2 + 9
4 + (4 + 4 + 6) + 6 + 5 * 9 + 8
(3 * 8 * (7 * 5 * 7 * 5 * 7 + 2)) * 7 * 4 + 3 + 2 + 4
(4 * 8 + 7 + 8 * 5 * 9) + 2 * (5 * 2 * 3 * 9) + 7 + 7 * 2
6 * 3 * (4 + 6) + 7 + 2
(5 + 4 + 4 * 8 + (4 * 6 * 5 + 7 * 4 * 2)) * 9 * 6 * 6 * (3 + 5 + 9 * 7)
4 * (5 * 2 + 8 * 9 * 3) + 3
7 * 3 + 7 + 5 + ((6 * 8 * 8 + 8 + 2 * 4) * 8 * 2 * 9)
4 * 2 + 6 + 2
(2 * 2 + 2 * 9 * 6) + (5 + 9) * 3 * 9 * 5
(5 + 5 * (3 + 3 + 7) * (3 * 7 * 7)) + 4
9 + 7 + 9 + 5 * 6
(6 + 9 + (4 + 7 * 7 * 4) + (9 * 2 + 9 + 5 + 6)) + 7 * 8
5 + (5 * (6 * 5 + 8 + 2) + (4 * 7 * 4 * 7 * 7 * 8) * 8)
4 + (6 + 6 * 2 + 9) + 7 * ((3 + 8) * (3 * 5 + 5 * 3 * 3 * 6) + (4 + 9 * 3 + 3 * 2 + 9))
(7 * (7 + 7 + 5) * 8 * 2 * 8 + 3) + (2 * 4 + 8 * 7 + 3 + 2) + 7 * (7 + 2 + 2)
(3 * 7 * 4) * 5 + 4 * 7 * 8 * 4
7 * 3 * (2 * 7 * 9 * 7 * (8 + 4 + 2) * 3) + 7
7 * (9 + 2 + 5 + 5 + 7 * 5)
5 + 2 * 9 * (8 * 6 * 8 + 2 * 7)
4 + (2 + (2 * 5 * 7 * 5) + 3 + 6) + 8 * ((3 + 4 * 4 + 5 * 3 + 6) + 2 + (5 * 8)) + 8 + 3
2 * (9 * 7 * 3) + (8 + 7 + 8 + 2 * 3 + 9) + 8 + 9
8 * (7 + 5 * 3 + (2 * 6 * 6 * 4) + 9) + 3 * 4
3 + 4 * 8 * 9 + (6 + (5 + 7 * 7 * 4)) + 7
(5 + 6 + 8 + 5 * 7) * 2 + 5 * (9 * (9 * 9 + 8 + 5) + 7 * 4)
8 + (8 * 2 * 4 * 2 + 3 * 2) * (3 * 3) * 6 + 8
(6 * 2 * (6 + 5 * 9 * 3) * 6 * 2 + 7) + 7 * 8 + 2 * 4
5 + (2 + 4 + 5 * 4 + 6) + 9 * (5 * (5 + 9) * 9 * 9 * 2 + 8) * 5
7 * 4 + 9 * (9 + (5 * 7 + 8 * 7 * 5) + 9 + 2 + 2 + (2 * 4 * 7 + 5))
7 + 2 + (4 + (8 + 8 + 5 * 9)) + 9
(8 * 3 * 9 + 6) * 8 + 8 + 7
(2 + 3 * 9 * 4) * 7 + (8 * 6 * 9) * (8 + 6 + 9 + 4)
((7 * 6 + 4) + 6 + 6) + 5 * 4 + 3 * 4
5 * (2 + (3 * 9 + 9 * 6) + (7 + 3 + 2 * 4 + 9)) + 7 + 8 * 5 * 5
7 * 9 * (5 + 6 + (7 * 6) + 4 + 4 + 3) * 2 + 9
(3 * 2 + 5) * 8 * (2 + 4 + 2 + 8 + 7 * (8 * 9))
((2 + 7 * 8 * 9) * 4 * 3 + 6 * 7) + 9 * 8 + 5 + 9
5 + 4 + 9 + 8
7 + 7 + 9 + 2 + 5 + ((6 * 3 + 3 + 6) * 4 * (4 + 4))
(9 * 4) + 8 * 4
3 * 9 * (9 + 5 * 4) + 8 + 9 * 3
3 + (9 * 8 * (6 + 4 + 6 + 5 * 2) + 9 + (4 * 7 * 7) + (3 + 4 + 6 * 8 + 9)) * (2 + 8) + 7 * 5 * 6
9 + 6
6 * 8 * 8 + 6 * 6 * ((9 + 3) + (4 + 2 * 8 + 8 * 2 + 5) * 2)
4 + (4 * (2 + 2)) + 7 + 4 + (4 * (8 + 8 + 4 + 4 + 2) + (3 + 2) * 9 + 8) + (4 + 9 * 9)
(2 * (3 * 7 + 6 + 2)) + (4 * 6) + 6 + (6 + 9 + (2 * 2 * 2 + 6 + 4) * 4) * 5 + (4 + 2 * 5 * 8 + 6 * 2)
4 * ((5 + 5 + 9 + 3 * 5) * 7 * (7 + 9 * 5 * 7 + 2) + 5 * (4 + 7)) + 7 * 9 * 6 * 4
4 * 7 + 4 + ((4 + 8 * 6 * 3 + 2) + 3 + 8 * (6 * 7 * 2 * 8) * 7) * 9 + 6
4 * 6 * ((3 * 6) + 4 + (2 * 2 * 2 * 7) + 9 + 8) * (3 + 8 * 2 * 4 * 2 * 3) + (4 + 3 * (7 + 5) + 6 + 9) + 5
(7 + 2 + (8 + 6 * 4)) + 8 + (7 + 5 + (2 * 5 + 9) * 5)
(7 * 8 + 5 + 8 + 8 * 2) * 6 + (5 + (8 + 3 + 4 * 5) * 9)
8 * (4 + 5 * 9 + 6 + 8 * 7) * 3 * 6 + 4 * 5
6 + ((6 * 3 * 4) + (8 * 8 * 2 * 5 * 8 + 2)) + 3
9 * 3 + 6 + 5 + ((5 * 2 + 9 * 5 + 6) + (4 * 9)) + (4 * 2 * 3 + 7)
6 + 8 + (6 + 2 + 8 + 2) * (5 + 8 + 5 * 5 + (4 + 9 + 3))
(2 * 7) + (6 + 4 + (8 + 6 + 5 + 9 * 4 + 7))
8 * 3 + 3 * (3 * 5) * 6 + 2
9 + 4 + ((5 * 4 + 2 + 6) + 5) * 5 + 6 + 4
(9 * 9 * 3 + 5 * 3 * 4) * 3 + (2 + 3 * 5 + (3 + 6 * 6 + 2) * 8 + 3)
(6 + 9 * 9 + 7 * 6) + 7
4 + 6 * (3 * 3 * 7 * 7 * 5 + 2) * (7 + 7 * 2 * 5 + 4 + 9) + (8 * 2 + (8 + 8 * 4 + 7 + 3 + 5) * 7) + 9
4 + 8 + 6 * 7 * 7 + (2 * 8 + 3 + 5)
4 * 8 * 4 * (9 * 9 * 5) + 9
8 * 5 + (2 + 3 + 2 + 8 * (3 + 5 + 8 + 7 * 9))
3 * ((8 * 6 + 9 * 8 * 5) + 9 * 6 + 6) * 6
5 * 8 + 6 * (5 * 2 * 8)
8 + (6 + 7 + 7 * (6 + 7 + 3) * (5 + 2 * 7) + 7) + (2 * 8)
6 + 5 + 4 + 2 + ((3 + 8) * (5 + 4 * 9) * (4 + 9 + 3 + 9 + 9 * 7) + (5 + 2 + 9 + 3) + (6 + 6) + 3)
3 * (2 + 5 * (5 * 6 * 5 + 9) + 9 * 5) * 8 * 5 + 4
2 * 4 + 6 + (9 * 4 * 3 * 4)
(4 * 6 * (3 + 9) + (3 * 5 + 8 * 5 * 9) + 6) + 9 + 8
(3 * 5 + 8) + 8 * 8 * 7 + 8 * (9 + 6)
(5 * 4 * 6 + 3 + 3) * (3 * 8 * (7 + 2 * 9 * 6)) + ((9 * 9 * 4 + 8 * 7 * 7) + 4 * 4) + 8 * 6
3 + 5 * 5 * 6 * ((3 + 3) * 8 + (6 + 9 + 2 + 6 * 7)) * 4
9 + ((4 * 7 + 2 + 2 * 6) + 8 * (4 * 6 + 7 * 5) * 7 + 4) + 6 + 6
(9 + 9 * (8 * 2 + 9 + 5) * 3 * 4 * 4) + 5 * ((3 + 6 * 3 * 7) + 6 * 4) * (3 + 8 * 9 + 6 + (4 + 3 * 4 + 2) + 6)
5 * 5 * (9 + 8 * 3 * 3 + 3) * 4 + 8
3 + (6 * 9 * 8) + 9 + (3 + 3 + 2 + 5 + 2)
3 + 4 * (4 * 8 + 2 * (3 + 3 + 4 + 9 * 7) + 4 + (6 + 9 + 4 * 6 + 9))
6 * 5 * 9 * ((6 + 9 * 6 + 7) + (6 * 4 + 2 * 4 * 6 * 6) + 9 + 6 + 8)
7 + 7 * 2 * 4 + 7 * 2
2 + 8 * (7 + 3 * 3 + 2) + 6 + 3 * 7
2 * 2 * 9 + 8 + 8
9 + 5 + 4 * (6 * 7 * 5 * 7 * 4 * 3) * 3
7 * 5 * 7 * 6 + 4 * 9
((9 + 7 + 9 + 7 * 7 * 4) * 6 * 5) + 5 + (8 + (2 + 6 * 9 * 7 * 9 + 9) * (9 * 3 * 8 + 9 * 6 * 2) + 6 * 7) * (2 + 6 + (3 * 4 + 4) * 6 * 5) * 9 * 5
(7 * 5 * (3 + 2 + 6 * 5 + 9) + 5 + (2 + 9) + 2) + 2 * 6 + (5 * (7 * 2 + 3 + 8 * 9) * 7 + 6 + 6 * (5 + 3 + 9)) * (4 * 6 + (9 + 7 + 4))
((3 + 5) + 7 + 3) + 6
3 * 4 + 4 * 6 + (5 + 8 * 2)
7 + (7 * (4 + 4)) * 3 + 7 * 4
(5 + 4 * 6 + 3 * 9 + 7) * (7 * 3 * 5) + 6
3 + 4 * (8 + 2) + ((6 * 7) + 8 + 8 * (9 * 3 + 2) * 9)
7 + (7 + 9 * 2 * 9 * 2 * (2 + 5 + 9 * 6)) * 4
(7 + 6 + 3 + 5 * 2) + 2 * 3 + 4 * (3 + 4 * 5 * (3 + 7) + (7 + 2 * 7 * 6) + 8) * 8
4 + (9 * 2 * 6 * (6 + 6 * 7 * 7 + 5) * 9) * 9 + (4 + 8 * 7) * 4 + 4
6 * 6 * 2 + (4 * 2 + 7 + 4 + (2 + 2 * 5)) + 2
8 + 2 + 3 + 3 + 8 + (6 + 4)
8 + 9 + 2 + ((3 * 9 * 3 * 5) * 3 + (2 + 2 + 8 + 6 + 9 + 7)) + 9
6 * (3 * (5 * 4 + 4 * 4 * 4 + 4)) * 8 * (5 + (5 + 2 * 7 + 8) * 3)
3 + ((3 + 7) + 2 + (5 * 3 + 4 * 9))
4 + 5 * 6 * (7 * 5 + 6 * 5 * 5 + (4 * 6 * 9 * 6)) + 7 + 3
7 * 4 * 7 * 5 * (3 + (5 + 6 + 9 * 9 * 3 * 7) * 2 * 8 + 2 + 6)
5 * 4 + (4 * 7 * (3 + 8 + 9)) + 4
(7 + (3 * 5 * 7 + 5 * 8) * (6 + 9 * 6 * 7) * (3 + 9 * 8 + 4) + 8 + 7) * 2 + 4
8 + 7 + (9 + 6 + 7 + 9 + 6 + 4) + (7 * 8 * 6 * 5 * 3) + (3 * 4 * 3 * 8)
7 * ((4 + 4 + 9 + 3 * 3) + (9 * 6 * 8 * 7 * 3 + 6) * 7 + (7 + 2 * 3 + 6 * 2)) + 3 + (5 * 8) + (4 + 9 * 6 * (2 * 5 + 7 * 3 * 5) * 3 * 8)
8 + (3 + (8 + 3 * 4 + 4)) * 2 * 4 * (3 + 4)
(4 + 9 + 4 + (4 + 7 * 3 * 2 * 5 + 7)) * 2
2 * 8
6 * (7 * 5 + (4 * 5 * 2))
(3 + 3 * 4 * 3 + 7 + 4) + 8 + 2 + 4 * 4 * 5
7 * 2 * 5 + (2 * (9 + 6) * (3 * 8 + 4) + 3) * 9
(6 * 9 * (6 + 6 + 7 + 7) * (5 * 7 + 8 * 5 + 2 * 8) + 5 + 8) * 9 * 9 + 3 * 2 + 7
(2 * 3 + 8 + (4 * 2 + 7 * 2 + 7 + 7) + 3 + 6) * 3 * (6 + (9 + 7 * 2 + 2) + 6) + (4 + 3) * 3
4 * (6 * (8 * 8 + 7) + 7) * 6 * 9 * (4 * (6 * 4 * 3 * 2 + 6) + (8 * 9) + (9 + 3) * 4)
5 * 7 * 2 * (2 * 2 * 5 * (8 + 6))
(8 * (7 + 7 + 8)) + 2 + 9 * 9 + 9 * 4
6 + 6 + 5 + (2 * (8 * 7 + 3 * 6) + 9) * 7 + 6
8 + 6 + (8 * 4 * 8 * 2 + (6 * 6 + 9 * 3 + 6)) + 3
9 * 5 * 4 * (5 + (3 + 7) + (4 + 4 * 5 + 5 * 8 * 9) * 5)
5 + 4 * 9 * ((2 * 4 + 8 * 2 * 7 + 2) + 4) * 9 * 3
3 + 6 * (6 + 2 + 3 * 2) + (3 + 5) + ((3 * 6 + 5 + 7 + 8 * 8) * 9 + (5 + 8 * 7 + 6 * 8 + 7) + 7 + 8 + 5)
7 * ((7 + 5 * 3 * 5 + 4) + 7 + (6 * 3 * 6 * 6 * 7 * 7))
((5 + 7 * 9 * 2 + 3) * 2 + 9 * 3) * (4 + 6) * (4 * 7 * (9 + 6 * 8 + 5) * (3 + 8 + 9) + 9 * (8 + 6 * 9 + 6)) * 6 + 4
2 * (6 * 3 + 4 + 4 * 2) + 6 + 7 + 5
2 + 7 + 5 + 5 * ((7 * 6 + 2) * 8 * 8) + (2 * 5 * 4 * 5)
3 + (7 * 8 * 5) + 5 + (5 + (4 * 4 + 7 + 2) + 6 + (8 + 3) * 9 + 4)
6 * (9 + 5 + 6) * 5 + 5 * (7 * (3 * 5 + 6 + 2 * 5) * 2)
(9 + 6 + (9 + 7 * 5 + 6 * 7) * 7 * 3) + 3 + 4 + 6
7 * ((5 + 4 + 6) + 7) + 2 * 3 + (6 + 9 * (6 * 4 * 8 * 3 + 4 * 2) + 7) + 3
7 * (8 + 9 + 5 * (9 * 7 * 9) + 2) + (7 + 7 + (7 + 3 + 2 * 2) + 4 * 2)
3 * (2 * (4 + 6) * 8)
8 + ((6 * 4 * 8 + 4) + 7) * 7
(7 + (2 + 8 * 8 * 6 * 2)) + 7 * 2
(4 * 2 + 4 * 8 + 4) + (3 * 9 + (2 * 4 + 2 * 7) * 9 + 7) * (5 + 9) * (7 + (3 * 4 * 4 * 6) + 8 * 7) + 8 + 8
8 + (2 + 2 * 8 * 7 + 7) + 2 + 4 * 3 + (8 + 9 * 9)
3 + 2 + 8 + (9 + 3 * (3 + 2 + 9 + 7) + 4 * 4 * 7) * 3
5 * 4 * 7 * 3 + (9 * (6 * 6 + 2 * 4) * 8 + 2 * 9)
4 * 7 * (3 + 6 * 6 + 4 + 8) + 5
(8 + (8 + 2 * 9 + 3 * 3) * 8 * 8 * (9 * 6 + 2 * 6)) * 9 + 5 * 2 + 5
5 + 6 + 3 + 4 * 9 + (4 + (4 + 3 + 9 * 2) + 4)
3 * (5 + 3) * 7 + 6
((3 * 2 + 2 * 6 + 5 + 3) + 4) + (4 * (8 + 2 + 9 * 2) * 8 + (8 * 3 + 6 + 2 + 6) * 2) + 7 + 2 * 9
6 * 8 * ((8 * 8 + 3 * 7 + 8 * 4) * 4 + 9) + (8 * 7 * (6 * 8 * 3 * 2) * 3) * 2 * 8
(2 * 7 + 4) * 2 * (5 * 4 + 2 + 5 + (7 + 5) * (4 * 3 + 6 * 8 * 5 + 9)) * 5
(6 * 8) * (7 * 7 + 8 * 3 * 3) * (5 * 8 + 2)
(6 + 6 * 2) * 5 + ((7 * 6 * 8) * 8 * 9 * 4)
(8 * 4 * 9) + ((5 * 3 + 6 * 3) + (9 + 9 + 9 * 2 * 2) * (4 + 9 * 7 + 2 * 2 + 3) + 6) * 7 * 6 * 6
((4 + 3) * (2 * 5 + 8 * 2 * 4) * 9) + 6 + (6 + (5 * 4 * 5 * 3 + 3) * 6 * (5 * 3 + 7 * 2 + 4 + 8)) + 4 + 7
(6 * 9 + 9 + 7) * (6 * 2 * (4 * 7 * 4 + 4 * 5 + 7) + (7 + 5 * 8 * 4 + 9 + 6)) * 7 + 8 * 5 + (9 * 5 * 2 + 7)
6 * 6 + ((2 + 9) * 5 + 2 * 3 + 3 * 3) + 9 * ((4 * 7) + 5 + 8 + 4)
5 + (4 * 5 + 5 * 3 + 7) * 6 * 5 + (2 + (9 + 7 + 8 + 4))
(2 * 4 + 5 + 8 + 6 * 9) + 3 + 6
9 + (9 + 8 * 3) * (3 + 8 + 6 + 5) * 5
(3 + 9 * 5 + 7) + 2
((9 + 5 * 2) * 5 + (4 + 2 * 7) + 9) * 8
(4 + 4) * 9 + 3 + 2 * 8
(3 + 4 * 8 + 9 * 6 + 6) * 5 + 8 + 9
3 * 8 + 9 * (3 * 4)
6 + 7 * 6 * 7
3 * 3 + (8 * 8 * 9 + 3 * 8 + 2) * 3 + 8 * 2
5 + ((6 + 2 * 6) * 8 + 6 * 5) + ((7 + 3) + 2 * 5 + 7 + 6 + 5) + (8 + 2 * 7 + 4 + 2 * 3) * 2 * 5
(6 * (6 * 7) * 7 + 3) * 9 + 6 * 3
(5 * 9 + 7) + 8
(3 + 9 * 3 * 9 * 2) * 9 * 5
5 + (6 * 3)

103
day19.ml Normal file
View file

@ -0,0 +1,103 @@
#load "str.cma";;
(* Common util. Should probably put this in a module or something.. *)
let get_one_line file =
try Some (input_line file) with
End_of_file -> None
let get_lines file =
let rec input lines =
match get_one_line file with
Some line -> input (line :: lines)
| None -> List.rev lines
in input []
let read_file file =
let channel = open_in(file) in
get_lines channel
let explode s = (* convert a string to a list of chars *)
let rec exp i l =
if i < 0 then l else exp (i - 1) (s.[i] :: l) in
exp (String.length s - 1) []
let implode l = String.of_seq (List.to_seq l)
let (<<) f g x = f(g(x))
let (>>) f g x = g(f(x))
let rec find_idx nth x = function (* find nth index of x in a list *)
| [] -> raise (Failure "Not Found")
| h :: t ->
if x = h
then if nth = 0 then 0 else 1 + find_idx (nth-1) x t
else 1 + find_idx nth x t
let rec take n l = (* take the first n elements *)
match n with
| 0 -> []
| n ->
match l with
| [] -> []
| x :: xs -> x :: (take (n-1) xs)
let rec drop n l = (* drop the first n elemnts *)
match n with
| 0 -> l
| n -> drop (n-1) @@ List.tl l
let string_of_char = String.make 1
(* --- *)
type rule = Char of char | List of int list | Pair of rule * rule
type rule' = Char' of char | List' of rule' list | Pair' of rule' * rule' (* deref'd *)
let rec string_of_rule' = function
| Char' x -> string_of_char x
| List' l -> List.fold_left (fun acc x -> acc ^ (string_of_rule' x)) "" l
| Pair' (a, b) -> "\\(" ^ (string_of_rule' a) ^ "\\|" ^ (string_of_rule' b) ^ "\\)"
let rec rule_of_string str =
let str' = String.trim str in
if String.contains str' '|'
then let [l; r] = String.split_on_char '|' str' in
Pair (rule_of_string l, rule_of_string r)
else if String.contains str' '"' then
Char (String.get str' 1)
else
List (List.map int_of_string (String.split_on_char ' ' str'))
let parse_rule_line line =
let [key; rule_string] = String.split_on_char ':' line in
let rule = rule_of_string rule_string in
(int_of_string key, rule)
let read_chunks lines =
let blank_idx = find_idx 0 "" lines in
let rules = take blank_idx lines |> List.map parse_rule_line in
let messages = drop blank_idx lines in
(rules, messages)
let rec deref rules depth rule =
if depth > 20 (* CHEATER MODE *)
then List' []
else
match rule with
| Char x -> Char' x
| Pair (a, b) -> Pair' (deref rules (depth+1) a, deref rules (depth+1) b)
| List l -> List' (List.map (fun key ->
let rule = List.assoc key rules in
deref rules depth rule) l)
let () =
let (rules, messages) = read_file "day19.txt" |> read_chunks in
let rule0 = deref rules 0 (List.assoc 0 rules) in
print_string (string_of_rule' rule0);
let rule0_str = string_of_rule' rule0 in
let r = Str.regexp ("^" ^ rule0_str ^ "$") in
let good = List.filter (fun m -> Str.string_match r m 0) messages in
Printf.printf "\nnum good: %i" (List.length good);

514
day19.txt Normal file
View file

@ -0,0 +1,514 @@
76: 125 57 | 102 58
6: 57 30 | 58 123
62: 58 58 | 57 58
90: 122 57 | 87 58
82: 57 58 | 57 57
118: 102 57 | 125 58
7: 103 57 | 77 58
130: 27 58 | 53 57
101: 58 107 | 57 117
31: 55 58 | 81 57
114: 123 57 | 62 58
48: 103 58 | 94 57
105: 58 113 | 57 20
100: 57 88 | 58 35
127: 121 54
80: 54 58 | 72 57
19: 5 58 | 102 57
28: 95 57 | 23 58
43: 30 58 | 123 57
119: 58 71 | 57 33
44: 94 58 | 24 57
72: 58 58
35: 109 57 | 106 58
85: 127 58 | 132 57
25: 57 30 | 58 102
42: 119 58 | 111 57
86: 58 5 | 57 125
54: 57 121 | 58 57
88: 58 97 | 57 129
71: 110 57 | 46 58
67: 94 57 | 125 58
12: 5 58 | 62 57
112: 58 70 | 57 69
123: 58 57
52: 10 58 | 48 57
122: 14 58 | 68 57
68: 82 58 | 94 57
23: 57 54 | 58 24
64: 58 54 | 57 72
89: 41 57 | 28 58
132: 103 58 | 47 57
115: 58 133 | 57 49
116: 58 103 | 57 77
15: 77 57 | 24 58
92: 58 62 | 57 30
4: 58 99 | 57 75
59: 57 72 | 58 102
26: 52 57 | 108 58
58: "b"
14: 58 103 | 57 30
47: 57 57 | 58 58
37: 58 82 | 57 125
32: 125 57 | 123 58
95: 123 58 | 123 57
83: 57 36 | 58 79
128: 65 58 | 32 57
125: 57 58 | 58 57
11: 42 31 | 42 11 31
65: 62 58
75: 58 1 | 57 67
30: 57 57
102: 121 121
0: 8 11
111: 50 57 | 93 58
113: 57 126 | 58 40
129: 25 58 | 29 57
45: 5 57 | 94 58
104: 24 121
24: 58 121 | 57 58
49: 57 12 | 58 6
17: 57 123 | 58 54
3: 74 57 | 131 58
94: 57 57 | 58 57
98: 57 86 | 58 2
13: 34 57 | 78 58
21: 57 98 | 58 120
107: 86 58 | 17 57
57: "a"
9: 57 112 | 58 90
40: 57 104 | 58 45
38: 58 94 | 57 30
106: 57 63 | 58 76
97: 57 60 | 58 116
96: 57 77 | 58 72
41: 63 57 | 19 58
63: 24 58 | 62 57
78: 57 47 | 58 103
131: 30 57 | 62 58
77: 57 58
55: 57 9 | 58 100
69: 96 58 | 43 57
36: 72 57 | 123 58
33: 58 101 | 57 26
53: 58 47 | 57 94
70: 38 58 | 37 57
20: 84 57 | 13 58
2: 57 123 | 58 72
84: 58 16 | 57 66
34: 58 5 | 57 62
56: 85 58 | 3 57
126: 15 57 | 59 58
87: 57 80 | 58 51
93: 58 61 | 57 4
99: 58 92 | 57 16
110: 57 83 | 58 124
10: 57 24 | 58 62
27: 57 30
29: 54 57 | 103 58
103: 57 121 | 58 58
46: 57 18 | 58 130
50: 89 57 | 115 58
79: 57 5 | 58 103
1: 123 58 | 77 57
61: 57 128 | 58 39
109: 116 58 | 96 57
66: 82 57 | 47 58
117: 53 58 | 91 57
124: 118 57 | 7 58
22: 77 57 | 125 58
39: 58 66 | 57 44
51: 58 77 | 57 47
73: 57 56 | 58 21
60: 77 57 | 82 58
91: 24 58 | 123 57
16: 30 58 | 82 57
120: 22 57 | 64 58
81: 57 105 | 58 73
133: 58 114 | 57 44
18: 57 60 | 58 22
8: 42 | 42 8
108: 58 10 | 57 118
74: 30 57 | 77 58
121: 58 | 57
5: 57 57 | 58 121
aaaabbaaaaababbaabbbbbbbabbbbaabbabaabbbbbbbaaba
ababaaabbbabababbabbbbba
bbbbaaaaabbbababaaabbbaa
bbbbbaaaabbbababbaaaabab
aaabaababbabaabaaabababaabaaaaabbbbabbba
bbaaabababbaabbbbabaaababababaaaabbbaaba
bbbaabbabaabaabaababaaaaabaaabaabaabbbabbaababbb
aaaaaabbabbaabbbbbbbaaaaaaaaabab
bbaaabbbbaababaabbbbbbaabbbbababbabbabaaaabaababbaaaaabbaabaaaba
ababbbbbabbaabbbbbbbbaab
aabbabaaaaabbaabaaaaaabb
aaabaabaaababbabaaabbaba
bbbaaaabbbbbaaabbababaabaaaaabba
aaaabbbbaaabaabaaaaaaaabbaabbaaababbbbbb
bbbbbbaabbaaababababbaaabbabbbaabaaaaaaa
aaabbaaaaabababaaababbbbabbbbabbbabaaaabbbbaabbb
baabbbbbaabbbabaabbaaabbbaaaabaababaabbaabbabaaa
abbaaababaaabbbaaabbbababbaabbbb
bbbaaababbbbaaabbaabbbaaaaaabababbaabaaaabbaaaababbabbaa
bbaaaaabbbabbabbbbabbbaa
baabababbbaaababbabababbabaaabab
babbababbbaaababbbaaaaaabababbbbabaabbaababbbbaabbbaabab
bababbbbbbaaaaaabaabbbbb
aabaaaabbabababbabaaaabaaabbaaaabbabbbbbbbbbabaaababbabb
baabbaabaababbabbabbbaab
abaaabaaabbbabababbababbbaaaaaab
babbaaabaabababaabaabababaaababa
bbbaaaaaaaabbbababaaabab
aaababaaaabaabbbaabaaaabbbababbabababbabaaabbaabbbaabbababbaabab
abbbaabbbabababbbabaabaabbaabbbbabaabbbb
aaaaaaabbaabaabaaabbaaab
aabbabbabbabaabbabaababaaaaaabaa
aaabbaabbabaabaababbbbaa
baabaababbabbaababbabaabbbabbaabaaabbabbabbaaabb
babbbbabbaababaababbbbabbbbaabab
bbaaaaaaabbbbbaabbbbbaabbaaaabbb
aabbbbbbaabbabbabbbbaaaabbbaaaaaabbbaabaabaabaaa
aaabbabbbaaababbaaabaaaabbbaaaaaabbbbbabbababbba
ababbaaabbbabaabbabbbbabbababababababaabaabaaabb
babaaabababaaaaaabaaabbabbaaaababaababbb
bbbabaabaaaaaaabaaabbaaabaababbb
abbaaaaaabbaaabababababababaaaaabaabbbbbabbabbba
abbbaabbbaabaabaaaabbbabaabaabba
aababbaabbaaaaaaaabaabbbbbababaaabababaa
aaabbabbbabaaababaabaaab
bbaaaabbaaabbabbbbbabaababbbbabaabbabbba
bababaaabbaaaaaabaaaabba
baaabaaabaaabbbbbaaaaaaa
bbbaaabaababaabbbbbaabbaaaaaaaabaabbabab
abaababaaabbaaaaaabaabaaabbbabba
aabbbbbbbaaabbbbaaabaabbbbbaaabaabbaaabaabbbababbabbabba
bbaababaaabbbbabbbbaaabbbbbbbbbaabbbabbbaaaaabaa
aabababbaaabaaaaaaaaabab
babaabbbabaaaaaaababbabaababbbbaaaabbaaabbbaabaa
aabaaaabbbaaabbaaabababbbbbbbabbaabbbaaaaabaababbabaaabbbbababbbabbbbaaa
abaabbababbababbaaaabbabaaaabbaaaaaabaaa
bbbaabaaaaabaaaabaababaaabbaabaabbbbabaa
babbabbbbabababbaabaabbbbbbabbbbabbbbbab
abbbabaaaaaabaabaaabbabbabaaaabbabaaabbb
abaaabbababaaabaaababbaabbabaaabbabaabbbaaaabaaaaababbba
bababbbbbaabaaaabaabababbbbaaabaaabbbbaaaabbbbba
ababbbbbaabababbaaababaababbbbbaabaabbaaabaaaaabaabbbbba
babaabaaabbababbaaabbbabbaababba
baaaabbbbbaaaaaaaababbbbaabaabba
abbababbaabbbbbbbbbbbaba
baaaabaaaabbbaaaabababbbbaaabbabaaaabaaaababaaaabbabbbaa
baababbaaaaaaaaababbaabaabbaaabaabbbbaababbbabaabbabbaaabaaaabbbbaaababa
abaaabaaabbaabbbbababbaabaaababbaabababaabbbaaba
baabbaabbbbbababbbaaaaabaaaabaababbbaaababababaababbaabaababbaab
abbbaabbaaaabbaabbaabaab
aabbbaaaaabbbaaaabbaabab
aaaababbabaabbabaaaaabbb
aaababaaaaaaaabbaaaaabab
aaaaaaababbabbababababaa
aaabaaaabaaababbabaaabaabaaabaaabbabbbaaaaaaabaa
abbbababaabaabbbabaabababbaaababbaabbbaababbbaab
babaaaabbbbbbbbabbbaaaabbababaabbabbaaabbbbababbababbababaabbaaa
aaaabbabababbaaaaababbabbaabaaaaabbaabab
bbabaabbaaababaabbaabbbb
aabaabbbbbabbabaabbbbbbbaaaabaababbaaabaabbabbbb
babbabbbaaaabbaabaabbaabbbbbababbbaabbbaaaabbbbababbbaba
abbbbbbabbabaaaababbaabaabababbabbbbbababbbbbaababbbaaaa
ababbbbbaaaababbbabbabbbabaababbbbababbabbbaababaaabbbbb
baaaaaaabbaabbababababbabbbbbaba
bbaaabbbbabbaaaabbbbbaaabaabbaaa
abaaaaaaababbbabbbbbabba
babababbabbaaaaabbabbaabaabbbbaaabbaabba
bbabaaabbababaabbbbabbba
abaaabbaabbaabbbabbaaaaabaabbaabaabbaabb
babbaaabbabbbbbaaabaaaba
babababbbbbbbabbbababbba
abbbababbababaaabbbbababbabbbaba
bbaaaaabbaaababbbbbbaaabbabaabbbabbabbaa
bbabaaaaabaaaabbbaaaaaba
babaabaababbbbbaaaaaaabababababbaabaabaaabaabbbb
babbabaaaabbabbbbaabbbab
bbabaaabbbbbaaaaababababbaababaaabaabbbaabaaabbb
bababaaabbabbaabbabaaaaababbabbaabbabbba
abbaabababababbbabaaabbb
bbabbbaaaaaabbbbbbbaaababbabaabaaabaaabbaabaabaa
baabbaabbabbbbabbaaabaab
aaaaaaabbbbbababbbbbababbabaabbabbbbbbbb
baabaaaabaabbbbabbaaabbababbabaababaaabb
bbaaaaaaabaababbbbbaabaababbaaba
bbbababaaababbaababaaaabbbaabaabbaabbbbb
abaabbabababaaaabbbaabbabaababbbbabbabba
bbbabababbbbbaaabbbbaaabaabbbbba
abbaabbbbbbbababaaaabbbbabbababbbbaabbab
abaaabaabbabbbaaaabbabbbbbbaabab
babaaaaabbabaaaabbabbaaaababababaababbabbabaabba
bbaaabbbbabaaababbabbabaaaaaaababababababaaaaabbabbabbabbaabbbaaaaaaabba
abaaabaaaaabbaabababaaabbaababaababaabbabbbbbbababbbbaba
bbababbababaaababbabbbba
abbbabbaaababbaabbabbaaaaaabaaaababaabab
aaababaababaabaaaaababbbabaabaaa
bbbbbbaababbaaabbbbaaabaaaaaaaabbbbaaababaaabbab
babbbbbaaabababbababaaaababbbabbaabaabba
bbaaababbbabaababaaabbaabbabaaaaaaaabbaabaaaaabb
aabbbaabbbabaababaabbaabbaababba
bbaaababbabbbabbbabaabbbbbababbb
aaababbaaaaaaababbbaaabbabbbaaabaabbbbaaaabaabab
aaababaaabbbabababaaabbabbaaabaaaaabbbba
bbaaaaaaabbabaabbbbababaaaaabbbbaabaaabb
bbabbbababbbbbbbaaaabbaabbaabababaabaabb
babababbabaaabbabbbabbbb
bbabbaabababaaaaaabbabaabaabaabaaabbaaab
aaaaaaabbbabababbbaaaaba
baababaabbabbababaaaaaab
ababababababababbbbbbabbabaaabababbbbbaa
abaabaabaabaaaaaabbababaabbbabbb
babbbbabbababaabbaababba
bbabaaabbaababaaaaaaaaaa
baaabbbbbbbababaabaababaaabababbabbaababababaaba
abbababbbabaaaabaaaaabba
abaababbaabbbaaabbbabbbababbbbbaabababababbbbbabbbbabaab
bbabbbaabaaabaaaaaaaaabbbbaaaaabbbbbbaab
abbbbaababaabbababbbaaabbaabbbab
abbbabbaabbbababbbbaaababababbba
abbaabbbababaabbabaaaabaabaaaabbbabbaaba
aabbbbbabbaaaabbabbbbbababaabaabbabbabbbabbaaabbbaabababababbbbaaabbababbbabbbba
bbaaabbaabaababbababbaba
abaaabbaabaaabaaaaabbabbbabbbaab
ababababbbabaabbabaabaab
aababbabbababbbbaababaaa
abbaaabaaaabbaabbbbbbaab
aababbbbabbaabbaaabaaaaaabaababbabbbbbbbbabaabbbbbabbabb
ababaabbaaaabaabababbaaaabbbababbbabbbbb
abaabbabbababaaabbbabababaabbabbbbaaaaba
bbbaabbabbabbbabbabaaaaaaaaababbaaabbaabbababaaa
aabbabaaabbbabbabaababababaaaababaababaabaabbbaaabaabbaaabbabbba
aaaabbbbbaaababbbababaabbaaaabbbbbabababbaaaaabb
baaaabbbbbabaaaaaaababbb
abbbbaabaaabbbbbbababaaaabaabbbbbbaabaaabbbabbabbbbaaaabaabbbbabbababbbaaabbbabb
bbaaaabbabaaaabbabbaaababbbabaaabaaabbba
abbababbbbbaabbaaaaaabba
babbabaabbbbbabbaaabaaab
abaaabbaaaababaabbaabbbb
abaabbabaaabbaabbaabababbbbabaaaabababba
ababababbabbbaaaababbabb
bbbbabaabbbbbbbbbabbbabbbbbbabaa
babaaaaaaabbabbababaabaababbabba
bbaaabbabababaabaaaaabab
abbbaaabaabaabbbbabbaaababbababbbaabaaab
abaaabaaaaabbabbbbbaabaaababbbbbaabbbbba
aabababbaaaabbbaaaabbbba
aabbbaabbbbaaabbbbbaabbaabababaa
bababbabbbabaababbbaaababababbaaaababbaabbbababb
bbbababaaababbabbabbbaba
aababababababbaababbbaba
aababbabaabbabbbaabaaaabaabbbabb
bbabababbababaaaaaababbabbbaabbb
aababbabbbaaaaabbbabbbba
bbaaaaabbaabaababaaabaaaaababbabbbbbaabbbaabaabbaaaaabbb
baabbaabbbbaaabbababababbbaabbbb
aaaabaaaaaabaaababaababbabbbbbbbababababaaabbbbbaabaaaba
abbbababbababbaabababbba
abbbbbbbaababbabbabbbaaaabaaaabbbaaabbbbbbaaabaaaaaaabbababbbbaa
babbbbbababbaaaaaaaaabaa
abbbbbbaaaaabaabbaaaaabb
aabaaaabbabababbbbaaababaabbbaabbaabbaaabbaabbaabbbbabaa
baaaabbbbaaabbbbaabbbaabbaabaabaaaaabbaaaaaaabaa
aaababbabababaaaaababbbbabababba
bbabbababaabaabaaabbbbbbababaabbabaaaabbabbbbbab
aababbabbbbaaaabbbaababaaababbaabbbbbaba
bababbabbbbbbbaababbbbaa
ababababaaaaaabaabbbbbbaaababbaabaaabaaaaabaaabb
aabbabbbababaaababaababbaababaaa
bbbaabbabaabbbbabbbaabbabaaaaaaa
aabababbabbaaabaaaabaaaaaaabbbabaabbbaba
aaabbaabbbbabaababbaaaab
baabbbbaaaaabaabbaaaaaaa
aaabbaaaabbbabaaababababbbabbbaabbbbaaaaabbbbaaa
aabbbaabbbbbbabbabaababaaaabaabaabbaaaaa
babbabaaaabbbbbbaaabababbbbbbaab
bbbbbabbbababababaaabaaaabaabbbbabaaabab
babbbbbabbaaababbbbabbaa
aaaaaabbbabbbbabbbaaaaabbbbaaaabaabaabaabaababbb
aabbbaaabbbbaaaaabaabaaa
aabababbbababbabaaaaabba
bbbbababbbaaaaaababaabba
aabbaaaaaabbabaaaaaaaabbbbaaabbabbbbbbab
aaaaaabbbbbbababbaaabbba
bbaaaaaababbababbbaaabaa
aaabbaaabbabbbababbbbabbbabaaaaaabbabbababbbbabaabaabbba
babaabaaaaababaabaabbaba
bbabbabaaabbbbabaaaaaababbbbaaabaabaaaababbbbbab
bbababbaabaababbbabbabbbbbaabbba
baaabbaaababbaaabababbabaabbaaaabaaaaaaa
abaaabababbbaaaaaaaaaabbbababbbabababbab
aaaaababaaabbbbbabbbbbab
aaaabbbabbaaaaaaaabaabaa
aabbbbbbabbaaababbaaaaaaaabbabbbbaabaabb
aabbbaabaaabaaaaaabbbbaabaabbaaa
ababbaaaabbbababbbbababb
babaabbbbaababbbbabbaaaaababbabababaaaabaabaaabaabaabbbababbbabb
baaaabbabbbbabbbbababbbbbbabbbaabbbbaaaabbbabaaa
aaabaaaaaaabaababbbbbabbbaababbaaabbaaba
bbabbaaaababaaabbbababaaaaaaabaaaaaaababaaabbbba
aaaabaabaabababbabaabbbb
bbababbaaababbabbabababaaabbaaba
abaaaabbbabbabaabbbbbbab
babaaaababaababaaabbabbbbbbbabba
aaaabaabaaabbabaaaabaaaaaabbbbaaaaaaaabbbabaabbbababbbbb
aaababaababaaabaabbaabbbaaabaaaababaabbbbaabaabb
baababaabbbbbbbababbaaabababbaaaaaaabbaabbabaabbbaaaaabbaabbbbba
bbabbaaabbbaaaabababbbba
bbbbaabbbabaaaaaaaaaaababaabaaaabaabbbabbbaababbbabbbbbbaabaaabb
abaaaabaaaaabaabababaaaabbbbaaab
ababaabbbbbbababbabbbbababaaaaaaabbbaaaa
aaaabbbbabbbbbbaabbbbabbabaaabbb
aabaababbbbbabbabbaaabaaabbaaaab
bababbabbaaaabbbabbabbab
ababbbbbbbbaabaaababbbbbbbaababb
aababbaaaaaabbbbaabbaaaababababbaabaaaaababbbbbbaabbbabb
bbaaaabbabbbbbbaaaabbaabaabbabab
aabbabbaaabaaaabbaababababaaabbb
ababababbbaaaaabaaaabbbaabbbbbbabaabababbabaaababbaabbbabbaabbaa
aabbabbaabbababbabbabaabbabbabba
baaaabbbabbabaabaaabbaabbaaaabaabaaabbba
bbbbaaabbabaaabaababaaaababbababababbaaababaaabbaabbbabbababbbba
bbbabaabbbbaaabababbaaabababbbbaabbababa
bbbaabaaaabbbbbbababbbbbababbbabbbabbbbabbbabbaa
babbababaaaabbbbabbbbaaa
bbabbbabbbaaaaaaaabaaabb
bbabababbbabaaabbaabbbbaaababaaa
aabaaaabbbbaaaaabababbbbabbaabba
aabbbbbbbabaaaaabaaaabaa
bbaaaaaabbbbbabbbbaabbba
bababbbbbabaaabbaaaabbba
ababaaabbababaabababbbbbabbbaaabbbaabbba
bbbbbbbaaaabbbababaaaaab
aaababbababbababbabbbaaaaaababababaaaababababbabbabbabaabaababbabbaaababbbabbbab
babbababbbabaabaabbbaaaa
babbabaaaaaabbabaababbba
babbaaabbabaaaaaaaaabbbbbbbaabbaaababbba
aaabaababaabaaaaaaaabaabaababababbaabbba
bbbaabbabbbaaaaaaabbbaabbbaaaaababaaaaaaaaaabaaaaaabbbba
abbbabbabbababbababbaaba
bbbaaaaabababbaabbbabaaa
babbabbbabbaaabaabbbaabbaabbbbaaaaabbabbaaabaababaabbaaa
bababbbbbbabbaaaabababaa
bbabbaabababababbaaaabaa
babaabaabbabaabbabbbbbbbababaaaaaabbbbbbbbbbababbaabbaba
bbaaabbaaaabaaaaabbaababaabbabab
bbbaaaaaabbbabbaaababbba
aaaabbaaaabaabbbbabaaaabbbbbbbbb
abbababbbbabbaaabaabaaab
aaababbbabbbaaabbbaaabbbaababbbbbabababaaababababbaabaab
bbabbbbaababbbaaabbbbabaaababaaa
bbbaabaaabbbbabbbaaabaaaaabaaaabbbbbaababbaaabaaaaaaaaaa
aaabbbabbbaaababbbabbaaabaaabbaaaaabababbaabbbab
bbabaabbaabbbbaaaabbaaaabaababbbabaabaaa
baaabbbbbbaaabbaabbbbbbaaaabaaab
bbbaaabbabbaaaaabaababbb
aabbabbbaaabaabbbabababbbabbbbabbbabaaabaaaaaaaaaaabbbba
bbbaabbaaaaabbbababbbbaa
aaaaaaabbbaaababaaabaabababbbaba
babababbbaababababaaaabaaaabbbaa
bbbaaaaaabbbbaabaaabaabbbbbaaabb
bbbbbaaabbbbbbbaaaaabbaaaaaabaaa
aabababbaaabbbabbbabaabbbaaabababaaaaaaa
bababaaabbabbbaabaabbaabaaaabbbbbaaababbbbabbabbbaababbb
bbbbbabbaaabbaabbbaababb
bbaaaabbaaabbabbbbabbbaababbbaabbbbbbbab
ababaabbbbabbaabbaaaaaaa
abaaaabaabaababbbababbabaabaababaaaaaaaa
abbbabaabbabababbbbaaaaaabbaabab
bbbbbabbaabbbbaaabbbbbba
bbaaaabbaaaababbbbbbbabbbababbbbaabbabaaaaabbbbbbabaabba
bbbaabaababaaaabaaabbbba
bbababbabbbbabbababaababbbabbbbbaabaabbaabbbabab
abbbabbabbabaabbbaababaaababaabbbbaabaaa
bababaaaaabbbaabbbbbbaabbaabbabb
abbbbbbaabbaaaaaaabbaaaaaabbbaaababaababbbbabbba
bbbabababbbaaabbabbbaaababbbabbb
aaaabaabaabbaaaaaaaaaabababbaabb
bbaaabbbababaabbbbbbbaaaababbabaaabbbbba
bbbaaabbaabaabbbaabbbbaaaababbbbabbbaabbbbaabbba
ababaaabbbabbbabaabababbabababaabbababaa
aabbabbbbabbaaababbbbbab
abaaabbabababbababbaabbbaaaabbabaababbaabbababaaabababbabbbbbbbb
abaabaaababbaabbbbbabaabbabbaabbabaabbaa
ababbbbbaaababaaaababaaa
abaaaabbaabbabbaaabbaaba
baabaaaabbbbababaabbabaaaababbaaabbabbbaabaabbaa
aaabaababaaababbaabbabbbbbbaabbb
abbbababbbabababbaabaabababbabababbbabbaaaaaaaaabaabbabb
abaaabbaaaaaaabbaaaabbaaaaababbababbabaabbaabbabbaabaabb
bbbaabaabbaaaaabaaabbabbaaaababa
bababbaaabbabbabbaaabbabbabaaabbaaaaabba
aabaabbbbaabbbbabababaababaabbbbbbbabbba
bbaabbbaabaabaaabbaabbbb
bababababaaaabbbbbaabbab
bbbbbabbaabaabbbbababbaaabbbaababbbbbbbb
abababaabbbbaaaababaaaaabbaaabbbabbababbbabaabba
abbbbabbbaabbbbaaabbbaababbbabbabaaaabaaaababaab
abaaaaaabababbaaaabbaaab
bbaaaababbbbbbbbbaaaabab
bbaaabbbaababababaabaaaaabaaabaaababbbabaabaaaababbabbbabbbbabbbababbbbaabbabbab
bbbbaaabbbbabbaaaababaaabababaabbabaabababbbbabbbabbbabbabaabbabbbbaaaaa
aababbabababbbbabbaabbbbbbaabaaaaabbaaabbaaaababbabbabaaababaaaa
aabbbbbbbababbabbbaabaaaabaaaaaabbbbababaaabaabaaabbbbbbabaabbbbaaababbbbaaaabba
baabbbbaaababbbbbbbbaaababaaaaabaabaabab
abaaaababbbbbbbaaaaaaabbbababbaaabbaabab
bbbbaaaaabbbabaaaaaaaaaa
bbbabaabbababbbbaabbabab
bbabaaaaabbaaabaabbaabba
bbabaaabbaabaaaababababaaaabbbbbbbaababb
abbbbaaababaabaababaabbbaabbbbbbbabaabbb
aabbbaababaababbaaabababbababaabaabaaaaa
baaabbbbaabbabbaabbbabbb
aaabbabbbaaabbaaaabbaaaabaabaabb
abaaabbababbaaaaabbbaaaa
aabbabbaaaabbabbaaabbbba
baaabaaabbbbabaabbbabbbbabaaaaababaaabaaabbbbbbaababbbbbbbbbabbaabbabbaababbaabababbaaba
aaabbabbbbbbaaabaaababbbbabbbaaaaaabbbba
aaabaaaaaabbabaaabaabbabaababbbabaababbb
aabababbabaababababbbaba
bbbbaaaabbaaaaaababaabbb
baabaababaaaabbbabbbbaabbaabbabb
baaaabbbaaaaaabaabbbaabbbabaabaaabbaaaab
aaabaabaaaabbabbbbaabbbb
bbbaaaaaababaaaababaabaabbbaabaababbaaaabbaaaaaaaabaaabb
abaabababbbaabaabbaaaaabaabbabab
aaababaabababbaabbbbbaaabaaabbbbbabaababbaabbaba
aaaabaababaabbabaaabbaaaababaaabaaabaabababbababaababaab
aaaaaabbaaabbabbbaabbbab
bbabbaabbbabbaabbbabbaaabbbbbaba
baabbbbaaaaaaababbbbbbbaabaabbbaaabbaabb
bbaaababababaaabbabbbaba
baaabaaabbbaaababbabbbaaaabbabaaabbabbab
bbaaabbbaaabaabbbaabbabb
bbbabaabaabbbbbbbabaabab
babbaaaaaaababbabaabaaaaababaaabbaabaabababababaaaaaabaabbaabbba
bbabbaabbaaabaaabaabaabbaabbabab
babbaaabaaabaaaabaaabbbbaababaaababbbbaa
abbaaaaababbbbbaabbaabaa
babbabababaaaabbbbbabaaa
abaaabaabbaaabbaaaabaabbaabbbabaaaaababa
bbbbabbbabbaabbabaaabbbaabbababbbabbbaabaabbababaabbabaabbabbbaaabaaabbbbbbabbaa
aababbabbbabaababbabaaab
baabbbbabbaababaaabababbaaabbabbaaabaabbaaabbaaabbabbbbbabbbbaaa
ababababababaaaabbbbabba
aabbbaaaaaababbbbbbaabaaabbbabababbaabbbaaaaabaa
bababaabbabbaaabbbbbbaba
abaaaabbbababbbbabaaabaaabbaaaab
babbababbaabbaabaaababaabaaabbaaaabbaaabbbababbbbabbbbaa
aaaabbababbbaabbbababbbbaaababbbabbaabab
bbaaaaaababbbbbaaabbbbbbabbbaaababaabababaaaaaab
abaaabbaaababbabbbbbbaaaababaaaaaabbaaab
aaababbabbbaabaabababbaabbabbbababbaaaabbaaaaaabaaaaabbbbabbaabb
bababbaaababbaaababbabaaaababbba
baabaabaabaaabaaaabbbaabaaaabaaabaaabbab
aaaaaabbabbababbbbaabaab
baabaababbbbaaaababbabab
aaaaaabbaaaabbaaaaaaaababaaaabaabbababbb
bbabaaababaaaabaababbbbbabaabbba
aaaababbbabaaababbbbaaba
babbaaabbaabbaabbbbbababbabaabaaabbbbaabaabbaaba