const std = @import("std"); const path = "data/day10/input.txt"; const Pairs = [4][2]u8{ .{ '(', ')' }, .{ '[', ']' }, .{ '{', '}' }, .{ '<', '>' }, }; const RetType = u64; fn parseInput() anyerror!RetType { const input = @embedFile(path); var lines = std.mem.tokenize(u8, input, "\n"); var gpa = std.heap.GeneralPurposeAllocator(.{}){}; const allocator = gpa.allocator(); var pairs = std.ArrayList(u8).init(allocator); defer pairs.deinit(); var scores = std.ArrayList(RetType).init(allocator); defer scores.deinit(); lines: while (lines.next()) |line| { pairs.clearRetainingCapacity(); chars: for (line) |ch| { for (Pairs) |p| { if (ch == p[1]) { // closing pair const last = pairs.popOrNull(); // XXX: zig compiler error! if (last == null) { continue :lines; } else if (last != p[0]) { continue :lines; } continue :chars; } } try pairs.append(ch); } var score: RetType = 0; var i: usize = pairs.items.len; while (i > 0) : (i -= 1) { score *= 5; score += getValue(pairs.items[i - 1]); } try scores.append(score); } std.sort.sort(RetType, scores.items, {}, comptime std.sort.asc(RetType)); return scores.items[scores.items.len / 2]; } fn getValue(ch: u8) RetType { var ret: RetType = undefined; switch (ch) { '(' => ret = 1, '[' => ret = 2, '{' => ret = 3, '<' => ret = 4, else => unreachable, } return ret; } pub fn second(allocator: ?std.mem.Allocator) anyerror!RetType { _ = allocator; return try parseInput(); } pub fn main() anyerror!void { var timer = try std.time.Timer.start(); const ret = try second(null); const f = timer.lap() / 1000; try std.testing.expectEqual(ret, @as(RetType, 3122628974)); std.debug.print("Day 10b result: {d} \ttime: {d}us\n", .{ ret, f }); } test "day10b" { try std.testing.expectEqual(@as(RetType, 3122628974), try second(std.testing.allocator)); }