Skip to content

Commit 4751c6e

Browse files
committed
fix: day 1 part 1 tests and upper lower limits
Signed-off-by: markkovari <kovarimarkofficial@gmail.com>
1 parent d438c15 commit 4751c6e

1 file changed

Lines changed: 92 additions & 4 deletions

File tree

2025/zig/src/day01/day01.zig

Lines changed: 92 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,35 @@ fn Rotation(comptime T: type) type {
1616
};
1717
}
1818

19+
fn Dial(comptime T: type) type {
20+
return struct {
21+
const Self = @This();
22+
23+
initial: T,
24+
position: T,
25+
26+
pub fn init(initial_position: T) Self {
27+
return .{
28+
.initial = initial_position,
29+
.position = initial_position,
30+
};
31+
}
32+
pub fn rotate(self: *Self, rotation: Rotation(T)) void {
33+
switch (rotation.dir) {
34+
.Left => {
35+
self.position = @mod(self.position - rotation.amount, 100);
36+
},
37+
.Right => {
38+
self.position = @mod(self.position + rotation.amount, 100);
39+
},
40+
}
41+
}
42+
pub fn getCurrentPosition(self: Self) T {
43+
return self.position;
44+
}
45+
};
46+
}
47+
1948
fn parseFromString(comptime T: type, input: []const u8) RotationParseError!Rotation(T) {
2049
if (input.len < 2) {
2150
return RotationParseError.InvalidLength;
@@ -49,10 +78,24 @@ pub fn parseAllLines(comptime T: type, allocator: std.mem.Allocator, input: []co
4978
return try results.toOwnedSlice(allocator);
5079
}
5180

52-
pub fn part1(input: []const u8) !i32 {
53-
// Parse and solve part 1
54-
_ = input;
55-
return 0;
81+
pub fn part1(input: []const u8) !u32 {
82+
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
83+
defer _ = gpa.deinit();
84+
const allocator = gpa.allocator();
85+
var amount: u32 = 0;
86+
87+
const rotations = try parseAllLines(i32, allocator, input);
88+
defer allocator.free(rotations);
89+
90+
var dial = Dial(i32).init(50);
91+
for (rotations) |rotation| {
92+
dial.rotate(rotation);
93+
if (dial.getCurrentPosition() == 0) {
94+
amount += 1;
95+
}
96+
}
97+
98+
return amount;
5699
}
57100

58101
pub fn part2(input: []const u8) !i32 {
@@ -104,3 +147,48 @@ test "parse with invalid length" {
104147
const asText = "G";
105148
try std.testing.expectError(RotationParseError.InvalidLength, parseFromString(u32, asText));
106149
}
150+
151+
test "dial initialization" {
152+
var dial = Dial(i32).init(100);
153+
try std.testing.expectEqual(@as(i32, 100), dial.initial);
154+
try std.testing.expectEqual(@as(i32, 100), dial.getCurrentPosition());
155+
}
156+
157+
test "dial rotation right" {
158+
var dial = Dial(i32).init(0);
159+
const rotation = Rotation(i32){ .dir = .Right, .amount = 10 };
160+
dial.rotate(rotation);
161+
try std.testing.expectEqual(@as(i32, 0), dial.initial); // initial unchanged
162+
try std.testing.expectEqual(@as(i32, 10), dial.getCurrentPosition());
163+
}
164+
165+
test "dial rotation left" {
166+
var dial = Dial(i32).init(50);
167+
const rotation = Rotation(i32){ .dir = .Left, .amount = 20 };
168+
dial.rotate(rotation);
169+
try std.testing.expectEqual(@as(i32, 50), dial.initial); // initial unchanged
170+
try std.testing.expectEqual(@as(i32, 30), dial.getCurrentPosition());
171+
}
172+
173+
test "dial multiple rotations" {
174+
var dial = Dial(i32).init(0);
175+
dial.rotate(.{ .dir = .Right, .amount = 10 });
176+
dial.rotate(.{ .dir = .Left, .amount = 5 });
177+
dial.rotate(.{ .dir = .Right, .amount = 15 });
178+
try std.testing.expectEqual(@as(i32, 0), dial.initial); // initial always unchanged
179+
try std.testing.expectEqual(@as(i32, 20), dial.getCurrentPosition());
180+
}
181+
182+
test "first part example" {
183+
const example_input = @embedFile("example.txt");
184+
const result = try part1(example_input);
185+
186+
try std.testing.expectEqual(3, result);
187+
}
188+
189+
test "first part input" {
190+
const example_input = @embedFile("input.txt");
191+
const result = try part1(example_input);
192+
193+
try std.testing.expectEqual(1071, result);
194+
}

0 commit comments

Comments
 (0)