108 lines
2.9 KiB
Zig
108 lines
2.9 KiB
Zig
const std = @import("std");
|
|
const print = std.debug.print;
|
|
|
|
const Rule = struct {
|
|
left: usize,
|
|
right: usize,
|
|
|
|
fn ok(self: Rule, sub_page: Rule) bool {
|
|
return !(sub_page.left == self.right and sub_page.right == self.left);
|
|
}
|
|
};
|
|
|
|
const PageIterator = struct {
|
|
indexL: usize = 0,
|
|
indexR: usize = 0,
|
|
buff: []usize,
|
|
|
|
fn next(self: *PageIterator) ?Rule {
|
|
self.indexR += 1;
|
|
|
|
if (self.indexR == self.buff.len) {
|
|
self.indexL += 1;
|
|
self.indexR = self.indexL + 1;
|
|
}
|
|
|
|
if (self.indexL == (self.buff.len - 1)) return null;
|
|
|
|
return Rule{
|
|
.left = self.buff[self.indexL],
|
|
.right = self.buff[self.indexR],
|
|
};
|
|
}
|
|
|
|
fn reset(self: *PageIterator) void {
|
|
self.indexL = 0;
|
|
self.indexR = 1;
|
|
}
|
|
|
|
fn swap(self: *PageIterator) void {
|
|
const buffR: usize = self.buff[self.indexR];
|
|
self.buff[self.indexR] = self.buff[self.indexL];
|
|
self.buff[self.indexL] = buffR;
|
|
}
|
|
};
|
|
|
|
pub fn main() !void {
|
|
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
|
|
const allocator = gpa.allocator();
|
|
defer {
|
|
const deinit_status = gpa.deinit();
|
|
if (deinit_status == .leak) @panic("TEST FAIL");
|
|
}
|
|
|
|
// ========= Load file ===========
|
|
const file = try std.fs.cwd().openFile("day5/input", .{});
|
|
defer file.close();
|
|
|
|
const file_size = (try file.stat()).size;
|
|
const buffer = try allocator.alloc(u8, file_size);
|
|
defer allocator.free(buffer);
|
|
|
|
_ = try file.readAll(buffer);
|
|
|
|
// ========= Parse Rules ===========
|
|
var bad_rules = std.AutoHashMap(Rule, void).init(allocator);
|
|
defer bad_rules.deinit();
|
|
|
|
var iter = std.mem.split(u8, buffer, "\n");
|
|
while (iter.next()) |line| {
|
|
if (std.mem.eql(u8, line, "")) break;
|
|
|
|
_ = try bad_rules.put(Rule{
|
|
.right = try std.fmt.parseInt(usize, line[0..2], 10),
|
|
.left = try std.fmt.parseInt(usize, line[3..5], 10),
|
|
}, {});
|
|
}
|
|
|
|
// ========= Evaluate ===========
|
|
var page = std.ArrayList(usize).init(allocator);
|
|
defer page.deinit();
|
|
|
|
var total: usize = 0;
|
|
while (iter.next()) |line| {
|
|
if (std.mem.eql(u8, line, "")) break;
|
|
defer page.clearRetainingCapacity();
|
|
|
|
var sub_iter = std.mem.split(u8, line, ",");
|
|
while (sub_iter.next()) |value_str| {
|
|
try page.append(try std.fmt.parseInt(usize, value_str, 10));
|
|
}
|
|
|
|
total += try evaluate(bad_rules, page.items);
|
|
}
|
|
|
|
try std.testing.expectEqual(6949, total);
|
|
}
|
|
|
|
fn evaluate(bad_rules: std.AutoHashMap(Rule, void), page: []usize) !usize {
|
|
var iter = PageIterator{ .indexL = 0, .indexR = 0, .buff = page };
|
|
|
|
defer iter.reset();
|
|
while (iter.next()) |sub_page| {
|
|
if (bad_rules.contains(sub_page)) return 0;
|
|
}
|
|
const middle = try std.math.divFloor(usize, page.len, 2);
|
|
return page[middle];
|
|
}
|