year 2022 day 12
3 files changed, 232 insertions(+), 0 deletions(-) A 2022/12/input A 2022/12/solve.zig M build.zig
A 2022/12/input => 2022/12/input +41 -0
@@ 0,0 1,41 @@ abcccccccccccccccccccccccccccccccccccccaaaaaaacccccccaaaaaaaaaaaccccccccccccccccccccaaacaaaaaaaacccccccccccccccccccccccccccccccccccaaaaa abccccccccccccccccccaaccaacccccccccccccaaaaaaaccccccccaaaaaaaaaaacccccccaaaaccccccccaaaaaaaaaaaaacccccccccccccccccccccccccccccccccaaaaaa abccccccccccccccccccaaaaaaccccccccccaaaccaaaaaacccccccaaaaaaaaaaccccccccaaaaccccccaaaaaaaaaaaaaaacccccccccccccccccccaaacccccccccccaaaaaa abcccccccccccccccccccaaaaacccccccccccaaccaacaaaccccccaaaaaaaaaaaccccccccaaaacccccaaaaaaaaacaaaaaaacccccccccccccccccaaaacccccccccccaaacaa abccccccccccccccccccaaaaaaccccccccaacaaaaaacccccccccaaaaaaaaaaaaacaaaccccaaccccccaaaaaaaaacaacccccccccccccccccaaaccaaaacccccccccccccccaa abcccccccccccccccccaaaaaaaacccccccaaaaaaaaccccccaaaaaaaacaaaacaaaaaaacccccccccaaccccaaaaaacaaacccccccccccccccaaaakkkaaccccccccccccccccaa abcccccccccccccccccaaaaaaaaccccccccaaaaaccccaacccaaaaaaaaaaaacaaaaaaccccccccccaacccaaaaaaaaaaaacccccccccccccccakkkkkklcccccccccccccccccc abaaacccccccccccaaccccaaccccccccccccaaaaaccaaacccaaaaaaaaaaaaaaaaaaaaccccccaaaaaaaacaacccaaaaaaccccccccccccccckkkkkkkllcccccccaaaccccccc abaaaacccccccaacaaccccaacccccccccccaaacaaaaaaaccccaaaaaaaaaaaaaaaaaaaacccccaaaaaaaaaaaccccaaaaacccccccccccccckkkksssllllccccccaaaaaacccc abaaaacccccccaaaaacccccccccccaaaccccaacaaaaaaccccaaaaaacaaaaaaaaaaaaaacccccccaaaaccccccccaaaaacccccccccccccckkkksssssllllcccccaaaaaacccc abaaacccccccccaaaaaaccccccccaaaaccccccccaaaaaaaacaaaaaaaaaaaaacaaacaaacccccccaaaaacccccccaaaaacccccccccccccjkkkrssssssllllccccccaaaccccc abccccccccccaaaaaaaaccccccccaaaacccccccaaaaaaaaacaacaaaaaaaaaacaaaccccccccccaaacaaccccccccccccccccccccccccjjkkrrsuuussslllllcccccaaccccc abccaaacccccaaaaacccccccccccaaaaccccccaaaaaaaaaacccccaaaaaaaaaacaaccccccccccaacccacccccccccccccccccccccjjjjjjrrrsuuuussslllllmcccddacccc abcccaaaccaccacaaaccccccccccccccccccccaaaaaaaccccccccccaaaaaaaaccccccaacccccccccccaaaaacccccccccccccccjjjjjjrrrruuuuuusssllmmmmmddddcccc abccaaaaaaaacccaaaccccccccccccccccaaacccccaaaccccccccccccaaacccccccccaacccccccccccaaaaacccccccccccccjjjjjrrrrrruuuxuuussqqqqmmmmmdddcccc abcaaaaaaaacccaaaaaacaaaaaccccccaaaaaaccccaaacccaaccccccccaaccccccaaaaaaaaccaaacccaaaaaaccccccccccccjjjjrrrrrruuuxxxuuuqqqqqqqmmmdddcccc abaaaaaaaaaccccaaaaacaaaaaccccccaaaaaaaaccccccaaaaaaccccccccccccccaaaaaaaaccaaacaaaaaaaacccccccccccjjjjrrrtttuuuuxxxyvvvvvqqqqmmmdddcccc abaaaaaaaaaccaaaaaaacaaaaaaccccccaaaaaaaacccccaaaaaaccccccccccccccccaaaaccaaaaaaaaaaaaaacccccccccaaiijqqqrttttuuuxxyyvvvvvvvqqmmmdddcccc abcaaaaaaaaccaaaaaaaaaaaaaacccccaaaaaaaacccccccaaaacccccaaaaccccccccaaaaacaaaaaaaaccaaccccccccccaaaiiiqqqttttxxxxxxyyyyyyvvvqqmmmdddcccc abcccaaaaaaacaaaaaaaaaaaaaacccccaaaaaaaaaaaccccaaaaccccaaaaacccccccaaaaaacaaaaaaacccccccccccccccaaaiiiqqqtttxxxxxxxyyyyyyvvqqqmmmdddcccc SbcccaacccaccccaaacacccaaacccccccccaaaaaaaaacccaccaccccaaaaaaccccccaaccaacccaaaaaccccccccccccccccaaiiiiqqtttxxxxEzzzyyyyvvvqqqmmmddccccc abccaaaccccccccaaccccccccccccccccccaaaaaaaaccccccccccccaaaaaaccccccccccccccaaacaaaccaacccccccccccccciiiqqqttttxxxyyyyyvvvvqqqmmmdddccccc abccccccccccccccccccccccccccccccccaaaaaaaccccccccccccccaaaaaacccccccccccccccaacccccaaaaaaaccccccccccciiiqqqttttxxyyyyyvvvrrrnnneeecccccc abcaaaaccccccccccccccccccccccccccaaaaaaaaccccccccccccccccaacccccccccccccccccccccccccaaaaacccccccccccciiiqqqqttxxyyyyyyyvvrrnnnneeecccccc abcaaaaacccccccccccccccccccccccccaaaacaaacccaccaaacccccccccccccccccccccccccaaaccccaaaaaaaccccccccccccciiiqqqttwwyywwyyywwrrnnneeeccccccc abaaaaaacccaccaccccccccccccccccccaaaaccaacccaaaaaaccccccccccccccccaaaccccaaaaaacccaaaaaaaacccccccccccciiiqqqtswwwwwwwwwwwrrnnneeeccccccc abaaaaaacccaaaaccccccccaaaacccccccaaacccccccaaaaaacccccccccccccccaaaaaaccaaaaaacccaaaaaaaacaaccccccaaciiiqppsswwwwsswwwwwrrrnneeeccccccc abcaaaaacccaaaaacccccccaaaacccccccccccccccccaaaaaaaccccccccccccccaaaaaaccaaaaaacccccaaaaaaaaaccccccaaaahhpppssswwsssswwwwrrrnneeeacccccc abcaaaccccaaaaaacccccccaaaaccccccccccccccccaaaaaaaaccccccccccccccaaaaacccaaaaaccccccaacaaaaaaaaccaaaaaahhpppsssssssssrrrrrrnnneeeacccccc abccccccccaaaaaaccccccccaacccccccccccccccccaaaaaaaaccccaacccccccccaaaaaccaaaaacccccccccaaaaaaaaccaaaaachhpppssssssoosrrrrrrnnneeeaaacccc abccccccccccaaccccccccccccccccaaaaaccccccaacccaaacccaaaaacccccccccaacaacccccccccccccccccaaaaaaacccaaaaahhhppppssppooooorroonnffeaaaacccc abaaccccccccccccccccccccccccccaaaaaccccccaacccaaaccccaaaaacccccccccccccccccccccccccccaacaaaaacccccaacaahhhppppppppoooooooooonfffaaaacccc abaccccccccccccccccccccccccccaaaaaacccaaaaaaaacccccccaaaaaccccccccccccccccccccccccaaaaaaaaaaaccccccccccchhhpppppppgggoooooooffffaacccccc abaccccccccccccccccccccccccccaaaaaacccaaaaaaaaccccccaaaaaccccccacccaacccccccccccccaaaaaccccaaccccccccccchhhhhhggggggggfffffffffaaacccccc abaacccccccccccccccccccccccccaaaaaacccccaaaacccccccccaaaacccaacaacaaacccccccccccccaaaaaaacccccccccccccccchhhhgggggggggffffffffccaacccccc abcccccccaacccccccccccccccccccaaaccccccaaaaaccccccccaaaaccaaaacaaaaacccccccccccccaaaaaaaaccccccccccccccccchhhggggaaaagffffffcccccccccccc abcccccccaacccccccccccccaacccccccccccccaaaaaaccaaccccaaaaaaaaacaaaaaacccccccaaaacaaaaaaaacccccccccccaacccccccaaaacaaaacccccccccccccccccc abccccaaaaaaaacccccccaacaaaccccccccccccaaccaacaaaacccaaaaaaaacaaaaaaaaccccccaaaaccacaaaccaaaccccaaaaaacccccccaacccaaaacccccccccccccaaaaa abccccaaaaaaaacccccccaaaaaccccccccccccccccccccaaaaccccaaaaaaacaaaaaaaaccccccaaaaccccaaaccaaaaaccaaaaaaaacccccccccccaaaccccccccccccccaaaa abccccccaaaaccccccccccaaaaaaccccccccccccccccccaaaacccaaaaaaaaaaccaaccccccccccaacccccccccaaaaacccaaaaaaaacccccccccccaaaccccccccccccccaaaa abcccccaaaaaacccccccaaaaaaaacccccccccccccccccccccccaaaaaaaaaaaaaaaacccccccccccccccccccccaaaaaacccaaaaaaaccccccccccccccccccccccccccaaaaaa
A 2022/12/solve.zig => 2022/12/solve.zig +190 -0
@@ 0,0 1,190 @@ const std = @import("std"); const fs = std.fs; const heap = std.heap; const io = std.io; const math = std.math; const mem = std.mem; const process = std.process; const testing = std.testing; const Point = struct { i: usize, j: usize, pub fn eql(self: Point, other: Point) bool { return self.i == other.i and self.j == other.j; } fn heuristic(self: Point, other: Point) usize { const di = math.absCast( @intCast(isize, self.i) - @intCast(isize, other.i), ); const dj = math.absCast( @intCast(isize, self.j) - @intCast(isize, other.j), ); return di + dj; } }; const Cell = struct { point: Point, priority: usize, pub fn compare(_: void, lhs: Cell, rhs: Cell) math.Order { return math.order(lhs.priority, rhs.priority); } }; const Search = struct { map: [41][136]u8, frontier: Frontier, came_from: CameFrom, cost_so_far: CostSoFar, const Frontier = std.PriorityQueue(Cell, void, Cell.compare); const CameFrom = std.AutoHashMap(Point, Point); const CostSoFar = std.AutoHashMap(Point, usize); pub fn init(alloc: mem.Allocator) !Search { return Search{ .map = undefined, .frontier = Frontier.init(alloc, {}), .came_from = CameFrom.init(alloc), .cost_so_far = CostSoFar.init(alloc), }; } pub fn deinit(self: *Search) void { self.frontier.deinit(); self.came_from.deinit(); self.cost_so_far.deinit(); } pub fn findPoint(self: Search, height: u8) ?Point { return p: for (self.map) |row, i| { const j = mem.indexOfScalar(u8, &row, height) orelse continue; break :p .{ .i = i, .j = j }; } else null; } pub fn findDistance(self: *Search, start: Point, goal: Point) !usize { self.frontier.len = 0; self.came_from.clearRetainingCapacity(); self.cost_so_far.clearRetainingCapacity(); try self.frontier.add(.{ .point = start, .priority = 0 }); try self.came_from.put(start, start); try self.cost_so_far.put(start, 0); var point_buf: [4]Point = undefined; while (self.frontier.removeOrNull()) |current| { if (current.point.eql(goal)) break; const cost = self.cost_so_far.get(current.point).? + 1; const neighbors = self.getNeighbors(&point_buf, current.point); for (neighbors) |next| { const next_cost = self.cost_so_far.get(next) orelse math.maxInt(usize); if (cost < next_cost) { try self.cost_so_far.put(next, cost); const priority = cost + next.heuristic(goal); try self.frontier.add(.{ .point = next, .priority = priority, }); try self.came_from.put(next, current.point); } } } var distance: usize = 0; var current = goal; while (!current.eql(start)) { current = self.came_from.get(current) orelse break; distance += 1; } return distance; } fn getNeighbors(self: Search, buffer: []Point, center: Point) []Point { const height = self.map[center.i][center.j]; var k: usize = 0; if (center.i > 0) { const i = center.i - 1; const j = center.j; if (self.map[i][j] <= height + 1) { buffer[k] = .{ .i = i, .j = j }; k += 1; } } if (center.j > 0) { const i = center.i; const j = center.j - 1; if (self.map[i][j] <= height + 1) { buffer[k] = .{ .i = i, .j = j }; k += 1; } } if (center.i < 40) { const i = center.i + 1; const j = center.j; if (self.map[i][j] <= height + 1) { buffer[k] = .{ .i = i, .j = j }; k += 1; } } if (center.j < 135) { const i = center.i; const j = center.j + 1; if (self.map[i][j] <= height + 1) { buffer[k] = .{ .i = i, .j = j }; k += 1; } } return buffer[0..k]; } }; pub fn main() !void { const stdout = io.getStdOut().writer(); var gpa: heap.GeneralPurposeAllocator(.{}) = .{}; defer _ = gpa.deinit(); const alloc = gpa.allocator(); var args = process.args(); _ = args.next(); const filename = args.next() orelse @panic("error: missing input arg."); var buffer: [41 * 137]u8 = undefined; const content = try fs.cwd().readFile(filename, &buffer); var search = try Search.init(alloc); defer search.deinit(); for (search.map) |*row, i| { const offset = i * 137; mem.copy(u8, row, content[offset .. offset + 136]); } const start = search.findPoint('S') orelse unreachable; const goal = search.findPoint('E') orelse unreachable; search.map[start.i][start.j] = 'a'; search.map[goal.i][goal.j] = 'z'; const result1 = try search.findDistance(start, goal); try stdout.print("solution 1: {d}\n", .{result1}); var result2 = result1; for (search.map) |row, i| { for (row) |height, j| { if (height == 'a') { const begin: Point = .{ .i = i, .j = j }; const dist = try search.findDistance(begin, goal); if (dist != 0 and dist < result2) result2 = dist; } } } try stdout.print("solution 2: {d}\n", .{result2}); }
M build.zig => build.zig +1 -0