solve_day9 :: (test: bool) {
contents := read_entire_file(ifx test then "inputs/day9_test.txt" else "inputs/day9.txt");
lines := split(contents, "\n");
tails: [10]Coord;
visited: Table(s64, Coord);
visited_2: Table(s64, Coord);
for line: lines {
dir := convert_dir(line[0]);
amount := string_to_int(slice(line, 2, line.count - 2), 10, s64);
for 0..amount - 1 {
tails[0].x += dir.x;
tails[0].y += dir.y;
for 1..tails.count - 1 {
tails[it] = move_tail(tails[it - 1], tails[it]);
}
table_set(*visited, convert_to_s64(tails[1]), tails[1]);
table_set(*visited_2, convert_to_s64(tails[tails.count - 1]), tails[tails.count - 1]);
}
}
print("Part 1: %\n", visited.count);
print("Part 2: %\n", visited_2.count);
}
move_tail :: (head: Coord, tail: Coord) -> Coord {
if abs(head.x - tail.x) <= 1 && abs(head.y - tail.y) <= 1 return tail;
x := head.x - tail.x;
y := head.y - tail.y;
if x == 0 || abs(x) < abs(y) {
return .{
x = head.x,
y = ifx y > 0 then head.y - 1 else head.y + 1,
};
}
if y == 0 || abs(x) > abs(y) {
return .{
y = head.y,
x = ifx x > 0 then head.x - 1 else head.x + 1,
};
}
return .{
x = ifx x > 0 then head.x - 1 else head.x + 1,
y = ifx y > 0 then head.y - 1 else head.y + 1,
};
}
convert_dir :: (dir: u8) -> Coord {
if dir == {
case #char "U";
return .{ x = 0, y = -1 };
case #char "R";
return .{ x = 1, y = 0 };
case #char "D";
return .{ x = 0, y = 1 };
case #char "L";
return .{ x = -1, y = 0 };
case; assert(false, "Bad dir '%'", dir);
}
return .{};
}
convert_to_s64 :: (c: Coord) -> s64 {
result := (cast,no_check(u64)c.x) << 32 | cast(u64)(cast,no_check(u32)c.y);
return cast,no_check(s64)result;
}
#scope_file
Coord :: struct {
x: s32;
y: s32;
}