You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
104 lines
2.7 KiB
104 lines
2.7 KiB
const std = @import("std");
|
|
|
|
fn StackList(comptime T: type, comptime capacity_type: type, comptime capacity: capacity_type) type {
|
|
return struct {
|
|
const Self = @This();
|
|
mem: [capacity]T,
|
|
length: capacity_type,
|
|
|
|
fn add(self: *Self, value: T) void {
|
|
self.mem[self.length] = value;
|
|
self.length += 1;
|
|
}
|
|
|
|
fn has(self: *const Self, needle: T) bool {
|
|
for (0..self.length) |i| {
|
|
if (self.mem[i] == needle) {
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
fn getMutableSlice(self: *Self) []T {
|
|
return (&self.mem)[0..self.length];
|
|
}
|
|
|
|
fn getSlice(self: *const Self) []const T {
|
|
return self.mem[0..self.length];
|
|
}
|
|
|
|
fn reset(self: *Self) void {
|
|
self.length = 0;
|
|
}
|
|
|
|
fn init() Self {
|
|
return Self{
|
|
.mem = undefined,
|
|
.length = 0,
|
|
};
|
|
}
|
|
};
|
|
}
|
|
|
|
fn addDigit(result: anytype, digit: u8) void {
|
|
result.* = (result.* * 10) + (digit - '0');
|
|
}
|
|
|
|
const ParsedLine = StackList(u32, u32, 15);
|
|
|
|
fn parseLine(line: []const u8) ParsedLine {
|
|
var result = ParsedLine.init();
|
|
|
|
var index: usize = 9;
|
|
while (index < line.len) {
|
|
while (line[index] == ' ') : (index += 1) {}
|
|
|
|
var current_number: u32 = 0;
|
|
while (index < line.len and line[index] != ' ') : (index += 1) {
|
|
addDigit(¤t_number, line[index]);
|
|
}
|
|
|
|
result.add(current_number);
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
fn solve(times: ParsedLine, distances: ParsedLine) u128 {
|
|
var result: u64 = 1;
|
|
|
|
for (times.getSlice(), distances.getSlice()) |time, distance| {
|
|
// This can be implemented in O(1) by solving the quadratic equation,
|
|
// but I'm not in the mood to deal with all the float <-> integer nonsense
|
|
// and with all the edge cases.
|
|
// Times in AOC inputs are low enough,
|
|
// there is not that much of a difference between O(1) and O(time)
|
|
|
|
var ways: u32 = 0;
|
|
for (0..(time + 1)) |i| {
|
|
if (i * (time - i) > distance) {
|
|
ways += 1;
|
|
}
|
|
}
|
|
|
|
result *= ways;
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
pub fn main() !void {
|
|
const stdout = std.io.getStdOut().writer();
|
|
|
|
const raw_in = std.io.getStdIn();
|
|
var buffered_reader = std.io.bufferedReader(raw_in.reader());
|
|
var reader = buffered_reader.reader();
|
|
|
|
var line_buffer: [1000]u8 = undefined;
|
|
var times = parseLine((try reader.readUntilDelimiterOrEof(&line_buffer, '\n')).?);
|
|
var distances = parseLine((try reader.readUntilDelimiterOrEof(&line_buffer, '\n')).?);
|
|
|
|
try stdout.print("{d}\n", .{solve(times, distances)});
|
|
}
|
|
|