@@ -5,44 +5,31 @@ import Aoc2024.Day07.Types
5
5
6
6
-- Part 1
7
7
8
- private def concatenate (a : Int) (b : Int) : Int := (reprStr a ++ reprStr b).toInt!
9
-
10
8
private def evalNumbers (numbers : List Int) (operators : List Operator): Int :=
11
- match numbers with
12
- | [] => 0
13
- | h :: t =>
14
- t.zip operators |>.foldl (fun acc (n, op) => match op with
15
- | .add => acc + n
16
- | .multiply => acc * n
17
- | .concatenation => concatenate acc n
18
- ) h
9
+ numbers.zip (.add :: operators) |>.foldl (λ acc (n, op) => op.fn acc n) 0
19
10
20
11
#guard evalNumbers [11 , 6 , 16 , 20 ] [.add, .multiply, .add] == 292
21
12
22
- private def replicateM (n : Nat) (options : List α) : List (List α) :=
23
- let rec loop (n : Nat) (acc : List (List α)) : List (List α) :=
24
- match n with
25
- | 0 => acc
26
- | n + 1 => loop n (acc.bind λ l => options.map (λ o => o :: l))
27
- loop n [[]]
28
- #guard replicateM 0 [1 , 2 ] == [[]]
29
- #guard replicateM 3 [1 , 2 ] == [[1 , 1 , 1 ], [2 , 1 , 1 ], [1 , 2 , 1 ], [2 , 2 , 1 ], [1 , 1 , 2 ], [2 , 1 , 2 ], [1 , 2 , 2 ], [2 , 2 , 2 ]]
13
+ private def Equation.isTrue (equation : Equation) (operators : List Operator) : Bool :=
14
+ evalNumbers equation.numbers operators == equation.testValue
15
+
16
+ private def Equation.operatorPositions (equation : Equation) : Nat := equation.numbers.length - 1
30
17
31
18
private def canEquationPossiblyBeTrue (operators : List Operator) (equation : Equation) : Bool :=
32
- let operators := replicateM equation.numbers.length operators
33
- operators.any λ ops => evalNumbers equation.numbers ops == equation.testValue
19
+ replicateM equation.operatorPositions operators |>.any equation.isTrue
20
+
21
+ private def solveGeneric (operators : List Operator) (equations : List Equation) : Int :=
22
+ equations.filter (canEquationPossiblyBeTrue operators) |>.sumBy (·.testValue)
34
23
35
- private def solvePart1 (equations : List Equation) : Int :=
36
- equations.filter (canEquationPossiblyBeTrue [.add, .multiply]) |>.sumBy (·.testValue)
24
+ private def solvePart1 : List Equation -> Int := solveGeneric [.add, .multiply]
37
25
38
26
def parseAndSolvePart1 (s : String): Except String Int := parseEquations s |>.map solvePart1
39
27
40
28
#guard parseAndSolvePart1 exampleInput == Except.ok 3749
41
29
42
30
-- Part 2
43
31
44
- private def solvePart2 (equations : List Equation) : Int :=
45
- equations.filter (canEquationPossiblyBeTrue [.add, .multiply, .concatenation]) |>.sumBy (·.testValue)
32
+ private def solvePart2 : List Equation -> Int := solveGeneric [.add, .multiply, .concatenation]
46
33
47
34
def parseAndSolvePart2 (s : String): Except String Int := parseEquations s |>.map solvePart2
48
35
0 commit comments