Watch
1
0
Fork
You've already forked advent-of-code
0

2024 Day 18 Part 2

This commit is contained in:
Jeremy Kaplan 2024-12-23 15:42:24 -08:00
commit ea22f10615

View file

@ -18,22 +18,23 @@ pub fn main() !void {
var bytes = try aoc.parseAll(Pos, allocator, text, "\n"); var bytes = try aoc.parseAll(Pos, allocator, text, "\n");
defer bytes.deinit(); defer bytes.deinit();
var grid = try Grid.init(allocator, Pos.new(70, 70));
defer grid.deinit();
for (bytes.items[0..1024]) |pos| {
try grid.put(pos, '#');
}
var bw = std.io.bufferedWriter(std.io.getStdOut().writer()); var bw = std.io.bufferedWriter(std.io.getStdOut().writer());
const stdout = bw.writer(); const stdout = bw.writer();
try stdout.print("{}\n", .{try search(allocator, grid, Pos.new(0, 0), grid.max)}); try stdout.print("{}\n", .{try part1(allocator, bytes.items)});
try bw.flush();
try stdout.print("{}\n", .{try part2(allocator, bytes.items)});
try bw.flush(); try bw.flush();
} }
fn search(allocator: Allocator, grid: Grid, pos: Pos, _: Pos) !u64 { fn part1(allocator: Allocator, bytes: []Pos) !u64 {
const start = State.new(pos); var grid = try Grid.init(allocator, Pos.new(70, 70));
defer grid.deinit();
try grid.populate(bytes[0..1024], '#');
const start = State.new(Pos.new(0, 0));
const ctx = State.Context{ const ctx = State.Context{
.grid = grid, .grid = grid,
@ -42,11 +43,40 @@ fn search(allocator: Allocator, grid: Grid, pos: Pos, _: Pos) !u64 {
var exits = try SearchIterator(State).init(allocator, ctx, start); var exits = try SearchIterator(State).init(allocator, ctx, start);
defer exits.deinit(); defer exits.deinit();
while (try exits.next(State.isGoal, State.heuristic)) |next| { const res = try exits.next(State.isGoal, State.heuristic);
return next.cost; return res.?.cost;
} }
return 0; fn part2(allocator: Allocator, bytes: []Pos) !Pos {
const start = State.new(Pos.new(0, 0));
var lo: usize = 1024;
var hi: usize = bytes.len;
while (hi - lo > 1) {
const mid = @divTrunc(hi + lo, 2);
var grid = try Grid.init(allocator, Pos.new(70, 70));
defer grid.deinit();
try grid.populate(bytes[0..(mid + 1)], '#');
const ctx = State.Context{
.grid = grid,
};
var exits = try SearchIterator(State).init(allocator, ctx, start);
defer exits.deinit();
// Bisect!
if (try exits.next(State.isGoal, State.heuristic)) |_| {
lo = mid;
} else {
hi = mid;
}
}
return bytes[hi];
} }
const State = struct { const State = struct {
@ -246,6 +276,12 @@ const Grid = struct {
try self.map.put(pos, v); try self.map.put(pos, v);
} }
fn populate(self: *Grid, positions: []Pos, v: u8) !void {
for (positions) |pos| {
try self.put(pos, v);
}
}
fn inBounds(self: Grid, pos: Pos) bool { fn inBounds(self: Grid, pos: Pos) bool {
return 0 <= pos.r and pos.r <= self.max.r and return 0 <= pos.r and pos.r <= self.max.r and
0 <= pos.c and pos.c <= self.max.c; 0 <= pos.c and pos.c <= self.max.c;