mirror of
https://github.com/MorizzG/aoc-2024.git
synced 2025-12-06 04:22:43 +00:00
day 6 finished
This commit is contained in:
parent
6178c3f3f6
commit
aa8c5b35b1
2 changed files with 586 additions and 0 deletions
456
day6.zig
Normal file
456
day6.zig
Normal file
|
|
@ -0,0 +1,456 @@
|
|||
const std = @import("std");
|
||||
|
||||
const utils = @import("utils.zig");
|
||||
|
||||
pub fn main() !void {
|
||||
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
|
||||
const alloc = gpa.allocator();
|
||||
|
||||
const filename = "inputs/day6.txt";
|
||||
|
||||
{
|
||||
const file_reader = try utils.FileReader.init(alloc, filename);
|
||||
defer file_reader.deinit();
|
||||
|
||||
const result = try part1(alloc, file_reader.reader());
|
||||
|
||||
try std.io.getStdOut().writer().print("Day 6, part 1: {}\n", .{result});
|
||||
}
|
||||
|
||||
{
|
||||
const file_reader = try utils.FileReader.init(alloc, filename);
|
||||
defer file_reader.deinit();
|
||||
|
||||
const result = try part2(alloc, file_reader.reader());
|
||||
|
||||
try std.io.getStdOut().writer().print("Day 6, part 1: {}\n", .{result});
|
||||
}
|
||||
}
|
||||
|
||||
const Orientation = enum {
|
||||
up,
|
||||
right,
|
||||
down,
|
||||
left,
|
||||
};
|
||||
|
||||
const MapElem = enum {
|
||||
empty,
|
||||
obstacle,
|
||||
guard,
|
||||
visited,
|
||||
};
|
||||
|
||||
const GuardPos = struct {
|
||||
x: i32,
|
||||
y: i32,
|
||||
orientation: Orientation,
|
||||
};
|
||||
|
||||
const Map = [][]MapElem;
|
||||
|
||||
const MapState = struct {
|
||||
alloc: std.mem.Allocator,
|
||||
|
||||
size_x: usize,
|
||||
size_y: usize,
|
||||
|
||||
map: Map,
|
||||
|
||||
guard_pos: GuardPos,
|
||||
|
||||
pub fn format(self: @This(), comptime fmt: []const u8, options: std.fmt.FormatOptions, writer: anytype) !void {
|
||||
_ = fmt;
|
||||
_ = options;
|
||||
|
||||
for (self.map) |line| {
|
||||
for (line) |elem| {
|
||||
const c: u8 = switch (elem) {
|
||||
.empty => '.',
|
||||
.guard => switch (self.guard_pos.orientation) {
|
||||
.up => '^',
|
||||
.down => 'v',
|
||||
.left => '<',
|
||||
.right => '>',
|
||||
},
|
||||
.obstacle => '#',
|
||||
.visited => 'X',
|
||||
};
|
||||
|
||||
try writer.print("{c}", .{c});
|
||||
}
|
||||
|
||||
try writer.print("\n", .{});
|
||||
}
|
||||
}
|
||||
|
||||
fn deinit(self: MapState) void {
|
||||
for (self.map) |map_line| {
|
||||
self.alloc.free(map_line);
|
||||
}
|
||||
|
||||
self.alloc.free(self.map);
|
||||
}
|
||||
|
||||
fn copyFrom(self: *MapState, other: MapState) void {
|
||||
for (self.map, other.map) |*map_line, map_line_orig| {
|
||||
@memcpy(map_line.*, map_line_orig);
|
||||
}
|
||||
}
|
||||
|
||||
fn clone(self: MapState, alloc: std.mem.Allocator) !MapState {
|
||||
const map_orig = self.map;
|
||||
|
||||
const map = try alloc.alloc([]MapElem, map_orig.len);
|
||||
|
||||
for (map, map_orig) |*map_line, map_line_orig| {
|
||||
map_line.* = try alloc.alloc(MapElem, map_line_orig.len);
|
||||
}
|
||||
|
||||
var new_map_state = MapState{
|
||||
.alloc = alloc,
|
||||
.size_x = self.size_x,
|
||||
.size_y = self.size_y,
|
||||
.guard_pos = self.guard_pos,
|
||||
.map = map,
|
||||
};
|
||||
|
||||
new_map_state.copyFrom(self);
|
||||
|
||||
return new_map_state;
|
||||
}
|
||||
|
||||
fn parse(alloc: std.mem.Allocator, reader: anytype) !MapState {
|
||||
var line_reader = utils.lineReader(alloc, reader);
|
||||
defer line_reader.deinit();
|
||||
|
||||
var map = std.ArrayList([]MapElem).init(alloc);
|
||||
|
||||
var guard_pos: GuardPos = undefined;
|
||||
|
||||
var x: usize = 0;
|
||||
while (try line_reader.next()) |line| : (x += 1) {
|
||||
const map_line = try alloc.alloc(MapElem, line.len);
|
||||
|
||||
for (0.., line, map_line) |y, c, *map_elem| {
|
||||
map_elem.* = switch (c) {
|
||||
'.' => .empty,
|
||||
'#' => .obstacle,
|
||||
'^' => blk: {
|
||||
guard_pos = GuardPos{
|
||||
.x = @intCast(x),
|
||||
.y = @intCast(y),
|
||||
.orientation = .up,
|
||||
};
|
||||
|
||||
break :blk .guard;
|
||||
},
|
||||
else => unreachable,
|
||||
};
|
||||
}
|
||||
|
||||
try map.append(map_line);
|
||||
}
|
||||
|
||||
const map_slice = try map.toOwnedSlice();
|
||||
map.deinit();
|
||||
|
||||
const size_x = map_slice.len;
|
||||
const size_y = map_slice[0].len;
|
||||
|
||||
for (map_slice) |map_line| {
|
||||
std.debug.assert(map_line.len == size_y);
|
||||
}
|
||||
|
||||
return .{
|
||||
.alloc = alloc,
|
||||
.size_x = size_x,
|
||||
.size_y = size_y,
|
||||
.map = map_slice,
|
||||
.guard_pos = guard_pos,
|
||||
};
|
||||
}
|
||||
|
||||
fn get(self: MapState, x: i32, y: i32) MapElem {
|
||||
std.debug.assert(0 <= x and x < (self.size_x));
|
||||
std.debug.assert(0 <= y and y < (self.size_y));
|
||||
|
||||
return self.map[@intCast(x)][@intCast(y)];
|
||||
}
|
||||
|
||||
fn set(self: *MapState, x: i32, y: i32, elem: MapElem) void {
|
||||
std.debug.assert(0 <= x and x < (self.size_x));
|
||||
std.debug.assert(0 <= y and y < (self.size_y));
|
||||
|
||||
self.map[@intCast(x)][@intCast(y)] = elem;
|
||||
}
|
||||
|
||||
fn turn(self: *MapState) void {
|
||||
self.guard_pos.orientation = switch (self.guard_pos.orientation) {
|
||||
.up => .right,
|
||||
.right => .down,
|
||||
.down => .left,
|
||||
.left => .up,
|
||||
};
|
||||
}
|
||||
|
||||
fn nextPos(self: MapState) ?struct { x: i32, y: i32 } {
|
||||
const guard_pos = self.guard_pos;
|
||||
|
||||
const x = guard_pos.x;
|
||||
const y = guard_pos.y;
|
||||
|
||||
var new_x: i32 = undefined;
|
||||
var new_y: i32 = undefined;
|
||||
|
||||
switch (guard_pos.orientation) {
|
||||
.up => {
|
||||
new_x = x - 1;
|
||||
new_y = y;
|
||||
|
||||
if (new_x < 0) {
|
||||
return null;
|
||||
}
|
||||
},
|
||||
.right => {
|
||||
new_x = x;
|
||||
new_y = y + 1;
|
||||
|
||||
if (new_y >= self.size_y) {
|
||||
return null;
|
||||
}
|
||||
},
|
||||
.down => {
|
||||
new_x = x + 1;
|
||||
new_y = y;
|
||||
|
||||
if (new_x >= self.size_x) {
|
||||
return null;
|
||||
}
|
||||
},
|
||||
.left => {
|
||||
new_x = x;
|
||||
new_y = y - 1;
|
||||
|
||||
if (new_y < 0) {
|
||||
return null;
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
return .{ .x = new_x, .y = new_y };
|
||||
}
|
||||
|
||||
fn advance(self: *MapState) enum { not_done, done } {
|
||||
const guard_pos = &self.guard_pos;
|
||||
|
||||
const x = guard_pos.x;
|
||||
const y = guard_pos.y;
|
||||
|
||||
if (self.get(x, y) != .guard) {
|
||||
std.debug.print("x: {} y: {}\n", .{ x, y });
|
||||
std.debug.print("map on failure:\n{}\n", .{self});
|
||||
}
|
||||
|
||||
std.debug.assert(self.get(x, y) == .guard);
|
||||
|
||||
const new_pos = self.nextPos() orelse {
|
||||
// walked out of the map
|
||||
std.debug.assert(self.get(x, y) == .guard);
|
||||
|
||||
self.set(x, y, .visited);
|
||||
|
||||
return .done;
|
||||
};
|
||||
|
||||
const new_x = new_pos.x;
|
||||
const new_y = new_pos.y;
|
||||
|
||||
if (self.get(new_x, new_y) == .obstacle) {
|
||||
// found obstacle: turn and advance
|
||||
self.turn();
|
||||
return advance(self);
|
||||
}
|
||||
|
||||
std.debug.assert(self.get(x, y) == .guard);
|
||||
self.set(x, y, .visited);
|
||||
|
||||
guard_pos.x = new_x;
|
||||
guard_pos.y = new_y;
|
||||
|
||||
self.set(new_x, new_y, .guard);
|
||||
|
||||
return .not_done;
|
||||
}
|
||||
|
||||
fn countVisited(self: MapState) u64 {
|
||||
var count: u64 = 0;
|
||||
|
||||
for (self.map) |line| {
|
||||
for (line) |elem| {
|
||||
std.debug.assert(elem != .guard);
|
||||
|
||||
if (elem == .visited) {
|
||||
count += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
};
|
||||
|
||||
fn part1(alloc: std.mem.Allocator, reader: anytype) !u64 {
|
||||
var map_arena = std.heap.ArenaAllocator.init(alloc);
|
||||
defer map_arena.deinit();
|
||||
|
||||
var map_state = try MapState.parse(map_arena.allocator(), reader);
|
||||
|
||||
while (map_state.advance() != .done) {}
|
||||
|
||||
const visited_count = map_state.countVisited();
|
||||
|
||||
return visited_count;
|
||||
}
|
||||
|
||||
fn part2(alloc: std.mem.Allocator, reader: anytype) !u64 {
|
||||
var map_arena = std.heap.ArenaAllocator.init(alloc);
|
||||
defer map_arena.deinit();
|
||||
|
||||
const map_state_orig = try MapState.parse(map_arena.allocator(), reader);
|
||||
|
||||
var map_state_iter = try map_state_orig.clone(map_arena.allocator());
|
||||
|
||||
var tmp_arena = std.heap.ArenaAllocator.init(alloc);
|
||||
defer tmp_arena.deinit();
|
||||
|
||||
var num_loops: u64 = 0;
|
||||
|
||||
var map_state_all_obstacles = try map_state_orig.clone(alloc);
|
||||
defer map_state_all_obstacles.deinit();
|
||||
|
||||
var guard_pos_set = std.AutoHashMap(GuardPos, void).init(alloc);
|
||||
defer guard_pos_set.deinit();
|
||||
|
||||
while (map_state_iter.advance() != .done) {
|
||||
|
||||
// current guard pos after last step
|
||||
const cur_guard_pos = map_state_iter.guard_pos;
|
||||
|
||||
const cur_x = cur_guard_pos.x;
|
||||
const cur_y = cur_guard_pos.y;
|
||||
|
||||
if (cur_x == map_state_orig.guard_pos.x and cur_y == map_state_orig.guard_pos.y) {
|
||||
// don't put obstacle at initial position!
|
||||
continue;
|
||||
}
|
||||
|
||||
if (map_state_all_obstacles.get(cur_x, cur_y) == .obstacle) {
|
||||
// we already tried this one
|
||||
continue;
|
||||
}
|
||||
|
||||
// clone original map state
|
||||
var map_state_modified = try map_state_orig.clone(tmp_arena.allocator());
|
||||
|
||||
// put a new obstacle at the current position of the guard
|
||||
// since obstacles only influence the path of the guard if she would step on,
|
||||
// conversely the only relevant positions for new obstacles are the tiles she actually
|
||||
// steps on
|
||||
map_state_modified.set(cur_x, cur_y, .obstacle);
|
||||
map_state_all_obstacles.set(cur_x, cur_y, .obstacle);
|
||||
|
||||
guard_pos_set.clearRetainingCapacity();
|
||||
|
||||
try guard_pos_set.put(map_state_modified.guard_pos, {});
|
||||
|
||||
while (map_state_modified.advance() != .done) {
|
||||
// std.debug.print("modified map:\n{}\n", .{map_state_modified});
|
||||
|
||||
const guard_pos = map_state_modified.guard_pos;
|
||||
|
||||
if (guard_pos_set.contains(guard_pos)) {
|
||||
num_loops += 1;
|
||||
break;
|
||||
}
|
||||
|
||||
try guard_pos_set.put(map_state_modified.guard_pos, {});
|
||||
}
|
||||
|
||||
_ = tmp_arena.reset(.retain_capacity);
|
||||
}
|
||||
|
||||
return num_loops;
|
||||
}
|
||||
|
||||
test "part1 example" {
|
||||
const alloc = std.testing.allocator;
|
||||
|
||||
const example =
|
||||
\\....#.....
|
||||
\\.........#
|
||||
\\..........
|
||||
\\..#.......
|
||||
\\.......#..
|
||||
\\..........
|
||||
\\.#..^.....
|
||||
\\........#.
|
||||
\\#.........
|
||||
\\......#...
|
||||
;
|
||||
|
||||
var stream = std.io.fixedBufferStream(example);
|
||||
|
||||
const result = try part1(alloc, stream.reader());
|
||||
|
||||
try std.testing.expect(result == 41);
|
||||
}
|
||||
|
||||
test "part1 input" {
|
||||
const alloc = std.testing.allocator;
|
||||
|
||||
const filename = "inputs/day6.txt";
|
||||
|
||||
const file_reader = try utils.FileReader.init(alloc, filename);
|
||||
defer file_reader.deinit();
|
||||
|
||||
const result = try part1(alloc, file_reader.reader());
|
||||
|
||||
try std.testing.expect(result == 4722);
|
||||
}
|
||||
|
||||
test "part2 example" {
|
||||
const alloc = std.testing.allocator;
|
||||
|
||||
const example =
|
||||
\\....#.....
|
||||
\\.........#
|
||||
\\..........
|
||||
\\..#.......
|
||||
\\.......#..
|
||||
\\..........
|
||||
\\.#..^.....
|
||||
\\........#.
|
||||
\\#.........
|
||||
\\......#...
|
||||
;
|
||||
|
||||
var stream = std.io.fixedBufferStream(example);
|
||||
|
||||
const result = try part2(alloc, stream.reader());
|
||||
|
||||
try std.testing.expect(result == 6);
|
||||
}
|
||||
|
||||
test "part2 input" {
|
||||
const alloc = std.testing.allocator;
|
||||
|
||||
const filename = "inputs/day6.txt";
|
||||
|
||||
const file_reader = try utils.FileReader.init(alloc, filename);
|
||||
defer file_reader.deinit();
|
||||
|
||||
const result = try part2(alloc, file_reader.reader());
|
||||
|
||||
try std.testing.expect(result == 1602);
|
||||
}
|
||||
130
inputs/day6.txt
Normal file
130
inputs/day6.txt
Normal file
|
|
@ -0,0 +1,130 @@
|
|||
..#.....................#............#....#...........#...............................#.....#.....................................
|
||||
.................#............................#.............##..#...............................#....#..#.........#...............
|
||||
.............................................##.........................................#....................#...............#...#
|
||||
...##....................#...............#.....#....................#......##..............#............................#....#....
|
||||
.................................#..#..............#...........#.............#..#........................#............#...........
|
||||
.................#.........................#...........................#........................#........................#........
|
||||
...#....................................#....#.........#................#...............#.....#................#.....#............
|
||||
.............#.#..........................................................#...#..................#....#.......#.....#...#.........
|
||||
.....#........................#....##...#............................................................#............................
|
||||
..................#...#.........................................#..................#.............................#.#........#.....
|
||||
......#...............................#.#..........##..#...........#.........................#.......#....................#.......
|
||||
.................................#..............#...............#........#..........#.........#............#.........#.......#...#
|
||||
..#..#............#...#.....................#...............#............#.#........................#........#...............#....
|
||||
..............#..#.#........................#.........#...........##.......#..........#.....................#..............#...#..
|
||||
..........................#.................##...................................#....#.........#.................................
|
||||
..................#..#........#....#...............#..............#.......#.......#......................................#..#...#.
|
||||
..........#.#.................#.........#...................#.......................##......#....................#.......#........
|
||||
..........#.........#...#......................................................................#.....#............#........#......
|
||||
...##.............#...........................................................#..#....................##.#...#.#..#.........#..#..
|
||||
.....#......#.............................#.......#...#...#...............#.....#............#........#..#.#......................
|
||||
........#................#.........#.......................................................................#..........#...........
|
||||
.......#........................................#..........#...............................#..#...................................
|
||||
..................##.......#.......#.....#............#.......#...#.........#....##...............#..#.............#..........#...
|
||||
.......#...........#...........#...........................#.............#.........#..#........................#.##...............
|
||||
.....................................................................#........#....#...........................................#..
|
||||
....#...........#......#.........#....................................#.................................#......#..................
|
||||
...#........................................#..#...............................#.....................#.#......#...................
|
||||
..#.....#.................................#.................#....#............................................#......#............
|
||||
...................................................##...........#.......#.............#.................#.......#.................
|
||||
..........................................................##..............#....#....#.............#...............................
|
||||
........................................................#.....................................#................................#..
|
||||
..............##....#..#..........#...........#......#..#....#.......#................#............................#..#...#.......
|
||||
..........................#....................#.................................................#................................
|
||||
#................................................#.....................#..#...............##........#...#...#.........#...........
|
||||
...........#.................................#..#....................#.#.......#..........................#.......#.......#.......
|
||||
..............................#......#......#.................#.................#.................#.#.............#..#.#..........
|
||||
.......................#....................#....................................#.....#.#.......#............................#...
|
||||
...............................................................................................#.#................................
|
||||
#..................#.....#...............................#..............#...#.....................................................
|
||||
..........................................................#.................................................#.....................
|
||||
..........#.........................#.....................................................#.........#..........#................#.
|
||||
........#..............#..#......................................#.........#............#.................................#.......
|
||||
.......#.........................................................#.........#................#...............................#.....
|
||||
...........#............................................#...#.............................#.....^................................#
|
||||
................#.............#...#..............................#..................................#.............................
|
||||
.........................................................................................................#........................
|
||||
.................................................#........#.......................#.#.....#......................#................
|
||||
.........#.........#...#....................................................#.....................................................
|
||||
##.##..#...................................#......................................................................................
|
||||
.................#...........................................................................................#........#...........
|
||||
.........................................................................#........................#....#......................#...
|
||||
..............#......................#........#..........................#.........#..............................................
|
||||
.......................#............................................................................##............................
|
||||
.....#.................#........#...#...............#.............................#......................#........................
|
||||
....#...................................................................................#............##...........................
|
||||
................#............................#............................................#.......................................
|
||||
.......................................................................................................#......#...................
|
||||
......................................................................................#...#.......................................
|
||||
...............................................#........#..........#............................#..............#.......#..........
|
||||
..............#.....................#........#..#............................#...#..#.#...................................#.......
|
||||
..........#...............................#............................#...........................................#..............
|
||||
....#............#.#....#......................................................................#..................................
|
||||
.......................#.......................#................................#..............#.....................#.........#..
|
||||
...........#.........................#.............#.#........#........#..........................................#...............
|
||||
.......#......................#....................#...............................#......................#...........#...........
|
||||
............#.....................................................................................................................
|
||||
....#.......#............................................................#.........#.............#..........#....#..........#.....
|
||||
.......#.........................................................................#..................#..#....#.......#.............
|
||||
............................#....#.......#......#.......#.....................#.................#.................................
|
||||
.......................................................#.............#..........................#.................................
|
||||
....................................#.....................................##......................#............................#..
|
||||
..............#...............#....................#.......................#................#......................#..............
|
||||
....................#...........................#...................................................................#.............
|
||||
...#..........................#...........................#............................................................#..........
|
||||
..............#.................#.............................#..#.......#.......................#.##.............................
|
||||
....................#.....#...#..............................................#......#...........#.................#..#....#.......
|
||||
#......................................#.....................#..#..#.#...........#.............#.................................#
|
||||
.....................#...........................................................#..........#............##..........#............
|
||||
.......#..................................#...............#..........#....#...................................................#...
|
||||
.............#.................#...........................#..............#.................................................#.....
|
||||
...............................#......................................##...................................#.#......#..........#..
|
||||
.................##....................#.................................................#......................#................#
|
||||
........#....................................#..........#.........................#..................#......................#.....
|
||||
...#....#...........................#..............................#.#..........................#.................................
|
||||
.#...................................#..#......#.................................................................#................
|
||||
.................................#...........#................#.#........................#....................................##..
|
||||
#..#.....##...............#................................................................#....#......#.........................#
|
||||
.#....#......................................................#.........................#.......................................#..
|
||||
.#..............................................#.................................................................#...............
|
||||
...............#..........................................#...#...............................#.#..#.#........#...................
|
||||
..............#................................#.......#..................................#.........................#........#....
|
||||
.......................##..................................................#......................................................
|
||||
..............................#...............................##..................................................................
|
||||
#....................#...........................................................#.............................#..................
|
||||
#..................................................................#...#..........................................................
|
||||
#..#........#...................................#..#..........##..............#...................................................
|
||||
.......................#.....................#....................................................................................
|
||||
.....................#...........#.............................................................#........................#....#....
|
||||
...............#............................................................................##...#..........................#.....
|
||||
...#......................................#.......................................................................................
|
||||
....#...........................#.........#.................................................#..........#...#........#....#........
|
||||
......#....#.#............................#..........................................#........................................#...
|
||||
...........#...#.............................................#......................#..................#.....................#....
|
||||
...#..........#........#..........#.......#..............#.............................#.......................#................#.
|
||||
...........#...............#...........................................................#..........................................
|
||||
..#..........##.................................................#...#...............#.......................#...............##....
|
||||
.......................#..............#.............#......................................................#..................#...
|
||||
..............#..#........##..........#...................................................#.............##....................#...
|
||||
...................#..................................................#................#......#.....#.........#.#...#.............
|
||||
..................#.................................................#.................................................#.........#.
|
||||
......................................#.#........#.....#...#..........#..............#.........................#...#..............
|
||||
.................................#..............#..#.....................#................#.............#..#..#...................
|
||||
.........#.......#.#..............#..#...............#.................#..................................#..#....................
|
||||
.............................#....#.......##..................................................................................##..
|
||||
.....................................................................................#........#.......#......#....................
|
||||
........#...........#..........#..........#............................#...............#........#.#...........................#...
|
||||
.#.................#...#..............#...#...................#........#...............#..........................................
|
||||
.........#............................................##........#......#.....................#.......................#............
|
||||
.......................................#..........#..#......#........#..........#..........................#....................#.
|
||||
....#......#..........................#....................#.......................................#.....###.......#..............
|
||||
.......#..................#....#.......................................................................#..........................
|
||||
....#........................#.............................................................#.......#..........................#...
|
||||
......................#.................................#..........#................#..#.........................#................
|
||||
...........#....................................................#..............#...........................#......................
|
||||
.....#................#........#...#....#........#............#...............#.......................#..#.........#..............
|
||||
#..................................................#...........................#....#...........#.................................
|
||||
....#.#.....................................#.#...............#................#....................................#.............
|
||||
............#....................#.#.#...............................................#...................##.......................
|
||||
...##..............#........................#.............#.......#...........#.#.##..............................#....##.........
|
||||
......#...........#....................................................#.........................##...............................
|
||||
Loading…
Add table
Add a link
Reference in a new issue