After achieving my goal of getting at least one point by placing in the top 100 finishers at some point on Day 1, I was psyched for Day 2.
In addition, this time I was at home where I got to use a monitor and my Kinesis Advantage keyboard.
Part 1
--- Day 2: Corruption Checksum ---
As you walk through the door, a glowing humanoid shape yells in your direction. "You there! Your state appears to be idle. Come help us repair the corruption in this spreadsheet - if we take another millisecond, we'll have to display an hourglass cursor!"
The spreadsheet consists of rows of apparently-random numbers. To make sure the recovery process is on the right track, they need you to calculate the spreadsheet's checksum. For each row, determine the difference between the largest value and the smallest value; the checksum is the sum of all of these differences.
For example, given the following spreadsheet:
5 1 9 5
7 5 3
2 4 6 8
- The first row's largest and smallest values are 9 and 1, and their difference is 8.
- The second row's largest and smallest values are 7 and 3, and their difference is 4.
- The third row's difference is 6.
In this example, the spreadsheet's checksum would be 8 + 4 + 6 = 18.
What is the checksum for the spreadsheet in your puzzle input?
Attempt
I starting panicking a bit because I realized that I couldn’t have new lines in the INPUT variable so the first solution that came to mind was to replace the new lines with commas by going to the end of the line in vim navigation mode Shift-A
, then Delete
then ,
then Escape
. After that, I just used the Vim .
and down arrow to edit each line. I lost some time here which I could have saved by writing a function to hit the advent of code input url and reading that text file.
I also realize that I lost some time because I had NERDTree open in Vim which forced me to take 3 keystrokes instead of 2 to get to the other pane to run my code.
INPUT="3458 3471 163 1299 170 4200 2425 167 3636 4001 4162 115 2859 130 4075 4269,2777 2712 120 2569 2530 3035 1818 32 491 872 113 92 2526 477 138 1360,2316 35 168 174 1404 1437 2631 1863 1127 640 1745 171 2391 2587 214 193,197 2013 551 1661 121 206 203 174 2289 843 732 2117 360 1193 999 2088,3925 3389 218 1134 220 171 1972 348 3919 3706 494 3577 3320 239 120 2508,239 947 1029 2024 733 242 217 1781 2904 2156 1500 3100 497 2498 3312 211,188 3806 3901 261 235 3733 3747 3721 267 3794 3814 3995 3004 915 4062 3400,918 63 2854 2799 178 176 1037 487 206 157 2212 2539 2816 2501 927 3147,186 194 307 672 208 351 243 180 619 749 590 745 671 707 334 224,1854 3180 1345 3421 478 214 198 194 4942 5564 2469 242 5248 5786 5260 4127,3780 2880 236 330 3227 1252 3540 218 213 458 201 408 3240 249 1968 2066,1188 696 241 57 151 609 199 765 1078 976 1194 177 238 658 860 1228,903 612 188 766 196 900 62 869 892 123 226 57 940 168 165 103,710 3784 83 2087 2582 3941 97 1412 2859 117 3880 411 102 3691 4366 4104,3178 219 253 1297 3661 1552 8248 678 245 7042 260 581 7350 431 8281 8117,837 80 95 281 652 822 1028 1295 101 1140 88 452 85 444 649 1247".split(',')
sum = 0
for line in INPUT:
most = -100000
least = 100000
for val in line.split(' '):
num = int(val)
most = max(num, most)
least = min(num, least)
sum = sum + most - least
print sum
I also hard coded the most
and least
variables which I could have easily gotten around by getting the first element in the row. This also ended up costing me debugging time since I started with least too low. I ended up finishing in 6 minutes, 21 seconds with a rank of 450.
Refactoring
This was a good opportunity to clean up my ugly code. I went back and did this the next day. First I tried getting the input automatically using urllib2.urlopen but realized that this required some form of authentication.
After watching someone achieve top 5 on the second part of Day 2 on Youtube, I decided to try a modified version of his default setup. I was sure why he had random imported. (Maybe for simulations?)
from collections import *
import itertools
import sys
def main():
sum = 0
for line in sys.stdin:
a = list(map(int, line.strip().split()))
sum += max(a) - min(a)
print sum
main()
Then I ran python 2_1.py 2.in
to get my result.
Part 2
--- Part Two ---
"Great work; looks like we're on the right track after all. Here's a star for your effort." However, the program seems a little worried. Can programs be worried?
"Based on what we're seeing, it looks like all the User wanted is some information about the evenly divisible values in the spreadsheet. Unfortunately, none of us are equipped for that kind of calculation - most of us specialize in bitwise operations."
It sounds like the goal is to find the only two numbers in each row where one evenly divides the other - that is, where the result of the division operation is a whole number. They would like you to find those numbers on each line, divide them, and add up each line's result.
For example, given the following spreadsheet:
5 9 2 8
9 4 7 3
3 8 6 5
- In the first row, the only two numbers that evenly divide are 8 and 2; the result of this division is 4.
- In the second row, the two numbers are 9 and 3; the result is 3.
- In the third row, the result is 2.
In this example, the sum of the results would be 4 + 3 + 2 = 9.
What is the sum of each row's result in your puzzle input?
Attempt
At this point I realized I probably wouldn’t make it onto the leaderboard but decided that I might as well try to finish up and see how I do. I reused code and was super lazy about setting variables. Here was my attempt at Part 2. Again I stumbled about trying to debug my code for some time because of how messy it was.
INPUT="3458 3471 163 1299 170 4200 2425 167 3636 4001 4162 115 2859 130 4075 4269,2777 2712 120 2569 2530 3035 1818 32 491 872 113 92 2526 477 138 1360,2316 35 168 174 1404 1437 2631 1863 1127 640 1745 171 2391 2587 214 193,197 2013 551 1661 121 206 203 174 2289 843 732 2117 360 1193 999 2088,3925 3389 218 1134 220 171 1972 348 3919 3706 494 3577 3320 239 120 2508,239 947 1029 2024 733 242 217 1781 2904 2156 1500 3100 497 2498 3312 211,188 3806 3901 261 235 3733 3747 3721 267 3794 3814 3995 3004 915 4062 3400,918 63 2854 2799 178 176 1037 487 206 157 2212 2539 2816 2501 927 3147,186 194 307 672 208 351 243 180 619 749 590 745 671 707 334 224,1854 3180 1345 3421 478 214 198 194 4942 5564 2469 242 5248 5786 5260 4127,3780 2880 236 330 3227 1252 3540 218 213 458 201 408 3240 249 1968 2066,1188 696 241 57 151 609 199 765 1078 976 1194 177 238 658 860 1228,903 612 188 766 196 900 62 869 892 123 226 57 940 168 165 103,710 3784 83 2087 2582 3941 97 1412 2859 117 3880 411 102 3691 4366 4104,3178 219 253 1297 3661 1552 8248 678 245 7042 260 581 7350 431 8281 8117,837 80 95 281 652 822 1028 1295 101 1140 88 452 85 444 649 1247".split(',')
sum = 0
for line in INPUT:
for i in xrange(0, len(line.split(' '))):
for j in xrange(i, len(line.split(' '))):
most = int(line.split(' ')[i])
least = int(line.split(' ')[j])
if most > least and most % least == 0:
sum = sum + most/least
elif most < least and least % most == 0:
sum = sum + least/most
print sum
I ended up finishing both parts in 13 minutes and 29 seconds, which resulted in a rank of 393. The cutoff time for the top 100 was 6 minutes and 13 seconds which was less time than it took me to solve part 1.
Refactoring
Here is how I would refactor it. I normally wouldn’t use one letter variable names except maybe for indices. Also xrange() is faster than range() but for these questions, runtime is negligible so from now on I’ll be using range to save a keystroke.
from collections import *
import itertools
import sys
def main():
sum = 0
for line in sys.stdin:
a = list(map(int, line.strip().split()))
for i in range(len(a)):
for j in range(len(a)):
if i != j and a[i] % a[j] == 0:
sum += a[i] / a[j]
print sum
main()
Conclusion
For the next challenge, I’ll be using a template and piping in input instead of copy pasting it into Python. I probably also didn’t need to have multiple tabs open pointing to the input and the question.
Day 2’s Results
You have 37 points.
-------Part 1-------- -------Part 2--------
Day Time Rank Score Time Rank Score
2 00:06:21 450 0 00:13:29 393 0
1 00:03:32 86 15 00:05:32 79 22