aboutsummaryrefslogtreecommitdiffstats
path: root/day02/solution.zig
diff options
context:
space:
mode:
authorOrfeas <38209077+0xfea5@users.noreply.github.com>2023-12-03 07:14:20 +0200
committerOrfeas <38209077+0xfea5@users.noreply.github.com>2025-10-28 23:20:45 +0200
commitcf6612350766ab6fc196cfbc860853fb18dae4ec (patch)
treed31dfaeb7d8776788b9f3b48fd1a3b808934fd6b /day02/solution.zig
parentupdate init.sh (diff)
downloadaoc23-cf6612350766ab6fc196cfbc860853fb18dae4ec.tar.gz
aoc23-cf6612350766ab6fc196cfbc860853fb18dae4ec.zip
day2 + example files
Diffstat (limited to 'day02/solution.zig')
-rw-r--r--day02/solution.zig161
1 files changed, 161 insertions, 0 deletions
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 @@
1const std = @import("std");
2const print = std.debug.print;
3const assert = std.debug.assert;
4const ArrayList = std.ArrayList;
5const mem = std.mem;
6
7const fin = mem.trim(u8, @embedFile("./input.txt"), &std.ascii.whitespace);
8var gpa = std.heap.GeneralPurposeAllocator(.{}){};
9const allocator = gpa.allocator();
10
11const Color = enum {
12 red,
13 green,
14 blue,
15};
16
17const Ball = struct {
18 color: Color,
19 num: u64,
20};
21
22const Set = struct {
23 red: u64,
24 green: u64,
25 blue: u64,
26};
27
28const Game = struct {
29 var curGameID: u64 = 1;
30 id: u64,
31 sets: ArrayList(Set),
32
33 fn init(self: *@This()) !void {
34 self.id = curGameID;
35 self.sets = ArrayList(Set).init(allocator);
36 curGameID += 1;
37 }
38
39 fn deinit(self: *@This()) void {
40 self.sets.deinit();
41 }
42};
43
44pub fn parseBall(text: []const u8) Ball {
45 const trimmed = mem.trim(u8, text, &std.ascii.whitespace);
46 var splitBalls = mem.splitScalar(u8, trimmed, ' ');
47
48 const nballs = std.fmt.parseInt(u64, splitBalls.next() orelse unreachable, 10) catch unreachable;
49 var color: Color = undefined;
50 color = blk: {
51 const s = splitBalls.next() orelse unreachable;
52
53 if (mem.eql(u8, s, "red")) {
54 break :blk .red;
55 }
56
57 if (mem.eql(u8, s, "green")) {
58 break :blk .green;
59 }
60
61 if (mem.eql(u8, s, "blue")) {
62 break :blk .blue;
63 }
64
65 unreachable;
66 };
67
68 return Ball{
69 .color = color,
70 .num = nballs,
71 };
72}
73
74pub fn parseSet(text: []const u8) Set {
75 const trimmed = mem.trim(u8, text, &std.ascii.whitespace);
76 var splitBalls = mem.splitScalar(u8, trimmed, ',');
77 var r: u64 = 0;
78 var g: u64 = 0;
79 var b: u64 = 0;
80
81 while (splitBalls.next()) |ball| {
82 const parsed_ball = parseBall(ball);
83 switch (parsed_ball.color) {
84 .red => r += parsed_ball.num,
85 .green => g += parsed_ball.num,
86 .blue => b += parsed_ball.num,
87 }
88 }
89
90 return Set{
91 .red = r,
92 .green = g,
93 .blue = b,
94 };
95}
96
97pub fn parseGame(text: []const u8) !Game {
98 const trimmed = mem.trim(u8, text, &std.ascii.whitespace);
99 var splitSets = mem.splitScalar(u8, trimmed, ';');
100 var game: Game = undefined;
101 try game.init();
102
103 while (splitSets.next()) |set| {
104 try game.sets.append(parseSet(set));
105 }
106
107 return game;
108}
109
110pub fn part1(input: ArrayList(Game)) void {
111 var ans: u64 = 0;
112
113 outer: for (input.items) |game| {
114 for (game.sets.items) |set| {
115 if (set.red > 12 or set.green > 13 or set.blue > 14) {
116 continue :outer;
117 }
118 }
119 ans += game.id;
120 }
121
122 print("{d}\n", .{ans});
123}
124
125pub fn part2(input: ArrayList(Game)) void {
126 var ans: u64 = 0;
127
128 for (input.items) |game| {
129 var max = Set{
130 .red = 0,
131 .blue = 0,
132 .green = 0,
133 };
134
135 for (game.sets.items) |set| {
136 max.red = @max(max.red, set.red);
137 max.green = @max(max.green, set.green);
138 max.blue = @max(max.blue, set.blue);
139 }
140 ans += max.red * max.green * max.blue;
141 }
142
143 print("{d}\n", .{ans});
144}
145
146pub fn main() !void {
147 var splitLines = mem.splitScalar(u8, fin, '\n');
148 var games = ArrayList(Game).init(allocator);
149 defer games.deinit();
150
151 while (splitLines.next()) |line| {
152 var splitGame = mem.splitScalar(u8, line, ':');
153 _ = splitGame.next();
154
155 const game = try parseGame(splitGame.next() orelse unreachable);
156 try games.append(game);
157 }
158
159 part1(games);
160 part2(games);
161}