AoC2025/src/days/day07.zig
2025-12-07 20:26:53 +00:00

133 lines
4.4 KiB
Zig

const std = @import("std");
pub const title = "Day 07: Laboratories";
pub fn run(allocator: std.mem.Allocator) !void {
const input = @embedFile("./input/day07.txt");
//const input =
// \\.......S.......
// \\...............
// \\.......^.......
// \\...............
// \\......^.^......
// \\...............
// \\.....^.^.^.....
// \\...............
// \\....^.^...^....
// \\...............
// \\...^.^...^.^...
// \\...............
// \\..^...^.....^..
// \\...............
// \\.^.^.^.^.^...^.
// \\...............
// ;
var lines = std.mem.tokenizeScalar(u8, input, '\n');
const first_line = lines.next() orelse unreachable;
const starting_position = for (first_line, 0..) |c, i| {
if (c == 'S') break i;
} else unreachable;
const line_len = first_line.len;
std.debug.print("starting_position = {d}\n", .{starting_position});
std.debug.print("{s}\n", .{first_line});
const previous_line = try allocator.alloc(Cell, line_len);
defer allocator.free(previous_line);
var i: usize = 0;
while (lines.next()) |line| {
defer i += 1;
const current_line = try allocator.alloc(Cell, line_len);
defer allocator.free(current_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 {
for (current_line) |cell| {
std.debug.print("{f}", .{cell});
}
std.debug.print("\n", .{});
}
if (i == 0) {
std.debug.assert(current_line[starting_position] == .empty);
current_line[starting_position] = .{ .beam = .{ .timelines = 1 } };
continue;
}
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 (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;
try stdout.print("{d}\n", .{accumulator});
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}),
}
}
};