about summary refs log tree commit diff
path: root/aoc/2021
diff options
context:
space:
mode:
authorNguyễn Gia Phong <mcsinyx@disroot.org>2021-12-10 18:48:20 +0700
committerNguyễn Gia Phong <mcsinyx@disroot.org>2021-12-10 18:48:20 +0700
commitf53ac491b1ec74ad9c44d20065517467c1877190 (patch)
tree33494f5bd7d8c72dade242c6862cb1bc7f095ab3 /aoc/2021
parent1606066809130d544aaf722d617a1df5670602cb (diff)
downloadcp-f53ac491b1ec74ad9c44d20065517467c1877190.tar.gz
[aoc/2021] Finish day 10
Diffstat (limited to 'aoc/2021')
-rw-r--r--aoc/2021/10/part-one.zig34
-rw-r--r--aoc/2021/10/part-two.zig56
-rw-r--r--aoc/2021/10/stack.zig39
3 files changed, 129 insertions, 0 deletions
diff --git a/aoc/2021/10/part-one.zig b/aoc/2021/10/part-one.zig
new file mode 100644
index 0000000..27ac20c
--- /dev/null
+++ b/aoc/2021/10/part-one.zig
@@ -0,0 +1,34 @@
+const Stack = @import("stack.zig").Stack;
+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(u8).alloc(page_allocator, max_len);
+    defer stack.free();
+
+    var sum: usize = 0;
+    defer print("{}\n", .{ sum });
+    input.reset();
+    while (input.next()) |line| {
+        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;
+                },
+            };
+        stack.reset();
+    }
+}
diff --git a/aoc/2021/10/part-two.zig b/aoc/2021/10/part-two.zig
new file mode 100644
index 0000000..6e5b11d
--- /dev/null
+++ b/aoc/2021/10/part-two.zig
@@ -0,0 +1,56 @@
+const Stack = @import("stack.zig").Stack;
+const asc = std.sort.asc(usize);
+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 incomplete: usize = 0;
+    var max_len: usize = 0;
+    while (input.next()) |line| : (incomplete += 1) {
+        if (line.len > max_len)
+            max_len = line.len;
+    }
+
+    var stack = try Stack(u8).alloc(page_allocator, max_len);
+    defer stack.free();
+    input.reset();
+    while (input.next()) |line| {
+        for (line) |c|
+            switch (c) {
+                '(', '[', '{', '<' => stack.push(c),
+                else => if (stack.pop() ^ c > 6) {
+                    incomplete -= 1;
+                    break;
+                },
+            };
+        stack.reset();
+    }
+
+    var scores = try page_allocator.alloc(usize, incomplete);
+    defer page_allocator.free(scores);
+    input.reset();
+    loop: while (input.next()) |line| {
+        stack.reset();
+        for (line) |c|
+            switch (c) {
+                '(', '[', '{', '<' => stack.push(c),
+                else => if (stack.pop() ^ c > 6) continue :loop,
+            };
+        incomplete -= 1;
+        scores[incomplete] = 0;
+        while (stack.len > 0) {
+            scores[incomplete] *= 5;
+            scores[incomplete] += @as(usize, switch (stack.pop()) {
+                '(' => 1, '[' => 2, '{' => 3, '<' => 4,
+                else => unreachable,
+            });
+        }
+    }
+
+    sort(usize, scores, {}, asc);
+    print("{}\n", .{ scores[scores.len / 2] });
+}
diff --git a/aoc/2021/10/stack.zig b/aoc/2021/10/stack.zig
new file mode 100644
index 0000000..1002d61
--- /dev/null
+++ b/aoc/2021/10/stack.zig
@@ -0,0 +1,39 @@
+const Allocator = @import("std").mem.Allocator;
+
+pub fn Stack(comptime T: type) type {
+    return struct {
+        allocator: *Allocator,
+        memory: []T,
+        len: usize,
+
+        const Self = @This();
+
+        pub fn alloc(allocator: *Allocator, size: usize) !Self {
+            return Self{
+                .allocator = allocator,
+                .memory = try allocator.alloc(T, size),
+                .len = 0,
+            };
+        }
+
+        pub fn free(self: *Self) void {
+            self.allocator.free(self.memory);
+            self.* = undefined;
+        }
+
+        pub fn push(self: *Self, node: T) void {
+            self.memory[self.len] = node;
+            self.len += 1;
+        }
+
+        pub fn pop(self: *Self) T {
+            self.len -= 1;
+            return self.memory[self.len];
+        }
+
+        pub fn reset(self: *Self) void {
+            self.len = 0;
+        }
+    };
+}
+