From 5bab305b7166befa27a43238ca1e72a86310567c Mon Sep 17 00:00:00 2001 From: Dustin Swan Date: Fri, 18 Dec 2020 14:22:49 -0500 Subject: [PATCH] day 17 yo --- day17.1.ml | 94 +++++++++++++++++++++++++++++++++++++++++++++++++++ day17.2.ml | 99 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 193 insertions(+) create mode 100644 day17.1.ml create mode 100644 day17.2.ml diff --git a/day17.1.ml b/day17.1.ml new file mode 100644 index 0000000..a41aa52 --- /dev/null +++ b/day17.1.ml @@ -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'); diff --git a/day17.2.ml b/day17.2.ml new file mode 100644 index 0000000..66a2f9a --- /dev/null +++ b/day17.2.ml @@ -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;