Year 2015 Day 6 Part 2
This commit is contained in:
parent
20dca6b098
commit
472dc28c3b
1 changed files with 76 additions and 20 deletions
|
@ -203,35 +203,77 @@ 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.
|
||||
|
||||
```idris
|
||||
applyCommand : Has IO fs =>
|
||||
{rows, cols : Nat} -> Grid rows cols (IORef Bool) -> Command rows cols -> Eff fs ()
|
||||
applyCommand xs (MkCmd action range) =
|
||||
let cells = extractRange range xs
|
||||
in case action of
|
||||
On => Lazy.traverse_ (`writeIORef` True) cells
|
||||
Off => Lazy.traverse_ (`writeIORef` False) cells
|
||||
Toggle => Lazy.traverse_ (`modifyIORef` not) cells
|
||||
applyCommand : Has IO fs =>
|
||||
{rows, cols : Nat} -> Grid rows cols (IORef Bool) -> Command rows cols -> Eff fs ()
|
||||
applyCommand xs (MkCmd action range) =
|
||||
let cells = extractRange range xs
|
||||
in case action of
|
||||
On => Lazy.traverse_ (`writeIORef` True) cells
|
||||
Off => Lazy.traverse_ (`writeIORef` False) cells
|
||||
Toggle => Lazy.traverse_ (`modifyIORef` not) cells
|
||||
```
|
||||
|
||||
Apply a list of commands to our `Grid` of `IORef`s, doing some debug logging along the way.
|
||||
|
||||
```idris
|
||||
applyCommands : Has IO fs => Has Logger fs =>
|
||||
{rows, cols : Nat} -> Grid rows cols (IORef Bool) -> 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 "Applying command \{show idx}/\{show len}: \{show x}"
|
||||
applyCommand grid x
|
||||
applyCommands' (S idx) len xs
|
||||
export
|
||||
applyCommands : Has IO fs => Has Logger fs =>
|
||||
{rows, cols : Nat} -> Grid rows cols (IORef Bool) -> 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 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
|
||||
```
|
||||
|
||||
## Day functions
|
||||
|
@ -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
|
||||
-->
|
||||
|
|
Loading…
Add table
Reference in a new issue