Added day 5
This commit is contained in:
parent
e87c57b83b
commit
65589c462e
21
README.md
21
README.md
@ -11,13 +11,14 @@ Done with 1000 epoch on a AMD Ryzen 7 7800X3D with a Samsung SSD 980 PRO 2TB (up
|
||||
Can be run with `zig run -O ReleaseFast benchmark.zig`
|
||||
|
||||
| Day | Part | Mean (μs) | Min (μs) | Max (μs) |
|
||||
|-----|------|-------------------|----------|----------|
|
||||
| 1 | 1 | +29 ± 3.00 | +28 | +78 |
|
||||
| 1 | 2 | +24 ± 2.65 | +24 | +56 |
|
||||
| 2 | 1 | +43 ± 8.37 | +37 | +241 |
|
||||
| 2 | 2 | +328 ± 33.84 | +298 | +728 |
|
||||
| 3 | 1 | +24 ± 6.24 | +20 | +170 |
|
||||
| 3 | 2 | +23 ± 1.73 | +20 | +58 |
|
||||
| 4 | 2 | +229 ± 26.15 | +214 | +417 |
|
||||
| 4 | 2 | +232 ± 26.13 | +213 | +337 |
|
||||
| Total| | +932 ± 108.11 | +854 | +2085 |
|
||||
| 1 | 1 | +29 ± 3.74 | +28 | +99 |
|
||||
| 1 | 2 | +26 ± 6.78 | +24 | +136 |
|
||||
| 2 | 1 | +39 ± 6.00 | +37 | +179 |
|
||||
| 2 | 2 | +314 ± 17.64 | +291 | +446 |
|
||||
| 3 | 1 | +21 ± 5.20 | +20 | +163 |
|
||||
| 3 | 2 | +19 ± 2.24 | +18 | +43 |
|
||||
| 4 | 1 | +225 ± 16.31 | +217 | +347 |
|
||||
| 4 | 2 | +220 ± 7.87 | +216 | +311 |
|
||||
| 5 | 1 | +166 ± 24.29 | +148 | +429 |
|
||||
| 5 | 2 | +228 ± 69.64 | +173 | +661 |
|
||||
| Total| | +1287 ± 159.71 | +1172 | +2814 |
|
||||
|
@ -9,6 +9,8 @@ const d31 = @import("day3/part1.zig");
|
||||
const d32 = @import("day3/part2.zig");
|
||||
const d41 = @import("day4/part1.zig");
|
||||
const d42 = @import("day4/part2.zig");
|
||||
const d51 = @import("day5/part1.zig");
|
||||
const d52 = @import("day5/part2.zig");
|
||||
|
||||
const NUMBER_OF_RUN = 1000;
|
||||
|
||||
@ -30,8 +32,11 @@ pub fn main() !void {
|
||||
try benchmark(d31.main, 3, 1);
|
||||
try benchmark(d32.main, 3, 2);
|
||||
separator();
|
||||
try benchmark(d42.main, 4, 1);
|
||||
try benchmark(d42.main, 4, 2);
|
||||
try benchmark(d42.main, 4, 2);
|
||||
separator();
|
||||
try benchmark(d51.main, 5, 1);
|
||||
try benchmark(d52.main, 5, 2);
|
||||
separator();
|
||||
print("| Total | {d: >8} ± {d: <6.2} | {d:>8} | {d:>8} |\n", .{ total_mean, total_std_dev, total_min, total_max });
|
||||
separator();
|
||||
|
1378
day5/input
Normal file
1378
day5/input
Normal file
File diff suppressed because it is too large
Load Diff
107
day5/part1.zig
Normal file
107
day5/part1.zig
Normal file
@ -0,0 +1,107 @@
|
||||
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.getOrPut(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];
|
||||
}
|
129
day5/part2.zig
Normal file
129
day5/part2.zig
Normal file
@ -0,0 +1,129 @@
|
||||
const std = @import("std");
|
||||
const print = std.debug.print;
|
||||
|
||||
const Rule = struct {
|
||||
left: usize,
|
||||
right: usize,
|
||||
|
||||
fn ok(self: Rule, sub_page: Rule) bool {
|
||||
if (sub_page.left == self.right and sub_page.right == self.left) return false;
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
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.getOrPut(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(4145, total);
|
||||
}
|
||||
|
||||
fn pageOk(bad_rules: std.AutoHashMap(Rule, void), page: []usize) bool {
|
||||
var iter = PageIterator{ .indexL = 0, .indexR = 0, .buff = page };
|
||||
|
||||
defer iter.reset();
|
||||
while (iter.next()) |sub_page| {
|
||||
if (bad_rules.contains(sub_page)) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
fn evaluate(bad_rules: std.AutoHashMap(Rule, void), page: []usize) !usize {
|
||||
var notOk = true;
|
||||
var iter = PageIterator{ .indexL = 0, .indexR = 0, .buff = page };
|
||||
|
||||
if (pageOk(bad_rules, page)) return 0;
|
||||
|
||||
while (notOk) {
|
||||
notOk = false;
|
||||
blk: {
|
||||
while (iter.next()) |sub_page| {
|
||||
if (bad_rules.contains(sub_page)) {
|
||||
notOk = true;
|
||||
iter.swap();
|
||||
break :blk;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
const middle = try std.math.divFloor(usize, page.len, 2);
|
||||
return page[middle];
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user