1diff --git a/.gitattributes b/.gitattributes
2new file mode 100644
3index 0000000000000000000000000000000000000000..b0c35a0179b4e3872773bcd87c6c68d86074b7f8
4--- /dev/null
5+++ b/.gitattributes
6@@ -0,0 +1 @@
7+src/input/** filter=git-crypt diff=git-crypt
8diff --git a/.gitignore b/.gitignore
9new file mode 100644
10index 0000000000000000000000000000000000000000..3389c86c99467f36e872462555659b4a6bcb399a
11--- /dev/null
12+++ b/.gitignore
13@@ -0,0 +1,2 @@
14+.zig-cache/
15+zig-out/
16diff --git a/build.zig b/build.zig
17new file mode 100644
18index 0000000000000000000000000000000000000000..a2c95a1b24be84341ee23c8894c471f414898382
19--- /dev/null
20+++ b/build.zig
21@@ -0,0 +1,40 @@
22+const std = @import("std");
23+
24+pub fn build(b: *std.Build) void {
25+ const target = b.standardTargetOptions(.{});
26+ const optimize = b.standardOptimizeOption(.{});
27+
28+ const exe = b.addExecutable(.{
29+ .name = "aoc2024",
30+ .root_module = b.createModule(.{
31+ .root_source_file = b.path("src/main.zig"),
32+ .target = target,
33+ .link_libc = false,
34+ .optimize = optimize,
35+ .single_threaded = true,
36+ }),
37+ });
38+
39+ b.installArtifact(exe);
40+
41+ const run_step = b.step("run", "Run the app");
42+
43+ const run_cmd = b.addRunArtifact(exe);
44+ run_step.dependOn(&run_cmd.step);
45+
46+ run_cmd.step.dependOn(b.getInstallStep());
47+
48+ if (b.args) |args| {
49+ run_cmd.addArgs(args);
50+ }
51+
52+ const exe_tests = b.addTest(.{
53+ .root_module = exe.root_module,
54+ });
55+
56+ const run_exe_tests = b.addRunArtifact(exe_tests);
57+
58+ const test_step = b.step("test", "Run tests");
59+ test_step.dependOn(&run_exe_tests.step);
60+
61+}
62diff --git a/build.zig.zon b/build.zig.zon
63new file mode 100644
64index 0000000000000000000000000000000000000000..9443f9672feda35aeab4b101200627c247bf1daa
65--- /dev/null
66+++ b/build.zig.zon
67@@ -0,0 +1,13 @@
68+.{
69+ .name = .aoc2024,
70+ .version = "0.0.0",
71+ .minimum_zig_version = "0.15.1",
72+ .fingerprint = 0x25105d439732947a,
73+ .dependencies = .{
74+ },
75+ .paths = .{
76+ "build.zig",
77+ "build.zig.zon",
78+ "src",
79+ },
80+}
81diff --git a/src/day1.zig b/src/day1.zig
82new file mode 100644
83index 0000000000000000000000000000000000000000..85771788737b1855af9510f05bd678a3e1bc0948
84--- /dev/null
85+++ b/src/day1.zig
86@@ -0,0 +1,89 @@
87+const std = @import("std");
88+
89+pub fn pt1(input: []const u8) u64 {
90+ var pointer: i64 = 50;
91+ var counter: u64 = 0;
92+
93+ var lines = std.mem.splitScalar(u8, input, '\n');
94+
95+ while (lines.next()) |l| {
96+ if (l.len == 0) {
97+ // this happens at the end so we are safe to return here.
98+ return counter;
99+ }
100+
101+ const op = l[0];
102+ const rotation = std.fmt.parseInt(i64, l[1..], 10) catch undefined;
103+
104+ if (op == 'R') {
105+ pointer = @mod(pointer + rotation, 100);
106+ } else {
107+ pointer = @mod(pointer - rotation, 100);
108+ }
109+
110+ if (pointer == 0) {
111+ counter += 1;
112+ }
113+ }
114+
115+ return counter;
116+}
117+
118+
119+const operator = enum { left, right };
120+pub fn pt2(input: []const u8) u64 {
121+ var pointer: i64 = 50;
122+ var counter: u64 = 0;
123+
124+ var lines = std.mem.splitScalar(u8, input, '\n');
125+
126+ while (lines.next()) |l| {
127+ if (l.len == 0) {
128+ // this happens at the end so we are safe to return here.
129+ return counter;
130+ }
131+
132+ const op = l[0];
133+ const rotation = std.fmt.parseInt(i64, l[1..], 10) catch undefined;
134+
135+ if (op == 'R') {
136+ for (0..@intCast(rotation)) |_| {
137+ pointer = step(pointer, .right);
138+ if (pointer == 0) counter += 1;
139+ }
140+ } else {
141+ for (0..@intCast(rotation)) |_| {
142+ pointer = step(pointer, .left);
143+ if (pointer == 0) counter += 1;
144+ }
145+ }
146+ }
147+
148+ return counter;
149+}
150+
151+fn step(p: i64, comptime o: operator) i64 {
152+ switch (o) {
153+ operator.left => {
154+ if (p == 99) return 0;
155+ return p + 1;
156+ },
157+ operator.right => {
158+ if (p == 0) return 99;
159+ return p - 1;
160+ },
161+ }
162+
163+ return p;
164+}
165+
166+test "Day 1 part 1" {
167+ const res = pt1(@embedFile("./input/day1"));
168+ try std.testing.expect(res == 1165);
169+}
170+
171+
172+test "Day 1 part 2" {
173+ const res = pt2(@embedFile("./input/day1"));
174+ try std.testing.expect(res == 6496);
175+}
176diff --git a/src/input/day1 b/src/input/day1
177new file mode 100644
178index 0000000000000000000000000000000000000000..f0f2e2539f8eeb15e0260db92af3e91b613e66b1
179Binary files /dev/null and b/src/input/day1 differ
180diff --git a/src/main.zig b/src/main.zig
181new file mode 100644
182index 0000000000000000000000000000000000000000..5e3e5db784a782f83dbbeb21cee134173fdc4a37
183--- /dev/null
184+++ b/src/main.zig
185@@ -0,0 +1,19 @@
186+const std = @import("std");
187+const day1 = @import("day1.zig");
188+
189+pub export fn main() void {
190+ if (std.os.argv.len != 2) {
191+ std.debug.print("Invalid day", .{});
192+ }
193+
194+ const day = std.mem.span(std.os.argv[1]);
195+
196+ if (std.mem.eql(u8, "--day1", day)) {
197+ const res1 = day1.pt1(@embedFile("./input/day1"));
198+ std.debug.print("{d}\n", .{res1});
199+ const res2 = day1.pt2(@embedFile("./input/day1"));
200+ std.debug.print("{d}\n", .{res2});
201+ } else {
202+ std.debug.print("Invalid day", .{});
203+ }
204+}