day 17 yo
parent
731d7aff61
commit
5bab305b71
@ -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');
|
@ -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;
|
Loading…
Reference in New Issue