added day 11 of aoc-2021
authorBrendan Hansen <brendan.f.hansen@gmail.com>
Sat, 11 Dec 2021 15:38:42 +0000 (09:38 -0600)
committerBrendan Hansen <brendan.f.hansen@gmail.com>
Sat, 11 Dec 2021 15:38:42 +0000 (09:38 -0600)
core/container/set.onyx
tests/aoc-2021/day11 [new file with mode: 0644]
tests/aoc-2021/day11.onyx [new file with mode: 0644]
tests/aoc-2021/input/day11.txt [new file with mode: 0644]

index c421bff21c4948b550ae5b0f5128a2444a9d1b65..d2c7f3bd0b01ad85a63b03d7dbc332844e2aa133 100644 (file)
@@ -57,6 +57,7 @@ free :: (use set: ^Set($T)) {
 }
 
 insert :: (use set: ^Set($T), value: T) {
+    if hashes.data == null do init(set);
     lr := lookup(set, value);
 
     if lr.entry_index >= 0 do return;
@@ -98,7 +99,7 @@ remove :: (use set: ^Set($T), value: T) {
 }
 
 clear :: (use set: ^Set($T)) {
-    array.fill(^hashes, -1);
+    array.fill(hashes, -1);
     array.clear(^entries);
 }
 
@@ -106,20 +107,21 @@ empty :: (use set: ^Set($T)) -> bool {
     return entries.count == 0;
 }
 
+#match (package core.iter).as_iterator iterator
 iterator :: (set: ^Set($T)) -> Iterator(T) {
     Context :: struct (T: type_expr) {
-        entry_array: [..] Set.Entry(T);
+        set: ^Set(T);
         position: i32;
     }
 
     context := new(Context(T));
-    context.entry_array = set.entries;
+    context.set = set;
     context.position = 0;
 
     next :: ($T: type_expr, use context: ^Context(T)) -> (T, bool) {
-        if position < entry_array.count {
+        if position < set.entries.count {
             defer position += 1;
-            return entry_array[position].value, true;
+            return set.entries[position].value, true;
 
         } else {
             return __zero_value(T), false;
diff --git a/tests/aoc-2021/day11 b/tests/aoc-2021/day11
new file mode 100644 (file)
index 0000000..fbf33c9
--- /dev/null
@@ -0,0 +1,2 @@
+Part 1: 1669
+Part 2: 351
diff --git a/tests/aoc-2021/day11.onyx b/tests/aoc-2021/day11.onyx
new file mode 100644 (file)
index 0000000..c3a5314
--- /dev/null
@@ -0,0 +1,79 @@
+#load "core/std"
+
+use package core
+
+Pos :: struct {x, y:i32;}
+#match hash.to_u32 (use p: Pos) => x * 45238271 + y * 34725643;
+#operator == (p1, p2: Pos) => p1.x == p2.x && p1.y == p2.y;
+
+main :: (args) => {
+    for file: os.with_file("./tests/aoc-2021/input/day11.txt") {
+        reader := io.reader_make(file);
+
+        octopuses: [..] u32;
+        while !io.reader_empty(^reader) {
+            line := io.read_line(^reader, consume_newline=false, inplace=true);
+            io.skip_whitespace(^reader);
+
+            for ch: line do octopuses << ~~(ch - #char "0");
+        }
+
+        get_octopus :: macro (x, y) => {
+            if x < 0 || y < 0 || x >= 10 || y >= 10 do return -1;
+            return octopuses[y * 10 + x];
+        }
+
+        set_octopus :: macro (x, y, v: i32) {
+            if !(x < 0 || y < 0 || x >= 10 || y >= 10) {
+                octopuses[y * 10 + x] = v;
+            }
+        }
+
+        inc_octopus :: macro (x, y) => {
+            if x < 0 || y < 0 || x >= 10 || y >= 10 do return -1;
+            octopuses[y * 10 + x] += 1;
+            return octopuses[y * 10 + x];
+        }
+
+        flash_count := 0;
+
+        step := 0;
+        sync_step := 0;
+        while true {
+            step += 1;
+            for ^o: octopuses do *o += 1;
+
+            #persist to_flash: Set(Pos);
+            for y: 10 do for x: 10 {
+                if get_octopus(x, y) >= 10 {
+                    to_flash << .{x, y};
+                }
+            }
+
+            for flash: iter.as_iterator(^to_flash) {
+                for y: -1 .. 2 do for x: -1 .. 2 {
+                    if y == 0 && x == 0 do continue;
+
+                    if inc_octopus(flash.x + x, flash.y + y) >= 10 {
+                        to_flash << .{flash.x + x, flash.y + y};
+                    }
+                }
+            }
+
+            for flash: iter.as_iterator(^to_flash) {
+                set_octopus(flash.x, flash.y, 0);
+                if step <= 100 do flash_count += 1;
+            }
+
+            if to_flash.entries.count == 100 {
+                sync_step = step;
+                break;
+            }
+
+            to_flash->clear();
+        }
+
+        printf("Part 1: {}\n", flash_count);
+        printf("Part 2: {}\n", sync_step);
+    }
+}
\ No newline at end of file
diff --git a/tests/aoc-2021/input/day11.txt b/tests/aoc-2021/input/day11.txt
new file mode 100644 (file)
index 0000000..a2f9f5b
--- /dev/null
@@ -0,0 +1,10 @@
+6788383436
+5526827441
+4582435866
+5152547273
+3746433621
+2465145365
+6324887128
+8537558745
+4718427562
+2283324746
\ No newline at end of file