advent-of-code/2023/day-02/common.zig

71 lines
1.9 KiB
Zig

const std = @import("std");
const List = std.ArrayList;
const alloc = std.heap.page_allocator;
pub const Game = struct {
id: u32,
sets: List(List(Cubes)),
};
pub const Cubes = struct {
amount: u32,
color: CubeColor,
};
pub const CubeColor = enum {
red,
green,
blue,
};
pub fn parse(data: []const u8) !List(Game) {
var lines = std.mem.tokenizeSequence(u8, data, "\n");
var games = List(Game).init(alloc);
while (lines.next()) |line| {
var game_seq = std.mem.tokenizeSequence(u8, line, ": ");
const game_info = game_seq.next().?;
const game_id = try std.fmt.parseInt(u32, game_info[5..], 10);
const game_sets = game_seq.next().?;
var sets_seq = std.mem.tokenizeSequence(u8, game_sets, "; ");
var sets = List(List(Cubes)).init(alloc);
while (sets_seq.next()) |set| {
var items = std.mem.tokenizeSequence(u8, set, ", ");
var x = List(Cubes).init(alloc);
while (items.next()) |item| {
var cubes_data = std.mem.tokenizeScalar(u8, item, ' ');
const amount = try std.fmt.parseInt(u32, cubes_data.next().?, 10);
const color_str = cubes_data.next().?;
var color: ?CubeColor = null;
if (std.mem.eql(u8, color_str, "blue")) {
color = CubeColor.blue;
} else if (std.mem.eql(u8, color_str, "red")) {
color = CubeColor.red;
} else if (std.mem.eql(u8, color_str, "green")) {
color = CubeColor.green;
} else {
unreachable;
}
try x.append(.{ .amount = amount, .color = color.? });
}
try sets.append(x);
}
const game = .{ .id = game_id, .sets = sets };
try games.append(game);
}
return games;
}