Solution to 2-2
This commit is contained in:
parent
84223d9b3b
commit
3a32b3e8ce
@ -3,11 +3,20 @@ const print = std.debug.print;
|
|||||||
const util = @import("util.zig");
|
const util = @import("util.zig");
|
||||||
|
|
||||||
pub fn main() !void {
|
pub fn main() !void {
|
||||||
const output = try part_one();
|
const output = try part_two();
|
||||||
print("{}\n", .{output});
|
print("{}\n", .{output});
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn part_one() !u32 {
|
pub fn part_one() !u32 {
|
||||||
|
return execute(&is_safe);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn part_two() !u32 {
|
||||||
|
return execute(&is_safe_with_damper);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Zig doesn't allow `!bool` for implicit error sets when referring to functions as parameter-types, have to list explicitly
|
||||||
|
pub fn execute(safe_tester: *const fn (reportAsArray: std.ArrayList(u32)) error{TooSmall, OutOfMemory}!bool) !u32 {
|
||||||
const isTestCase = true;
|
const isTestCase = true;
|
||||||
// Reading the input...
|
// Reading the input...
|
||||||
// Making use of example here: https://cookbook.ziglang.cc/01-01-read-file-line-by-line.html
|
// Making use of example here: https://cookbook.ziglang.cc/01-01-read-file-line-by-line.html
|
||||||
@ -37,7 +46,7 @@ pub fn part_one() !u32 {
|
|||||||
line_no += 1;
|
line_no += 1;
|
||||||
|
|
||||||
const report = try parseLineToNumbers(line.items, allocator);
|
const report = try parseLineToNumbers(line.items, allocator);
|
||||||
if (try is_safe(report)) {
|
if (try safe_tester(report)) {
|
||||||
safe_count += 1;
|
safe_count += 1;
|
||||||
}
|
}
|
||||||
report.deinit();
|
report.deinit();
|
||||||
@ -67,7 +76,7 @@ pub const IllegalDataError = error{
|
|||||||
// all-decreasing report?") as:
|
// all-decreasing report?") as:
|
||||||
// - "The first pair of levels is within 1-3"
|
// - "The first pair of levels is within 1-3"
|
||||||
// - "For all triples in the report, both pairs have the same direction, and the final pair is within 1-3"
|
// - "For all triples in the report, both pairs have the same direction, and the final pair is within 1-3"
|
||||||
fn is_safe(reportAsArray: std.ArrayList(u32)) !bool {
|
fn is_safe(reportAsArray: std.ArrayList(u32)) error{TooSmall, OutOfMemory}!bool {
|
||||||
const report = reportAsArray.items;
|
const report = reportAsArray.items;
|
||||||
// Legality-check that the report contains at least two levels
|
// Legality-check that the report contains at least two levels
|
||||||
if (report.len < 2) {
|
if (report.len < 2) {
|
||||||
@ -104,6 +113,41 @@ fn is_safe(reportAsArray: std.ArrayList(u32)) !bool {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
fn is_safe_with_damper(reportAsArray: std.ArrayList(u32)) error{TooSmall, OutOfMemory}!bool {
|
||||||
|
if (try is_safe(reportAsArray)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create a new allocator to save having to change the "interface" of the functions to pass a useless allocator
|
||||||
|
// into `is_safe`
|
||||||
|
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
|
||||||
|
defer _ = gpa.deinit();
|
||||||
|
const allocator = gpa.allocator();
|
||||||
|
|
||||||
|
var val_to_drop: u32 = 0;
|
||||||
|
while (val_to_drop < reportAsArray.items.len) {
|
||||||
|
|
||||||
|
// Lol there _must_ be a better way of doing this
|
||||||
|
|
||||||
|
var array_list_with_dropped_item = std.ArrayList(u32).init(allocator);
|
||||||
|
var i: u32 = 0;
|
||||||
|
|
||||||
|
while (i < reportAsArray.items.len) {
|
||||||
|
if (i != val_to_drop) {
|
||||||
|
try array_list_with_dropped_item.append(reportAsArray.items[i]);
|
||||||
|
}
|
||||||
|
i += 1;
|
||||||
|
}
|
||||||
|
if (try is_safe(array_list_with_dropped_item)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
val_to_drop += 1;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// TODO - probably extract this to utils?
|
// TODO - probably extract this to utils?
|
||||||
// (Though note that this differs from the example in 01.zig)
|
// (Though note that this differs from the example in 01.zig)
|
||||||
fn parseLineToNumbers(line: []u8, allocator: std.mem.Allocator) !std.ArrayList(u32) {
|
fn parseLineToNumbers(line: []u8, allocator: std.mem.Allocator) !std.ArrayList(u32) {
|
||||||
@ -126,3 +170,7 @@ const expect = std.testing.expect;
|
|||||||
test "part one" {
|
test "part one" {
|
||||||
try expect(try part_one() == 2);
|
try expect(try part_one() == 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
test "part two" {
|
||||||
|
try expect(try part_two() == 4);
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user