aboutsummaryrefslogtreecommitdiffstats
path: root/day15
diff options
context:
space:
mode:
authorOrfeas <38209077+0xfea5@users.noreply.github.com>2023-12-16 01:01:17 +0200
committerOrfeas <38209077+0xfea5@users.noreply.github.com>2025-10-28 23:20:45 +0200
commit799b53427777c8a1a2cc25ce96249a461bd83563 (patch)
tree13b2c3f4656ce4ae5146920c27ee5719bcedb71f /day15
parentday12 revamped (diff)
downloadaoc23-799b53427777c8a1a2cc25ce96249a461bd83563.tar.gz
aoc23-799b53427777c8a1a2cc25ce96249a461bd83563.zip
day15
Diffstat (limited to 'day15')
-rw-r--r--day15/example.txt1
-rw-r--r--day15/solution.zig100
2 files changed, 101 insertions, 0 deletions
diff --git a/day15/example.txt b/day15/example.txt
new file mode 100644
index 0000000..4f58f74
--- /dev/null
+++ b/day15/example.txt
@@ -0,0 +1 @@
rn=1,cm-,qp=3,cm=2,qp-,pc=4,ot=9,ab=5,pc-,pc=6,ot=7
diff --git a/day15/solution.zig b/day15/solution.zig
new file mode 100644
index 0000000..eb6dcbe
--- /dev/null
+++ b/day15/solution.zig
@@ -0,0 +1,100 @@
1const std = @import("std");
2const print = std.debug.print;
3const assert = std.debug.assert;
4const ArrayList = std.ArrayList;
5const HashMap = std.HashMap;
6const mem = std.mem;
7
8const fin = mem.trim(u8, @embedFile("./input.txt"), &std.ascii.whitespace);
9var gpa = std.heap.GeneralPurposeAllocator(.{}){};
10const allocator = gpa.allocator();
11
12fn hash(s: []const u8) u64 {
13 var h: u64 = 0;
14 for (s) |c| {
15 h += c;
16 h *= 17;
17 h %= 256;
18 }
19
20 return @bitCast(h);
21}
22
23fn part1(strings: []const []const u8) void {
24 var ans: u64 = 0;
25
26 for (strings) |s| {
27 ans += hash(s);
28 }
29
30 print("{d}\n", .{ans});
31}
32
33const Pair = struct {
34 label: []const u8,
35 value: u64,
36};
37
38fn part2(strings: []const []const u8) !void {
39 var map: [256]ArrayList(Pair) = undefined;
40
41 for (&map) |*e| {
42 e.* = ArrayList(Pair).init(allocator);
43 }
44
45 for (strings) |s| {
46 const action = s[mem.indexOfAny(u8, s, "-=").?];
47 var toks = mem.tokenizeAny(u8, s, "-=");
48 const label = toks.next().?;
49 const value = toks.next();
50
51 if (action == '=') {
52 const v = try std.fmt.parseInt(u64, value.?, 10);
53 const m = &map[hash(label)];
54 for (m.items) |*i| {
55 if (mem.eql(u8, i.label, label)) {
56 i.value = v;
57 break;
58 }
59 } else {
60 try map[hash(label)].append(Pair{
61 .value = v,
62 .label = label,
63 });
64 }
65 } else {
66 var m = &map[hash(label)];
67 for (m.items, 0..) |e, i| {
68 if (mem.eql(u8, e.label, label)) {
69 _ = m.orderedRemove(i);
70 break;
71 }
72 }
73 }
74 }
75
76 var ans: u64 = 0;
77 for (map, 1..) |m, i| {
78 for (m.items, 1..) |e, j| {
79 ans += i * j * e.value;
80 }
81 }
82
83 print("{d}\n", .{ans});
84}
85
86pub fn solve(strings: []const []const u8) !void {
87 part1(strings);
88 try part2(strings);
89}
90
91pub fn main() !void {
92 var splitComma = mem.splitScalar(u8, fin, ',');
93 var strings = ArrayList([]const u8).init(allocator);
94
95 while (splitComma.next()) |s| {
96 try strings.append(s);
97 }
98
99 try solve(strings.items);
100}