mirror of
https://github.com/MorizzG/aoc-2024.git
synced 2025-12-06 04:22:43 +00:00
day 3 done
also fixed up a bunch of stuff on day 1 and day 2
This commit is contained in:
parent
61d7d0f486
commit
ec56f69ecd
11 changed files with 1907 additions and 330 deletions
240
day2.zig
Normal file
240
day2.zig
Normal file
|
|
@ -0,0 +1,240 @@
|
|||
const std = @import("std");
|
||||
|
||||
const utils = @import("utils.zig");
|
||||
|
||||
fn Chain(comptime T: type) type {
|
||||
return struct {
|
||||
slice1: []const T,
|
||||
slice2: []const T,
|
||||
|
||||
fn len(self: *const @This()) usize {
|
||||
return self.slice1.len + self.slice2.len;
|
||||
}
|
||||
|
||||
fn get(self: *const @This(), i: usize) T {
|
||||
var idx = i;
|
||||
|
||||
if (idx < self.slice1.len) {
|
||||
return self.slice1[idx];
|
||||
}
|
||||
|
||||
idx -= self.slice1.len;
|
||||
|
||||
if (idx < self.slice2.len) {
|
||||
return self.slice2[idx];
|
||||
}
|
||||
|
||||
unreachable;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
pub fn main() !void {
|
||||
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
|
||||
const alloc = gpa.allocator();
|
||||
|
||||
const filename = "inputs/day2.txt";
|
||||
|
||||
{
|
||||
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 2, 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 2, part 2: {}\n", .{result});
|
||||
}
|
||||
}
|
||||
|
||||
fn check(report: []const i32) bool {
|
||||
var window = std.mem.window(i32, report, 2, 1);
|
||||
|
||||
if (report[0] < report[1]) {
|
||||
while (window.next()) |x| {
|
||||
std.debug.assert(x.len == 2);
|
||||
|
||||
const diff = x[1] - x[0];
|
||||
|
||||
if (diff < 1 or diff > 3) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
} else if (report[0] > report[1]) {
|
||||
while (window.next()) |x| {
|
||||
std.debug.assert(x.len == 2);
|
||||
|
||||
const diff = x[0] - x[1];
|
||||
|
||||
if (diff < 1 or diff > 3) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
fn check_with_skip(report: []const i32, skip_idx: usize) bool {
|
||||
const chain = Chain(i32){ .slice1 = report[0..skip_idx], .slice2 = report[skip_idx + 1 ..] };
|
||||
|
||||
if (chain.get(0) < chain.get(1)) {
|
||||
for (0..(chain.len() - 1)) |i| {
|
||||
const diff = chain.get(i + 1) - chain.get(i);
|
||||
|
||||
if (diff < 1 or diff > 3) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
} else if (chain.get(0) > chain.get(1)) {
|
||||
for (0..(chain.len() - 1)) |i| {
|
||||
const diff = chain.get(i) - chain.get(i + 1);
|
||||
|
||||
if (diff < 1 or diff > 3) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
fn part1(alloc: std.mem.Allocator, reader: anytype) !u32 {
|
||||
var line_reader = utils.lineReader(alloc, reader);
|
||||
defer line_reader.deinit();
|
||||
|
||||
var report = std.ArrayList(i32).init(alloc);
|
||||
defer report.deinit();
|
||||
|
||||
var num_safe_reports: u32 = 0;
|
||||
|
||||
while (try line_reader.next()) |line| {
|
||||
report.clearRetainingCapacity();
|
||||
|
||||
var number_parser = utils.numberParser(i32, line);
|
||||
|
||||
while (try number_parser.next()) |n| {
|
||||
try report.append(n);
|
||||
}
|
||||
|
||||
if (check(report.items)) {
|
||||
num_safe_reports += 1;
|
||||
}
|
||||
}
|
||||
|
||||
return num_safe_reports;
|
||||
}
|
||||
|
||||
fn part2(alloc: std.mem.Allocator, reader: anytype) !u32 {
|
||||
var line_reader = utils.lineReader(alloc, reader);
|
||||
defer line_reader.deinit();
|
||||
|
||||
var report = std.ArrayList(i32).init(alloc);
|
||||
defer report.deinit();
|
||||
|
||||
var num_safe_reports: u32 = 0;
|
||||
|
||||
report_loop: while (try line_reader.next()) |line| {
|
||||
report.clearRetainingCapacity();
|
||||
|
||||
// var it = std.mem.tokenizeScalar(u8, line, ' ');
|
||||
|
||||
var number_parser = utils.numberParser(i32, line);
|
||||
|
||||
while (try number_parser.next()) |n| {
|
||||
try report.append(n);
|
||||
}
|
||||
|
||||
if (report.items.len < 2) {
|
||||
return error.ReportTooSmall;
|
||||
}
|
||||
|
||||
if (check(report.items)) {
|
||||
num_safe_reports += 1;
|
||||
} else {
|
||||
for (0..report.items.len) |skip_idx| {
|
||||
if (check_with_skip(report.items, skip_idx)) {
|
||||
num_safe_reports += 1;
|
||||
continue :report_loop;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return num_safe_reports;
|
||||
}
|
||||
|
||||
test "part1 example" {
|
||||
const alloc = std.testing.allocator;
|
||||
|
||||
const example =
|
||||
\\7 6 4 2 1
|
||||
\\1 2 7 8 9
|
||||
\\9 7 6 2 1
|
||||
\\1 3 2 4 5
|
||||
\\8 6 4 4 1
|
||||
\\1 3 6 7 9
|
||||
;
|
||||
|
||||
var stream = std.io.fixedBufferStream(example);
|
||||
|
||||
const result = try part1(alloc, stream.reader());
|
||||
|
||||
try std.testing.expect(result == 2);
|
||||
}
|
||||
|
||||
test "part1 input" {
|
||||
const alloc = std.testing.allocator;
|
||||
|
||||
const filename = "inputs/day2.txt";
|
||||
|
||||
const file_reader = try utils.FileReader.init(alloc, filename);
|
||||
defer file_reader.deinit();
|
||||
|
||||
const result = try part1(alloc, file_reader.reader());
|
||||
|
||||
try std.testing.expect(result == 549);
|
||||
}
|
||||
|
||||
test "part2 example" {
|
||||
const alloc = std.testing.allocator;
|
||||
|
||||
const example =
|
||||
\\7 6 4 2 1
|
||||
\\1 2 7 8 9
|
||||
\\9 7 6 2 1
|
||||
\\1 3 2 4 5
|
||||
\\8 6 4 4 1
|
||||
\\1 3 6 7 9
|
||||
;
|
||||
|
||||
var stream = std.io.fixedBufferStream(example);
|
||||
|
||||
const result = try part2(alloc, stream.reader());
|
||||
|
||||
try std.testing.expect(result == 4);
|
||||
}
|
||||
|
||||
test "part2 input" {
|
||||
const alloc = std.testing.allocator;
|
||||
|
||||
const filename = "inputs/day2.txt";
|
||||
|
||||
const file_reader = try utils.FileReader.init(alloc, filename);
|
||||
defer file_reader.deinit();
|
||||
|
||||
const result = try part2(alloc, file_reader.reader());
|
||||
|
||||
try std.testing.expect(result == 589);
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue