Better late than never!#

I’ve never done Advent of Code, which is a series of Christmas themed programming challenges. I’m always looking for ways to strengthen my Python so time to join the game. A new puzzle is released every day and I’m 12 days behind so let’s get started!

The Chief Historian is missing!#

He hasn’t been seen in months and we need to find him before the big day when the sleigh goes off.

We have to reconcile two lists of station ID’s and our first task is to calculate the distance between them.

Their example list is:

3   4
4   3
2   5
1   3
3   9
3   3

They explain the process and get the smallest numbers from both lists and then calculating the distance. We would then add up all the distances from both lists.

Before we start#

Let’s figure out the things I need right off the bat. I need to read this input text file, split it up and add the left side and right side to their own arrays. I’ll create two lists. Afterwards I’ll read the file line by line and add them to both lists after splitting it up. I had to account for empty lines by checking the length of the split output and cast to ints.

leftSide = []
rightSide = []

with open("input.txt", "r") as file:
    for line in file:
        numbers = (line.split())
        if len(numbers) > 0:
            leftSide.append(int(numbers[0]))
            rightSide.append(int(numbers[1]))

Instead of making my own constant O(1) sorting function, I’m gonna make it easier for me. let’s make Python do that for us.

leftSide.sort()
rightSide.sort()

Now that they are sorted, let’s calculate the distance between the numbers. I’ll create an empty list, iterate through the left list and add the absolute value of the difference of the values in the lists. Python has a nice sum function which will add the values in a list(Python is hacky sometimes and I love it.)

distances = []
for i in range(len(leftSide)):
    distances.append(abs(leftSide[i] - rightSide[i]))

total = sum(distances)
print(total)

This will give us a total number of 1189304 after running the script.

Second part#

These distances don’t give us too much details for the chief’s wherabouts but you find that some of the values from the left list appear multiple times in the right list. We now need to apply a similarity score based on these frequencies.

3 in the left list appears 3 times in the right list so its similarity score will be 3*3=9.

My thought here was maps! Or in this case a dict, something that will help me map the right lists’ values from a frequency count.

freq = {}
for i in rightSide:
    freq[i] = freq.get(i,0) + 1

Using the dicts’ get function, I’m assigning the value of the right to either 0 if it’s not found and adding 1 if it is. I’ve mapped all the values based on their frequency in the right lists.

Just to be fancy, I’m gonna use list comprehenstion to multiply the values on the left side times the frequency from the right list. I’m using get with 0 to handle values that aren’t in the right list. Once that’s done, we can print the sum and I get my answer of 24349736

similarities = [leftSide[i]*freq.get(leftSide[i],0) for i in range(len(leftSide))]
print(sum(similarities))

We are now one step closer to finding the Chief Historian… once I know what the numbers mean, Mason.

Disclaimer#

I’m making these posts to indicate my thought process, but I completely encourage people to try other variations. There’s a Collections library that could help with the frequency counting but I like simpler solutions, using less libraries if I can avoid it. If you just copy these answers and post them to your account, you do you bro.