This repository has been archived on 2022-12-11. You can view files and clone it, but cannot push or open issues or pull requests.
aoc2022/01/2.zig

71 lines
2.1 KiB
Zig

const std = @import("std");
// NOTE: I know this is way too overengineered, but I wanted
// to make it as efficient as possible.
pub fn main() !void {
const input = @embedFile("input");
// Putting part 1's solution as an extra :P
std.debug.print("Part 1's solution: {}\n", .{sumTopNElves(input, 1)});
std.debug.print("Part 2's solution: {}\n", .{sumTopNElves(input, 3)});
}
// Returns the sum of the <cant> elves with the most calories from <string>
pub fn sumTopNElves(input: []const u8, comptime cant: usize) usize {
var iter = ElfIterator.init(input);
// Initialize the buffer where the 3 numbers will lie
var maxArr: [cant]usize = .{0} ** cant;
// Keeps track of which is the smallest index of the array
var min_i: usize = 0;
// Iterate through each elf's sum of calories as usize
while (iter.next()) |elf| {
// Check if the current elf carries more
// calories than the previous smallest max
if (elf > maxArr[min_i]) {
maxArr[min_i] = elf;
// maxArr changed, update what is the smallest index
var advance: usize = 1;
while (advance < cant) : (advance += 1) {
// Advance and wrap around
const i = (min_i + advance) % cant;
if (maxArr[i] < maxArr[min_i]) min_i = i;
}
}
}
var res: usize = 0;
inline for (maxArr) |num| {
res += num;
}
return res;
}
// Helper to return the total of calories per elf one at a time
const ElfIterator = struct {
iter: std.mem.SplitIterator(u8),
pub fn init(input: []const u8) ElfIterator {
return ElfIterator{
// We assume the input file is properly formatted
.iter = std.mem.split(u8, input, "\n"),
};
}
pub fn next(self: *ElfIterator) ?usize {
var res: usize = 0;
while (self.iter.next()) |calories| {
// If non numeric assume EOF (End Of elF)
res += std.fmt.parseInt(usize, calories, 10) catch return res;
}
// If we reach EOF (End Of File, do not confuse with End Of elF), return null
return null;
}
};