const std = @import("std");
const Str = []const u8;
const PATH = "input/day02.txt";
pub fn first(allocator: ?std.mem.Allocator) !usize {
_ = allocator;
const input = @embedFile(PATH);
return try wrapPaper(input);
}
pub fn second(allocator: ?std.mem.Allocator) !usize {
_ = allocator;
const input = @embedFile(PATH);
return try wrapRibbon(input);
}
fn wrapPaper(input: Str) !usize {
var lines = std.mem.tokenize(u8, input, "\n");
var total: usize = 0;
while (lines.next()) |line| {
var lwh = std.mem.tokenize(u8, line, "x");
const l = try std.fmt.parseUnsigned(usize, lwh.next().?, 10);
const w = try std.fmt.parseUnsigned(usize, lwh.next().?, 10);
const h = try std.fmt.parseUnsigned(usize, lwh.next().?, 10);
const size = 2 * l * w + 2 * w * h + 2 * h * l + std.math.min3(l * w, w * h, h * l);
total += size;
}
return total;
}
fn wrapRibbon(input: Str) !usize {
var lines = std.mem.tokenize(u8, input, "\n");
var total: usize = 0;
while (lines.next()) |line| {
var lwh = std.mem.tokenize(u8, line, "x");
const l = try std.fmt.parseUnsigned(usize, lwh.next().?, 10);
const w = try std.fmt.parseUnsigned(usize, lwh.next().?, 10);
const h = try std.fmt.parseUnsigned(usize, lwh.next().?, 10);
const max = std.math.max3(l, w, h);
const ribbon = blk: {
var rr: usize = undefined;
if (l == max) {
rr = w + w + h + h;
} else if (w == max) {
rr = l + l + h + h;
} else if (h == max) {
rr = l + l + w + w;
} else unreachable;
break :blk rr;
};
const bow = l * w * h;
total += ribbon + bow;
}
return total;
}
test "2x3x4" {
try std.testing.expectEqual(@as(usize, 58), try wrapPaper("2x3x4"));
try std.testing.expectEqual(@as(usize, 34), try wrapRibbon("2x3x4"));
}
test "1x1x10" {
try std.testing.expectEqual(@as(usize, 43), try wrapPaper("1x1x10"));
try std.testing.expectEqual(@as(usize, 14), try wrapRibbon("1x1x10"));
}
test "day02a" {
try std.testing.expectEqual(@as(usize, 1606483), try first(std.testing.allocator));
}
test "day02b" {
try std.testing.expectEqual(@as(usize, 3842356), try second(std.testing.allocator));
}