2020/13.py
def part2_2():
    """
    This was my second attempt. It's slightly more intelligent as it uses the smallest
    and largest bus IDs to calculate a larger step.

    This would have worked if I also had the additional insight that I needed to then
    use that to bootstrap finding how each subsequent bus lines up by iterating until I
    got to a point where another bus lined up and then use that as a step.
    """
    busses = []
    gaps = [0]
    for b in lines[1].split(","):
        if b == "x":
            gaps[-1] += 1
            continue
        else:
            gaps.append(1)
            busses.append(int(b))

    max_bus = 0
    min_bus = INF
    max_bus_i = 0
    min_bus_i = 0
    for i, b in enumerate(busses):
        if b > max_bus:
            max_bus = b
            max_bus_i = i
        if b < min_bus:
            min_bus = b
            min_bus_i = i

    indexes = sorted([min_bus_i, max_bus_i])
    i = arrow_alignment(
        red_len=busses[indexes[0]],
        green_len=busses[indexes[1]],
        advantage=sum(gaps[indexes[0] : indexes[1] + 1]),
    )
    jmp = lcm([busses[indexes[0]], busses[indexes[1]]])
    i = arrow_alignment(
        red_len=busses[0],
        green_len=busses[1],
        advantage=gaps[1],
    )
    jmp = lcm([busses[0], busses[1]])

    assert jmp != 0

    k = 0
    while True:
        if k % 100000 == 0:
            print(i)
            if k == 1:
                break
        ok = True
        for j, b in enumerate(busses):
            if i % b != b - sum(gaps[: j + 1]):
                ok = False
                break
        if ok:
            print("ITERS:", k)
            return i

        k += 1
        i += jmp

    This was my second attempt. It's slightly more intelligent as it uses the smallest
    and largest bus IDs to calculate a larger step.

    This would have worked if I also had the additional insight that I needed to then
    use that to bootstrap finding how each subsequent bus lines up by iterating until I
    got to a point where another bus lined up and then use that as a step.
    
This was my second attempt. It's slightly more intelligent as it uses the smallest
and largest bus IDs to calculate a larger step.

This would have worked if I also had the additional insight that I needed to then
use that to bootstrap finding how each subsequent bus lines up by iterating until I
got to a point where another bus lined up and then use that as a step.
This was my second attempt . It ' s slightly more intelligent as it uses the smallest and largest bus IDs to calculate a larger step . This would have worked if I also had the additional insight that I needed to then use that to bootstrap finding how each subsequent bus lines up by iterating until I got to a point where another bus lined up and then use that as a step .
def part2_2():
    busses = []
    gaps = [0]
    for b in lines[1].split(","):
        if b == "x":
            gaps[-1] += 1
            continue
        else:
            gaps.append(1)
            busses.append(int(b))
    max_bus = 0
    min_bus = INF
    max_bus_i = 0
    min_bus_i = 0
    for i, b in enumerate(busses):
        if b > max_bus:
            max_bus = b
            max_bus_i = i
        if b < min_bus:
            min_bus = b
            min_bus_i = i
    indexes = sorted([min_bus_i, max_bus_i])
    i = arrow_alignment(
        red_len=busses[indexes[0]],
        green_len=busses[indexes[1]],
        advantage=sum(gaps[indexes[0] : indexes[1] + 1]),
    )
    jmp = lcm([busses[indexes[0]], busses[indexes[1]]])
    i = arrow_alignment(
        red_len=busses[0],
        green_len=busses[1],
        advantage=gaps[1],
    )
    jmp = lcm([busses[0], busses[1]])
    assert jmp != 0
    k = 0
    while True:
        if k % 100000 == 0:
            print(i)
            if k == 1:
                break
        ok = True
        for j, b in enumerate(busses):
            if i % b != b - sum(gaps[: j + 1]):
                ok = False
                break
        if ok:
            print("ITERS:", k)
            return i
        k += 1
        i += jmp
def part2_2 ( ) : busses = [ ] gaps = [ 0 ] for b in lines [ 1 ] . split ( "," ) : if b == "x" : gaps [ - 1 ] += 1 continue else : gaps . append ( 1 ) busses . append ( int ( b ) ) max_bus = 0 min_bus = INF max_bus_i = 0 min_bus_i = 0 for i , b in enumerate ( busses ) : if b > max_bus : max_bus = b max_bus_i = i if b < min_bus : min_bus = b min_bus_i = i indexes = sorted ( [ min_bus_i , max_bus_i ] ) i = arrow_alignment ( red_len = busses [ indexes [ 0 ] ] , green_len = busses [ indexes [ 1 ] ] , advantage = sum ( gaps [ indexes [ 0 ] : indexes [ 1 ] + 1 ] ) , ) jmp = lcm ( [ busses [ indexes [ 0 ] ] , busses [ indexes [ 1 ] ] ] ) i = arrow_alignment ( red_len = busses [ 0 ] , green_len = busses [ 1 ] , advantage = gaps [ 1 ] , ) jmp = lcm ( [ busses [ 0 ] , busses [ 1 ] ] ) assert jmp != 0 k = 0 while True : if k % 100000 == 0 : print ( i ) if k == 1 : break ok = True for j , b in enumerate ( busses ) : if i % b != b - sum ( gaps [ : j + 1 ] ) : ok = False break if ok : print ( "ITERS:" , k ) return i k += 1 i += jmp
This was my second attempt.
This was my second attempt .
"""
    This was my second attempt. It's slightly more intelligent as it uses the smallest
    and largest bus IDs to calculate a larger step.

    This would have worked if I also had the additional insight that I needed to then
    use that to bootstrap finding how each subsequent bus lines up by iterating until I
    got to a point where another bus lined up and then use that as a step.
    """