Files
aoc2024/10/src/main.zig
2024-12-11 01:01:57 -06:00

155 lines
4.2 KiB
Zig

// zig is growing on me tbh
const std = @import("std");
var arena = std.heap.ArenaAllocator.init(std.heap.page_allocator);
const alloc = arena.allocator();
const test_data = @embedFile("test");
const input_data = @embedFile("input");
pub fn main() !void {
const stdout = std.io.getStdOut().writer();
const value1 = try run1(input_data);
try stdout.print("{d}\n", .{value1});
const value2 = try run2(input_data);
try stdout.print("{d}\n", .{value2});
}
test "test input part 1" {
std.debug.print("\n", .{});
const value = try run1(test_data);
std.debug.print("{d}\n", .{value});
try std.testing.expectEqual(36, value);
}
test "test input part 2" {
std.debug.print("\n",.{});
const value = try run2(test_data);
std.debug.print("{d}\n", .{value});
try std.testing.expectEqual(81, value);
}
fn parseIntFromReader(reader: anytype) anyerror!u64 {
const f = try reader.readByte();
if (f < '0' or f > '9') return error.BadCharacter;
var v: u64 = f - '0';
while (true) {
const c = try reader.readByte();
if (c < '0' or c > '9') {
break;
} else {
v = (v * 10) + (c - '0');
}
}
return v;
}
fn run2(input: []const u8) !u64 {
var map: [64][64]u8 = [_][64]u8{[_]u8{0}**64}**64;
var lines = std.mem.splitScalar(u8, input, '\n');
var y: usize = 0;
var x: usize = 0;
var dim: usize = undefined;
while (lines.next()) |line| {
if (std.mem.eql(u8, line, "")) continue;
std.mem.copyForwards(u8, &map[y], line);
std.debug.print("{s}\n",.{line});
dim = line.len;
y += 1;
}
std.debug.print("map max {}\n", .{dim});
var total: u64 = 0;
var outmap: [64][64]u8 = [_][64]u8{[_]u8{0}**64}**64;
y = 0;
while (y < dim) : (y += 1) {
x = 0;
while (x < dim) : (x += 1) {
if (map[y][x] == '9') {
checkpath2(y, x, dim, &map, &outmap);
}
}
}
y = 0;
while (y < dim) : (y += 1) {
x = 0;
while (x < dim) : (x += 1) {
total += outmap[y][x];
}
}
return total;
}
fn checkpath2(y: usize, x: usize, dim: usize, map: *[64][64]u8, outmap: *[64][64]u8) void {
const c = map[y][x];
if (c == '0') {
outmap[y][x] += 1;
return;
}
if (y > 0) if (map[y-1][x] == c-1) { checkpath2(y-1, x, dim, map, outmap); };
if (x > 0) if (map[y][x-1] == c-1) { checkpath2(y, x-1, dim, map, outmap); };
if (y < dim-1) if (map[y+1][x] == c-1) { checkpath2(y+1, x, dim, map, outmap); };
if (x < dim-1) if (map[y][x+1] == c-1) { checkpath2(y, x+1, dim, map, outmap); };
}
fn checkpath(y: usize, x: usize, dim: usize, map: *[64][64]u8, outmap: *[64][64]u8) void {
const c = map[y][x];
if (c == '0') {
outmap[y][x] = 1;
return;
}
if (y > 0) if (map[y-1][x] == c-1) { checkpath(y-1, x, dim, map, outmap); };
if (x > 0) if (map[y][x-1] == c-1) { checkpath(y, x-1, dim, map, outmap); };
if (y < dim-1) if (map[y+1][x] == c-1) { checkpath(y+1, x, dim, map, outmap); };
if (x < dim-1) if (map[y][x+1] == c-1) { checkpath(y, x+1, dim, map, outmap); };
}
fn run1(input: []const u8) !u64 {
var map: [64][64]u8 = [_][64]u8{[_]u8{0}**64}**64;
var lines = std.mem.splitScalar(u8, input, '\n');
var y: usize = 0;
var x: usize = 0;
var dim: usize = undefined;
while (lines.next()) |line| {
if (std.mem.eql(u8, line, "")) continue;
std.mem.copyForwards(u8, &map[y], line);
std.debug.print("{s}\n",.{line});
dim = line.len;
y += 1;
}
std.debug.print("map max {}\n", .{dim});
var total: u64 = 0;
var outmap: [64][64]u8 = undefined;
y = 0;
while (y < dim) : (y += 1) {
x = 0;
while (x < dim) : (x += 1) {
if (map[y][x] == '9') {
outmap = [_][64]u8{[_]u8{0}**64}**64;
checkpath(y, x, dim, &map, &outmap);
var iy: usize = 0;
while (iy < dim) : (iy += 1) {
var ix: usize = 0;
while (ix < dim) : (ix += 1) {
total += outmap[iy][ix];
}
}
}
}
}
return total;
}