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; }