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.
100 lines
2.9 KiB
100 lines
2.9 KiB
const std = @import("std");
|
|
|
|
fn setMaxValue(field: anytype, new_value: anytype) void {
|
|
comptime {
|
|
if (!std.meta.trait.isPtrTo(@typeInfo(@TypeOf(new_value)))(@TypeOf(field))) {
|
|
@compileError("Expects field to be pointer type to new_value.");
|
|
}
|
|
}
|
|
field.* = @max(field.*, new_value);
|
|
}
|
|
|
|
const Cubes = struct {
|
|
red: u32 = 0,
|
|
green: u32 = 0,
|
|
blue: u32 = 0,
|
|
|
|
fn getPower(self: *Cubes) u32 {
|
|
return self.red * self.green * self.blue;
|
|
}
|
|
|
|
fn setRed(self: *Cubes, value: u32) void {
|
|
setMaxValue(&self.red, value);
|
|
}
|
|
|
|
fn setGreen(self: *Cubes, value: u32) void {
|
|
setMaxValue(&self.green, value);
|
|
}
|
|
|
|
fn setBlue(self: *Cubes, value: u32) void {
|
|
setMaxValue(&self.blue, value);
|
|
}
|
|
};
|
|
|
|
fn solve(line: []const u8) u32 {
|
|
var current_number: u32 = 0;
|
|
var current_pick = Cubes{};
|
|
|
|
var index: usize = 0;
|
|
while (index < line.len) : (index += 1) {
|
|
const char = line[index];
|
|
switch (char) {
|
|
'0'...'9' => {
|
|
current_number = current_number * 10 + (char - '0');
|
|
},
|
|
'G' => {
|
|
index += 4;
|
|
},
|
|
':' => {
|
|
current_number = 0;
|
|
},
|
|
' ' => {},
|
|
',' => {},
|
|
'r' => {
|
|
current_pick.setRed(current_number);
|
|
current_number = 0;
|
|
index += 2;
|
|
},
|
|
'g' => {
|
|
current_pick.setGreen(current_number);
|
|
current_number = 0;
|
|
index += 4;
|
|
},
|
|
'b' => {
|
|
current_pick.setBlue(current_number);
|
|
current_number = 0;
|
|
index += 3;
|
|
},
|
|
';' => {},
|
|
else => unreachable,
|
|
}
|
|
}
|
|
|
|
return current_pick.getPower();
|
|
}
|
|
|
|
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 result: u32 = 0;
|
|
var line_buffer: [1000]u8 = undefined;
|
|
while (try reader.readUntilDelimiterOrEof(&line_buffer, '\n')) |line| {
|
|
result += solve(line);
|
|
}
|
|
try stdout.print(
|
|
"{d}\n",
|
|
.{result},
|
|
);
|
|
}
|
|
|
|
test "solve" {
|
|
try std.testing.expectEqual(@as(?u32, 48), solve("Game 1: 3 blue, 4 red; 1 red, 2 green, 6 blue; 2 green"));
|
|
try std.testing.expectEqual(@as(?u32, 12), solve("Game 2: 1 blue, 2 green; 3 green, 4 blue, 1 red; 1 green, 1 blue"));
|
|
try std.testing.expectEqual(@as(?u32, 1560), solve("Game 3: 8 green, 6 blue, 20 red; 5 blue, 4 red, 13 green; 5 green, 1 red"));
|
|
try std.testing.expectEqual(@as(?u32, 630), solve("Game 4: 1 green, 3 red, 6 blue; 3 green, 6 red; 3 green, 15 blue, 14 red"));
|
|
try std.testing.expectEqual(@as(?u32, 36), solve("Game 5: 6 red, 1 blue, 3 green; 2 blue, 1 red, 2 green"));
|
|
}
|
|
|