13
votes
Day 11: Seating System
Today's problem description: https://adventofcode.com/2020/day/11
Join the Tildes private leaderboard! You can do that on this page, by entering join code 730956-de85ce0c
.
Please post your solutions in your own top-level comment. Here's a template you can copy-paste into your comment to format it nicely, with the code collapsed by default inside an expandable section with syntax highlighting (you can replace python
with any of the "short names" listed in this page of supported languages):
<details>
<summary>Part 1</summary>
```python
Your code here.
```
</details>
This was a fun one. I love me a good cellular automata.
C#
Part 1
Part 2
Helpers
Commentary
This was a satisfying one. The part1/part2 solvers themselves are identical, aside from the "neighbor list" helper and the "seat-empties" count.
There's definitely a cleaner way to do the line-of-sight search for part 2, but I wanted to get something down quickly.
This one ended up being really annoying. Mostly because I missed one critical part of the rules in part B, so I spend like an hour tracking down a bug that wasn't there. FML.
Oh well, more time spent writing code means more time listening to eurobeat.
And it was an interesting problem, I just wish I had read the instructions more carefully.
Day 11 Part A – Python
For this one I made a list that stored the vector information for one step in each direction. I just stepped through it to find if the seat in each direction was occupied or empty (or out of bounds. It's also important to change the entire grid at the same time. If you overwrite it while you're still working on it, you'll fuck everything up. Rather than checking if my seat arrangement was the same, I just made sure I was using a hashable type and stored a list of hashes which I could compare against
Day 11 Part B – Python
For this one I converted my check surroundings method to keep stepping in a direction until it found a seat or exited a grid.... then after an hour of searching I added a check to make it stop if found an empty seat. I missed that portion of the rules. FFFFFUUUUCCCCCKKKK.I also shoved a couple of debugging tools in there that I made while searching for why my shit wasn't working.
Tips and Commentary
Read the instructions carefully. Read them again. One more time for good measure. If you get stuck, go read the instructions again. Seriously, I wasted like an hour because I misunderstood one of the rules
You can deal with this grid in the same way you dealt with your grid on day 3, reuse your own code shamelessly
Hashing is a technique of converting anything into a unique* number called a hash. If you convert something into a hash and store the hash, you can then compare other objects to that hash. If the hashes match you have the same thing
*Not technically unique, but a good hash function will rarely have duplicates when it shouldn't. These false duplicates are called collisions
Make sure not to update your seat arrangement until you're finished doing all your calculations. If you make changes mid-operation, the incoming or outgoing people will mess up your results
Make sure you don't have your x and y coordinates swapped
Python
I wasn't a big fan of this problem! My solutions are admittedly not the best, but they worked out in the end and they're easy for me to understand. Will definitely look forward to seeing others' better solutions. It was especially difficult for me to debug the program (in one instance, I was missing a critical rule in part B, like @PapaNachos wrote). My incompetent reading strikes again!
Repo link
Part 1
I padded the entire seating matrix with floors, just because I didn't want to have to deal with special cases for the edge seats. Though there probably is just be an entirely easier way to solve this problem, I decided to go with this. Then I used a boolean flag so that I could keep running my function until equilibrium.Part 2
A similar approach to part 1 with padding and a flag system for handling the equilibrium. The important rule I missed was in regards to how an empty seat blocks off the sight of an occupied seat. As a result, I wasted time trying to debug my program.Python
Repo Link
Part 1
This was pretty straightforward. The only trick I used was to pad the grid with extra floor cells to avoid having to do boundary checks.
Part 2
For this part, I only had to modify the threshold for flipping seats and added a
search_direction
function to check for occupied or empty seats in all eight directions (rather than adjacent cells).I was too tired to think of a clean solution for this; I might clean it up tomorrow and usually wait to post until then, but I thought it would be fun to post the completely unedited solutions! Part 1 and part 2 take over 10 and 17 seconds respectively to process my input. :)
I also missed the rule @PapaNachos pointed out, but thankfully it didn't take me long to debug since the example had step-by-step states. Really, the coverage of the examples is a huge part in determining how hard it is for me to solve it; the passport one took me a while because I passed all the examples immediately but failed the actual input in ~5 distinct ways!
(My choice of music was evermore and it kept me distracted enough to go through with my hacky solutions)
Part 1
Part 2
Mit scheme. Went with vectors today.
Part 1 & 2
Rust
Edited to optimize solution. I was originally keeping track of previously seen states with a HashSet thinking it'd be like a Game of Life, but ended up only needing to check when there were zero changes.
Rust
This is driving me mad, I have a solution to part 1 that outputs the correct end result for the test data but a wrong number for the actual input data. I honestly don't know what to even look for, it's a perfect match for the test.
EDIT:
I got it to work by basically redoing the whole thing. I suspect @wycy is right and I accidentally searched a perfectly square-shaped area (rows == columns) while the final input was a rectangular area. I didn't make any assumptions about that, though and thought I determined the height and width correctly in my first attempt, so maybe it was something else? Who cares! It works now!
I'm not printing anything in these solutions but it was fun to see the area fill up in debug mode, I love it when the solution produces a bit of an animation.
Part 1+2 (Python)
Did you perhaps set up a square map but have non-square input data? I see the sample is a 10x10 square but my input was something like 91x97.
I don't think so, but that could be it! Anyway, I just redid the whole thing from scratch and it works, now! No idea why, lol.
Elixir
I went try-hard on this one and defined + documented a
CharGrid
data structure in a separate module, since this kind of input tends to get used a lot in AoC puzzles.I also went a little crazy making several functions that take other functions as arguments to modify their behavior, in order to avoid repeating code as much as possible. The result is questionably readable but runs well, and makes sense to me, at least for the next day or so. 😄
CharGrid data structure
Parts 1 and 2
Messy solution for this one, but part 2 was not as bad as I initially thought.
Part 1
Decided to do memoization again since my nearest neighbor lookup is slow, will probably do it again for the second part since that looks to be even more expensive for my not so great design pattern.
Part 2 additions
Part 2 was actually not too bad since I had split out the neighbor finding code in part 1.
I agree with others, this was a very fun problem in comparison to Day 10, especially part 2. I admit I got a little far behind, I had to take a bit of a break for my own mental health, because I was losing way too much sleep staying up to get these coded. I have today off, and a couple days next week, and basically no plans, so I definitely intend to get caught up as much I can. :)
Part 1
Part 2