From: Brendan Hansen Date: Tue, 14 Dec 2021 20:05:46 +0000 (-0600) Subject: added day 14 of aoc-2021 X-Git-Url: https://git.brendanfh.com/?a=commitdiff_plain;h=b0e7d79705fb03f059dd3c16dcabc2a3316b4590;p=onyx.git added day 14 of aoc-2021 --- diff --git a/core/io/reader.onyx b/core/io/reader.onyx index ca14f2f4..edc568db 100644 --- a/core/io/reader.onyx +++ b/core/io/reader.onyx @@ -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); diff --git a/core/io/writer.onyx b/core/io/writer.onyx index 8928c986..05766b12 100644 --- a/core/io/writer.onyx +++ b/core/io/writer.onyx @@ -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 index 00000000..6e6f1149 --- /dev/null +++ b/tests/aoc-2021/day14 @@ -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 index 00000000..088ba4b3 --- /dev/null +++ b/tests/aoc-2021/day14.onyx @@ -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 index 00000000..2c261d8b --- /dev/null +++ b/tests/aoc-2021/input/day14.txt @@ -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