@@ -2,46 +2,62 @@ module Day07
2
2
3
3
using AdventOfCode2024
4
4
5
-
6
5
function day07 (input:: String = readInput (joinpath (@__DIR__ , " .." , " data" , " day07.txt" )))
7
- test_values, numbers = parse_input (input)
8
- solve (test_values, numbers)
6
+ test_values, numbers, concat_factors = parse_input (input)
7
+ return solve (test_values, numbers, concat_factors )
9
8
end
10
9
11
10
function parse_input (input)
12
- data = [(x, y) for (x, y) ∈ eachsplit .(eachsplit (rstrip (input), ' \n ' ), ' :' )]
13
- test_values = [parse (Int, x[1 ]) for x ∈ data]
14
- numbers = [parse .(Int, split (lstrip (x[2 ]))) for x ∈ data]
15
- return test_values, numbers
11
+ lines = split (rstrip (input), ' \n ' )
12
+ test_values = Int[]
13
+ numbers = Vector{Int}[]
14
+ concat_factors = Vector{Int}[]
15
+
16
+ for line in lines
17
+ left, right = split (line, ' :' )
18
+ nums = parse .(Int, split (right))
19
+ factors = [10 ^ ndigits (n) for n in nums]
20
+ push! (test_values, parse (Int, left))
21
+ push! (numbers, nums)
22
+ push! (concat_factors, factors)
23
+ end
24
+
25
+ return test_values, numbers, concat_factors
16
26
end
17
27
18
- function solve (test_values:: Vector{Int} , numbers:: Vector{Vector{Int}} )
28
+ function solve (test_values:: Vector{Int} , numbers:: Vector{Vector{Int}} , concat_factors :: Vector{Vector{Int}} )
19
29
p1 = p2 = 0
20
- for (test_value, nl) ∈ zip (test_values, numbers)
21
- if valid_p1 (test_value, nl[1 ], @view nl[2 : end ])
22
- p1 += test_value
23
- p2 += test_value
24
- elseif valid_p2 (test_value, nl[1 ], @view nl[2 : end ])
25
- p2 += test_value
26
- end
30
+ for i in eachindex (test_values)
31
+ nums = numbers[i]
32
+ isempty (nums) && continue
33
+ tv = test_values[i]
34
+ cf = concat_factors[i]
35
+
36
+ valid1 = _valid_p1 (tv, nums[1 ], 2 , nums)
37
+ valid2 = valid1 ? true : _valid_p2 (tv, nums[1 ], 2 , nums, cf)
38
+
39
+ p1 += valid1 * tv
40
+ p2 += (valid1 || valid2) * tv
27
41
end
28
42
return [p1, p2]
29
43
end
30
44
31
- function valid_p1 (goal:: Int , curr:: Int , remaining :: AbstractArray {Int} )
32
- isempty (remaining ) && curr != goal && return false
45
+ @inline function _valid_p1 (goal:: Int , curr:: Int , idx :: Int , numbers :: Vector {Int} )
46
+ idx > length (numbers ) && return curr == goal
33
47
curr > goal && return false
34
- curr == goal && isempty (remaining) && return true
35
- return valid_p1 (goal, curr + remaining[1 ], @view remaining[2 : end ]) || valid_p1 (goal, curr * remaining[1 ], @view remaining[2 : end ])
48
+ @inbounds next_num = numbers[idx]
49
+ return _valid_p1 (goal, curr + next_num, idx + 1 , numbers) ||
50
+ _valid_p1 (goal, curr * next_num, idx + 1 , numbers)
36
51
end
37
52
38
- function valid_p2 (goal:: Int , curr:: Int , remaining :: AbstractArray {Int} )
39
- isempty (remaining ) && curr != goal && return false
53
+ @inline function _valid_p2 (goal:: Int , curr:: Int , idx :: Int , numbers :: Vector{Int} , concat_factors :: Vector {Int} )
54
+ idx > length (numbers ) && return curr == goal
40
55
curr > goal && return false
41
- curr == goal && isempty (remaining) && return true
42
- return valid_p2 (goal, curr + remaining[1 ], @view remaining[2 : end ]) || valid_p2 (goal, curr * remaining[1 ], @view remaining[2 : end ]) || valid_p2 (goal, concat (curr, remaining[1 ]), @view remaining[2 : end ])
56
+ @inbounds next_num = numbers[idx]
57
+ @inbounds cf = concat_factors[idx]
58
+ return _valid_p2 (goal, curr + next_num, idx + 1 , numbers, concat_factors) ||
59
+ _valid_p2 (goal, curr * next_num, idx + 1 , numbers, concat_factors) ||
60
+ _valid_p2 (goal, curr * cf + next_num, idx + 1 , numbers, concat_factors)
43
61
end
44
62
45
- concat (x:: Int , y:: Int ) = x * 10 ^ (length (digits (y))) + y
46
-
47
63
end # module
0 commit comments