# Advent of Code 2020 Day 11

[2020-12-11]

#development #adventofcode #julia

Previous: Advent of Code 2020 Day 10

Next: Advent of Code 2020 Day 12

## Part 1

Alright, a Conway’s Game of Life/cellular automata problem. Also see AoC 2019 day 24, which I happened to do just a week ago (finally!) in Julia. May as well leverage that code…

I immediately hit a bit of a problem, I used a `BitArray`

for that, while this
is a trinary state (empty seat, filled seat, floor). An enum may be handy here,
let’s see how Julia’s `@enum`

macro works.

```
@enum Ferry empty filled floor
```

Trying to construct an array of Enums is a bit more complicated, since `zeros()`

etc. don’t work. Comprehension it is!

```
board = [floor for j in 1:rows, i in 1:cols]
```

Logic is simple: loop over `board`

, count neighbors, and update. I leverage
Julia’s
views to concisely grab the neighbors (without copying!) and count the filled seats:

```
v = @view board[max(j-1,1):min(j+1,r), max(i-1,1):min(i+1,c)]
n = count(x->x==filled, v)
```

I do, however, make a new copy of the board with each `update`

, rather than
trying to juggle two boards for instance. So I won’t win any allocation prizes.

## Part 2

Is there a clever way to do this? My first thought was an overlay filter, but
no, since we need to actually “walk” away from the seat to find the *first*
seat, filled or not. I’ll at least take advantage of Julia’s array slicing, e.g.:

```
up(board, j, i) = j==1 ? Ferry[] : board[j-1:-1:1, i]
upright(board, j, i) = j==1 || i==size(board,2) ? Ferry[] :
[board[j-x,i+x] for x in 1:min(j-1, size(board,2)-i)]
```

Then it’s just a `reduce()`

call to walk through and find the first seat.

```
firstfilled(v:Vector{Ferry})::Bool = reduce((x,y)->x==floor ? y : x, v; init=floor) == filled
```

Do this for every direction, and we get the number of occupied seats:

```
n = [up,upright,right,downright,down,downleft,left,upleft] .|> f->firstfilled(f(board,j,i)) |> sum
```

Admittedly this solution gets a bit ugly. Maybe there’s some clever topological math we can use instead?