Solution to 5-1
This commit is contained in:
parent
098bebd25e
commit
658b63d795
1381
inputs/05/real.txt
Normal file
1381
inputs/05/real.txt
Normal file
File diff suppressed because it is too large
Load Diff
28
inputs/05/test.txt
Normal file
28
inputs/05/test.txt
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
47|53
|
||||||
|
97|13
|
||||||
|
97|61
|
||||||
|
97|47
|
||||||
|
75|29
|
||||||
|
61|13
|
||||||
|
75|53
|
||||||
|
29|13
|
||||||
|
97|29
|
||||||
|
53|29
|
||||||
|
61|53
|
||||||
|
97|53
|
||||||
|
61|29
|
||||||
|
47|13
|
||||||
|
75|47
|
||||||
|
97|75
|
||||||
|
47|61
|
||||||
|
75|61
|
||||||
|
47|29
|
||||||
|
75|13
|
||||||
|
53|13
|
||||||
|
|
||||||
|
75,47,61,53,29
|
||||||
|
97,61,53,29,13
|
||||||
|
75,29,13
|
||||||
|
75,97,47,61,53
|
||||||
|
61,13,29
|
||||||
|
97,13,75,29,47
|
135
solutions/05.zig
Normal file
135
solutions/05.zig
Normal file
@ -0,0 +1,135 @@
|
|||||||
|
const std = @import("std");
|
||||||
|
const print = std.debug.print;
|
||||||
|
const util = @import("util.zig");
|
||||||
|
|
||||||
|
pub fn main() !void {
|
||||||
|
const output = try part_one(false);
|
||||||
|
print("{}\n", .{output});
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn part_one(is_test_case: bool) !u32 {
|
||||||
|
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
|
||||||
|
defer _ = gpa.deinit();
|
||||||
|
const allocator = gpa.allocator();
|
||||||
|
|
||||||
|
const input_file = try util.getInputFile("05", is_test_case);
|
||||||
|
const data = try util.readAllInputWithAllocator(input_file, allocator);
|
||||||
|
|
||||||
|
// https://stackoverflow.com/a/79199470/1040915
|
||||||
|
var it = std.mem.splitScalar(u8, data, '\n');
|
||||||
|
var lines_list = std.ArrayList([]const u8).init(allocator);
|
||||||
|
defer lines_list.deinit();
|
||||||
|
|
||||||
|
var end_of_rules = false;
|
||||||
|
var rules = std.ArrayList(Rule).init(allocator);
|
||||||
|
defer rules.deinit();
|
||||||
|
var updates = std.ArrayList(Update).init(allocator);
|
||||||
|
defer updates.deinit();
|
||||||
|
|
||||||
|
while (it.next()) |line| {
|
||||||
|
if (line.len == 0) {
|
||||||
|
end_of_rules = true;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!end_of_rules) {
|
||||||
|
try rules.append(try ruleFromLine(line));
|
||||||
|
} else {
|
||||||
|
const update = try updateFromLine(line, allocator);
|
||||||
|
print("DEBUG - adding new update {any}\n", .{update.values});
|
||||||
|
try updates.append(update);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
print("DEBUG - rules are:\n", .{});
|
||||||
|
for (rules.items) |rule| { // Type annotations are weird here - ZLS reports `rule` as `[]const u8`, not `Rule`.
|
||||||
|
print("{}|{}\n", .{ rule.first, rule.second });
|
||||||
|
}
|
||||||
|
print("DEBUG - length of updates is {}\n", .{updates.items.len});
|
||||||
|
print("DEBUG - first update is {any}\n", .{updates.items[0]});
|
||||||
|
|
||||||
|
var total: u32 = 0;
|
||||||
|
for (updates.items) |update| {
|
||||||
|
// I considered implementing a `fn all(comptime T: type, arr: []T, func: fn(t: T) bool) bool` to make this
|
||||||
|
// more concise, but it looks like there's no simple way to make an anonymous function (so cannot pass in
|
||||||
|
// `r.passes` as the function parameter)
|
||||||
|
|
||||||
|
if (updatePassesAllRules(update, rules.items)) {
|
||||||
|
total += getMiddleValueOfUpdate(update);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return total;
|
||||||
|
}
|
||||||
|
|
||||||
|
const Rule = struct {
|
||||||
|
first: u32,
|
||||||
|
second: u32,
|
||||||
|
|
||||||
|
fn passes(self: Rule, update: Update) bool {
|
||||||
|
var second_encountered = false;
|
||||||
|
for (update.values) |value| {
|
||||||
|
if (value == self.second) {
|
||||||
|
second_encountered = true;
|
||||||
|
}
|
||||||
|
if (value == self.first) {
|
||||||
|
print("DEBUG - does update {any} pass rule {}|{}? {}\n", .{ update, self.first, self.second, !second_encountered });
|
||||||
|
return !second_encountered;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
fn updatePassesAllRules(update: Update, rules: []Rule) bool {
|
||||||
|
for (rules) |rule| {
|
||||||
|
print("DEBUG - checking {any} against {}|{}\n", .{ update.values, rule.first, rule.second });
|
||||||
|
if (!rule.passes(update)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn getMiddleValueOfUpdate(update: Update) u32 {
|
||||||
|
return update.values[update.values.len / 2]; // Assumes that they're all of odd length.
|
||||||
|
}
|
||||||
|
|
||||||
|
fn ruleFromLine(line: []const u8) !Rule {
|
||||||
|
var it = std.mem.splitScalar(u8, line, '|');
|
||||||
|
const first = try std.fmt.parseInt(u32, it.next().?, 10);
|
||||||
|
const second = try std.fmt.parseInt(u32, it.next().?, 10);
|
||||||
|
return Rule{ .first = first, .second = second };
|
||||||
|
}
|
||||||
|
|
||||||
|
const Update = struct { values: []u32 };
|
||||||
|
|
||||||
|
fn updateFromLine(line: []const u8, allocator: std.mem.Allocator) !Update {
|
||||||
|
print("DEBUG - processing line as update\n", .{});
|
||||||
|
for (line) |c| {
|
||||||
|
print("{c}", .{c});
|
||||||
|
}
|
||||||
|
print("\n", .{});
|
||||||
|
|
||||||
|
var it = std.mem.splitScalar(u8, line, ',');
|
||||||
|
var item_list = std.ArrayList(u32).init(allocator);
|
||||||
|
// If this is commented-out, lots of memory-leaks are reported - but with this line in, a segmentation fault occurs
|
||||||
|
// on referencing the result of this function.
|
||||||
|
// defer item_list.deinit();
|
||||||
|
|
||||||
|
while (it.next()) |item| {
|
||||||
|
print("DEBUG - adding {any} to the item_list\n", .{item});
|
||||||
|
try item_list.append(try std.fmt.parseInt(u32, item, 10));
|
||||||
|
}
|
||||||
|
print("DEBUG - items are {any}\n", .{item_list.items});
|
||||||
|
const return_update = Update{ .values = item_list.items };
|
||||||
|
print("DEBUG - return values are {any}\n", .{return_update.values});
|
||||||
|
return return_update;
|
||||||
|
}
|
||||||
|
|
||||||
|
const expect = std.testing.expect;
|
||||||
|
|
||||||
|
test "part_one" {
|
||||||
|
const part_one_value = try part_one(true);
|
||||||
|
print("DEBUG - part_one_value is {}\n", .{part_one_value});
|
||||||
|
try expect(part_one_value == 143);
|
||||||
|
}
|
@ -50,7 +50,6 @@ fn concat(comptime T: type, allocator: std.mem.Allocator, arr1: []const T, arr2:
|
|||||||
return combined;
|
return combined;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Ugh. There are a _ton_ of problems with this because of overflow nonsense - but it's good enough to use until
|
// Ugh. There are a _ton_ of problems with this because of overflow nonsense - but it's good enough to use until
|
||||||
// test cases demonstrate that it's not.
|
// test cases demonstrate that it's not.
|
||||||
pub fn diffOfNumbers(a: u32, b: u32) u32 {
|
pub fn diffOfNumbers(a: u32, b: u32) u32 {
|
||||||
@ -61,7 +60,6 @@ pub fn diffOfNumbers(a: u32, b: u32) u32 {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// I originally tried https://cookbook.ziglang.cc/01-01-read-file-line-by-line.html,
|
// I originally tried https://cookbook.ziglang.cc/01-01-read-file-line-by-line.html,
|
||||||
// but it's super-unwieldy.
|
// but it's super-unwieldy.
|
||||||
// Stole https://codeberg.org/andyscott/advent-of-code/src/branch/main/2024/src/util.zig instead!
|
// Stole https://codeberg.org/andyscott/advent-of-code/src/branch/main/2024/src/util.zig instead!
|
||||||
@ -76,7 +74,15 @@ pub fn readAllInput(path: []u8) ![]const u8 {
|
|||||||
|
|
||||||
const stat = try file.stat();
|
const stat = try file.stat();
|
||||||
return try file.reader().readAllAlloc(alloc, stat.size);
|
return try file.reader().readAllAlloc(alloc, stat.size);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn readAllInputWithAllocator(path: []u8, alloc: std.mem.Allocator) ![]const u8 {
|
||||||
|
std.debug.print("Path is {s}\n", .{path});
|
||||||
|
const file = try std.fs.cwd().openFile(path, .{});
|
||||||
|
defer file.close();
|
||||||
|
|
||||||
|
const stat = try file.stat();
|
||||||
|
return try file.reader().readAllAlloc(alloc, stat.size);
|
||||||
}
|
}
|
||||||
|
|
||||||
const expect = @import("std").testing.expect;
|
const expect = @import("std").testing.expect;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user