summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMathias Magnusson <mathias@magnusson.space>2025-12-04 19:31:18 +0100
committerMathias Magnusson <mathias@magnusson.space>2025-12-04 19:31:18 +0100
commitc356e76c4e75f9aa4f0fc1a18f6848b277144f6b (patch)
tree045ad34ec71ad8340fa7ed5c02fec4ee89da9900
parent925abcbe2159c3b0ea13670a62b57912bd3e8994 (diff)
downloadprogramming-problem-solving-main.tar.gz
aoc2025: day 2HEADmain
-rw-r--r--aoc25/src/day2.zig88
1 files changed, 88 insertions, 0 deletions
diff --git a/aoc25/src/day2.zig b/aoc25/src/day2.zig
new file mode 100644
index 0000000..a5bb3db
--- /dev/null
+++ b/aoc25/src/day2.zig
@@ -0,0 +1,88 @@
+const std = @import("std");
+
+const test_input =
+ \\11-22,95-115,998-1012,1188511880-1188511890,222220-222224,1698522-1698528,446443-446449,38593856-38593862,565653-565659,824824821-824824827,2121212118-2121212124
+ \\
+;
+
+test part1 {
+ var arena = std.heap.ArenaAllocator.init(std.testing.allocator);
+ defer arena.deinit();
+ const allocator = arena.allocator();
+
+ try std.testing.expectEqual(1227775554, try part1(allocator, try parse(allocator, test_input)));
+}
+
+test part2 {
+ var arena = std.heap.ArenaAllocator.init(std.testing.allocator);
+ defer arena.deinit();
+ const allocator = arena.allocator();
+
+ try std.testing.expectEqual(4174379265, try part2(allocator, try parse(allocator, test_input)));
+}
+
+const Input = []struct {
+ from: u64,
+ to: u64,
+};
+
+pub fn parse(allocator: std.mem.Allocator, input: []const u8) !Input {
+ var spans = std.mem.splitScalar(u8, input, ',');
+
+ var parsed = try std.ArrayList(@typeInfo(Input).pointer.child).initCapacity(allocator, 0);
+
+ while (spans.next()) |span_| {
+ var span = if (std.mem.endsWith(u8, span_, "\n")) span_[0 .. span_.len - 1] else span_;
+ const dash = std.mem.indexOfScalar(u8, span, '-') orelse return error.InvalidInput;
+ const from = try std.fmt.parseInt(u64, span[0..dash], 10);
+ const to = try std.fmt.parseInt(u64, span[dash + 1 ..], 10);
+ try parsed.append(allocator, .{ .from = from, .to = to });
+ }
+
+ return parsed.toOwnedSlice(allocator);
+}
+
+pub fn part1(allocator: std.mem.Allocator, input: Input) !usize {
+ var allocating_writer = std.io.Writer.Allocating.init(allocator);
+ const writer = &allocating_writer.writer;
+ var answer: usize = 0;
+ for (input) |span| {
+ for (span.from..span.to + 1) |n| {
+ allocating_writer.clearRetainingCapacity();
+ try writer.print("{}", .{n});
+ const written = allocating_writer.written();
+ if (written.len % 2 == 1) continue;
+ const len = written.len / 2;
+ if (!std.mem.eql(u8, written[0..len], written[len..])) continue;
+ // std.debug.print("{}\n", .{n});
+ answer += n;
+ }
+ }
+ return answer;
+}
+
+pub fn part2(allocator: std.mem.Allocator, input: Input) !usize {
+ var allocating_writer = std.io.Writer.Allocating.init(allocator);
+ const writer = &allocating_writer.writer;
+ var answer: usize = 0;
+ for (input) |span| {
+ n: for (span.from..span.to + 1) |n| {
+ allocating_writer.clearRetainingCapacity();
+ try writer.print("{}", .{n});
+ const written = allocating_writer.written();
+ for (2..written.len + 1) |repetitions| {
+ if (written.len % repetitions != 0) continue;
+ const len = written.len / repetitions;
+ const first = written[0..len];
+ var windows = std.mem.window(u8, written, len, len);
+ while (windows.next()) |window| {
+ if (!std.mem.eql(u8, first, window)) break;
+ } else { // all were equal
+ answer += n;
+ continue :n;
+ }
+ }
+ }
+ }
+ return answer;
+}