Skip to content
4 changes: 3 additions & 1 deletion AdventOfCode2020.cabal
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ cabal-version: 1.12
--
-- see: https://github.com/sol/hpack
--
-- hash: 24cbc4fea003cd6fb1589dae73fa50ce21efce6b103444f09e22b4490e9b7ee6
-- hash: c776df2c7388f0018c9a5988ce515debb8e3d8c2349f47541399322c6a62ae17

name: AdventOfCode2020
version: 2.0.2.0
Expand Down Expand Up @@ -41,6 +41,7 @@ library
Day08.Utils
Day09.Solution
Day09.Utils
Day11.Solution
Practice.Foldable
Template.Solution
other-modules:
Expand Down Expand Up @@ -75,6 +76,7 @@ test-suite AdventOfCode2020-test
Day08.UtilsSpec
Day09.SolutionSpec
Day09.UtilsSpec
Day11.SolutionSpec
Practice.FoldableSpec
Template.SolutionSpec
Paths_AdventOfCode2020
Expand Down
14 changes: 9 additions & 5 deletions src/Advent/Utils.hs
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,12 @@ import Data.List (tails)
isBetween :: Ord a => a -> a -> a -> Bool
isBetween lower upper target = target >= lower && target <= upper

occurrences :: Eq a => a -> [a] -> Int
occurrences target = length . filter (target ==)
occurrences :: (Foldable t, Eq a) => a -> t a -> Int
occurrences target = foldr go 0
where
go value
| value == target = succ
| otherwise = id
Comment on lines -8 to +13
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Generalized this function to work with Foldables including Data.Map


readInt :: String -> Int
readInt n = read n :: Int
Expand All @@ -22,6 +26,6 @@ combinations n xs =
ys <- combinations (pred n) xs'
]

fromRightOrError' :: Show a => Either a b -> b
fromRightOrError' (Left x) = error (show x)
fromRightOrError' (Right x) = x
fromRightOrShowError :: Show a => Either a b -> b
fromRightOrShowError (Left x) = error (show x)
fromRightOrShowError (Right x) = x
Comment on lines -25 to +31
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was lookin' for a name for this thing. This is inspired by Debug.Trace.traceShow

6 changes: 3 additions & 3 deletions src/Day07/Solution.hs
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,15 @@ module Day07.Solution
)
where

import Advent.Utils (fromRightOrError', readInt)
import Advent.Utils (fromRightOrShowError, readInt)
import qualified Data.Map.Strict as Map
import Text.Parsec

part1 :: String -> String
part1 = show . pathsToTarget "shiny gold" . fromRightOrError' . parseRules
part1 = show . pathsToTarget "shiny gold" . fromRightOrShowError . parseRules

part2 :: String -> String
part2 = show . countBags "shiny gold" . asTree . fromRightOrError' . parseRules
part2 = show . countBags "shiny gold" . asTree . fromRightOrShowError . parseRules

type Bag = String

Expand Down
6 changes: 3 additions & 3 deletions src/Day08/Solution.hs
Original file line number Diff line number Diff line change
Expand Up @@ -13,18 +13,18 @@ module Day08.Solution
)
where

