added day 14 of aoc-2021
authorBrendan Hansen <brendan.f.hansen@gmail.com>
Tue, 14 Dec 2021 20:05:46 +0000 (14:05 -0600)
committerBrendan Hansen <brendan.f.hansen@gmail.com>
Tue, 14 Dec 2021 20:05:46 +0000 (14:05 -0600)
core/io/reader.onyx
core/io/writer.onyx
tests/aoc-2021/day14 [new file with mode: 0644]
tests/aoc-2021/day14.onyx [new file with mode: 0644]
tests/aoc-2021/input/day14.txt [new file with mode: 0644]

index ca14f2f4490c1bdb770dabdab5ab7a923a928292..edc568dba09307241bb8eec63a6c3875c0fd16eb 100644 (file)
@@ -86,6 +86,8 @@ read_all :: (use reader: ^Reader, allocator := context.allocator) -> [] u8 {
 
 read_byte :: (use reader: ^Reader) -> u8 {
     while start == end {
+        if reader_empty(reader) do return 0;
+
         if error != .None {
             reader_consume_error(reader);
             return 0;
@@ -127,6 +129,7 @@ read_bytes :: (use reader: ^Reader, bytes: [] u8) -> (i32, Error) {
 
     if start == end {
         if error != .None do return 0, reader_consume_error(reader);
+        if reader_empty(reader) do return 0, reader_consume_error(reader);
 
         if n >= buffer.count {
             error, n = stream_read(stream, bytes);
index 8928c98675fe332b9ad58af653ad8705147f0fa9..05766b12d2524a2fbcf5c28fd29917a4d39174f9 100644 (file)
@@ -12,6 +12,13 @@ writer_make :: (s: ^Stream) -> Writer {
     return Writer.{ s };
 }
 
+string_builder :: (allocator := context.allocator) -> (Writer, ^DynamicStringStream) {
+    new_stream := new(DynamicStringStream, allocator=allocator);
+    *new_stream = dynamic_string_stream_make();
+
+    return writer_make(new_stream), new_stream;
+}
+
 write_byte :: (use writer: ^Writer, byte: u8) {
     stream_write_byte(stream, byte);
 }
diff --git a/tests/aoc-2021/day14 b/tests/aoc-2021/day14
new file mode 100644 (file)
index 0000000..6e6f114
--- /dev/null
@@ -0,0 +1,13 @@
+{
+    H => 206420145579
+    S => 252943215762
+    C => 422415532942
+    K => 193200271244
+    P => 6287180922765
+    F => 12464638059775
+    B => 211999150163
+    O => 198828019091
+    V => 274816464465
+    N => 378279145958
+}
+Part 2: 12271437788530
diff --git a/tests/aoc-2021/day14.onyx b/tests/aoc-2021/day14.onyx
new file mode 100644 (file)
index 0000000..088ba4b
--- /dev/null
@@ -0,0 +1,98 @@
+#load "core/std"
+
+use package core
+
+Rule :: struct {
+    pair: Pair;
+    insert: u8;
+}
+
+Pair :: struct {a, b:u8;}
+#match hash.to_u32 (p: Pair) => cast(u32) (p.a * 3 + p.b * 7);
+#operator == (p1, p2: Pair) => p1.a == p2.a && p1.b == p2.b;
+
+State :: struct {
+    now, next: u64;
+}
+
+// Nicer way of printing a Map.
+#match io.write (w: ^io.Writer, x: ^Map($K, $V)) {
+    io.write(w, "{\n");
+    for e: x.entries {
+        io.write(w, "    {} => {}\n", e.key, e.value);
+    }
+    io.write(w, "}");
+}
+
+main :: (args) => {
+    for file: os.with_file("./tests/aoc-2021/input/day14.txt") {
+        reader := io.reader_make(file);
+
+        start_polymer := io.read_line(^reader, consume_newline=false);
+        io.skip_whitespace(^reader);
+
+        rules: [..] Rule;
+        while !io.reader_empty(^reader) {
+            r: Rule;
+            io.read_bytes(^reader, .{cast(^u8) ^r.pair, 2});
+            io.skip_bytes(^reader, 4);
+            r.insert = io.read_byte(^reader);
+
+            rules << r;
+            io.skip_whitespace(^reader);
+        }
+
+        polymer_state: Map(Pair, State);
+        add_to_state :: macro (pair: Pair, count: u64) {
+            if polymer_state->has(pair) {
+                (^polymer_state[pair]).next += ~~count;
+            } else {
+                polymer_state[pair] = .{ 0, ~~count };
+            }
+        }
+
+        step_state :: macro () {
+            for^ polymer_state.entries {
+                it.value.now = it.value.next;
+                it.value.next = 0;
+            }
+        }
+
+        for start_polymer.count - 1 {
+            p := Pair.{ start_polymer[it], start_polymer[it + 1] };
+            add_to_state(p, 1);
+        }
+
+        step_state();
+
+        for 40 {
+            for^ rule: rules {
+                pair_count := ^polymer_state[rule.pair];
+                if pair_count != null {
+                    if pair_count.now > 0 {
+                        pair1 := Pair.{ rule.pair.a, rule.insert };
+                        pair2 := Pair.{ rule.insert, rule.pair.b };
+                        add_to_state(pair1, pair_count.now);
+                        add_to_state(pair2, pair_count.now);
+                    }
+                }
+            }
+            step_state();
+        }
+
+        mode: Map(u8, u64);
+        for^ polymer_state.entries {
+            if !mode->has(it.key.b) {
+                mode[it.key.b] = it.value.now;
+            } else {
+                mode[it.key.b] = mode[it.key.b] + it.value.now;
+            }
+        }
+
+        maximum := array.fold(mode.entries, cast(u64) 0, (x, y) => math.max(x.value, y));
+        minimum := array.fold(mode.entries, maximum, (x, y) => math.min(x.value, y));
+
+        println(^mode);
+        printf("Part 2: {}\n", maximum - minimum - 1);
+    }
+}
\ No newline at end of file
diff --git a/tests/aoc-2021/input/day14.txt b/tests/aoc-2021/input/day14.txt
new file mode 100644 (file)
index 0000000..2c261d8
--- /dev/null
@@ -0,0 +1,102 @@
+KHSSCSKKCPFKPPBBOKVF
+
+BB -> C
+BC -> B
+BF -> N
+BH -> F
+BK -> V
+BN -> O
+BO -> F
+BP -> O
+BS -> K
+BV -> F
+CB -> V
+CC -> S
+CF -> H
+CH -> H
+CK -> C
+CN -> O
+CO -> B
+CP -> V
+CS -> P
+CV -> N
+FB -> V
+FC -> V
+FF -> P
+FH -> F
+FK -> K
+FN -> C
+FO -> F
+FP -> F
+FS -> C
+FV -> K
+HB -> N
+HC -> P
+HF -> K
+HH -> F
+HK -> H
+HN -> B
+HO -> S
+HP -> H
+HS -> K
+HV -> B
+KB -> C
+KC -> P
+KF -> H
+KH -> V
+KK -> N
+KN -> V
+KO -> O
+KP -> B
+KS -> C
+KV -> B
+NB -> N
+NC -> K
+NF -> F
+NH -> C
+NK -> S
+NN -> F
+NO -> H
+NP -> H
+NS -> C
+NV -> N
+OB -> V
+OC -> C
+OF -> V
+OH -> B
+OK -> F
+ON -> S
+OO -> K
+OP -> S
+OS -> N
+OV -> V
+PB -> F
+PC -> O
+PF -> F
+PH -> N
+PK -> H
+PN -> F
+PO -> H
+PP -> H
+PS -> C
+PV -> V
+SB -> K
+SC -> C
+SF -> H
+SH -> V
+SK -> B
+SN -> B
+SO -> C
+SP -> F
+SS -> P
+SV -> H
+VB -> V
+VC -> S
+VF -> F
+VH -> B
+VK -> O
+VN -> B
+VO -> B
+VP -> P
+VS -> K
+VV -> N
\ No newline at end of file