Day 9
This commit is contained in:
parent
7535c2cd8f
commit
df57aacd4c
|
@ -0,0 +1,79 @@
|
|||
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;
|
||||
}
|
Reference in New Issue