mirror of
https://github.com/MorizzG/aoc-2024.git
synced 2025-12-06 04:22:43 +00:00
day 9 finished
This commit is contained in:
parent
f080dd64dd
commit
8b34776508
7 changed files with 722 additions and 2 deletions
2
day6.zig
2
day6.zig
|
|
@ -23,7 +23,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 6, part 1: {}\n", .{result});
|
try std.io.getStdOut().writer().print("Day 6, part 2: {}\n", .{result});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
2
day7.zig
2
day7.zig
|
|
@ -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 7, part 1: {}\n", .{result});
|
try std.io.getStdOut().writer().print("Day 7, part 2: {}\n", .{result});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
308
day8.zig
Normal file
308
day8.zig
Normal file
|
|
@ -0,0 +1,308 @@
|
||||||
|
const std = @import("std");
|
||||||
|
|
||||||
|
const utils = @import("lib/utils.zig");
|
||||||
|
|
||||||
|
const spice = @import("lib/spice.zig");
|
||||||
|
|
||||||
|
const filename = "inputs/day8.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 8, 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 8, part 2: {}\n", .{result});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn part1(alloc: std.mem.Allocator, reader: anytype) !u64 {
|
||||||
|
const Pos = struct {
|
||||||
|
x: usize,
|
||||||
|
y: usize,
|
||||||
|
};
|
||||||
|
|
||||||
|
var arena = std.heap.ArenaAllocator.init(alloc);
|
||||||
|
defer arena.deinit();
|
||||||
|
|
||||||
|
var freq_pos = std.AutoHashMap(u8, std.ArrayList(Pos)).init(arena.allocator());
|
||||||
|
defer freq_pos.deinit();
|
||||||
|
|
||||||
|
var line_reader = utils.lineReader(alloc, reader);
|
||||||
|
defer line_reader.deinit();
|
||||||
|
|
||||||
|
var x_size: usize = 0;
|
||||||
|
var y_size: usize = 0;
|
||||||
|
|
||||||
|
while (try line_reader.next()) |line| : (x_size += 1) {
|
||||||
|
if (line.len == 0) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (y_size == 0) {
|
||||||
|
y_size = line.len;
|
||||||
|
} else {
|
||||||
|
std.debug.assert(y_size == line.len);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (0.., line) |y, c| {
|
||||||
|
if (c != '.') {
|
||||||
|
const entry = try freq_pos.getOrPut(c);
|
||||||
|
|
||||||
|
const pos_list = entry.value_ptr;
|
||||||
|
|
||||||
|
if (!entry.found_existing) {
|
||||||
|
pos_list.* = std.ArrayList(Pos).init(arena.allocator());
|
||||||
|
}
|
||||||
|
|
||||||
|
try pos_list.append(.{ .x = x_size, .y = y });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const antinodes = try utils.allocGridInit(bool, alloc, x_size, y_size, false);
|
||||||
|
defer utils.deinitGrid(bool, alloc, antinodes);
|
||||||
|
|
||||||
|
for (antinodes) |line| {
|
||||||
|
for (line) |b| {
|
||||||
|
std.debug.assert(b == false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var it = freq_pos.iterator();
|
||||||
|
|
||||||
|
while (it.next()) |entry| {
|
||||||
|
const pos_list = entry.value_ptr.items;
|
||||||
|
const n = pos_list.len;
|
||||||
|
|
||||||
|
for (0..n) |i| {
|
||||||
|
const pos_i = pos_list[i];
|
||||||
|
|
||||||
|
for (0..i) |j| {
|
||||||
|
const pos_j = pos_list[j];
|
||||||
|
|
||||||
|
const diff_x = pos_i.x -% pos_j.x;
|
||||||
|
const diff_y = pos_i.y -% pos_j.y;
|
||||||
|
|
||||||
|
const antinode1_x = pos_i.x +% diff_x;
|
||||||
|
const antinode1_y = pos_i.y +% diff_y;
|
||||||
|
|
||||||
|
if (antinode1_x < x_size and antinode1_y < y_size) {
|
||||||
|
antinodes[antinode1_x][antinode1_y] = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
const antinode2_x = pos_j.x -% diff_x;
|
||||||
|
const antinode2_y = pos_j.y -% diff_y;
|
||||||
|
|
||||||
|
if (antinode2_x < x_size and antinode2_y < y_size) {
|
||||||
|
antinodes[antinode2_x][antinode2_y] = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var antinode_count: u64 = 0;
|
||||||
|
|
||||||
|
for (antinodes) |line| {
|
||||||
|
for (line) |b| {
|
||||||
|
if (b) {
|
||||||
|
antinode_count += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return antinode_count;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn part2(alloc: std.mem.Allocator, reader: anytype) !u64 {
|
||||||
|
const Pos = struct {
|
||||||
|
x: usize,
|
||||||
|
y: usize,
|
||||||
|
};
|
||||||
|
|
||||||
|
var arena = std.heap.ArenaAllocator.init(alloc);
|
||||||
|
defer arena.deinit();
|
||||||
|
|
||||||
|
var freq_pos = std.AutoHashMap(u8, std.ArrayList(Pos)).init(arena.allocator());
|
||||||
|
defer freq_pos.deinit();
|
||||||
|
|
||||||
|
var line_reader = utils.lineReader(alloc, reader);
|
||||||
|
defer line_reader.deinit();
|
||||||
|
|
||||||
|
var x_size: usize = 0;
|
||||||
|
var y_size: usize = 0;
|
||||||
|
|
||||||
|
while (try line_reader.next()) |line| : (x_size += 1) {
|
||||||
|
if (line.len == 0) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (y_size == 0) {
|
||||||
|
y_size = line.len;
|
||||||
|
} else {
|
||||||
|
std.debug.assert(y_size == line.len);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (0.., line) |y, c| {
|
||||||
|
if (c != '.') {
|
||||||
|
const entry = try freq_pos.getOrPut(c);
|
||||||
|
|
||||||
|
const pos_list = entry.value_ptr;
|
||||||
|
|
||||||
|
if (!entry.found_existing) {
|
||||||
|
pos_list.* = std.ArrayList(Pos).init(arena.allocator());
|
||||||
|
}
|
||||||
|
|
||||||
|
try pos_list.append(.{ .x = x_size, .y = y });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const antinodes = try utils.allocGridInit(bool, alloc, x_size, y_size, false);
|
||||||
|
defer utils.deinitGrid(bool, alloc, antinodes);
|
||||||
|
|
||||||
|
for (antinodes) |line| {
|
||||||
|
for (line) |b| {
|
||||||
|
std.debug.assert(b == false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var it = freq_pos.iterator();
|
||||||
|
|
||||||
|
while (it.next()) |entry| {
|
||||||
|
const pos_list = entry.value_ptr.items;
|
||||||
|
const n = pos_list.len;
|
||||||
|
|
||||||
|
for (0..n) |i| {
|
||||||
|
const pos_i = pos_list[i];
|
||||||
|
|
||||||
|
for (0..i) |j| {
|
||||||
|
const pos_j = pos_list[j];
|
||||||
|
|
||||||
|
const i_minus_j_x = pos_i.x -% pos_j.x;
|
||||||
|
const i_minus_j_y = pos_i.y -% pos_j.y;
|
||||||
|
|
||||||
|
{
|
||||||
|
var antinode_x = pos_i.x;
|
||||||
|
var antinode_y = pos_i.y;
|
||||||
|
|
||||||
|
while (antinode_x < x_size and antinode_y < y_size) {
|
||||||
|
antinodes[antinode_x][antinode_y] = true;
|
||||||
|
|
||||||
|
antinode_x +%= i_minus_j_x;
|
||||||
|
antinode_y +%= i_minus_j_y;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
var antinode_x = pos_j.x;
|
||||||
|
var antinode_y = pos_j.y;
|
||||||
|
|
||||||
|
while (antinode_x < x_size and antinode_y < y_size) {
|
||||||
|
antinodes[antinode_x][antinode_y] = true;
|
||||||
|
|
||||||
|
antinode_x -%= i_minus_j_x;
|
||||||
|
antinode_y -%= i_minus_j_y;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var antinode_count: u64 = 0;
|
||||||
|
|
||||||
|
for (antinodes) |line| {
|
||||||
|
for (line) |b| {
|
||||||
|
if (b) {
|
||||||
|
antinode_count += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return antinode_count;
|
||||||
|
}
|
||||||
|
|
||||||
|
test "part1 example" {
|
||||||
|
const alloc = std.testing.allocator;
|
||||||
|
|
||||||
|
const example =
|
||||||
|
\\............
|
||||||
|
\\........0...
|
||||||
|
\\.....0......
|
||||||
|
\\.......0....
|
||||||
|
\\....0.......
|
||||||
|
\\......A.....
|
||||||
|
\\............
|
||||||
|
\\............
|
||||||
|
\\........A...
|
||||||
|
\\.........A..
|
||||||
|
\\............
|
||||||
|
\\............
|
||||||
|
;
|
||||||
|
|
||||||
|
var stream = std.io.fixedBufferStream(example);
|
||||||
|
|
||||||
|
const result = try part1(alloc, stream.reader());
|
||||||
|
|
||||||
|
try std.testing.expectEqual(14, 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(381, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
test "part2 example" {
|
||||||
|
const alloc = std.testing.allocator;
|
||||||
|
|
||||||
|
const example =
|
||||||
|
\\............
|
||||||
|
\\........0...
|
||||||
|
\\.....0......
|
||||||
|
\\.......0....
|
||||||
|
\\....0.......
|
||||||
|
\\......A.....
|
||||||
|
\\............
|
||||||
|
\\............
|
||||||
|
\\........A...
|
||||||
|
\\.........A..
|
||||||
|
\\............
|
||||||
|
\\............
|
||||||
|
;
|
||||||
|
|
||||||
|
var stream = std.io.fixedBufferStream(example);
|
||||||
|
|
||||||
|
const result = try part2(alloc, stream.reader());
|
||||||
|
|
||||||
|
try std.testing.expectEqual(34, 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(1184, result);
|
||||||
|
}
|
||||||
329
day9.zig
Normal file
329
day9.zig
Normal file
|
|
@ -0,0 +1,329 @@
|
||||||
|
const std = @import("std");
|
||||||
|
|
||||||
|
const utils = @import("lib/utils.zig");
|
||||||
|
|
||||||
|
const spice = @import("lib/spice.zig");
|
||||||
|
|
||||||
|
const filename = "inputs/day9.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 8, 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 8, part 2: {}\n", .{result});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn part1(alloc: std.mem.Allocator, reader: anytype) !u64 {
|
||||||
|
const FsEntry = enum(u32) {
|
||||||
|
empty = std.math.maxInt(u32),
|
||||||
|
_,
|
||||||
|
};
|
||||||
|
|
||||||
|
const input = try reader.readAllAlloc(alloc, std.math.maxInt(usize));
|
||||||
|
defer alloc.free(input);
|
||||||
|
|
||||||
|
var filesystem_list = std.ArrayList(FsEntry).init(alloc);
|
||||||
|
defer filesystem_list.deinit();
|
||||||
|
|
||||||
|
var next_id: u16 = 0;
|
||||||
|
var is_gap = false;
|
||||||
|
|
||||||
|
for (input) |byte| {
|
||||||
|
if (byte == '\n') {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
std.debug.assert('0' <= byte and byte <= '9');
|
||||||
|
|
||||||
|
const len: usize = @as(usize, byte - '0');
|
||||||
|
|
||||||
|
if (is_gap) {
|
||||||
|
try filesystem_list.appendNTimes(.empty, len);
|
||||||
|
} else {
|
||||||
|
try filesystem_list.appendNTimes(@enumFromInt(next_id), len);
|
||||||
|
|
||||||
|
next_id += 1;
|
||||||
|
|
||||||
|
std.debug.assert(next_id != @intFromEnum(FsEntry.empty));
|
||||||
|
}
|
||||||
|
|
||||||
|
is_gap = !is_gap;
|
||||||
|
}
|
||||||
|
|
||||||
|
const filesystem = filesystem_list.items;
|
||||||
|
|
||||||
|
// for (filesystem) |x| {
|
||||||
|
// switch (x) {
|
||||||
|
// .empty => std.debug.print(".", .{}),
|
||||||
|
// else => std.debug.print("{}", .{@intFromEnum(x)}),
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// std.debug.print("\n", .{});
|
||||||
|
|
||||||
|
var start_idx: usize = 0;
|
||||||
|
var end_idx: usize = filesystem.len - 1;
|
||||||
|
|
||||||
|
while (start_idx < end_idx) {
|
||||||
|
|
||||||
|
// for start_idx: seek next empty position
|
||||||
|
if (filesystem[start_idx] != .empty) {
|
||||||
|
start_idx += 1;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// for end_idx: seek next full position
|
||||||
|
if (filesystem[end_idx] == .empty) {
|
||||||
|
end_idx -= 1;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
std.debug.assert(filesystem[start_idx] == .empty and filesystem[end_idx] != .empty);
|
||||||
|
|
||||||
|
filesystem[start_idx] = filesystem[end_idx];
|
||||||
|
filesystem[end_idx] = .empty;
|
||||||
|
}
|
||||||
|
|
||||||
|
const first_empty_idx = std.mem.indexOfScalar(FsEntry, filesystem, .empty).?;
|
||||||
|
|
||||||
|
for (filesystem[first_empty_idx..]) |id| {
|
||||||
|
std.debug.assert(id == .empty);
|
||||||
|
}
|
||||||
|
|
||||||
|
var checksum: u64 = 0;
|
||||||
|
|
||||||
|
for (0.., filesystem) |idx, id| {
|
||||||
|
if (id == .empty) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
checksum += @as(u64, idx) * @intFromEnum(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
return checksum;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn part2(alloc: std.mem.Allocator, reader: anytype) !u64 {
|
||||||
|
const FsId = enum(u16) {
|
||||||
|
empty = std.math.maxInt(u16),
|
||||||
|
_,
|
||||||
|
};
|
||||||
|
|
||||||
|
const FsEntry = struct {
|
||||||
|
len: u16,
|
||||||
|
id: FsId,
|
||||||
|
};
|
||||||
|
|
||||||
|
const input = try reader.readAllAlloc(alloc, std.math.maxInt(usize));
|
||||||
|
defer alloc.free(input);
|
||||||
|
|
||||||
|
var filesystem = std.ArrayList(FsEntry).init(alloc);
|
||||||
|
defer filesystem.deinit();
|
||||||
|
|
||||||
|
var max_id: u16 = undefined;
|
||||||
|
|
||||||
|
{
|
||||||
|
var next_id: u16 = 0;
|
||||||
|
var is_gap = false;
|
||||||
|
|
||||||
|
for (input) |byte| {
|
||||||
|
if (byte == '\n') {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
std.debug.assert('0' <= byte and byte <= '9');
|
||||||
|
|
||||||
|
const len: u16 = @as(u16, byte - '0');
|
||||||
|
|
||||||
|
if (is_gap) {
|
||||||
|
try filesystem.append(.{ .len = len, .id = .empty });
|
||||||
|
} else {
|
||||||
|
try filesystem.append(.{ .len = len, .id = @enumFromInt(next_id) });
|
||||||
|
|
||||||
|
next_id += 1;
|
||||||
|
|
||||||
|
std.debug.assert(next_id != @intFromEnum(FsId.empty));
|
||||||
|
}
|
||||||
|
|
||||||
|
is_gap = !is_gap;
|
||||||
|
}
|
||||||
|
|
||||||
|
max_id = next_id - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// for (filesystem.items) |entry| {
|
||||||
|
// for (0..entry.len) |_| {
|
||||||
|
// switch (entry.id) {
|
||||||
|
// .empty => std.debug.print(".", .{}),
|
||||||
|
// else => std.debug.print("{}", .{@intFromEnum(entry.id)}),
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// std.debug.print("\n", .{});
|
||||||
|
|
||||||
|
{
|
||||||
|
// next ID to check; neccessary for checking all files once
|
||||||
|
// since file entries are sorted in increasing order, we can simply decrease this with each
|
||||||
|
// checked file
|
||||||
|
var next_id = max_id;
|
||||||
|
|
||||||
|
// index of next filesystem entry to check
|
||||||
|
var idx: usize = filesystem.items.len - 1;
|
||||||
|
while (idx > 0) : (idx -= 1) {
|
||||||
|
const entry = filesystem.items[idx];
|
||||||
|
|
||||||
|
// we should never see and ID smaller than the one we're looking for
|
||||||
|
// if we do that means we would skip that file
|
||||||
|
std.debug.assert(entry.id == .empty or @intFromEnum(entry.id) >= next_id);
|
||||||
|
|
||||||
|
if (@intFromEnum(entry.id) != next_id) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// found next entry to move
|
||||||
|
|
||||||
|
// decrease next ID to find
|
||||||
|
next_id -= 1;
|
||||||
|
|
||||||
|
const len = entry.len;
|
||||||
|
|
||||||
|
for (0..idx) |jdx| {
|
||||||
|
const target_entry = filesystem.items[jdx];
|
||||||
|
|
||||||
|
// find the first entry with is empty and at least as large as our entry
|
||||||
|
if (target_entry.id != .empty or target_entry.len < len) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// found target entry
|
||||||
|
|
||||||
|
if (target_entry.len == entry.len) {
|
||||||
|
// exact hit! no need to split entry, just swap IDs
|
||||||
|
|
||||||
|
std.mem.swap(FsId, &filesystem.items[idx].id, &filesystem.items[jdx].id);
|
||||||
|
} else {
|
||||||
|
// empty space is larger than our entry; need to split
|
||||||
|
|
||||||
|
// warning! this (potentially) invalidates all pointers into filesystem.items
|
||||||
|
// and we need to adjust indices (i.e. increase idx by one) since everything after
|
||||||
|
// jdx shift back by one index
|
||||||
|
|
||||||
|
_ = try filesystem.addManyAt(jdx + 1, 1);
|
||||||
|
|
||||||
|
idx += 1;
|
||||||
|
|
||||||
|
// jdx + 1 becomes empty entry of len target_entry.len - entry.len
|
||||||
|
filesystem.items[jdx + 1].id = .empty;
|
||||||
|
filesystem.items[jdx + 1].len = target_entry.len - entry.len;
|
||||||
|
|
||||||
|
// jdx becomes entry
|
||||||
|
filesystem.items[jdx].len = entry.len;
|
||||||
|
filesystem.items[jdx].id = entry.id;
|
||||||
|
|
||||||
|
// idx becomes empty
|
||||||
|
filesystem.items[idx].id = .empty;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// for (filesystem.items) |entry| {
|
||||||
|
// for (0..entry.len) |_| {
|
||||||
|
// switch (entry.id) {
|
||||||
|
// .empty => std.debug.print(".", .{}),
|
||||||
|
// else => std.debug.print("{}", .{@intFromEnum(entry.id)}),
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// std.debug.print("\n", .{});
|
||||||
|
|
||||||
|
var checksum: u64 = 0;
|
||||||
|
|
||||||
|
{
|
||||||
|
var idx: usize = 0;
|
||||||
|
|
||||||
|
for (filesystem.items) |entry| {
|
||||||
|
const len = entry.len;
|
||||||
|
|
||||||
|
// skip over empty entry
|
||||||
|
if (entry.id == .empty) {
|
||||||
|
idx += len;
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
const id = @intFromEnum(entry.id);
|
||||||
|
|
||||||
|
for (0..len) |_| {
|
||||||
|
checksum += id * idx;
|
||||||
|
|
||||||
|
idx += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return checksum;
|
||||||
|
}
|
||||||
|
|
||||||
|
test "part1 example" {
|
||||||
|
const alloc = std.testing.allocator;
|
||||||
|
|
||||||
|
const example = "2333133121414131402";
|
||||||
|
|
||||||
|
var stream = std.io.fixedBufferStream(example);
|
||||||
|
|
||||||
|
const result = try part1(alloc, stream.reader());
|
||||||
|
|
||||||
|
try std.testing.expectEqual(1928, 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(6307275788409, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
test "part2 example" {
|
||||||
|
const alloc = std.testing.allocator;
|
||||||
|
|
||||||
|
const example = "2333133121414131402";
|
||||||
|
|
||||||
|
var stream = std.io.fixedBufferStream(example);
|
||||||
|
|
||||||
|
const result = try part2(alloc, stream.reader());
|
||||||
|
|
||||||
|
try std.testing.expectEqual(2858, 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(6327174563252, result);
|
||||||
|
}
|
||||||
50
inputs/day8.txt
Normal file
50
inputs/day8.txt
Normal file
|
|
@ -0,0 +1,50 @@
|
||||||
|
......................D....B...h..................
|
||||||
|
..............................h...................
|
||||||
|
.............D...3.....X..................9.......
|
||||||
|
...........C........X....2.hB......v........b.....
|
||||||
|
....................................O.............
|
||||||
|
......u.....3.........p...........................
|
||||||
|
....u......................v....6.................
|
||||||
|
......................y..D.....Ov.2..............b
|
||||||
|
.....u..........X...........o........y............
|
||||||
|
.........................y...B.f...........s......
|
||||||
|
.7....................C.2.....Bsyp..........t...q.
|
||||||
|
.u.7...........X............................Oe..t.
|
||||||
|
...........V........3......6v.s........o....h....t
|
||||||
|
..E........L.................6..........o......9..
|
||||||
|
........E......m.2.P.......O...9...8....b.........
|
||||||
|
..m..........3.......p..........M8................
|
||||||
|
..1.....................K.p....................b.e
|
||||||
|
5...............L...........s.6..........S.M......
|
||||||
|
....5..1.......E.........k.f.........M............
|
||||||
|
.E..Y..V......l.......T...D.......9....Q..........
|
||||||
|
..............................M...................
|
||||||
|
.....5....P................m...x..q......F......e.
|
||||||
|
................f...c......................x..F...
|
||||||
|
..V.C...........7.......a....o....8.........F.....
|
||||||
|
.......4....L.a..g..P.....8......Q....7d..........
|
||||||
|
...1......4..a............k......t...d............
|
||||||
|
..........V..........L....m........K....Q........S
|
||||||
|
..................1....k.....T....................
|
||||||
|
..........l......a...............F................
|
||||||
|
...........P...4.......l......x...................
|
||||||
|
.............c....g........T......................
|
||||||
|
.....g............c...Q.......................S...
|
||||||
|
...............l..................A.d.T.U.........
|
||||||
|
..........................f...0.............d.....
|
||||||
|
..........G..................A............e.S...x.
|
||||||
|
.........Y.......q........g....K..................
|
||||||
|
.....................q.H4...0.................j...
|
||||||
|
....................HA..............J.............
|
||||||
|
..Y..........................0...J.......j........
|
||||||
|
.......................G.JA...................U...
|
||||||
|
.......5..........................................
|
||||||
|
...........c..............G.........K.............
|
||||||
|
...............................G..................
|
||||||
|
...........................0.j....................
|
||||||
|
............................H.......k..........U..
|
||||||
|
.........................H........................
|
||||||
|
...................................Y....J.........
|
||||||
|
..................................j...............
|
||||||
|
..................................................
|
||||||
|
..................................................
|
||||||
1
inputs/day9.txt
Normal file
1
inputs/day9.txt
Normal file
File diff suppressed because one or more lines are too long
|
|
@ -100,6 +100,38 @@ pub fn numberParserWithDelimiter(comptime T: type, input: []const u8, delimiter:
|
||||||
return NumberParser(T){ .token_it = std.mem.tokenizeScalar(u8, input, delimiter) };
|
return NumberParser(T){ .token_it = std.mem.tokenizeScalar(u8, input, delimiter) };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn allocGrid(comptime T: type, alloc: std.mem.Allocator, n: usize, m: usize) ![][]T {
|
||||||
|
const grid = try alloc.alloc([]T, n);
|
||||||
|
|
||||||
|
for (grid) |*line| {
|
||||||
|
line.* = try alloc.alloc(T, m);
|
||||||
|
}
|
||||||
|
|
||||||
|
return grid;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn allocGridInit(comptime T: type, alloc: std.mem.Allocator, n: usize, m: usize, init: T) ![][]T {
|
||||||
|
const grid = try alloc.alloc([]T, n);
|
||||||
|
|
||||||
|
for (grid) |*line| {
|
||||||
|
line.* = try alloc.alloc(T, m);
|
||||||
|
|
||||||
|
for (line.*) |*x| {
|
||||||
|
x.* = init;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return grid;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn deinitGrid(comptime T: type, alloc: std.mem.Allocator, grid: [][]T) void {
|
||||||
|
for (grid) |line| {
|
||||||
|
alloc.free(line);
|
||||||
|
}
|
||||||
|
|
||||||
|
alloc.free(grid);
|
||||||
|
}
|
||||||
|
|
||||||
pub fn rangeComptime(comptime n: usize) [n]usize {
|
pub fn rangeComptime(comptime n: usize) [n]usize {
|
||||||
var array: [n]usize = undefined;
|
var array: [n]usize = undefined;
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue