mirror of
https://github.com/MorizzG/aoc-2024.git
synced 2025-12-06 04:22:43 +00:00
day 10 finished
This commit is contained in:
parent
8b34776508
commit
e0ceda6bb0
3 changed files with 413 additions and 2 deletions
361
day10.zig
Normal file
361
day10.zig
Normal file
|
|
@ -0,0 +1,361 @@
|
||||||
|
const std = @import("std");
|
||||||
|
|
||||||
|
const utils = @import("lib/utils.zig");
|
||||||
|
|
||||||
|
const spice = @import("lib/spice.zig");
|
||||||
|
|
||||||
|
const filename = "inputs/day10.txt";
|
||||||
|
|
||||||
|
pub fn main() !void {
|
||||||
|
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
|
||||||
|
const alloc = gpa.allocator();
|
||||||
|
|
||||||
|
{
|
||||||
|
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 10, 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 10, part 2: {}\n", .{result});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const Pos = struct {
|
||||||
|
x: i32,
|
||||||
|
y: i32,
|
||||||
|
};
|
||||||
|
|
||||||
|
const Map = struct {
|
||||||
|
size_x: u32,
|
||||||
|
size_y: u32,
|
||||||
|
|
||||||
|
map: []const []const u8,
|
||||||
|
|
||||||
|
pub fn format(self: Map, comptime fmt: []const u8, options: std.fmt.FormatOptions, writer: anytype) !void {
|
||||||
|
_ = fmt;
|
||||||
|
_ = options;
|
||||||
|
|
||||||
|
for (self.map) |line| {
|
||||||
|
for (line) |x| {
|
||||||
|
try writer.print("{} ", .{x});
|
||||||
|
}
|
||||||
|
|
||||||
|
_ = try writer.write("\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get(self: Map, x: i32, y: i32) ?u8 {
|
||||||
|
if (x < 0 or x >= @as(i32, @intCast(self.size_x)) or y < 0 or y >= @as(i32, @intCast(self.size_y))) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return self.map[@intCast(x)][@intCast(y)];
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
fn findAllEnds(ends: *std.AutoHashMap(Pos, void), map: Map, start_pos: Pos) !void {
|
||||||
|
const findAllEndsRec = struct {
|
||||||
|
fn findAllEndsRec(_ends: *std.AutoHashMap(Pos, void), _map: Map, cur_pos: Pos, height: u8) !void {
|
||||||
|
const cur_x = cur_pos.x;
|
||||||
|
const cur_y = cur_pos.y;
|
||||||
|
|
||||||
|
std.debug.assert(_map.get(cur_x, cur_y).? == height);
|
||||||
|
|
||||||
|
if (height == 9) {
|
||||||
|
try _ends.put(cur_pos, {});
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
const new_x = cur_x - 1;
|
||||||
|
const new_y = cur_y;
|
||||||
|
|
||||||
|
if (_map.get(new_x, new_y)) |new_height| {
|
||||||
|
if (new_height == height + 1) {
|
||||||
|
try findAllEndsRec(_ends, _map, .{ .x = new_x, .y = new_y }, new_height);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
const new_x = cur_x + 1;
|
||||||
|
const new_y = cur_y;
|
||||||
|
|
||||||
|
if (_map.get(new_x, new_y)) |new_height| {
|
||||||
|
if (new_height == height + 1) {
|
||||||
|
try findAllEndsRec(_ends, _map, .{ .x = new_x, .y = new_y }, new_height);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
const new_x = cur_x;
|
||||||
|
const new_y = cur_y - 1;
|
||||||
|
|
||||||
|
if (_map.get(new_x, new_y)) |new_height| {
|
||||||
|
if (new_height == height + 1) {
|
||||||
|
try findAllEndsRec(_ends, _map, .{ .x = new_x, .y = new_y }, new_height);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
const new_x = cur_x;
|
||||||
|
const new_y = cur_y + 1;
|
||||||
|
|
||||||
|
if (_map.get(new_x, new_y)) |new_height| {
|
||||||
|
if (new_height == height + 1) {
|
||||||
|
try findAllEndsRec(_ends, _map, .{ .x = new_x, .y = new_y }, new_height);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}.findAllEndsRec;
|
||||||
|
|
||||||
|
try findAllEndsRec(ends, map, start_pos, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn countAllTrails(map: Map, start_pos: Pos) !u64 {
|
||||||
|
const countAllTrailsRec = struct {
|
||||||
|
fn countAllTrailsRec(_map: Map, cur_pos: Pos, height: u8) !u64 {
|
||||||
|
const cur_x = cur_pos.x;
|
||||||
|
const cur_y = cur_pos.y;
|
||||||
|
|
||||||
|
std.debug.assert(_map.get(cur_x, cur_y).? == height);
|
||||||
|
|
||||||
|
if (height == 9) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
var count: u64 = 0;
|
||||||
|
|
||||||
|
{
|
||||||
|
const new_x = cur_x - 1;
|
||||||
|
const new_y = cur_y;
|
||||||
|
|
||||||
|
if (_map.get(new_x, new_y)) |new_height| {
|
||||||
|
if (new_height == height + 1) {
|
||||||
|
count += try countAllTrailsRec(_map, .{ .x = new_x, .y = new_y }, new_height);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
const new_x = cur_x + 1;
|
||||||
|
const new_y = cur_y;
|
||||||
|
|
||||||
|
if (_map.get(new_x, new_y)) |new_height| {
|
||||||
|
if (new_height == height + 1) {
|
||||||
|
count += try countAllTrailsRec(_map, .{ .x = new_x, .y = new_y }, new_height);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
const new_x = cur_x;
|
||||||
|
const new_y = cur_y - 1;
|
||||||
|
|
||||||
|
if (_map.get(new_x, new_y)) |new_height| {
|
||||||
|
if (new_height == height + 1) {
|
||||||
|
count += try countAllTrailsRec(_map, .{ .x = new_x, .y = new_y }, new_height);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
const new_x = cur_x;
|
||||||
|
const new_y = cur_y + 1;
|
||||||
|
|
||||||
|
if (_map.get(new_x, new_y)) |new_height| {
|
||||||
|
if (new_height == height + 1) {
|
||||||
|
count += try countAllTrailsRec(_map, .{ .x = new_x, .y = new_y }, new_height);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
}.countAllTrailsRec;
|
||||||
|
|
||||||
|
return try countAllTrailsRec(map, start_pos, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn part1(alloc: std.mem.Allocator, reader: anytype) !u64 {
|
||||||
|
var map_arena = std.heap.ArenaAllocator.init(alloc);
|
||||||
|
defer map_arena.deinit();
|
||||||
|
|
||||||
|
var map_list = std.ArrayList([]const u8).init(map_arena.allocator());
|
||||||
|
defer map_list.deinit();
|
||||||
|
|
||||||
|
var line_reader = utils.lineReader(alloc, reader);
|
||||||
|
defer line_reader.deinit();
|
||||||
|
|
||||||
|
while (try line_reader.next()) |line| {
|
||||||
|
const map_line = try map_arena.allocator().alloc(u8, line.len);
|
||||||
|
|
||||||
|
for (line, map_line) |c, *x| {
|
||||||
|
std.debug.assert('0' <= c and c <= '9');
|
||||||
|
|
||||||
|
x.* = c - '0';
|
||||||
|
}
|
||||||
|
|
||||||
|
try map_list.append(map_line);
|
||||||
|
}
|
||||||
|
|
||||||
|
const size_x = map_list.items.len;
|
||||||
|
const size_y = map_list.items[0].len;
|
||||||
|
|
||||||
|
for (map_list.items) |line| {
|
||||||
|
std.debug.assert(line.len == size_y);
|
||||||
|
}
|
||||||
|
|
||||||
|
const map = Map{ .size_x = @intCast(size_x), .size_y = @intCast(size_y), .map = map_list.items };
|
||||||
|
|
||||||
|
var count: u64 = 0;
|
||||||
|
|
||||||
|
var ends = std.AutoHashMap(Pos, void).init(alloc);
|
||||||
|
defer ends.deinit();
|
||||||
|
|
||||||
|
for (0..size_x) |x| {
|
||||||
|
for (0..size_y) |y| {
|
||||||
|
if (map.get(@intCast(x), @intCast(y)) != 0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
ends.clearRetainingCapacity();
|
||||||
|
|
||||||
|
try findAllEnds(&ends, map, .{ .x = @intCast(x), .y = @intCast(y) });
|
||||||
|
|
||||||
|
count += @intCast(ends.count());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn part2(alloc: std.mem.Allocator, reader: anytype) !u64 {
|
||||||
|
var map_arena = std.heap.ArenaAllocator.init(alloc);
|
||||||
|
defer map_arena.deinit();
|
||||||
|
|
||||||
|
var map_list = std.ArrayList([]const u8).init(map_arena.allocator());
|
||||||
|
defer map_list.deinit();
|
||||||
|
|
||||||
|
var line_reader = utils.lineReader(alloc, reader);
|
||||||
|
defer line_reader.deinit();
|
||||||
|
|
||||||
|
while (try line_reader.next()) |line| {
|
||||||
|
const map_line = try map_arena.allocator().alloc(u8, line.len);
|
||||||
|
|
||||||
|
for (line, map_line) |c, *x| {
|
||||||
|
std.debug.assert('0' <= c and c <= '9');
|
||||||
|
|
||||||
|
x.* = c - '0';
|
||||||
|
}
|
||||||
|
|
||||||
|
try map_list.append(map_line);
|
||||||
|
}
|
||||||
|
|
||||||
|
const size_x = map_list.items.len;
|
||||||
|
const size_y = map_list.items[0].len;
|
||||||
|
|
||||||
|
for (map_list.items) |line| {
|
||||||
|
std.debug.assert(line.len == size_y);
|
||||||
|
}
|
||||||
|
|
||||||
|
const map = Map{ .size_x = @intCast(size_x), .size_y = @intCast(size_y), .map = map_list.items };
|
||||||
|
|
||||||
|
var count: u64 = 0;
|
||||||
|
|
||||||
|
var ends = std.AutoHashMap(Pos, void).init(alloc);
|
||||||
|
defer ends.deinit();
|
||||||
|
|
||||||
|
for (0..size_x) |x| {
|
||||||
|
for (0..size_y) |y| {
|
||||||
|
if (map.get(@intCast(x), @intCast(y)) != 0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
ends.clearRetainingCapacity();
|
||||||
|
|
||||||
|
const num_trails = try countAllTrails(map, .{ .x = @intCast(x), .y = @intCast(y) });
|
||||||
|
|
||||||
|
count += num_trails;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
|
test "part1 example" {
|
||||||
|
const alloc = std.testing.allocator;
|
||||||
|
|
||||||
|
const example =
|
||||||
|
\\89010123
|
||||||
|
\\78121874
|
||||||
|
\\87430965
|
||||||
|
\\96549874
|
||||||
|
\\45678903
|
||||||
|
\\32019012
|
||||||
|
\\01329801
|
||||||
|
\\10456732
|
||||||
|
;
|
||||||
|
|
||||||
|
var stream = std.io.fixedBufferStream(example);
|
||||||
|
|
||||||
|
const result = try part1(alloc, stream.reader());
|
||||||
|
|
||||||
|
try std.testing.expectEqual(36, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
test "part1 input" {
|
||||||
|
const alloc = std.testing.allocator;
|
||||||
|
|
||||||
|
const file_reader = try utils.FileReader.init(alloc, filename);
|
||||||
|
defer file_reader.deinit();
|
||||||
|
|
||||||
|
const result = try part1(alloc, file_reader.reader());
|
||||||
|
|
||||||
|
try std.testing.expectEqual(629, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
test "part2 example" {
|
||||||
|
const alloc = std.testing.allocator;
|
||||||
|
|
||||||
|
const example =
|
||||||
|
\\89010123
|
||||||
|
\\78121874
|
||||||
|
\\87430965
|
||||||
|
\\96549874
|
||||||
|
\\45678903
|
||||||
|
\\32019012
|
||||||
|
\\01329801
|
||||||
|
\\10456732
|
||||||
|
;
|
||||||
|
|
||||||
|
var stream = std.io.fixedBufferStream(example);
|
||||||
|
|
||||||
|
const result = try part2(alloc, stream.reader());
|
||||||
|
|
||||||
|
try std.testing.expectEqual(81, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
test "part2 input" {
|
||||||
|
const alloc = std.testing.allocator;
|
||||||
|
|
||||||
|
const file_reader = try utils.FileReader.init(alloc, filename);
|
||||||
|
defer file_reader.deinit();
|
||||||
|
|
||||||
|
const result = try part2(alloc, file_reader.reader());
|
||||||
|
|
||||||
|
try std.testing.expectEqual(1242, result);
|
||||||
|
}
|
||||||
4
day9.zig
4
day9.zig
|
|
@ -16,7 +16,7 @@ pub fn main() !void {
|
||||||
|
|
||||||
const result = try part1(alloc, file_reader.reader());
|
const result = try part1(alloc, file_reader.reader());
|
||||||
|
|
||||||
try std.io.getStdOut().writer().print("Day 8, part 1: {}\n", .{result});
|
try std.io.getStdOut().writer().print("Day 9, part 1: {}\n", .{result});
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
|
|
@ -25,7 +25,7 @@ pub fn main() !void {
|
||||||
|
|
||||||
const result = try part2(alloc, file_reader.reader());
|
const result = try part2(alloc, file_reader.reader());
|
||||||
|
|
||||||
try std.io.getStdOut().writer().print("Day 8, part 2: {}\n", .{result});
|
try std.io.getStdOut().writer().print("Day 9, part 2: {}\n", .{result});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
50
inputs/day10.txt
Normal file
50
inputs/day10.txt
Normal file
|
|
@ -0,0 +1,50 @@
|
||||||
|
56760198543405456770107687012987873265430701234123
|
||||||
|
47891087612514320889298596543236982176321878985054
|
||||||
|
30932912503423411978321436760145453089490965076567
|
||||||
|
21043803498598502565450345897896334569584324105498
|
||||||
|
43256754387687643445601231056787276578675013212389
|
||||||
|
50105620896014553238782322348996189432106522301210
|
||||||
|
60234211205423469109695210567345023456987101232569
|
||||||
|
71454301312345678100556501051269010787832198543478
|
||||||
|
82365985407856743291447892340178732696949037643323
|
||||||
|
99878876556989856782332309650065341054658743252110
|
||||||
|
12389565445845698943221218761234456565789650167087
|
||||||
|
03458890330532787892100321052442787074656782108996
|
||||||
|
12766721221621056521098478934321692183245891210105
|
||||||
|
00875437876521245430167569035630013290194300121234
|
||||||
|
21980356985430130101456122128754324389980215432101
|
||||||
|
32341245234561221212340033439961015671271326990123
|
||||||
|
41239832101676678703121542345872343760362347887654
|
||||||
|
50146701098787569254035671096112654854454558943210
|
||||||
|
69655410889693452164549389987003569943003967656787
|
||||||
|
78789324989582543076678432176124578752112876545490
|
||||||
|
49670123476451001289986581065437669801198743454321
|
||||||
|
34565404560302654345677893034458954321034652345210
|
||||||
|
21670313401212701238766732123361056700125601216787
|
||||||
|
10781223304343870349676678901272341811098700305891
|
||||||
|
87690433210154901234587565078980110925643212456730
|
||||||
|
98521049873269100448996652169765223434756965569821
|
||||||
|
83430656794378234567385543258894304589807874321034
|
||||||
|
12345690185123247855434789043210113676212981012125
|
||||||
|
04396783276030110982329872178901923494345891234596
|
||||||
|
65287654896543225671012763561032876587436780989687
|
||||||
|
70132108987652334430101654432945214306525891078765
|
||||||
|
89945345456701498521012346547876305211014342569854
|
||||||
|
67876276789876567677890107236521456523210213410743
|
||||||
|
56940189678930438988743298101430567894765104323212
|
||||||
|
45434328509821321089654340122334567765894101298701
|
||||||
|
50125613410030012127763019831021998568903210345692
|
||||||
|
23498701322147897898892123742340867478912653210789
|
||||||
|
10567654213456786721089054654356789302801743105678
|
||||||
|
01678123402110995437658766789210676211010892234109
|
||||||
|
67569016567021874378941043212101245432346781103201
|
||||||
|
58454323898134565632332456701234306011015490321232
|
||||||
|
49323454234012906701454327890965412102367305410147
|
||||||
|
31012365125643812898765410378876543233458216568758
|
||||||
|
21009876034756763019034101269989100146569325679669
|
||||||
|
21898745129829654323129654352123299656478012784578
|
||||||
|
30743231065018760563238765543034788798329983693056
|
||||||
|
45656189654323011056769894672145632347012674212147
|
||||||
|
01218088745896522349850123283034701456981065100238
|
||||||
|
14309893236787631438943210190129892123672578921109
|
||||||
|
25456782101896540127654301012010181034543465433212
|
||||||
Loading…
Add table
Add a link
Reference in a new issue