const std = @import("std");
const PATH = "input/day06.txt";
pub fn first(allocator: std.mem.Allocator) !usize {
const races = try parseInput(allocator, @embedFile(PATH));
defer allocator.free(races);
var ret: usize = 1;
for (races) |race| {
var beaten: usize = 0;
for (0..race.time) |speed| {
const d = speed * (race.time - speed);
if (d > race.distance) beaten += 1;
}
ret *= beaten;
}
return ret;
}
pub fn second(allocator: std.mem.Allocator) !usize {
var race: struct { time: u32, distance: usize } = undefined;
var buf = std.ArrayList(u8).init(allocator);
defer buf.deinit();
var lines = std.mem.splitScalar(u8, @embedFile(PATH), '\n');
{
const line = lines.next().?;
for (line) |ch| {
switch (ch) {
'0'...'9' => {
try buf.append(ch);
},
else => {},
}
}
race.time = try std.fmt.parseUnsigned(u32, buf.items, 10);
}
{
try buf.resize(0);
for (lines.next().?) |ch| {
switch (ch) {
'0'...'9' => {
try buf.append(ch);
},
else => {},
}
}
race.distance = try std.fmt.parseUnsigned(usize, buf.items, 10);
}
var beaten: usize = 0;
for (0..race.time) |speed| {
const d = speed * (race.time - speed);
if (d > race.distance) beaten += 1;
}
return beaten;
}
const Race = struct {
time: u8,
distance: u16,
};
fn parseInput(allocator: std.mem.Allocator, input: []const u8) ![]Race {
var races = std.ArrayList(Race).init(allocator);
var lines = std.mem.splitScalar(u8, input, '\n');
var line = lines.next().?;
var times = std.mem.tokenizeScalar(u8, line, ' ');
_ = times.next(); // drop "Time:"
while (times.next()) |time| {
var r: Race = undefined;
const t = try std.fmt.parseUnsigned(u8, time, 10);
r.time = t;
try races.append(r);
}
line = lines.next().?;
var distances = std.mem.tokenizeScalar(u8, line, ' ');
_ = distances.next(); // drop "Distance:"
var i: usize = 0;
while (distances.next()) |distance| {
const d = try std.fmt.parseUnsigned(u16, distance, 10);
races.items[i].distance = d;
i += 1;
}
return races.toOwnedSlice();
}
test "day06a" {
try std.testing.expectEqual(@as(usize, 6209190), try first(std.testing.allocator));
}
test "day06b" {
try std.testing.expectEqual(@as(usize, 28545089), try second(std.testing.allocator));
}
const test_input =
\\Time: 7 15 30
\\Distance: 9 40 200
;