2024 Day 15 Part 2
This commit is contained in:
parent
f39ff98bf3
commit
83e5d44f61
1 changed files with 181 additions and 0 deletions
|
|
@ -26,6 +26,7 @@ pub fn main() !void {
|
||||||
const stdout = bw.writer();
|
const stdout = bw.writer();
|
||||||
|
|
||||||
try stdout.print("{d}\n", .{try part1(grid, moves.items)});
|
try stdout.print("{d}\n", .{try part1(grid, moves.items)});
|
||||||
|
try stdout.print("{d}\n", .{try part2(grid, moves.items)});
|
||||||
try bw.flush();
|
try bw.flush();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -67,6 +68,88 @@ fn part1(start: Grid, moves: []const Direction) !i64 {
|
||||||
return score;
|
return score;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn part2(original: Grid, moves: []const Direction) !i64 {
|
||||||
|
var start: Pos = undefined;
|
||||||
|
|
||||||
|
var grid = v: {
|
||||||
|
var map = Map(Pos, u8).init(original.allocator);
|
||||||
|
|
||||||
|
var it = original.iterator();
|
||||||
|
while (it.next()) |entry| {
|
||||||
|
const pos = entry.key_ptr.*;
|
||||||
|
const char = entry.value_ptr.*;
|
||||||
|
|
||||||
|
const left, const right = .{
|
||||||
|
Pos.new(pos.r, 2 * pos.c),
|
||||||
|
Pos.new(pos.r, 2 * pos.c + 1),
|
||||||
|
};
|
||||||
|
|
||||||
|
if (char == '#') {
|
||||||
|
try map.put(left, '#');
|
||||||
|
try map.put(right, '#');
|
||||||
|
}
|
||||||
|
if (char == 'O') {
|
||||||
|
try map.put(left, '[');
|
||||||
|
try map.put(right, ']');
|
||||||
|
}
|
||||||
|
if (char == '.') {
|
||||||
|
try map.put(left, '.');
|
||||||
|
try map.put(right, '.');
|
||||||
|
}
|
||||||
|
if (char == '@') {
|
||||||
|
try map.put(left, '@');
|
||||||
|
try map.put(right, '.');
|
||||||
|
start = left;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
break :v Grid{
|
||||||
|
.allocator = original.allocator,
|
||||||
|
.map = map,
|
||||||
|
.max = Pos.new(original.max.r, 2 * original.max.c + 1),
|
||||||
|
};
|
||||||
|
};
|
||||||
|
defer grid.deinit();
|
||||||
|
|
||||||
|
var pos = v: {
|
||||||
|
var it = grid.iterator();
|
||||||
|
while (it.next()) |entry| {
|
||||||
|
const pos = entry.key_ptr.*;
|
||||||
|
const char = entry.value_ptr.*;
|
||||||
|
|
||||||
|
if (char == '@') {
|
||||||
|
break :v pos;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
unreachable;
|
||||||
|
};
|
||||||
|
|
||||||
|
for (moves) |dir| {
|
||||||
|
if (grid.can_move2(pos, dir)) {
|
||||||
|
var moved = Set(Pos).init(grid.allocator);
|
||||||
|
defer moved.deinit();
|
||||||
|
|
||||||
|
try grid.do_move2(pos, dir, &moved);
|
||||||
|
pos = pos.add(dir.delta());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var score: i64 = 0;
|
||||||
|
var it = grid.iterator();
|
||||||
|
while (it.next()) |entry| {
|
||||||
|
const box = entry.key_ptr.*;
|
||||||
|
const char = entry.value_ptr.*;
|
||||||
|
|
||||||
|
if (char != '[') {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
score += 100 * box.r + box.c;
|
||||||
|
}
|
||||||
|
|
||||||
|
return score;
|
||||||
|
}
|
||||||
|
|
||||||
const Pos = struct {
|
const Pos = struct {
|
||||||
r: i32,
|
r: i32,
|
||||||
c: i32,
|
c: i32,
|
||||||
|
|
@ -201,6 +284,22 @@ const Grid = struct {
|
||||||
0 <= pos.c and pos.c <= self.max.c;
|
0 <= pos.c and pos.c <= self.max.c;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn format(
|
||||||
|
self: Grid,
|
||||||
|
comptime _: []const u8,
|
||||||
|
_: std.fmt.FormatOptions,
|
||||||
|
writer: anytype,
|
||||||
|
) !void {
|
||||||
|
var r: i32 = 0;
|
||||||
|
while (r <= self.max.r) : (r += 1) {
|
||||||
|
var c: i32 = 0;
|
||||||
|
while (c <= self.max.c) : (c += 1) {
|
||||||
|
try writer.print("{c}", .{self.get(Pos.new(r, c)).?});
|
||||||
|
}
|
||||||
|
try writer.print("\n", .{});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn move(self: *Grid, robot: Pos, dir: Direction) !Pos {
|
fn move(self: *Grid, robot: Pos, dir: Direction) !Pos {
|
||||||
var stack = List(Pos).init(self.allocator);
|
var stack = List(Pos).init(self.allocator);
|
||||||
defer stack.deinit();
|
defer stack.deinit();
|
||||||
|
|
@ -223,4 +322,86 @@ const Grid = struct {
|
||||||
|
|
||||||
return robot.add(delta);
|
return robot.add(delta);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn can_move2(self: *Grid, pos: Pos, dir: Direction) bool {
|
||||||
|
const delta = dir.delta();
|
||||||
|
const next = pos.add(delta);
|
||||||
|
|
||||||
|
switch (self.get(next).?) {
|
||||||
|
'#' => return false,
|
||||||
|
'.' => return true,
|
||||||
|
'@' => return self.can_move2(next, dir),
|
||||||
|
|
||||||
|
'[' => switch (dir) {
|
||||||
|
.n, .s => {
|
||||||
|
const left = self.can_move2(next, dir);
|
||||||
|
const right = self.can_move2(next.add(Direction.e.delta()), dir);
|
||||||
|
return left and right;
|
||||||
|
},
|
||||||
|
.e => return self.can_move2(next.add(Direction.e.delta()), dir),
|
||||||
|
.w => return self.can_move2(next, dir),
|
||||||
|
},
|
||||||
|
']' => switch (dir) {
|
||||||
|
.n, .s => {
|
||||||
|
const left = self.can_move2(next, dir);
|
||||||
|
const right = self.can_move2(next.add(Direction.w.delta()), dir);
|
||||||
|
return left and right;
|
||||||
|
},
|
||||||
|
.w => return self.can_move2(next.add(Direction.w.delta()), dir),
|
||||||
|
.e => return self.can_move2(next, dir),
|
||||||
|
},
|
||||||
|
else => unreachable,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn do_move2(self: *Grid, pos: Pos, dir: Direction, moved: *Set(Pos)) !void {
|
||||||
|
if (moved.contains(pos)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
try moved.put(pos);
|
||||||
|
|
||||||
|
const delta = dir.delta();
|
||||||
|
const next = pos.add(delta);
|
||||||
|
|
||||||
|
const content = self.get(pos).?;
|
||||||
|
|
||||||
|
switch (content) {
|
||||||
|
'#' => unreachable,
|
||||||
|
'.' => return,
|
||||||
|
'@' => try self.do_move2(next, dir, moved),
|
||||||
|
|
||||||
|
'[' => {
|
||||||
|
const pair = pos.add(Direction.e.delta());
|
||||||
|
switch (dir) {
|
||||||
|
.n, .s => {
|
||||||
|
try self.do_move2(next, dir, moved);
|
||||||
|
try self.do_move2(pair, dir, moved);
|
||||||
|
},
|
||||||
|
.e => {
|
||||||
|
try self.do_move2(pair, dir, moved);
|
||||||
|
try self.do_move2(next, dir, moved);
|
||||||
|
},
|
||||||
|
.w => try self.do_move2(next, dir, moved),
|
||||||
|
}
|
||||||
|
},
|
||||||
|
']' => {
|
||||||
|
const pair = pos.add(Direction.w.delta());
|
||||||
|
switch (dir) {
|
||||||
|
.n, .s => {
|
||||||
|
try self.do_move2(pair, dir, moved);
|
||||||
|
try self.do_move2(next, dir, moved);
|
||||||
|
},
|
||||||
|
.w => {
|
||||||
|
try self.do_move2(pair, dir, moved);
|
||||||
|
try self.do_move2(next, dir, moved);
|
||||||
|
},
|
||||||
|
.e => try self.do_move2(next, dir, moved),
|
||||||
|
}
|
||||||
|
},
|
||||||
|
else => unreachable,
|
||||||
|
}
|
||||||
|
|
||||||
|
try self.map.put(next, content);
|
||||||
|
try self.map.put(pos, '.');
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue