Пример #1
0
def part_two(data):
    buses_by_offset = {}
    for i, bus in enumerate(data[1]):
        if bus != "x":
            buses_by_offset[i] = int(bus)
    time = -1
    solved = False
    step = 1
    buses_matched = set()
    while not solved:
        solved = True
        time += step
        num_buses_matched = 0
        for offset, bus in buses_by_offset.items():
            if (time + offset) % bus == 0:
                num_buses_matched += 1
                if num_buses_matched > len(buses_matched):
                    buses_matched.add(bus)
                    # Full disclosure: I saw a spoiler on Reddit about Chinese Remainder
                    # Theorem that pointed me in this general direction :(
                    step = lcm.reduce(list(buses_matched), dtype=int64)
                continue
            else:
                solved = False
                break
    return time
Пример #2
0
def main():
    data = getInts('input')

    planets = list()
    i = 0
    for planet in data:
        a = {}
        a['pos'] = dict(zip(['x','y','z'], planet ))
        a['vel'] = {'x':0, 'y':0, 'z':0}
        a['id'] = i
        planets.append( a )
        i+= 1

    pairs = list(combinations(range(len(planets)), 2))

    planets2 = planets.copy()

    # part 1
    simulation(planets, pairs, 1000)
    p1 = sum([ getEnergy(x) for x in planets ])
    print("p1: {}".format(p1))


    # part 2 
    p2_s = simulation(planets2, pairs, 9999999999, True)
    p2 = lcm.reduce([x for x in p2_s.values()])
    print("p2: {}".format(p2))
Пример #3
0
 def find_cycle(self):
     cycles = [None, None, None]
     self.steps = 0
     memory = [self.state(0), self.state(1), self.state(2)]
     while not all(cycles):
         self.next_step()
         for k in range(3):
             state = self.state(k)
             if not cycles[k] and state == memory[k]:
                 cycles[k] = self.steps
     return lcm.reduce(cycles)
Пример #4
0
def prize_time(buses):
    time = 1
    interval = 1
    for i in range(len(buses)):
        bus_ids_to_check = [bus_id for bus_id, _ in buses[:i + 1]]
        while True:
            if deltas_correct(time, buses[:i + 1]):
                break
            time += interval
        interval = int(lcm.reduce(bus_ids_to_check, dtype=int64))
    return time
Пример #5
0
def get_action_order(action):
    """
    calculate the order of a move given as a list of permutations

    inputs:
    -------
        action - (list) of lists of ints - a move given as a list of cycles

    returns:
    --------
        (int) - the order of the given move
    """
    cycle_lengths = [len(cycle) for cycle in action]
    return lcm.reduce(cycle_lengths)
Пример #6
0
def loop_finder(positions):
    return_times = []
    for dimension in range(3):
        jupiter = SolarSystem1D(positions, dimension)
        steps = 0
        states = dict()
        states[jupiter.get_states()] = steps
        while True:
            steps += 1
            jupiter.apply_gravity()
            jupiter.apply_velocity()
            new_state = jupiter.get_states()
            if new_state in states:
                out = steps - states[new_state]
                break
            else:
                states[new_state] = steps
        return_times.append(out)
    return lcm.reduce(return_times)
Пример #7
0
# pad
arg = arg + bytes([16 - len(arg) % 16] * (16 - len(arg) % 16))

n, m = 256, 48

binv = [None] * m
for i in range(m):
    binv[b[i]] = i
b = binv[:]
assert None not in b

cycles = []
for pos, val in enumerate(arg):
    seen = set()
    count = 0
    while (pos, val) not in seen:
        seen.add((pos, val))
        val = a[val]
        pos = b[pos]
        count += 1
    cycles.append(count)

rep = int(lcm.reduce(cycles))

X = b'\xbe\xf5@\xddk"\x80cTH\x87iT\x0b\xa4\x15\x8fp\x8f\x14\x9b\xd1$d\x98\xac\x92\'\x13\x80\xdf[}SH\x9f\xac'
Y = int.to_bytes(
    pow(
        rep, 65537,
        127314748520905380391777855525586135065716774604121015664758778084648831235208544136462397
    ), len(X), 'big')
print(''.join((chr(x ^ y) for x, y in zip(X, Y))))
Пример #8
0
def get_common_denominator(probabilities):
    """Return least Z such that each probability is a multiple of 1/Z."""
    denominators = [p.denominator for p in probabilities]
    return lcm.reduce(denominators)
Пример #9
0
        moons[moon2] = update_velocity(moons[moon2], moon2_changes)
    # now we've calculate the velocities, change the new positions
    new_moons = dict()
    for moon in moons.keys():
        new_moons[add(moon, moons[moon])] = moons[moon]
    return new_moons


x_states = set()
y_states = set()
z_states = set()

while True:
    x_pos = tuple(i[0] for i in moons.keys())
    y_pos = tuple(i[1] for i in moons.keys())
    z_pos = tuple(i[2] for i in moons.keys())
    x_vel = tuple(i[0] for i in moons.values())
    y_vel = tuple(i[1] for i in moons.values())
    z_vel = tuple(i[2] for i in moons.values())
    x_state = (x_pos, x_vel)
    y_state = (y_pos, y_vel)
    z_state = (z_pos, z_vel)
    if x_state in x_states and y_state in y_states and z_state in z_states:
        break
    x_states.add(x_state)
    y_states.add(y_state)
    z_states.add(z_state)
    moons = advance_time(moons)

