Skip to content

Commit

Permalink
day 3 part 2 with no tidying yet!
Browse files Browse the repository at this point in the history
  • Loading branch information
mdr committed Dec 3, 2024
1 parent 81c718f commit d409a20
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 15 deletions.
2 changes: 1 addition & 1 deletion Aoc2024/Day03/Main.lean
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ def solve (name: String) (inputPath: String) : IO Unit := do
IO.println name
let input <- IO.FS.readFile inputPath
IO.println s!"Part 1: {solvePart1 input}"
-- IO.println s!"Part 2: {<- parseAndSolvePart2 input}"
IO.println s!"Part 2: {solvePart2 input}"

def main : IO Unit := do
IO.println "Day 03"
Expand Down
46 changes: 32 additions & 14 deletions Aoc2024/Day03/Solve.lean
Original file line number Diff line number Diff line change
Expand Up @@ -6,40 +6,58 @@ open Regex (Match Captures)

inductive Instruction where
| mul (n m : Nat) : Instruction
-- | do : Instruction
-- | dont: Instruction
| do : Instruction
| dont: Instruction
deriving instance BEq, Hashable, Repr for Instruction

def mulRegex: Regex := regex% r"mul\((\d+),(\d+)\)"
def instructionRegex: Regex := regex% r"mul\((\d+),(\d+)\)|do\(\)|don't\(\)"

def matchToNat (m : Match) : Option Nat := m.toNat?

def optMatchToNat (m : Option Match) : Option Nat := m >>= matchToNat

def matchesToNatPair (ms : Array (Option Match)): Option Instruction :=
def matchesToInstruction (ms : Array (Option Match)): Option Instruction :=
match ms.toList with
| [some m1, some m2] => Instruction.mul <$> matchToNat m1 <*> matchToNat m2
| _ => none

def capturesToNatPair (captures: Captures) : Option Instruction :=
matchesToNatPair captures.groups
def capturesToInstruction (captures: Captures) : Option Instruction :=
if captures.fullMatch == "do()" then some Instruction.do
else if captures.fullMatch == "don't()" then some Instruction.dont
else matchesToInstruction captures.groups

def findMatches (s : String) : List Instruction :=
Regex.all_captures s mulRegex |>.toList |>.bind (fun captures => captures |> capturesToNatPair |> Option.toList)
def findInstructions (s : String) : List Instruction :=
Regex.all_captures s instructionRegex |>.toList |>.bind (fun captures => captures |> capturesToInstruction |> Option.toList)

#guard findMatches "mul(1,2) mul(3,4)" == [Instruction.mul 1 2, Instruction.mul 3 4]
#guard findInstructions "mul(1,2) mul(3,4)" == [Instruction.mul 1 2, Instruction.mul 3 4]
#guard findInstructions "do()" == [Instruction.do]
#guard findInstructions "don't()" == [Instruction.dont]

def solvePart1 (s : String) : Int := findMatches s |>.sumBy (fun
def solvePart1 (s : String) : Int := findInstructions s |>.sumBy (fun
| Instruction.mul n m => n * m
| _ => 1
)

#guard solvePart1 exampleInput = 161

private def solvePart2 (things : List Int) : Int := sorry
private def filterInstructions (enabled : Bool) : List Instruction -> List Instruction
| List.nil => []
| List.cons (Instruction.mul m n) rest =>
if enabled then List.cons (Instruction.mul m n) (filterInstructions enabled rest)
else filterInstructions enabled rest
| List.cons Instruction.do rest => filterInstructions true rest
| List.cons Instruction.dont rest => filterInstructions false rest

def instrRegex := regex% r"mul\((\d+),(\d+)\)|do()\)"
#eval Regex.all_captures "mul(1,2) do()" instrRegex
#eval findInstructions "xmul(2,4)&mul[3,7]!^don't()_mul(5,5)+mul(32,64](mul(11,8)undo()?mul(8,5))" |> filterInstructions true

def solvePart2 (s : String) : Int := s |> findInstructions |> filterInstructions true |> List.sumBy (fun
| Instruction.mul n m => n * m
| _ => 1
)

#eval solvePart2 "xmul(2,4)&mul[3,7]!^don't()_mul(5,5)+mul(32,64](mul(11,8)undo()?mul(8,5))"

#guard solvePart2 "xmul(2,4)&mul[3,7]!^don't()_mul(5,5)+mul(32,64](mul(11,8)undo()?mul(8,5))" == 48

def parseAndSolvePart2 (s : String): Except String Int := parseThings s |>.map solvePart2

-- #guard parseAndSolvePart2 exampleInput == Except.ok 4

0 comments on commit d409a20

Please sign in to comment.