This repository has been archived on 2022-12-11. You can view files and clone it, but cannot push or open issues or pull requests.
aoc2022/09/1.zig

80 lines
2.6 KiB
Zig
Raw Permalink Normal View History

2022-12-11 11:14:05 +00:00
const std = @import("std");
const v2d = [2]i32;
pub fn main() void {
const input = @embedFile("input");
std.debug.print("Part 1: {}\n", .{nVisitedSnake(input, 2)});
std.debug.print("Part 2: {}\n", .{nVisitedSnake(input, 10)});
}
pub fn nVisitedSnake(input: []const u8, comptime len: usize) usize {
if (len < 2) @compileError("The length has to be greater than 1.");
var arena = std.heap.ArenaAllocator.init(std.heap.page_allocator);
defer arena.deinit();
const allocator = arena.allocator();
var knots = [_]v2d{v2d{ 0, 0 }} ** len;
var visited = std.ArrayList(v2d).init(allocator);
var iter = std.mem.split(u8, input, "\n");
while (iter.next()) |line| {
// Line not valid
if (line.len < 2) continue;
// Get the number, continue on error
const num = std.fmt.parseInt(usize, line[2..], 10) catch continue;
// Direction of said movement
const dir: v2d = switch (line[0]) {
'U' => .{ 0, 1 },
'D' => .{ 0, -1 },
'R' => .{ 1, 0 },
'L' => .{ -1, 0 },
else => unreachable,
};
// Move the head one step at a time
var step: usize = 0;
while (step < num) : (step += 1) {
// Move the head
knots[0][0] += dir[0];
knots[0][1] += dir[1];
// Go through each pair of "head/tail" knots
var tailIdx: usize = 1;
while (tailIdx < knots.len) : (tailIdx += 1) {
const head = &knots[tailIdx - 1];
const tail = &knots[tailIdx];
var axis: u8 = 0;
while (axis < 2) : (axis += 1) {
const diff = head[axis] - tail[axis];
const dist = std.math.absInt(diff) catch unreachable;
if (dist >= 2) {
// Move it to where the head is -1
tail[axis] = head[axis] - @divTrunc(dist, diff);
// If one axis is at a +2 distance, snap the other one
const otherAxis = (axis + 1) % 2;
tail[otherAxis] = head[otherAxis];
break;
}
}
}
// Register the poisition again if it hasn't been saved before
const tail = knots[knots.len - 1];
for (visited.items) |coord| {
if (coord[0] == tail[0] and coord[1] == tail[1]) break;
} else {
visited.append(tail) catch unreachable;
}
}
}
return visited.items.len;
}