Skip to content

Commit 00d115c

Browse files
committed
day 7 part 1
1 parent 1c3b6be commit 00d115c

10 files changed

+979
-2
lines changed

Aoc2024/Day07/Examples.lean

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
def exampleInput :=
2+
"190: 10 19
3+
3267: 81 40 27
4+
83: 17 5
5+
156: 15 6
6+
7290: 6 8 6 15
7+
161011: 16 10 13
8+
192: 17 8 14
9+
21037: 9 7 18 13
10+
292: 11 6 16 20"

Aoc2024/Day07/Main.lean

+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import Aoc2024.Day07.Solve
2+
import Aoc2024.CustomMonadLift
3+
4+
def main : IO Unit := do
5+
IO.println "Day 07"
6+
IO.println ""
7+
IO.println "Part 1"
8+
let exampleInput <- IO.FS.readFile "Aoc2024/Day07/inputs/example.txt"
9+
let puzzleInput <- IO.FS.readFile "Aoc2024/Day07/inputs/input.txt"
10+
IO.println s!"Example: {<- parseAndSolvePart1 exampleInput}"
11+
let answerPart1 <- parseAndSolvePart1 puzzleInput
12+
IO.println s!"Puzzle: {answerPart1}"
13+
assert! (answerPart1 == 66343330034722)
14+
IO.println ""
15+
IO.println "Part 2"
16+
IO.println s!"Example: {<- parseAndSolvePart2 exampleInput}"
17+
let answerPart2 <- parseAndSolvePart2 puzzleInput
18+
IO.println s!"Puzzle: {answerPart2}"
19+
assert! (answerPart2 == -1)

Aoc2024/Day07/Parser.lean

+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import Aoc2024.Day07.Examples
2+
import Aoc2024.Day07.Types
3+
import Aoc2024.Utils
4+
import Std
5+
open Std.Internal.Parsec.String
6+
open Std.Internal.Parsec
7+
8+
private def number : Parser Int := do pure (<- digits)
9+
10+
private def equation : Parser Equation := do
11+
let testValue <- number
12+
let _ ← skipString ": "
13+
let numbers <- sepBy number (skipChar ' ')
14+
pure { testValue, numbers }
15+
16+
private def equations : Parser (List Equation) := sepBy equation (skipChar '\n')
17+
18+
def parseEquations : String -> Except String (List Equation) := equations.run
19+
20+
#guard parseEquations "190: 10 19\n3267: 81 40 27" == Except.ok [
21+
{ testValue := 190, numbers := [10, 19] },
22+
{ testValue := 3267, numbers := [81, 40, 27] }
23+
]

Aoc2024/Day07/Solve.lean

+45
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
import Aoc2024.Utils
2+
import Aoc2024.Day07.Examples
3+
import Aoc2024.Day07.Parser
4+
import Aoc2024.Day07.Types
5+
6+
-- Part 1
7+
8+
private def evalNumbers (numbers : List Int) (operators : List Operator): Int :=
9+
match numbers with
10+
| [] => 0
11+
| h :: t =>
12+
t.zip operators |>.foldl (fun acc (n, op) => match op with
13+
| .add => acc + n
14+
| .multiply => acc * n
15+
) h
16+
17+
#guard evalNumbers [11, 6, 16, 20] [.add, .multiply, .add] == 292
18+
19+
private def replicateM (n : Nat) (options : List α) : List (List α) :=
20+
let rec loop (n : Nat) (acc : List (List α)) : List (List α) :=
21+
match n with
22+
| 0 => acc
23+
| n + 1 => loop n (acc.bind λ l => options.map (λ o => o :: l))
24+
loop n [[]]
25+
#guard replicateM 0 [1, 2] == [[]]
26+
#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]]
27+
28+
private def canEquationPossiblyBeTrue (equation : Equation) : Bool :=
29+
let operators := replicateM equation.numbers.length [.add, .multiply]
30+
operators.any λ ops => evalNumbers equation.numbers ops == equation.testValue
31+
32+
private def solvePart1 (equations : List Equation) : Int :=
33+
equations.filter canEquationPossiblyBeTrue |>.sumBy (λ e => e.testValue)
34+
35+
def parseAndSolvePart1 (s : String): Except String Int := parseEquations s |>.map solvePart1
36+
37+
#guard parseAndSolvePart1 exampleInput == Except.ok 3749
38+
39+
-- Part 2
40+
41+
private def solvePart2 (equations : List Equation) : Int := sorry
42+
43+
def parseAndSolvePart2 (s : String): Except String Int := parseEquations s |>.map solvePart2
44+
45+
-- #guard parseAndSolvePart2 exampleInput == Except.ok -1

Aoc2024/Day07/Types.lean

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
structure Equation where
2+
testValue : Int
3+
numbers : List Int
4+
deriving Repr, BEq, Hashable, Inhabited
5+
6+
inductive Operator where
7+
| add
8+
| multiply
9+
deriving Repr, BEq, Hashable, Inhabited
10+
11+
def Operator.all : List Operator := [Operator.add, Operator.multiply]

Aoc2024/Day07/inputs/example.txt

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
190: 10 19
2+
3267: 81 40 27
3+
83: 17 5
4+
156: 15 6
5+
7290: 6 8 6 15
6+
161011: 16 10 13
7+
192: 17 8 14
8+
21037: 9 7 18 13
9+
292: 11 6 16 20

0 commit comments

Comments
 (0)