const std = @import("std");
const PATH = "../input/day10.txt";
const Str = []const u8;
pub fn first(allocator: ?std.mem.Allocator) anyerror!usize {
const adapters = try parseInput(allocator.?, @embedFile(PATH));
defer allocator.?.free(adapters);
var one: usize = 0;
var three: usize = 0;
var idx: usize = 1;
while (idx < adapters.len) : (idx += 1) {
switch (adapters[idx] - adapters[idx - 1]) {
1 => one += 1,
3 => three += 1,
else => unreachable,
}
}
return one * three;
}
pub fn second(allocator: ?std.mem.Allocator) anyerror!usize {
const adapters = try parseInput(allocator.?, @embedFile(PATH));
defer allocator.?.free(adapters);
var sum: usize = 1;
var count: u3 = 0;
var idx: usize = 1;
while (idx < adapters.len) : (idx += 1) {
const diff = adapters[idx] - adapters[idx - 1];
if (diff == 1) {
count += 1;
} else {
switch (count) {
4 => sum *= 7, // ways to arrange 4 items
3 => sum *= 4,
2 => sum *= 2,
1, 0 => {},
else => unreachable,
}
count = 0;
}
}
return sum;
}
fn parseInput(allocator: std.mem.Allocator, input: Str) ![]usize {
var ret = std.ArrayList(usize).init(allocator);
var lines = std.mem.tokenize(u8, input, "\n");
while (lines.next()) |line| {
try ret.append(try std.fmt.parseUnsigned(usize, line, 0));
}
try ret.append(0); // add charging outlet
std.sort.sort(usize, ret.items, {}, comptime std.sort.asc(usize));
try ret.append(ret.items[ret.items.len - 1] + 3); // add built-in adapter
return ret.toOwnedSlice();
}
test "day10a" {
try std.testing.expectEqual(@as(usize, 2482), try first(std.testing.allocator));
}
test "day10b" {
try std.testing.expectEqual(@as(usize, 96717311574016), try second(std.testing.allocator));
}