import Advent.Utils (fromRightOrError', readInt)
import Advent.Utils (fromRightOrShowError, readInt)
import Data.Either (isRight)
import qualified Data.IntMap.Strict as IntMap
import qualified Data.IntSet as IntSet
import Day08.Utils (asIntMap, fromLeftOrError)
import Text.Parsec

part1 :: String -> String
part1 = show . programAcc . fromLeftOrError . runProgram initialState . fromRightOrError' . parseInstructions
part1 = show . programAcc . fromLeftOrError . runProgram initialState . fromRightOrShowError . parseInstructions

part2 :: String -> String
part2 = show . programAcc . fromRightOrError' . fixProgram initialState . fromRightOrError' . parseInstructions
part2 = show . programAcc . fromRightOrShowError . fixProgram initialState . fromRightOrShowError . parseInstructions

data Sign = Plus | Minus deriving (Show, Eq)

Expand Down
246 changes: 246 additions & 0 deletions src/Day11/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,246 @@
## Day 11: Seating System

Your plane lands with plenty of time to spare. The final leg of your journey is a ferry that goes directly to the tropical island where you can finally start your vacation. As you reach the waiting area to board the ferry, you realize you're so early, nobody else has even arrived yet!

By modeling the process people use to choose (or abandon) their seat in the waiting area, you're pretty sure you can predict the best place to sit. You make a quick map of the seat layout (your puzzle input).

The seat layout fits neatly on a grid. Each position is either floor ( `.` ), an empty seat ( `L` ), or an occupied seat ( `#` ). For example, the initial seat layout might look like this:

```
L.LL.LL.LL
LLLLLLL.LL
L.L.L..L..
LLLL.LL.LL
L.LL.LL.LL
L.LLLLL.LL
..L.L.....
LLLLLLLLLL
L.LLLLLL.L
L.LLLLL.LL
```

Now, you just need to model the people who will be arriving shortly. Fortunately, people are entirely predictable and always follow a simple set of rules. All decisions are based on the _number of occupied seats_ adjacent to a given seat (one of the eight positions immediately up, down, left, right, or diagonal from the seat). The following rules are applied to every seat simultaneously:

- If a seat is _empty_ ( `L` ) and there are _no_ occupied seats adjacent to it, the seat becomes _occupied_ .
- If a seat is _occupied_ ( `#` ) and _four or more_ seats adjacent to it are also occupied, the seat becomes _empty_ .
- Otherwise, the seat's state does not change.

Floor ( `.` ) never changes ; seats don't move, and nobody sits on the floor.

After one round of these rules, every seat in the example layout becomes occupied:

```
#.##.##.##
#######.##
#.#.#..#..
####.##.##
#.##.##.##
#.#####.##
..#.#.....
##########
#.######.#
#.#####.##
```

After a second round, the seats with four or more occupied adjacent seats become empty again:

```
#.LL.L#.##
#LLLLLL.L#
L.L.L..L..
#LLL.LL.L#
#.LL.LL.LL
#.LLLL#.##
..L.L.....
#LLLLLLLL#
#.LLLLLL.L
#.#LLLL.##
```

This process continues for three more rounds:

```
#.##.L#.##
#L###LL.L#
L.#.#..#..
#L##.##.L#
#.##.LL.LL
#.###L#.##
..#.#.....
#L######L#
#.LL###L.L
#.#L###.##
```

```
#.#L.L#.##
#LLL#LL.L#
L.L.L..#..
#LLL.##.L#
#.LL.LL.LL
#.LL#L#.##
..L.L.....
#L#LLLL#L#
#.LLLLLL.L
#.#L#L#.##
```

```
#.#L.L#.##
#LLL#LL.L#
L.#.L..#..
#L##.##.L#
#.#L.LL.LL
#.#L#L#.##
..L.L.....
#L#L##L#L#
#.LLLLLL.L
#.#L#L#.##
```

At this point, something interesting happens: the chaos stabilizes and further applications of these rules cause no seats to change state! Once people stop moving around, you count _`37`_ occupied seats.

Simulate your seating area by applying the seating rules repeatedly until no seats change state. _How many seats end up occupied?_

## Part Two

As soon as people start to arrive, you realize your mistake. People don't just care about adjacent seats - they care about _the first seat they can see_ in each of those eight directions!

Now, instead of considering just the eight immediately adjacent seats, consider the _first seat_ in each of those eight directions. For example, the empty seat below would see _eight_ occupied seats:

```
.......#.
...#.....
.#.......
.........
..#L....#
....#....
.........
#........
...#.....
```

The leftmost empty seat below would only see _one_ empty seat, but cannot see any of the occupied ones:

```
.............
.L.L.#.#.#.#.
.............
```

The empty seat below would see _no_ occupied seats:

```
.##.##.
#.#.#.#
##...##
...L...
##...##
#.#.#.#
.##.##.
```

Also, people seem to be more tolerant than you expected: it now takes _five or more_ visible occupied seats for an occupied seat to become empty (rather than _four or more_ from the previous rules). The other rules still apply: empty seats that see no occupied seats become occupied, seats matching no rule don't change, and floor never changes.

Given the same starting layout as above, these new rules cause the seating area to shift around as follows:

```
L.LL.LL.LL
LLLLLLL.LL
L.L.L..L..
LLLL.LL.LL
L.LL.LL.LL
L.LLLLL.LL
..L.L.....
LLLLLLLLLL
L.LLLLLL.L
L.LLLLL.LL
```

```
#.##.##.##
#######.##
#.#.#..#..
####.##.##
#.##.##.##
#.#####.##
..#.#.....
##########
#.######.#
#.#####.##
```

```
#.LL.LL.L#
#LLLLLL.LL
L.L.L..L..
LLLL.LL.LL
L.LL.LL.LL
L.LLLLL.LL
..L.L.....
LLLLLLLLL#
#.LLLLLL.L
#.LLLLL.L#
```

```
#.L#.##.L#
#L#####.LL
L.#.#..#..
##L#.##.##
#.##.#L.##
#.#####.#L
..#.#.....
LLL####LL#
#.L#####.L
#.L####.L#
```

```
#.L#.L#.L#
#LLLLLL.LL
L.L.L..#..
##LL.LL.L#
L.LL.LL.L#
#.LLLLL.LL
..L.L.....
LLLLLLLLL#
#.LLLLL#.L
#.L#LL#.L#
```

```
#.L#.L#.L#
#LLLLLL.LL
L.L.L..#..
##L#.#L.L#
L.L#.#L.L#
#.L####.LL
..#.#.....
LLL###LLL#
#.LLLLL#.L
#.L#LL#.L#
```

```
#.L#.L#.L#
#LLLLLL.LL
L.L.L..#..
##L#.#L.L#
L.L#.LL.L#
#.LLLL#.LL
..#.L.....
LLL###LLL#
#.LLLLL#.L
#.L#LL#.L#
```

Again, at this point, people stop shifting around and the seating area reaches equilibrium. Once this occurs, you count _`26`_ occupied seats.

Given the new visibility method and the rule change for occupied seats becoming empty, once equilibrium is reached, _how many seats end up occupied?_

## Link

[https://adventofcode.com/2020/day/11][1]

[1]: https://adventofcode.com/2020/day/11
Loading