Categories
Tech

Advent of Code 2020 days 12 & 13

Day 12

The first part of this day’s challenge was primarily comprised of vector maths. From the text, it comes that the current position relative to the starting point, and the current bearing need to be controlled.

Keeping the position & bearing

From there the first part was analysing the input data and changing position when NSEW commands appear. Following this was correcting the bearings. The input data only has multiples of 90, which means once the bearings are corrected no function is needed to move in diagonals. By correcting the bearing at the beginning of the routine the move Forward instructions can use the NSEW instructions, with no need to create additional subroutines or otherwise.

Small REGEX

The regex matches all lines of the input due to the given format. It avoids needing to convert between data structures with split / join and provides the ability to include data validation should it be required. The do-if instructions replace Switch cases while maintaining readability (as opposed to continuous if blocks). Finally, the result requires to find the Manhattan Distance, which is the sum of the absolute values of the coordinates.

Day 13

This day input was on 2 rows, where the data did not have the same format. The first row was a timestamp, and the 2nd row had a list of bus numbers. In order to process this, I decided to use an array temporarily, such that I could then access the input data outside of the readline loop.

Odd data formats

@buses2 is for the 2nd part of the day’s challenge. The bus numbers are not provided in increasing order. However, it makes sense to assume that smaller bus numbers will come by more regularly hence sorting the @buses array. Because we are only interested in buses active that day, we can get rid of all the elements containing an x. Following that we look for the first time at which a bus arrives.

Part 1 loop

The loop is fairly simple:
First check if a bus arrives at the given time. If not, increase time by 1. Should a bus arrive, get the bus id and find how long it took to wait for this bus. Since now there is a definite departure, increase $departure in order to exit the while loop.

The second part of the challenge is to find at which time the buses depart at their respective offsets. Given I don’t have the list ordering use of @buses2 comes up. (Could also have read the file into memory again). The naive solution is to check timestamps and then use nested if blocks to see if at the next level a bus arrives. However, the first bus ID is most likely not 1. This means there are N failed tests before hitting the first bus. The same at each subsequent level. This is solved by using a bit of modulo arithmetic: if the first bus is 7, then the next time it arrives will be at time 14, then 21. By moving to those positions directly, negative tests are then only involved with the next bus in the list.

The hash table used a key:value pair system comprised of position:bus id for all buses where the id exists. The above image shows some debugging elements. For each bus we are going to look for the point at which a time stamp hits the next bus in the list. The moment a bus is found at the given time stamp (if condition) exit the while loop and multiply the amount timestamp is incremented by, such that all previous bus conditions remain used. At the final level, the print statement provides the timestamp at which all buses are found.

Categories
Tech

Advent of Code 2020 days 10 & 11

Day 10

Todays challenge required analysing a list of numbers (output units). The first thing was to place these numbers in an array, sort it, and add 0 (initial output unit) at the begining of the array. I couldn’t find a nice way to regex this one, most likely because the challenge did not involve text processing. Given the list was sorted from the previous steps, and I trust the data to not be poisoned with impossible elements, I used a simple foreach loop to check wether the increase in (output units) is of 1 or 3.

Possibly the fastest solution this year

Part 2 was a bit more of a roller coaster. My initial thoughts involved combinations and permutations. Permutations and combinations are nice and all, but figuring out the adequate mechanisms was beyond my pay grade. I initially wanted to try arriving at the end and work my way from the start, but this doesn’t work as the only fixed point is the start with 0 (output units). By using a hash with the output of the devices as the key and 0 as the initial value, it is possible to traverse the keys in order such that the value is how many routes there are up to that output. The initial output, 0, has only 1 route and is therefore defined before the loop.

Simple iteration

By checking at each key if the next 3 integers are keys, no routes are forgotten, and no need to look at possible combinations of selected or non selected devices which still provide a valid route. The twist at part 2 made it a rather challenging day, while keeping the initial part accessible for people switching languages, brushing up on them, or simply starting out in code.

Day 11

It looks like day 11 is the day my over engineering ways start making sense. Until they don’t. Had to call it a day after spending far too long on part 1. This challenge was fairly interesting, in essence an implementation of the game of life. I started off by selecting the data structure. Against my better judgement, or perhaps due to the better judgement I went with an array of arrays. Or… array of array refs.

Processing input data

Here I already have 2 variables which will help later on for the data processing. After some testing, they are in scope of the subroutine and don’t need to be passed as arguments (trivial to do for the testing if that were the case). The next part was writing the test subroutine. I wanted the subroutine to perform the change on the waiting room and return if it had made a change. At just over 100 lines, this is the engine for this problem.

Some basic definitions
All the edge cases

Each position in the map can have 1 of 3 states: Empty chair, Occupied chair or floor. Floor is never occupied so doesn’t change. Because the mutations all happen simultaneously, I need to check if the adjacent chairs are occupied. However, given some chairs may change states and affect this decision I needed the 2 additional states: Future Empty (FE) and Future Used (FU). By using return 0 I was able ti limit the number of checks done on each chair although that is not necessarily the most elegant solution.

There are only edge cases

Same logic as before, except in this case rather than returning 0, counter went up and was analysed at the end. Of course, if the state is neither empty or occupied, then the floor is lava.

The actual calculation

After a few too many infinite loops (see the interesting debugging tool from the 00’s) this do-while loop provided the solution. I had initially tried $changes++ if testchange($i,$j); but most likely that wasn’t working due to other factors leading to the infinite loops. Used a tiny regex, just for the sake of it. That initial loop does the entire control, as it checks each cell if it will change, thus changing the variable for the control. The second for loop simply standardises the content being worked on.

Finally, the solution to the task at hand:

8/174 lines, or approx 6%

Because this happens after the do-while block the state of the waiting room won’t change. From there it’s a simple nested loop to check the number of occupied chairs. could have been added to the do while loop with a control block depending on changes being equal to 0. I did not have the patience for part 2… maybe later