about summary refs log tree commit diff
path: root/aoc/2021/10
diff options
context:
space:
mode:
Diffstat (limited to 'aoc/2021/10')
-rw-r--r--aoc/2021/10/Stack.zig35
-rw-r--r--aoc/2021/10/part-one.zig32
-rw-r--r--aoc/2021/10/part-two.zig44
3 files changed, 111 insertions, 0 deletions
diff --git a/aoc/2021/10/Stack.zig b/aoc/2021/10/Stack.zig
new file mode 100644
index 0000000..1aab8eb
--- /dev/null
+++ b/aoc/2021/10/Stack.zig
@@ -0,0 +1,35 @@
+const Allocator = @import("std").mem.Allocator;
+const Self = @This();
+
+allocator: *Allocator,
+memory: []u8,
+len: usize,
+
+pub fn alloc(allocator: *Allocator, size: usize) !Self {
+    return Self{
+        .allocator = allocator,
+        .memory = try allocator.alloc(u8, size),
+        .len = 0,
+    };
+}
+
+pub fn free(self: *Self) void {
+    self.allocator.free(self.memory);
+    self.* = undefined;
+}
+
+pub fn push(self: *Self, node: u8) void {
+    self.memory[self.len] = node;
+    self.len += 1;
+}
+
+pub fn pop(self: *Self) ?u8 {
+    if (self.len < 1)
+        return null;
+    self.len -= 1;
+    return self.memory[self.len];
+}
+
+pub fn reset(self: *Self) void {
+    self.len = 0;
+}
diff --git a/aoc/2021/10/part-one.zig b/aoc/2021/10/part-one.zig
new file mode 100644
index 0000000..130fc4a
--- /dev/null
+++ b/aoc/2021/10/part-one.zig
@@ -0,0 +1,32 @@
+const Stack = @import("Stack.zig");
+const page_allocator = std.heap.page_allocator;
+const print = std.debug.print;
+const std = @import("std");
+const tokenize = std.mem.tokenize;
+
+pub fn main() !void {
+    var input = tokenize(@embedFile("input"), "\n");
+    var max_len: usize = 0;
+    while (input.next()) |line| {
+        if (line.len > max_len)
+            max_len = line.len;
+    }
+    var stack = try Stack.alloc(page_allocator, max_len);
+    defer stack.free();
+
+    var sum: usize = 0;
+    defer print("{}\n", .{ sum });
+    input.reset();
+    while (input.next()) |line| : (stack.reset())
+        for (line) |c|
+            switch (c) {
+                '(', '[', '{', '<' => stack.push(c),
+                else => if (stack.pop().? ^ c > 6) {
+                    sum += @as(usize, switch (c) {
+                        ')' => 3, ']' => 57, '}' => 1197, '>' => 25137,
+                        else => unreachable,
+                    });
+                    break;
+                },
+            };
+}
diff --git a/aoc/2021/10/part-two.zig b/aoc/2021/10/part-two.zig
new file mode 100644
index 0000000..4578272
--- /dev/null
+++ b/aoc/2021/10/part-two.zig
@@ -0,0 +1,44 @@
+const Stack = @import("Stack.zig");
+const desc = std.sort.desc(usize);
+const indexOfScalar = std.mem.indexOfScalar;
+const page_allocator = std.heap.page_allocator;
+const print = std.debug.print;
+const sort = std.sort.sort;
+const std = @import("std");
+const tokenize = std.mem.tokenize;
+
+pub fn main() !void {
+    var input = tokenize(@embedFile("input"), "\n");
+    var i: usize = 0;
+    var max_len: usize = 0;
+    while (input.next()) |line| : (i += 1) {
+        if (line.len > max_len)
+            max_len = line.len;
+    }
+    var stack = try Stack.alloc(page_allocator, max_len);
+    defer stack.free();
+
+    var scores = try page_allocator.alloc(usize, i);
+    defer page_allocator.free(scores);
+    input.reset();
+    loop: while (input.next()) |line| : (stack.reset()) {
+        i -= 1;
+        scores[i] = 0;
+        for (line) |c|
+            switch (c) {
+                '(', '[', '{', '<' => stack.push(c),
+                else => if (stack.pop().? ^ c > 6) continue :loop,
+            };
+        while (stack.pop()) |c| {
+            scores[i] *= 5;
+            scores[i] += @as(usize, switch (c) {
+                '(' => 1, '[' => 2, '{' => 3, '<' => 4,
+                else => unreachable,
+            });
+        }
+    }
+
+    sort(usize, scores, {}, desc);
+    i = indexOfScalar(usize, scores, 0).?;
+    print("{}\n", .{ scores[i / 2] });
+}