This commit is contained in:
2024-12-02 00:21:59 -06:00
parent 551311fca6
commit 398a587d95
3 changed files with 301 additions and 0 deletions

163
02/src/main.zig Normal file
View File

@@ -0,0 +1,163 @@
// Day 2! Yea. Still not idiomatic.
// Implementation of both sucks bad.
// Whatever
const std = @import("std");
var arena = std.heap.ArenaAllocator.init(std.heap.page_allocator);
const alloc = arena.allocator();
const test_data = @embedFile("test");
const input_data = @embedFile("input");
pub fn main() !void {
const stdout = std.io.getStdOut().writer();
const value1 = try run1(input_data);
try stdout.print("{d}\n", .{value1});
const value2 = try run2(input_data);
try stdout.print("{d}\n", .{value2});
}
test "test input part 1" {
const value = try run1(test_data);
std.debug.print("{d}\n", .{value});
try std.testing.expectEqual(value, 2);
}
test "test input part 2" {
const value = try run2(test_data);
std.debug.print("{d}\n", .{value});
try std.testing.expectEqual(value, 4);
}
// this sucks and i don't know if i actually
// need to check all these cases
// ...but it's fast still
fn check_good(a: []i64) u64 {
if (a.len < 2) {
return 0;
}
var skip_i: i64 = -1;
attempt: while (true) {
var last: i64 = 0;
var good: u64 = 1;
var c: usize = 0;
var desc: bool = false;
var i: usize = 0;
line: while (i < a.len) {
if (i == skip_i) {
i += 1;
continue;
}
const dif = last - a[i];
const abs = @abs(dif);
switch (c) {
0 => {},
1 => {
desc = dif < 0;
if (abs < 1 or abs > 3) {
good = 0;
break :line;
}
},
else => {
if ((dif < 0) != desc or abs < 1 or abs > 3) {
good = 0;
break :line;
}
},
}
last = a[i];
c += 1;
i += 1;
}
if (good == 0) {
skip_i += 1;
if (skip_i == a.len) {
return 0;
}
continue :attempt;
} else {
return 1;
}
}
}
fn run2(s: []const u8) !u64 {
var lines = std.mem.splitScalar(u8, s, '\n');
var total: u64 = 0;
var arr = std.ArrayList(i64).init(alloc);
while (lines.next()) |line| {
arr.clearRetainingCapacity();
var split = std.mem.splitScalar(u8, line, ' ');
while (split.next()) |i| {
if (std.mem.eql(u8, i, "")) continue;
const num = try std.fmt.parseInt(i64, i, 10);
try arr.append(num);
}
if (arr.items.len == 0) continue;
const good = check_good(arr.items);
std.debug.print("{s} safe: {d}\n", .{ line, good });
total += good;
}
return total;
}
fn run1(s: []const u8) !u64 {
var lines = std.mem.splitScalar(u8, s, '\n');
var total: u64 = 0;
while (lines.next()) |line| {
var split = std.mem.splitScalar(u8, line, ' ');
var last: i64 = 0;
var good: u64 = 1;
var desc: bool = true;
var c: usize = 0;
line: while (split.next()) |i| {
if (std.mem.eql(u8, i, "")) continue;
const num = try std.fmt.parseInt(i64, i, 10);
const dif = last - num;
const abs = @abs(dif);
switch (c) {
0 => {},
1 => {
desc = dif < 0;
if (abs < 1 or abs > 3) {
good = 0;
break :line;
}
},
else => {
if ((dif < 0) != desc or abs < 1 or abs > 3) {
good = 0;
break :line;
}
},
}
last = num;
c += 1;
}
if (c < 2) continue;
std.debug.print("{s} safe: {d}\n", .{ line, good });
total += good;
}
return total;
}