Seating System
Tags: adventofcode, algorithms, computerscience, programming
Published: 2022-04-04 18:29:34

## [Advent of Code 2020 Day 11](https://adventofcode.com/2020/day/11)

## [Try the simulator](https://aocseatingsystem.rmion.repl.co/)
![Simulator of Part 1](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/neb2cmmm95a5kzxddeib.gif)

## Task: Solve for X where...
```
X = the number of seats occupied once seat occupation no longer changes
```

### Example input
```
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
```
It represents:
- A waiting area where
- `.` is the floor
- `L` is an empty seat
- `#` is an occupied seat

## Part 1
1. This puzzle type again?
2. How does this puzzle compare?
3. Writing a working algorithm
4. Build a simulator

### This puzzle type again?
- [2021 Day 25: Sea Cucumbers](https://adventofcode.com/2021/day/25) featured a constant grid size with toggling tiles that eventually stopped changing
- [2021 Day 22: Reactor Reboot](https://adventofcode.com/2021/day/22) featured toggling-state cubes in a 3D space
- [2021 Day 20: Trench Map](https://adventofcode.com/2021/day/20) featured a 2D infinite grid with toggling tile states
- [2021 Day 11: Dumbo Octopus](https://adventofcode.com/2021/day/11) featured a constant 2D grid with toggling tiles that each eventually had the same state
- [2021 Day 5: Hydrothermal Venture](https://adventofcode.com/2021/day/5) featured an increasingly revealed - albeit of a constant size - grid whose tiles remained 'unmarked' or increased in value
- [2021 Day 4: Giant Squid](https://adventofcode.com/2021/day/4) featured several constant 2D grids where tiles became increasingly toggled as marked
- [2020 Day 24: Lobby Layout](https://adventofcode.com/2020/day/24#part2) also featured a 2D infinite grid with toggling tile states
- [2020 Day 17: Conway Cubes](https://adventofcode.com/2020/day/17) featured a 3D infinite grid with toggling cube states

### How does this puzzle compare?
- This puzzle's grid is 2D
- This puzzle's grid remains a constant size
- This puzzle's tiles can be one of 3 states
- This puzzle's tiles eventually stop changing state

### Writing a working algorithm
Set the stage
```
Process the input into an array of arrays:
  Split the input at each new line character into an array of strings
  Split each string into an array of characters

Create an array of 8 pairs that represent the coordinates of each cell's adjacent cells
```

Pad the array with a 1-element shell:
```
Turn an array like this:
L.L
.L.
L.L

Into an array like this:
.....
.L.L.
..L..
.L.L.
.....
```

The main loop:
```
Do at least one time, then again only if an array of cells to switch is not empty:
  Empty the array of cells
  For each cell in the grid of seats, except for the bordering cells:
    Check each adjacent cell and accumulate tallies for each of the three possible characters found: . # L
    If the current cell contains an 'L' and the number of '#'s found is 0
      Add the cell's coordinates to the list of switchers with an instruction to change it's value to '#'
    Else, if the current cell contains an '#' and the number of '#'s found is 4 or more
      Add the cell's coordinates to the list of switchers with an instruction to change it's value to 'L'

For each coordinate and instruction set in the list of switchers
  Update the cell in the grid of seats at the current location to the value specified
```

Lastly, calculate the count of occupied seats:
```
For each nested array in the grid of seats
  Accumulate a sum - starting at 0 - of the count of '#' characters in each array

Return the sum
```

### Build a simulator
- This felt like an easy task given how many times I built similar-functioning simulators for the challenges referenced above

[Try the simulator for Part 1](https://aocseatingsystem.rmion.repl.co/)
![Simulator of Part 1](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/neb2cmmm95a5kzxddeib.gif)

## Part 2
1. What a fun twist!
2. Writing newly-needed sub-routines
3. Updating the working algorithm
4. Updating the simulator

### What a fun twist!
Instead of checking the eight adjacent cells:
```
.....
.!!!.
.!S!.
.!!!.
.....
```
We must check in straight lines in all eight directions, until we find a seat or we exceeded the boundary of the room:
```
!.!.!
.!!!.
!!S!!
.!!!.
!.!.!
```

## Writing newly-needed sub-routines
1. Check if the next-checked cell is within the boundary of the room
2. Recursively check the next cell along a straight line until we find a seat or exceed the boundary of the room

#### Function: `isAtAValidLocation()`
```
Expects two parameters
  1. Row index
  2. Column index

Return false, unless:
  Both indices are greater than or equal to 0
  And Row is less than the length of the number of arrays in the outer-most array
  And Column is less than the length of any nested array (they are all the same length)
```

#### Function: `firstVisibleSeat()`
```
Expects two parameters
  1. A pair of coordinates representing the direction to travel from an origin point
  2. A pair of coordinates representing the originating row and column indices

Return '.' to indicate 'No seat found', unless:
  The next cell along the path 'isAtAValidLocation'
  If the next cell is at a valid location
    And its value is '.'
      Continue along the path
    Else - its value is not '.'
      Return its value - being either 'L' or '#' 
```

### Updating the working algorithm
- Same setup to process the input into an array
- Removed the process of padding the array

The new main loop:
```
Do at least one time, then again only if an array of cells to switch is not empty:
  Empty the array of cells
  For each cell in the grid of seats:
    Continue along a straight line - starting from each adjacent cell and continuing until either a seat is found or reaching the boundary of the room - and accumulate tallies for each of the three possible characters found: . # L
    If the current cell contains an 'L' and the number of '#'s found is 0
      Add the cell's coordinates to the list of switchers with an instruction to change it's value to '#'
    Else, if the current cell contains an '#' and the number of '#'s found is 5 or more
      Add the cell's coordinates to the list of switchers with an instruction to change it's value to 'L'

For each coordinate and instruction set in the list of switchers
  Update the cell in the grid of seats at the current location to the value specified
```

### Updating the simulator
Aside from copy-pasting the code from my algorithm into the page's script, this required adding logic to toggle which part's function to call based on which button was pressed.

I got sloppy with my copy-pasting and created a small headache to troubleshoot.

Overall, no big deal.

[Try the simulator for Part 2](https://aocseatingsystem.rmion.repl.co/)
![Simulator of Part 2](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/m85frm96rax0pvus8k6s.gif)