Year 2015 Day 6 Part 2

This commit is contained in:
Nathan McCarty 2025-01-10 14:15:07 -05:00
parent 20dca6b098
commit 472dc28c3b

View file

@ -203,6 +203,11 @@ purify grid = traverse (traverse readIORef) grid
## Solver Functions
### Part 1 Variants
```idris
namespace Part1
```
Apply a given command to our `Grid` of `IORef`s.
Use our `extractRange` function to extract all the `IORef`s in the grid cells touched by our `Range` and then traverse an appropriate mutating action over them.
@ -221,6 +226,7 @@ applyCommand xs (MkCmd action range) =
Apply a list of commands to our `Grid` of `IORef`s, doing some debug logging along the way.
```idris
export
applyCommands : Has IO fs => Has Logger fs =>
{rows, cols : Nat} -> Grid rows cols (IORef Bool) -> List (Command rows cols)
-> Eff fs ()
@ -229,7 +235,43 @@ applyCommands grid xs = applyCommands' 0 (length xs) xs
applyCommands' : (idx, len : Nat) -> List (Command rows cols) -> Eff fs ()
applyCommands' idx len [] = pure ()
applyCommands' idx len (x :: xs) = do
debug "Applying command \{show idx}/\{show len}: \{show x}"
debug "Part 1 - Applying command \{show idx}/\{show len}: \{show x}"
applyCommand grid x
applyCommands' (S idx) len xs
```
### Part 2 Variants
```idris
namespace Part2
```
Much the same as above, but instead we apply the part 2 rules to a `Grid` of `Nat`.
```idris
applyCommand : Has IO fs =>
{rows, cols : Nat} -> Grid rows cols (IORef Nat) -> Command rows cols -> Eff fs ()
applyCommand xs (MkCmd action range) =
let cells = extractRange range xs
in case action of
On => Lazy.traverse_ (`modifyIORef` (+ 1)) cells
Off => Lazy.traverse_ (`modifyIORef` (`minus` 1)) cells
Toggle => Lazy.traverse_ (`modifyIORef` (+ 2)) cells
```
Identical to above, except for using our part 2 `applyCommand`. We can use the same name here because we have the two variants behind namespaces and Idris can disambiguate via the types.
```idris
export
applyCommands : Has IO fs => Has Logger fs =>
{rows, cols : Nat} -> Grid rows cols (IORef Nat) -> List (Command rows cols)
-> Eff fs ()
applyCommands grid xs = applyCommands' 0 (length xs) xs
where
applyCommands' : (idx, len : Nat) -> List (Command rows cols) -> Eff fs ()
applyCommands' idx len [] = pure ()
applyCommands' idx len (x :: xs) = do
debug "Part 2 - Applying command \{show idx}/\{show len}: \{show x}"
applyCommand grid x
applyCommands' (S idx) len xs
```
@ -254,8 +296,22 @@ part1 = do
pure $ (lights_on, commands)
```
### Part 2
This time, use an initial `Grid` with all brightness values at 0, apply our list of preparsed commands using our part 2 `applyCommands` function (selected via the type signature), and then add up the brightnesses.
```idris
part2 : List (Command 999 999) -> Eff (PartEff String) Nat
part2 commands = do
grid <- ioGrid 999 999 (the Nat 0)
applyCommands grid commands
grid <- purify grid
let brightness = sum . map sum $ grid
pure brightness
```
<!-- idris
public export
day6 : Day
day6 = First 6 part1
day6 = Both 6 part1 part2
-->