diff --git a/src/days/day07.zig b/src/days/day07.zig index 9319ce8..7f2c4a8 100644 --- a/src/days/day07.zig +++ b/src/days/day07.zig @@ -35,46 +35,75 @@ pub fn run(allocator: std.mem.Allocator) !void { std.debug.print("{s}\n", .{first_line}); - const previous_line = try allocator.alloc(u8, line_len); + const previous_line = try allocator.alloc(Cell, line_len); defer allocator.free(previous_line); - var accumulator: usize = 0; - var i: usize = 0; while (lines.next()) |line| { defer i += 1; - const current_line = try allocator.alloc(u8, line_len); + const current_line = try allocator.alloc(Cell, line_len); defer allocator.free(current_line); - @memcpy(current_line, line); + for (line, 0..) |c, ci| { + switch (c) { + '.' => current_line[ci] = .empty, + '^' => current_line[ci] = .splitter, + else => unreachable, // There shouldn't be beams on this line yet! + } + } defer @memcpy(previous_line, current_line); - defer std.debug.print("{s}\n", .{current_line}); + defer { + for (current_line) |cell| { + std.debug.print("{f}", .{cell}); + } + std.debug.print("\n", .{}); + } if (i == 0) { - std.debug.assert(current_line[starting_position] == '.'); - current_line[starting_position] = '|'; + std.debug.assert(current_line[starting_position] == .empty); + current_line[starting_position] = .{ .beam = .{ .timelines = 1 } }; continue; } - for (line, 0..) |c, ci| { - if (previous_line[ci] == '|') { - if (c == '.') { - current_line[ci] = '|'; - } else if (c == '^') { - accumulator += 1; - if (ci != 0 and current_line[ci - 1] == '.') { - current_line[ci - 1] = '|'; + for (current_line, 0..) |cell, celli| { + const previous_cell = previous_line[celli]; + if (previous_cell == .beam) { + if (cell == .empty) { + current_line[celli] = .{ .beam = .{ .timelines = previous_cell.beam.timelines } }; + } else if (cell == .splitter) { + if (celli != 0) { + const left = current_line[celli - 1]; + if (left == .empty) { + current_line[celli - 1] = .{ .beam = .{ .timelines = previous_cell.beam.timelines } }; + } else if (left == .beam) { + current_line[celli - 1] = .{ .beam = .{ .timelines = left.beam.timelines + previous_cell.beam.timelines } }; + } } - if (ci != line_len - 1 and current_line[ci + 1] == '.') { - current_line[ci + 1] = '|'; + if (celli != line_len - 1) { + const right = current_line[celli + 1]; + if (right == .empty) { + current_line[celli + 1] = .{ .beam = .{ .timelines = previous_cell.beam.timelines } }; + } else if (right == .beam) { + current_line[celli + 1] = .{ .beam = .{ .timelines = right.beam.timelines + previous_cell.beam.timelines } }; + } } + } else if (cell == .beam and previous_cell == .beam) { + current_line[celli] = .{ .beam = .{ .timelines = cell.beam.timelines + previous_cell.beam.timelines } }; } } } } + var accumulator: usize = 0; + for (previous_line) |cell| { + accumulator += switch (cell) { + .empty, .splitter => 0, + .beam => |beam| beam.timelines, + }; + } + var buffer: [8]u8 = undefined; var stdout_writer = std.fs.File.stdout().writer(&buffer); const stdout = &stdout_writer.interface; @@ -84,3 +113,21 @@ pub fn run(allocator: std.mem.Allocator) !void { try stdout.flush(); } +const Cell = union(enum) { + empty: void, + splitter: void, + beam: struct { + timelines: usize, + }, + + const Self = @This(); + + pub fn format(self: Cell, w: *std.io.Writer) std.io.Writer.Error!void { + switch (self) { + .empty => try w.print(".", .{}), + .splitter => try w.print("^", .{}), + .beam => |beam| try w.print("{d}", .{beam.timelines}), + } + } +}; +