Today’s lesson in extremely, incredibly, stupidly, inefficient methodology, is brought to you by, the letter “i” and the number “640856202464541”. Day 13 consisted of calculating bus departure times. Part 1 was stupidly simple. You have a list of buses, each bus makes a regular round trip to wherever, and the round trip always takes the same amount of minutes. At some point in the past, the buses all left at once.

Say the buses were 4, 5, and 6, each number also being the minutes for a round trip. Every 4 minutes, bus 4 returns, every 5 minutes bus 5 returns, every 6 minutes, bus 6 returns. If you are available to leave at 9 minutes, which bus leaves first. In this example, the first bus to return would be 5 (5*2=10)

Part 1 was easy, start at your departure time, check to see if any of the numbers divide into it evenly, if not, increment by one and repeat.

with open('day13data.txt') as f:
    lines = [line.rstrip() for line in f]

time = int(lines[0])
raw = lines[1].split(',')
busses= [] 

for i in raw:
  if i != 'x':
    busses.append(int(i))

print time
print busses

for x in busses:
  bus_time=x*(round((float(time)/float(x))+.5))
  wait=bus_time-time
  print "For bus "+str(x)+": "+str(bus_time)+" and you will wait: "+str(wait)+" Ans: "+str(x*wait)

The trickiest part is that the data contained non existent buses, labeled with an “x”. These are not a factor for part 1, so they just get stripped out.

Part 2 is where the pain in the ass was. For Part 2, you have to find a starting time where each bus, will leave, one minute apart, according to their offset. This includes the “missing” buses. So for the quick example I had above of 4,5,6, this time would occur at well, 4 minutes, because I made them sequential, but the next one would occur at 64,65,66 (16*4, 13*5, 11*6). This gets even more complicated when you add in the blanks, for example, 4,x,5,x,6 occurs at 68,70,72. As you spread the numbers apart and rearrange them to be non sequential, it complicates everything more.

I actually figured out the methodology pretty quickly, and wrote a working, good bit of code pretty quickly, my problem, was picking a starting point. I am sure there is some numerology methods (I am pretty sure you can do something using remainders), to calculate even an approximate starting point. In my standard of ugly code, I was just brute forcing it.

with open('day13data.txt') as f:
    lines = [line.rstrip() for line in f]

lines_array = lines[1].split(',')
times = []
counter=0
#First for sample Data Set day13datab.txt, second for real data
#multiplier=152600
multiplier=15630639084400
offsets=[]
busses=[]

for i in lines_array:
  if i != 'x':
    busses.append(i)
    offsets.append(lines_array.index(i))

#print busses
#print offsets

while (1):
  for i in offsets:
    times.append(((int(busses[0]))*multiplier)+i)

  #print times
  counter=1
  for j in busses[1:]:
    #print j
    if (times[counter]/float(j)).is_integer():
      counter+=1
    else:
      break
        
  #print times
  #print counter
  if counter == len(busses):
    break
  counter = 0
  times =[]
  multiplier+=1
  #print multiplier

print times

The problem is, this takes a very, very, very, very, very, long time. I left this code running for hours on my server and it didn’t finish, I honestly feel like it could very likely run for days, weeks, years, and never finish. The iteration on my multiplier that gives the correct set, for my data (every person has a different data set) was 15,630,639,084,501. 15 TRILLION.

So I fudged it a bit, because I was pretty sure my code was good, but I didn’t have an eternity to wait. So I found someone else’s code, found the correct answer, then worked out my starting offset from there. Sure enough, when I start at 15,630,6390,084,400. It quickly finds the correct answer.

If I needed this code for something important, I would certainly try to clean it up. I even started working on an iteration that would sort out my bus list to start with the largest number, instead of iterating the list every (low value) it would iterate every (high value), which in my case I believe was something like 15 versus 900. This was trickier than a straight sort though because I had a second list of offsets that I needed to also re order. I got this code working for the sample data set, but it failed in my proper data set because, while the sample data set started with the lowest bus number, the actual data set did not, and I had not calculated for that.

PS, yes, I misspelled “busses” in my code