Part 1


In [30]:
class Raceipy:
    
    def __init__(self):
        self.strip = [3, 7] 
        self.pos1  = 0
        self.pos2  = 1
    
    def step(self):
        s = self.strip[self.pos1] + self.strip[self.pos2]
        self.strip += list(map(int, str(s)))
        self.pos1 = (self.pos1 + self.strip[self.pos1] + 1) % len(self.strip)
        self.pos2 = (self.pos2 + self.strip[self.pos2] + 1) % len(self.strip)
    
    def show(self):
        printable = ''
        for i, v in enumerate(self.strip):
            if i == self.pos1:
                printable += '({0})'.format(v)
            elif i == self.pos2:
                printable += '[{0}]'.format(v)
            else:
                printable += ' {0} '.format(v)
        print(printable)

def after(first, last):
    race = Raceipy()
    while len(race.strip) < first + last:
        race.step()
    return ''.join(map(str, race.strip[first: first + last]))

Test


In [31]:
assert(after(9, 10) == '5158916779')
assert(after(5, 10) == '0124515891')
assert(after(18, 10) == '9251071085')
assert(after(2018, 10) == '5941429882')

Solution


In [27]:
after(505961, 10)


Out[27]:
'9315164154'

Part 2


In [35]:
def first(seq):
    race = Raceipy()
    while len(race.strip) < len(seq):
        race.step()
    match = False
    i = 0
    while not match:
        last = ''.join(map(str, race.strip[i: i + len(seq)]))
        if last == seq:
            match = True
            return i
        else:
            race.step()
            i += 1

Test


In [37]:
assert(first('51589') == 9)
assert(first('01245') == 5)
assert(first('92510') == 18)
assert(first('59414') == 2018)

Solution


In [38]:
first('505961')


Out[38]:
20231866