From 45b25120e06ab13df098ef6b576c5fe646bc1c2f Mon Sep 17 00:00:00 2001 From: ktkk Date: Tue, 2 Dec 2025 10:41:55 +0000 Subject: [PATCH 1/4] Finish day02, part 1 --- src/days/day02.zig | 38 +++++++++++++++++++++++++++++++++++++- src/days/input/day02.txt | 1 + 2 files changed, 38 insertions(+), 1 deletion(-) create mode 100755 src/days/input/day02.txt diff --git a/src/days/day02.zig b/src/days/day02.zig index 4de3c68..098b80e 100644 --- a/src/days/day02.zig +++ b/src/days/day02.zig @@ -2,6 +2,42 @@ const std = @import("std"); pub const title = "Day 02"; -pub fn run(_: std.mem.Allocator) !void { +pub fn run(allocator: std.mem.Allocator) !void { + const input = @embedFile("./input/day02.txt"); + var ranges = std.mem.tokenizeScalar(u8, input, ','); + + var accumulator: u64 = 0; + + while (ranges.next()) |range| { + var components = std.mem.tokenizeScalar(u8, range, '-'); + const start_s = std.mem.trim(u8, components.next() orelse continue, &std.ascii.whitespace); + const end_s = std.mem.trim(u8, components.next() orelse continue, &std.ascii.whitespace); + const start = try std.fmt.parseUnsigned(u64, start_s, 10); + const end = try std.fmt.parseUnsigned(u64, end_s, 10); + + std.debug.print("{d} to {d}\n", .{start, end}); + + outer: for (start..end+1) |id| { + const id_s = try std.fmt.allocPrint(allocator, "{}", .{id}); + defer allocator.free(id_s); + + if (id_s.len % 2 == 1) continue; + + for (0..id_s.len / 2) |i| { + if (id_s[i] != id_s[i + id_s.len / 2]) { + continue :outer; + } + } + accumulator += id; + } + } + + var buffer: [64]u8 = undefined; + var stdout_writer = std.fs.File.stdout().writer(&buffer); + const stdout = &stdout_writer.interface; + + try stdout.print("{d}\n", .{accumulator}); + + try stdout.flush(); } diff --git a/src/days/input/day02.txt b/src/days/input/day02.txt new file mode 100755 index 0000000..69086d8 --- /dev/null +++ b/src/days/input/day02.txt @@ -0,0 +1 @@ +52500467-52574194,655624494-655688785,551225-576932,8418349387-8418411293,678-1464,33-79,74691-118637,8787869169-8787890635,9898977468-9899009083,548472423-548598890,337245835-337375280,482823-543075,926266-991539,1642682920-1642753675,3834997-3940764,1519-2653,39697698-39890329,3-21,3251796-3429874,3467-9298,26220798-26290827,80-124,200638-280634,666386-710754,21329-64315,250-528,9202893-9264498,819775-903385,292490-356024,22-32,2663033-2791382,133-239,56514707-56704320,432810-458773,4949427889-4949576808 From 89d248d3b860f42456a7d34697408fd3141df1db Mon Sep 17 00:00:00 2001 From: ktkk Date: Tue, 2 Dec 2025 12:22:28 +0000 Subject: [PATCH 2/4] Improve part 1 efficiency --- src/days/day02.zig | 35 +++++++++++++++++++++++++++++------ 1 file changed, 29 insertions(+), 6 deletions(-) diff --git a/src/days/day02.zig b/src/days/day02.zig index 098b80e..8e45652 100644 --- a/src/days/day02.zig +++ b/src/days/day02.zig @@ -2,7 +2,7 @@ const std = @import("std"); pub const title = "Day 02"; -pub fn run(allocator: std.mem.Allocator) !void { +pub fn run(_: std.mem.Allocator) !void { const input = @embedFile("./input/day02.txt"); var ranges = std.mem.tokenizeScalar(u8, input, ','); @@ -18,13 +18,17 @@ pub fn run(allocator: std.mem.Allocator) !void { std.debug.print("{d} to {d}\n", .{start, end}); outer: for (start..end+1) |id| { - const id_s = try std.fmt.allocPrint(allocator, "{}", .{id}); - defer allocator.free(id_s); + // IDs smaller than 10 cannot possibly have repeated digits + if (id / 10 == 0) continue; - if (id_s.len % 2 == 1) continue; + const len = getLen(id); + // Uneven numbers cannot consist of 2 sequences + if (len % 2 == 1) continue; - for (0..id_s.len / 2) |i| { - if (id_s[i] != id_s[i + id_s.len / 2]) { + for (0..len / 2) |i| { + const a = getDigit(id, i); + const b = getDigit(id, i + len / 2); + if (a != b) { continue :outer; } } @@ -41,3 +45,22 @@ pub fn run(allocator: std.mem.Allocator) !void { try stdout.flush(); } +fn getDigit(x: u64, n: usize) u8 { + var new_x = x; + for (0..n) |_| { + new_x /= 10; + } + return @intCast(new_x % 10); +} + +fn getLen(x: u64) usize { + var new_x = x; + var n: usize = 0; + while (true) { + n += 1; + new_x /= 10; + if (new_x == 0) break; + } + return n; +} + From 34f9fff423e7c49527266ffeff03dae2c5015efd Mon Sep 17 00:00:00 2001 From: ktkk Date: Tue, 2 Dec 2025 16:36:13 +0000 Subject: [PATCH 3/4] WIP: implement part 2 --- src/days/day02.zig | 39 ++++++++++++++++++++++++++++++--------- 1 file changed, 30 insertions(+), 9 deletions(-) diff --git a/src/days/day02.zig b/src/days/day02.zig index 8e45652..12f66ea 100644 --- a/src/days/day02.zig +++ b/src/days/day02.zig @@ -17,23 +17,44 @@ pub fn run(_: std.mem.Allocator) !void { std.debug.print("{d} to {d}\n", .{start, end}); - outer: for (start..end+1) |id| { + for (start..end+1) |id| { + std.debug.print("-- Checking {d} --\n", .{id}); + // IDs smaller than 10 cannot possibly have repeated digits - if (id / 10 == 0) continue; + if (id / 10 == 0) { + std.debug.print("Skipping {d}\n", .{id}); + continue; + } const len = getLen(id); - // Uneven numbers cannot consist of 2 sequences - if (len % 2 == 1) continue; + inner: for (2..len + 1) |divisor| { + if (len % divisor != 0) continue; - for (0..len / 2) |i| { - const a = getDigit(id, i); - const b = getDigit(id, i + len / 2); - if (a != b) { - continue :outer; + std.debug.print("divisor = {d}\n", .{divisor}); + + const window_len = len / divisor; + + std.debug.print("window_len = {d}\n", .{window_len}); + + for (0..window_len) |i| { + const a = getDigit(id, i); + std.debug.print("a = {d}\n", .{a}); + for (1..divisor) |n| { + const b = getDigit(id, i + window_len * n); + std.debug.print("b = {d}\n", .{b}); + if (a != b) { + continue :inner; + } + } } + // If we get here, it means id is a valid cadidate + std.debug.print("result = {d}\n", .{id}); + break; } accumulator += id; } + + break; } var buffer: [64]u8 = undefined; From ee219fc9b2f9b0ebc078508778294e82fd83e64a Mon Sep 17 00:00:00 2001 From: ktkk Date: Tue, 2 Dec 2025 20:19:23 +0000 Subject: [PATCH 4/4] Finish day02, part 2 --- src/days/day02.zig | 91 +++++++++++++++++++++++++--------------------- 1 file changed, 49 insertions(+), 42 deletions(-) diff --git a/src/days/day02.zig b/src/days/day02.zig index 12f66ea..849737f 100644 --- a/src/days/day02.zig +++ b/src/days/day02.zig @@ -3,58 +3,25 @@ const std = @import("std"); pub const title = "Day 02"; pub fn run(_: std.mem.Allocator) !void { - const input = @embedFile("./input/day02.txt"); + const input = std.mem.trim(u8, @embedFile("./input/day02.txt"), &std.ascii.whitespace); + //const input = + // \\11-22,95-115,998-1012,1188511880-1188511890,222220-222224,1698522-1698528,446443-446449,38593856-38593862,565653-565659,824824821-824824827,2121212118-2121212124 + // ; var ranges = std.mem.tokenizeScalar(u8, input, ','); var accumulator: u64 = 0; while (ranges.next()) |range| { var components = std.mem.tokenizeScalar(u8, range, '-'); - const start_s = std.mem.trim(u8, components.next() orelse continue, &std.ascii.whitespace); - const end_s = std.mem.trim(u8, components.next() orelse continue, &std.ascii.whitespace); + + const start_s = components.next() orelse continue; + const end_s = components.next() orelse continue; + const start = try std.fmt.parseUnsigned(u64, start_s, 10); const end = try std.fmt.parseUnsigned(u64, end_s, 10); std.debug.print("{d} to {d}\n", .{start, end}); - - for (start..end+1) |id| { - std.debug.print("-- Checking {d} --\n", .{id}); - - // IDs smaller than 10 cannot possibly have repeated digits - if (id / 10 == 0) { - std.debug.print("Skipping {d}\n", .{id}); - continue; - } - - const len = getLen(id); - inner: for (2..len + 1) |divisor| { - if (len % divisor != 0) continue; - - std.debug.print("divisor = {d}\n", .{divisor}); - - const window_len = len / divisor; - - std.debug.print("window_len = {d}\n", .{window_len}); - - for (0..window_len) |i| { - const a = getDigit(id, i); - std.debug.print("a = {d}\n", .{a}); - for (1..divisor) |n| { - const b = getDigit(id, i + window_len * n); - std.debug.print("b = {d}\n", .{b}); - if (a != b) { - continue :inner; - } - } - } - // If we get here, it means id is a valid cadidate - std.debug.print("result = {d}\n", .{id}); - break; - } - accumulator += id; - } - - break; + try processRange(&accumulator, start, end); } var buffer: [64]u8 = undefined; @@ -66,6 +33,46 @@ pub fn run(_: std.mem.Allocator) !void { try stdout.flush(); } +fn processRange(accumulator: *u64, start: u64, end: u64) !void { + for (start..end+1) |id| { + std.debug.print("-- Checking {d} --\n", .{id}); + + // IDs smaller than 10 cannot possibly have repeated digits + if (id / 10 == 0) { + std.debug.print("Skipping {d}\n", .{id}); + continue; + } + + const len = getLen(id); + inner: for (2..len + 1) |divisor| { + if (len % divisor != 0) continue; + + std.debug.print("divisor = {d}\n", .{divisor}); + + const offset = len / divisor; + + std.debug.print("offset = {d}\n", .{offset}); + + for (0..offset) |i| { + const a = getDigit(id, i); + std.debug.print("a = {d}\n", .{a}); + for (1..divisor) |n| { + const b = getDigit(id, i + offset * n); + std.debug.print("b = {d}\n", .{b}); + if (a != b) { + continue :inner; + } + } + } + + // If we get here, it means id is a valid cadidate + std.debug.print("result = {d}\n", .{id}); + accumulator.* += id; + break; + } + } +} + fn getDigit(x: u64, n: usize) u8 { var new_x = x; for (0..n) |_| {