Skip to content

Commit 0a403b7

Browse files
committed
feat: solution for day 7 part 2
1 parent e164c68 commit 0a403b7

File tree

2 files changed

+57
-5
lines changed

2 files changed

+57
-5
lines changed

2024/SUMMARY.md

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,15 @@ guard moves in a loop.
101101
**Part1:** parse the equations and use recursion to check if any of the options
102102
is valid.
103103

104-
**Part2:**
104+
**Part2:** to implement the number concatenation operator (`||`), count the
105+
digits of the right number (use comptime to pre-calculate possible bins) then
106+
raise the right number with `10^digit_count`, e.g.
107+
```zig
108+
const lhs: usize = 12;
109+
const rhs: usize = 34;
110+
const digits_rhs = countDigits(rhs);
111+
const concatenated = (std.math.pow(10, digits_rhs) * lhs) + rhs;
112+
```
105113

106114
## Day 8
107115
**Part1:** Make sure to allow overriding antennas with antinodes, if their

2024/day7.zig

Lines changed: 48 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,17 @@ fn solveTree(depth: usize, needed_result: usize, result: usize, numbers: []usize
7171
if (depth >= numbers.len) {
7272
return result == needed_result;
7373
}
74-
return solveTree(depth + 1, needed_result, result + numbers[depth], numbers) or solveTree(depth + 1, needed_result, result * numbers[depth], numbers);
74+
return solveTree(depth + 1, needed_result, result + numbers[depth], numbers) or
75+
solveTree(depth + 1, needed_result, result * numbers[depth], numbers);
76+
}
77+
78+
fn solveTreeWithConcat(depth: usize, needed_result: usize, result: usize, numbers: []usize) bool {
79+
if (depth >= numbers.len) {
80+
return result == needed_result;
81+
}
82+
return solveTreeWithConcat(depth + 1, needed_result, result + numbers[depth], numbers) or
83+
solveTreeWithConcat(depth + 1, needed_result, result * numbers[depth], numbers) or
84+
solveTreeWithConcat(depth + 1, needed_result, concatNumbers(result, numbers[depth]), numbers);
7585
}
7686

7787
fn part1(allocator: Allocator, input: []const u8) anyerror!void {
@@ -90,8 +100,42 @@ fn part1(allocator: Allocator, input: []const u8) anyerror!void {
90100
}
91101

92102
fn part2(allocator: Allocator, input: []const u8) anyerror!void {
93-
_ = allocator;
94-
_ = input;
103+
const equations = try parseInput(allocator, input);
104+
105+
var result: usize = 0;
106+
107+
for (0..equations.items.len) |i| {
108+
const eq = equations.items[i];
109+
const is_valid = solveTreeWithConcat(1, eq.result, eq.numbers[0], eq.numbers);
110+
if (is_valid)
111+
result += eq.result;
112+
}
113+
114+
std.debug.print("\nResult: {d}", .{result});
115+
}
116+
117+
fn concatNumbers(lhs: usize, rhs: usize) usize {
118+
const digits_b = countDigits(usize, rhs, 5) catch unreachable;
119+
return (lhs * std.math.pow(usize, 10, digits_b)) + rhs;
120+
}
121+
122+
fn countDigits(comptime T: type, n: T, comptime max: T) !T {
123+
inline for (1..max) |i| {
124+
if (n < std.math.pow(T, 10, i)) return i;
125+
}
126+
unreachable;
127+
}
128+
129+
test "Test concatenation operator" {
130+
var lhs: usize = 9;
131+
var rhs: usize = 2;
132+
try std.testing.expectEqual(@as(usize, 92), concatNumbers(lhs, rhs));
133+
lhs = 13;
134+
rhs = 75;
135+
try std.testing.expectEqual(@as(usize, 1375), concatNumbers(lhs, rhs));
136+
lhs = 123;
137+
rhs = 45;
138+
try std.testing.expectEqual(@as(usize, 12345), concatNumbers(lhs, rhs));
95139
}
96140

97141
pub fn main() !void {
@@ -100,5 +144,5 @@ pub fn main() !void {
100144
const allocator = arena.allocator();
101145

102146
try aoc.runPart(allocator, 2024, DAY, .PUZZLE, part1);
103-
try aoc.runPart(allocator, 2024, DAY, .EXAMPLE, part2);
147+
try aoc.runPart(allocator, 2024, DAY, .PUZZLE, part2);
104148
}

0 commit comments

Comments
 (0)