added day 17
authorBrendan Hansen <brendan.f.hansen@gmail.com>
Thu, 17 Dec 2020 15:04:09 +0000 (09:04 -0600)
committerBrendan Hansen <brendan.f.hansen@gmail.com>
Thu, 17 Dec 2020 15:04:09 +0000 (09:04 -0600)
day17.onyx [new file with mode: 0644]
input/day17.txt [new file with mode: 0644]

diff --git a/day17.onyx b/day17.onyx
new file mode 100644 (file)
index 0000000..49f9929
--- /dev/null
@@ -0,0 +1,110 @@
+#include_file "core/std/wasi"
+
+use package core
+use package core.string.reader as reader
+
+CubePos :: struct {
+    x : i32;
+    y : i32;
+    z : i32;
+    w : i32;
+}
+
+CubeState :: struct {
+    alive : bool = false;
+    next  : bool = false;
+}
+
+proc (c: CubePos) -> u32 #add_overload map.hash_function {
+    return 17 * c.x + 13 * c.y + 11 * c.z + 19 * c.w;
+}
+
+proc (a: CubePos, b: CubePos) -> bool #add_overload map.cmp_function {
+    return (a.x == b.x)
+        && (a.y == b.y)
+        && (a.z == b.z)
+        && (a.w == b.w);
+}
+
+get_neighbor_count :: proc (cubes: ^map.Map(CubePos, CubeState), pos: CubePos) -> u32 {
+    count := 0;
+
+    for x: -1 .. 2 do for y: -1 .. 2 do for z: -1 .. 2 do for w: -1 .. 2{
+        if x == 0 && y == 0 && z == 0 && w == 0 do continue;
+        key := CubePos.{ pos.x + x, pos.y + y, pos.z + z, pos.w + w };
+        state := map.get(cubes, key, CubeState.{});
+        if state.alive do count += 1;
+    }
+
+    return count;
+}
+
+main :: proc (args: [] cstr) {
+    contents := file.get_contents("input/day17.txt");
+    defer string.free(contents);
+
+    file := reader.make(contents);
+
+    cubes : map.Map(CubePos, CubeState);
+    map.init(^cubes, 1021);
+    defer map.free(^cubes);
+
+    z := 0;
+    while !reader.empty(^file) {
+        line := reader.read_line(^file);
+
+        x := 0;
+        for ch: line {
+            if ch == #char "#" do map.put(^cubes, CubePos.{ x, 0, z, 0 }, CubeState.{ alive = true });
+
+            x += 1;
+        }
+
+        z += 1;
+    }
+
+    cubes_to_consider : [..] CubePos;
+    array.init(^cubes_to_consider);
+    defer array.free(^cubes_to_consider);
+
+    for i: 0 .. 6 {
+        for ^cube_entry: cubes.entries {
+            if cube_entry.value.alive {
+                for x: -1 .. 2 do for y: -1 .. 2 do for z: -1 .. 2 do for w: -1 .. 2 {
+                    array.push(^cubes_to_consider, CubePos.{
+                        cube_entry.key.x + x,
+                        cube_entry.key.y + y,
+                        cube_entry.key.z + z,
+                        cube_entry.key.w + w
+                    });
+                }
+            }
+        }
+
+        for ^cube: cubes_to_consider {
+            state  := map.get(^cubes, *cube, CubeState.{});
+            ncount := get_neighbor_count(^cubes, *cube);
+            
+            if state.alive {
+                state.next = ncount == 2 || ncount == 3;
+            } else {
+                state.next = ncount == 3;
+            }
+
+            map.put(^cubes, *cube, state);
+        }
+
+        for ^cube: cubes_to_consider {
+            state := map.get(^cubes, *cube, CubeState.{});
+            state.alive = state.next;
+            map.put(^cubes, *cube, state);
+        }
+
+        array.clear(^cubes_to_consider);
+    }
+
+    active_count := 0;
+    for ^cube_entry: cubes.entries do if cube_entry.value.alive do active_count += 1;
+
+    printf("Active count: %i\n", active_count);
+}
\ No newline at end of file
diff --git a/input/day17.txt b/input/day17.txt
new file mode 100644 (file)
index 0000000..f215d03
--- /dev/null
@@ -0,0 +1,8 @@
+.#.#.#..
+..#....#
+#####..#
+#####..#
+#####..#
+###..#.#
+#..##.##
+#.#.####
\ No newline at end of file