10
votes
Day 20: Jurassic Jigsaw
Today's problem description: https://adventofcode.com/2020/day/20
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>
Part A has some interesting tricks to it. Part B is uh... Part B will be interesting. Some of the shortcuts I used for part A definitely won't help with part B.
Edit: I made a ton of progress on part B, but I've had a headache all day and this isn't helping. I'll probably come back to this one in the future. We'll see how I'm feeling later tonight
Day 20 Part A – Python
For this one I use the same trick I used on day 5 (replacing the text with binary), Then I also reverse the strings, and I convert them to decimal. That gives me 8 numbers for each tile that I can then compare.
From there, I compare each tile's borders to each other tile. The ones that only match up 4 times (2 borders x2 because flipped) are the corner pieces.
Tips and Commentary
For part A you only really need to care about the borders
The borders can be converted into numbers a few different ways
Python
Repo Link
Part 1
I almost didn't do this one because I did not want to implement flipping and rotating (just tedious)... but then I realized that for Part 1, you do not need to actually perform the flips and rotations... you can just hash the edges. Once you hash the edges (ie. top, bottom, left, right, and their reversed versions) and track which tiles correspond to those edges, then you will see that edges will have a mapping to which tiles are neighbors. After you create this mapping, you can then count how many matched edges each tile has. The corners will have exactly
2
neighbors, so you can pick them out easily.That is how I avoided having to actually flip or rotate the pieces and generate the actual image... Unfortunately, I think Part 2 may require actually forming the image, so I will probably go to sleep... I may or may not attempt Part 2 in the morning.
I finally finished both parts of today's!!! woo! part 2 took a very long time lol, at least the program runs quickly.
This was such a hard problem imo.
Repo link: https://github.com/OrangeBacon/adventofcode2020/blob/main/src/days/day20.rs
Notes:
For part 1 only the edges of each tile needs to be considered, as each edge is included either once or twice, it is possible to get a single way of organising the tiles. To make the edge comparison nicer, the `#` can be replaced with `1` and `.` with `0` and then each edge can be converted to a binary number. To make the rotations easier, I read those numbers clockwise round the edge of each tile, rather than left to right. For this part, the image doesn't need to be constructed as the corners will be the tiles with two edges that are included twice. For part 2, the orientation of the image doesn't matter, so it can be started from any corner. The input is small enough that all rotations of each tile can be checked to find the correct rotation, rather than trying to find a clever way of working out the tile rotations. For finding the monster, I search through the complete image for one monster, if it is not found, i rotate the whole image, repeat for all 4 orientations, flip and repeat again, to find the one orientation and flip when one monster is found. I then search through the input for all monsters, keeping a set of all coordinates included in monsters and subtract the size of that set from the total number of `#` in the input.Rust part 1 + 2 (336 lines)
Well, damn.
This was a tough one.
The code isn't exactly clean, but it does work.
Fair warning, the formatting is rather horrid, but I'm hoping the comments will make it more readable.
Parts 1 and 2
Well, I got part 1 much faster than I thought I would. Unfortunately, part 2 negates my shortcut for part 1, so I'll have to come back to this.
Part 1
Ignoring the need to actually make the image seemed like the move here. Part 2 is making me regret this lol.
Rust
Absolute mess, but finally got it. I'll clean this up some day, probably after AoC.
Rust
Question
I'll only have a bit of time later tonight to work on this, so a question to help me speed things along later:
Spoilers?
Does anyone know if each tile edge will only match another tile edge exactly once when its in its correct orientation, or do you have to handle duplicates? In other words, can one tile edge match 1 other tile edge in one orientation, but when rotated/flipped it then correctly matches all 4 tiles around it?Spoilers
I don't know if it holds for part B yet, but at least for my data set that assumption held for what I considered important for part A.
Spoiler?
Yeah, I only ever checked "the new tile" against "the current tile", without also checking that other neighbours matched, and it works. I did some sanity-checking to be sure, and it seems there are never more than two tiles that could match each other.This one was brutal—storing the tiles as sets of coordinates helped a lot.