print(lcm.reduce([len(x_states), len(y_states), len(z_states)]))
Пример #10
0
        return hash(state)

    step = 0
    axis_to_check = {0, 1, 2}
    axis_found = set()
    states_by_axis = [set(), set(), set()]
    periods = []

    while True:
        # debug output
        if step % 100000 == 0:
            print(f'{datetime.datetime.now().time()}: After {step} steps')

        if not axis_to_check:
            result = lcm.reduce(periods)
            print(
                f'Planets will return where they started after {result} steps')
            break

        for axis_i in axis_to_check:
            current_hash = axis_hash(positions, velocities, axis_i)
            if current_hash in states_by_axis[axis_i]:
                print(f'Repeat found for {axis_i} after {step} states')
                axis_found.add(axis_i)
                periods.append(step)
            else:
                states_by_axis[axis_i].add(current_hash)

        axis_to_check -= axis_found
Пример #11
0
def part2(path):
    pos = read_positions(path)
    x, y, z = positions_to_pv_coord_pairs(pos)
    steps = [steps_until_repeat(pv) for pv in (x, y, z)]
    return lcm.reduce(steps)
Пример #12
0
def partB():
    def periods_set(x, y, z):
        return (x > 0) and (y > 0) and (z > 0)

    moons = [
        Moon([14, 15, -2], 'Io'),
        Moon([17, -3, 4], 'Europa'),
        Moon([6, 12, -13], 'Ganymede'),
        Moon([-2, 10, -8], 'Callisto')
    ]
    #moons = [Moon([-8,-10,0],'Io'),Moon([5,5,10],'Europa'),Moon([2,-7,3],'Ganymede'),Moon([9,-8,-3],'Callisto')]
    pairs = list(combinations(moons, 2))

    x_visited = []
    y_visited = []
    z_visited = []

    x_steps = 0
    y_steps = 0
    z_steps = 0

    while not (periods_set(x_steps, y_steps, z_steps)):
        ## apply gravity
        for (m1, m2) in pairs:
            for i, (p1, p2) in enumerate(zip(m1.position, m2.position)):
                if p1 < p2:
                    m1.velocity[i] = m1.velocity[i] + 1
                    m2.velocity[i] = m2.velocity[i] - 1
                elif p1 > p2:
                    m1.velocity[i] = m1.velocity[i] - 1
                    m2.velocity[i] = m2.velocity[i] + 1

        xpos_vel = []
        ypos_vel = []
        zpos_vel = []

        for m in moons:
            m.step()
            xpos_vel.append([m.position[0], m.velocity[0]])
            ypos_vel.append([m.position[1], m.velocity[1]])
            zpos_vel.append([m.position[2], m.velocity[2]])

        if xpos_vel in x_visited and x_steps == 0:
            print('X STEPS: ', (m.steps - 1))
            x_steps = m.steps - 1

        if ypos_vel in y_visited and y_steps == 0:
            print('Y STEPS: ', (m.steps - 1))
            y_steps = m.steps - 1

        if zpos_vel in z_visited and z_steps == 0:
            print('Z STEPS: ', (m.steps - 1))
            z_steps = m.steps - 1

        x_visited.append(xpos_vel)
        y_visited.append(ypos_vel)
        z_visited.append(zpos_vel)

        if m.steps % 10000 == 0:
            print(m.steps)

    #loopsin = []
    #for m in moons:
    #    print(m.periods)
    #    m_period = lcm.reduce(m.periods)
    #    loopsin.append(m_period)

    #print(loopsin)
    print(lcm.reduce([x_steps, y_steps, z_steps]))
Пример #13
0
    if b == 0:
        return t0
    return (a + 1) * bus_id, bus_id


next_arrivals = [next_arrival(timestamp0, bus_id) for bus_id in bus_ids]
t_arrive, bus_id = min(next_arrivals, key=lambda x: x[0])
print((t_arrive - timestamp0) * bus_id)

# Part 2
from numpy import lcm

with open('p13.txt') as f:
    timestamp0 = int(f.readline())
    schedule = [(i, int(x)) for i, x in enumerate(f.readline().split(','))
                if x != 'x']

N = len(schedule)
t0 = 100000000000000
dt = schedule[0][1]
t = t0 // dt * dt

while True:
    ids = [bus_id for phi, bus_id in schedule if (t + phi) % bus_id == 0]

    if len(ids) == N:
        print(t)
        break

    t += lcm.reduce(ids)
Пример #14
0
                nvel[j] += 1

    # update positions
    npos = [pos[i] + nvel[i] for i in range(nmoons)]
    return npos, nvel


def key(pos, vel):
    return '{},{},{};{},{},{}'.format(*pos, *vel)


periods = []
for dim in [0, 1, 2]:
    counter = 0
    pos = [positions[i][dim] for i in range(nmoons)]
    vel = [0] * nmoons
    initkey = key(pos, vel)
    #vis = {initkey: 0}
    while True:
        pos, vel = one_step(pos, vel)
        counter += 1
        k = key(pos, vel)
        if k == initkey:
            #if k in vis:
            periods += [(counter, pos, vel)]
            break
        #vis[k] = counter

print(periods)
period = lcm.reduce([p[0] for p in periods])
print(period)
Пример #15
0
# 2520 is the smallest number that can be divided by each of the numbers from 1 to 10 without any remainder.
# What is the smallest positive number that is evenly divisible by all of the numbers from 1 to 20?

from functools import reduce
from numpy import lcm

smallest_multiple = lcm.reduce(range(2, 21))
print(f"Smallest multiple: {smallest_multiple}")
Пример #16
0
 def create_solution(self):
     return [gcd.reduce(self.nums), lcm.reduce(self.nums)]