You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

119 lines
3.4 KiB
Zig

const std = @import("std");
pub fn main() !void {
const file = try std.fs.cwd().openFile("./data.txt", .{});
defer file.close();
var buffer: [30000]u8 = undefined;
_ = try file.readAll(&buffer);
var it = std.mem.split(u8, &buffer, "\n");
var total1: u64 = 0;
var total2: u64 = 0;
while (it.next()) |line| {
if (!std.ascii.isAlphanumeric(line[0])) {
continue;
}
var game: u64 = 0;
var busted: bool = false;
var min_red: u64 = 1;
var min_green: u64 = 1;
var min_blue: u64 = 1;
// Split the row on colons
var parts = std.mem.split(u8, line, ": ");
while (parts.next()) |part| {
// if it contais "Game", parse out the game ID
if (std.mem.eql(u8, part[0..4], "Game")) {
game = try std.fmt.parseInt(u8, part[5..], 10);
} else {
// Split the turns up by semicolons
var turns = std.mem.split(u8, part, "; ");
var red: u64 = 0;
var green: u64 = 0;
var blue: u64 = 0;
while (turns.next()) |turn| {
// Split the colors up by commas
var colors = std.mem.split(u8, turn, ", ");
while (colors.next()) |color| {
const idx = findIdx(color, ' ').?;
const num = try std.fmt.parseInt(u8, color[0..idx], 10);
if (endsWith(color, "red")) {
if (num > min_red) {
min_red = num;
}
if (num > 12) {
busted = true;
}
red += num;
} else if (endsWith(color, "green")) {
if (num > min_green) {
min_green = num;
}
if (num > 13) {
busted = true;
}
green += num;
} else if (endsWith(color, "blue")) {
if (num > min_blue) {
min_blue = num;
}
if (num > 14) {
busted = true;
}
blue += num;
}
}
}
}
}
if (!busted) {
total1 += game;
}
const power: u64 = min_red * min_green * min_blue;
total2 += power;
}
std.debug.print("part 1 total: {any}\n", .{total1});
std.debug.print("part 2 total: {any}\n", .{total2});
}
// does the outer string end with the inner string
fn endsWith(outer: []const u8, inner: []const u8) bool {
if (outer.len < inner.len) {
return false;
}
const offset = outer.len - inner.len;
for (inner, 0..) |c, idx| {
if (c != outer[idx + offset]) {
return false;
}
}
return true;
}
// find the index of char in string
fn findIdx(string: []const u8, char: u8) ?usize {
for (string, 0..) |c, idx| {
if (c == char) {
return idx;
}
}
return null;
}