const std = @import("std");
const path = "data/day25/input.txt";
const grid_rows = 137;
const grid_cols = 139;
const Grid = [grid_rows][grid_cols]u8;
pub fn main() !void {
var timer = try std.time.Timer.start();
const ret = try first(null);
const t = timer.lap() / 1000;
try std.testing.expectEqual(@as(usize, 432), ret);
std.debug.print("Day 25a result: {d} \t\ttime: {d}us\n", .{ ret, t });
}
pub fn first(allocator: ?std.mem.Allocator) !usize {
_ = allocator;
var grid = parseInput();
var steps: usize = 0;
while (true) : (steps += 1) {
// std.debug.print("\nstep: {d}\n", .{steps});
// drawGrid(&grid);
const e = moveEast(&grid);
const s = moveSouth(&grid);
if (!e and !s) {
break;
}
}
return steps + 1;
}
fn moveEast(g: *Grid) bool {
var ret = false;
for (g) |row, row_idx| {
for (row) |ch, col_idx| {
if (ch == '>') { // must be captured ch, not g[row][col]
const right = (col_idx + 1) % grid_cols;
// This check _must_ use the row, so we can alter the grid
if (row[right] == '.') {
ret = true;
g[row_idx][col_idx] = '.';
g[row_idx][right] = '>';
}
}
}
}
return ret;
}
fn moveSouth(g: *Grid) bool {
var ret = false;
var col_idx: usize = 0;
while (col_idx < grid_cols) : (col_idx += 1) {
// fill in the current state to col to avoid snowballing
// in moveEast it is already done with payload capturing
var fill_idx: usize = 0;
var col: [grid_rows]u8 = undefined;
while (fill_idx < grid_rows) : (fill_idx += 1) {
col[fill_idx] = g[fill_idx][col_idx];
}
for (col) |ch, row_idx| {
if (ch == 'v') { // using ch instead of g[row][col]
const down = (row_idx + 1) % grid_rows;
if (col[down] == '.') { // using col[row], not g[row][col]
ret = true;
g[row_idx][col_idx] = '.';
g[down][col_idx] = 'v';
}
}
}
}
return ret;
}
fn drawGrid(g: *Grid) void {
for (g) |line| {
std.debug.print("{s}\n", .{line});
}
}
fn parseInput() Grid {
const input = @embedFile(path);
var lines = std.mem.split(u8, input, "\n");
var g: Grid = undefined;
var row: usize = 0;
while (lines.next()) |line| : (row += 1) {
for (line) |ch, col| {
std.debug.assert(ch == 'v' or ch == '.' or ch == '>');
g[row][col] = ch;
}
}
return g;
}
test "day25a" {
try std.testing.expectEqual(@as(usize, 432), try first(std.testing.allocator));
}