Solutions of most (39 out of 50 so far) puzzles in Zig (system language, alternative for C). My first experience with it.
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

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(&current_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)});
}