From cf6612350766ab6fc196cfbc860853fb18dae4ec Mon Sep 17 00:00:00 2001 From: Orfeas <38209077+0xfea5@users.noreply.github.com> Date: Sun, 3 Dec 2023 07:14:20 +0200 Subject: day2 + example files --- day02/solution.zig | 161 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 161 insertions(+) create mode 100644 day02/solution.zig (limited to 'day02/solution.zig') diff --git a/day02/solution.zig b/day02/solution.zig new file mode 100644 index 0000000..5e8d6f6 --- /dev/null +++ b/day02/solution.zig @@ -0,0 +1,161 @@ +const std = @import("std"); +const print = std.debug.print; +const assert = std.debug.assert; +const ArrayList = std.ArrayList; +const mem = std.mem; + +const fin = mem.trim(u8, @embedFile("./input.txt"), &std.ascii.whitespace); +var gpa = std.heap.GeneralPurposeAllocator(.{}){}; +const allocator = gpa.allocator(); + +const Color = enum { + red, + green, + blue, +}; + +const Ball = struct { + color: Color, + num: u64, +}; + +const Set = struct { + red: u64, + green: u64, + blue: u64, +}; + +const Game = struct { + var curGameID: u64 = 1; + id: u64, + sets: ArrayList(Set), + + fn init(self: *@This()) !void { + self.id = curGameID; + self.sets = ArrayList(Set).init(allocator); + curGameID += 1; + } + + fn deinit(self: *@This()) void { + self.sets.deinit(); + } +}; + +pub fn parseBall(text: []const u8) Ball { + const trimmed = mem.trim(u8, text, &std.ascii.whitespace); + var splitBalls = mem.splitScalar(u8, trimmed, ' '); + + const nballs = std.fmt.parseInt(u64, splitBalls.next() orelse unreachable, 10) catch unreachable; + var color: Color = undefined; + color = blk: { + const s = splitBalls.next() orelse unreachable; + + if (mem.eql(u8, s, "red")) { + break :blk .red; + } + + if (mem.eql(u8, s, "green")) { + break :blk .green; + } + + if (mem.eql(u8, s, "blue")) { + break :blk .blue; + } + + unreachable; + }; + + return Ball{ + .color = color, + .num = nballs, + }; +} + +pub fn parseSet(text: []const u8) Set { + const trimmed = mem.trim(u8, text, &std.ascii.whitespace); + var splitBalls = mem.splitScalar(u8, trimmed, ','); + var r: u64 = 0; + var g: u64 = 0; + var b: u64 = 0; + + while (splitBalls.next()) |ball| { + const parsed_ball = parseBall(ball); + switch (parsed_ball.color) { + .red => r += parsed_ball.num, + .green => g += parsed_ball.num, + .blue => b += parsed_ball.num, + } + } + + return Set{ + .red = r, + .green = g, + .blue = b, + }; +} + +pub fn parseGame(text: []const u8) !Game { + const trimmed = mem.trim(u8, text, &std.ascii.whitespace); + var splitSets = mem.splitScalar(u8, trimmed, ';'); + var game: Game = undefined; + try game.init(); + + while (splitSets.next()) |set| { + try game.sets.append(parseSet(set)); + } + + return game; +} + +pub fn part1(input: ArrayList(Game)) void { + var ans: u64 = 0; + + outer: for (input.items) |game| { + for (game.sets.items) |set| { + if (set.red > 12 or set.green > 13 or set.blue > 14) { + continue :outer; + } + } + ans += game.id; + } + + print("{d}\n", .{ans}); +} + +pub fn part2(input: ArrayList(Game)) void { + var ans: u64 = 0; + + for (input.items) |game| { + var max = Set{ + .red = 0, + .blue = 0, + .green = 0, + }; + + for (game.sets.items) |set| { + max.red = @max(max.red, set.red); + max.green = @max(max.green, set.green); + max.blue = @max(max.blue, set.blue); + } + ans += max.red * max.green * max.blue; + } + + print("{d}\n", .{ans}); +} + +pub fn main() !void { + var splitLines = mem.splitScalar(u8, fin, '\n'); + var games = ArrayList(Game).init(allocator); + defer games.deinit(); + + while (splitLines.next()) |line| { + var splitGame = mem.splitScalar(u8, line, ':'); + _ = splitGame.next(); + + const game = try parseGame(splitGame.next() orelse unreachable); + try games.append(game); + } + + part1(games); + part2(games); +} -- cgit v1.2.3