day 2
This commit is contained in:
163
02/src/main.zig
Normal file
163
02/src/main.zig
Normal 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;
|
||||
}
|
Reference in New Issue
Block a user