示例#1
0
def main():

    lines = open_data("13.data")

    wait = int(lines[0])

    earliest = 0
    earliest_id = 0

    for b in ints(lines[1]):
        ap = wait // b + 1
        if ap * b < earliest or earliest == 0:
            earliest = ap * b
            earliest_id = b

    print((earliest - wait) * earliest_id)

    busses = [(int(t), i) for i, t in enumerate(lines[1].split(","))
              if t != "x"]

    # unzip list of tuples in to two lists with the elements
    remainder, modulos = unzip(busses)

    # So I can search for it later: chinese remainder theorem, CRT, crt, Chinese Remainder Theorem.
    a, b = crt(remainder, modulos)

    # WHY do I need to substract the first (actual) result from the second something???
    print(b - a)
示例#2
0
def poly_mult(A, B):
    # Pad
    L = next_pow2(len(A) + len(B))
    while len(A) < L:
        A.append(0)
    while len(B) < L:
        B.append(0)
    # FFT for each prime
    list_C = []
    for p in primes:
        a = A[:]
        b = B[:]
        for i in range(L):
            a[i] %= p
            b[i] %= p
        list_C.append(poly_mult_prime(a, b, p))
    # Solve congruences to get actual C
    L = len(list_C[0])
    C = [0 for _ in range(L)]
    for i in range(L):
        cong = []
        for j in range(num_primes):
            cong.append(list_C[j][i])
        val, mod = crt(primes, cong, check=False)
        C[i] = int(val % mod) % N
    # Unpad
    while C[-1] == 0:
        C.pop()
    # print(A, '*', B, '=', C)
    return C
def library_CRT(e, d, p, q, y):
    """
    Chinese Remainder Theorem as performed with python's preexisting methods
    :param e:
    :param d:
    :param p:
    :param q:
    :param y:
    :return: result + time
    """
    # time:
    start = time.time()

    x_q = library_modular_exponentiation(y % q, d % (q - 1), q)

    # Hensel:
    x0 = library_modular_exponentiation(y % p, d % (p - 1), p)
    x1 = (((y - library_modular_exponentiation(x0, e, p * p)) / p) *
          library_modular_inverse(
              e * library_modular_exponentiation(x0, e - 1, p * p), p)) % p
    x_p2 = int((x1 * p + x0) % (p * p))

    # for CRT:
    moduli = [p * p, q]
    residues = [x_p2, x_q]
    return crt(moduli, residues)[0], time.time() - start
示例#4
0
    def as_subindex(self, index):
        # The docstring of this method is currently on NDindex.as_subindex, as
        # this is the only method that is actually implemented so far.

        from .ndindex import ndindex
        index = ndindex(index)

        if not isinstance(index, Slice):
            raise NotImplementedError(
                "Slice.as_subindex is only implemented for slices")

        s = self.reduce()
        index = index.reduce()

        if s.step < 0 or index.step < 0:
            raise NotImplementedError(
                "Slice.as_subindex is only implemented for slices with positive steps"
            )

        # After reducing, start is not None when step > 0
        if index.stop is None or s.stop is None or s.start < 0 or index.start < 0 or s.stop < 0 or index.stop < 0:
            raise NotImplementedError(
                "Slice.as_subindex is only implemented for slices with nonnegative start and stop. Try calling reduce() with a shape first."
            )

        # Chinese Remainder Theorem. We are looking for a solution to
        #
        # x = s.start (mod s.step)
        # x = index.start (mod index.step)
        #
        # If crt() returns None, then there are no solutions (the slices do
        # not overlap).
        res = crt([s.step, index.step], [s.start, index.start])
        if res is None:
            return Slice(0, 0, 1)
        common, _ = res
        lcm = ilcm(s.step, index.step)
        start = max(s.start, index.start)

        def _smallest(x, a, m):
            """
            Gives the smallest integer >= x that equals a (mod m)

            Assumes x >= 0, m >= 1, and 0 <= a < m.
            """
            n = int(math.ceil((x - a) / m))
            return a + n * m

        # Get the smallest lcm multiple of common that is >= start
        start = _smallest(start, common, lcm)
        # Finally, we need to shift start so that it is relative to index
        start = (start - index.start) // index.step

        step = lcm // index.step  # = s.step//igcd(s.step, index.step)

        stop = math.ceil((min(s.stop, index.stop) - index.start) / index.step)
        if stop < 0:
            stop = 0

        return Slice(start, stop, step)
示例#5
0
def part2(input):
    bus_times = input[1]

    conditions = []
    for offset, bus_time in enumerate(bus_times):
        if bus_time == "x":
            continue
        else:
            conditions.append((int(bus_time), offset))

    conditions = sorted(conditions, key=lambda x: -x[1])
    n, a = zip(*conditions)
    a = [-num for num in a]
    for bus_time, offset in conditions:
        print(f"(t + {offset}) mod {bus_time} = 0", end=", ")
    print()
    print(crt(n, a))

    cur_num = -conditions[0][1]  # initial offset
    increase = conditions[0][0]
    for bus_time, offset in conditions[1:]:
        rest = (cur_num + offset) % bus_time
        not_done = rest != 0
        while not_done:
            cur_num += increase
            rest = (cur_num + offset) % bus_time
            not_done = rest != 0
        increase *= bus_time
    return cur_num
def SilverPohligHellman(base, gen, element):
    # El orden del generador es el cardinal de todos los elementos menos el 0
    order = base - 1

    # Si no tenemos el generador o la base correctos...
    if base != BASE or gen != GEN:
        # Generamos las raíces que usaremos
        GenerateSquareRoots(base, gen)

    # Lista de restos y subbases
    subbases = []
    remainders = []

    # Buscamos el logaritmo
    for i in P_FACTS:
        # Inicialmente el exponente es 0
        exp = 0

        # Recorremos los posibles valores en los que p_i^j es divisor de n
        for j in range(P_FACTS[i]):
            y = element * FastExp(gen, order - exp, base)
            x = ROOTS[i][FastExp(y, order / (i**(j + 1)), base)]
            exp += x * i**j

        # Añadimos la ecuación con congruencias
        subbases.append(i**P_FACTS[i])
        remainders.append(exp)

    # Resolvemos el sistema de congruencias
    return crt(subbases, remainders)[0]
示例#7
0
def chinesereminder():
    #accepting positive integer a,b,c and r,s,t from user
    print("Enter the values for  divisors A,B,C and remainders R,S,T:-")
    a = input('A:')
    b = input('B:')
    c = input('C:')
    r = input('R:')
    s = input('S:')
    t = input('T:')

    a = int(a)
    b = int(b)
    c = int(c)
    r = int(r)
    s = int(s)
    t = int(t)

    if r > 0 and s > 0 and t > 0 and a > 0 and b > 0 and c > 0:
        #checking for pairwaise relatively prime integers
        if math.gcd(r, s) == 1 and math.gcd(s, t) == 1 and math.gcd(r, t) == 1:
            x = [r, s, t]
            y = [a, b, c]
            final_value = crt(x, y)  #crt
            print("Result of the Chinese Remainder Theorem = {} ".format(
                final_value[0]))
        else:
            print("Something went wrong. Please enter the input again")
    #return
    print("Enter 'Y' to go back to menu and 'E' to exit")
    user_input = input("Enter your choice as 'Y' or 'E': ")
    if user_input == "Y":
        menu()
    elif user_input == "E":
        exit()
示例#8
0
def main():
    t, *busses = [
        int(x) for x in open(file).read().replace('x', '1').replace(
            '\n', ',').split(',')
    ]
    m, r = zip(*((b, b - i) for i, b in enumerate(busses) if b > 1))
    print(crt(m, r)[0])
示例#9
0
def main():
    """
	parse input data:
	second line has the busIDs and x's, convert the busIDs to integers and make a list,
	"""
    data = open('data.txt', 'r')
    lines = data.read().split()
    busses = lines[1].split(',')
    for i in range(len(busses)):
        if (busses[i] != 'x'):
            busses[i] = int(busses[i])
    """
	create system of linear congruencies:
	at timestamp t every bus has to come in i minutes, i being the position of the bus in the list
	therefore, at t the following equation has to be true:
	busID-i=t mod busID
	we can solve this system of equations using the chinese remainder theorem. The solution is our timestamp t
	"""
    busID = []
    value_at_timestamp = []
    for i, bus in enumerate(busses):
        if (bus != 'x'):
            busID = busID + [bus]
            value_at_timestamp = value_at_timestamp + [(bus - i) % bus]
    print(
        "The earliest timestamp at which all listed busIDs depart at offsets matching their position in the list is:\nt =",
        crt(busID, value_at_timestamp)[0])
示例#10
0
def part2(s: str) -> int:
    line = s.splitlines()[1]
    buses = [(i, int(x)) for i, x in enumerate(line.split(",")) if x != "x"]
    bus_ids = [bus[1] for bus in buses]
    mods = [-1 * bus[0] for bus in buses]

    return crt(bus_ids, mods)[0]
示例#11
0
 def try_random_residue():
     res = pow(randint(1, max_x), 2, n)
     try:
         rev_res = int(crt((res, n), (0, 1))[0]) // res
         return res, rev_res
     except (ZeroDivisionError, TypeError):
         return None
示例#12
0
def solver(s: str) -> int:
    bus_ids = [(int(bus), i)
               for i, bus in enumerate(s.splitlines()[1].split(","))
               if bus != "x"]
    busses = [b[0] for b in bus_ids]
    final = [-1 * b[1] for b in bus_ids]
    return crt(busses, final)[0]
示例#13
0
def part2(data):
    (est, ids) = data.splitlines()
    est = int(est)
    nums = [(int(x), -i) for i, x in enumerate(ids.split(",")) if x != "x"]
    print(nums)
    ids, times = zip(*nums)
    # chinese remainder theorem
    return crt(ids, times)[0]
示例#14
0
def main():
    est = int(input())
    times = [x for x in input().split(",")]
    nums = [int(t) for t in times if t != "x"]
    mods = [int(times[i]) - i for i in range(len(times)) if times[i] != "x"]
    # realizing i needed the chinese remainder theorem was a challenge in itself
    # i decided i'd earned the right to "cheat" by importing an implementation
    print(crt(nums, mods)[0])
示例#15
0
文件: part2.py 项目: yankev/aoc2020
def compute(s: str) -> int:
    lines = s.splitlines()
    parsed = [(int(s), i) for i, s in enumerate(lines[1].split(','))
              if s != 'x']
    buses = [pt[0] for pt in parsed]
    mods = [-1 * pt[1] for pt in parsed]

    return crt(buses, mods)[0]
示例#16
0
def find_open_key(p, gx):
    """
    Используя китайскую теорему об остатках, найдём у из открытого ключа
    :param p: p из открытого ключа
    :param gx: g**x, x - секретный ключ
    :return: y
    """
    return int(crt((gx, p), (0, 1))[0]) // gx
示例#17
0
def part_2():
    _, buses = utils.get_input(__file__, delimiter=None, cast=str)

    buses, offsets = zip(*[(int(bus), -1 * i)
                           for i, bus in enumerate(buses.split(','))
                           if bus != 'x'])

    print(crt(buses, offsets)[0])
示例#18
0
def find_lambda(numerator, denominator, n):
    """
    Вычисление значения l = numerator/denominator (mod n)
    :return: l
    """
    left = positive_mod(denominator, n)
    right = positive_mod(numerator, n)
    return int(crt((left, n), (0, right))[0] // left)
示例#19
0
文件: s.py 项目: artcz/adventofcode
def p2crt():
    desc = lines[1].split(",")
    buses = [(i, int(x)) for i, x in enumerate(desc) if x != "x"]

    mods = [b[1] - b[0] for b in buses]
    divs = [b[1] for b in buses]

    print("p2crt:", crt(divs, mods)[0])
示例#20
0
def part2():
    bus_ids = map(int, all_lines[1].replace("x", "-1").split(","))
    ids = [(bus_id, -offset) for offset, bus_id in enumerate(bus_ids)
           if bus_id != -1]
    ids = zip(*ids)
    m = list(next(ids))
    v = list(next(ids))
    (x, _) = crt(m, v, check=False)
    print(x)
示例#21
0
def part_two(data):
    modulii = list()
    remainders = list()

    for idx, id_ in data[1].items():
        modulii.append(id_)
        remainders.append(-idx % id_)

    return crt(modulii, remainders)[0]
示例#22
0
def part2(busses):
    coprimes = []
    modulos = []
    for i, bus in enumerate(busses):
        if bus != 'x':
            coprimes.append(int(bus))
            modulos.append(i)
    a, b = crt(coprimes, modulos)
    return b - a
示例#23
0
def find_consecutive_offsets(depart_ids_with_unknowns):
    id_position = {
        int(bus_id): depart_ids_with_unknowns.index(bus_id)
        for bus_id in depart_ids_with_unknowns if bus_id != "x"
    }
    mods = list(id_position.keys())
    offsets = [-offset for offset in id_position.values()]
    lowest_multiple, _ = crt(mods, offsets)
    return lowest_multiple
示例#24
0
def main(day, part=1):
    start_time, bus_ids, tolerance = preprocess(day.data)
    if part == 1:
        bus_id, minutes = schedule(start_time, bus_ids)
        out = bus_id * minutes
    if part == 2:
        smort = crt(bus_ids, tolerance)
        out = smort[1] - smort[0]
    return out
示例#25
0
def part2(buses) -> int:
    from sympy.ntheory.modular import crt
    activeBuses = []
    remainders = []
    for i in range(len(buses)):
        if buses[i] != "x":
            activeBuses.append(buses[i])
            remainders.append(-i)
    return crt(activeBuses, remainders)[0]
示例#26
0
def attack(ms):
    nn = [int(nnn, 16) for nnn in n]
    x = crt(nn, ms)

    xx = (Decimal(x[0]).__pow__(Decimal(1) / Decimal(e)))

    m = int(xx) + 1

    print(hex(m))
示例#27
0
def _help(m, prime_modulo_method, diff_method, expr_val):
    """
    Helper function for _nthroot_mod_composite and polynomial_congruence.

    Parameters
    ==========

    m : positive integer
    prime_modulo_method : function to calculate the root of the congruence
    equation for the prime divisors of m
    diff_method : function to calculate derivative of expression at any
    given point
    expr_val : function to calculate value of the expression at any
    given point
    """
    from sympy.ntheory.modular import crt

    f = factorint(m)
    dd = {}
    for p, e in f.items():
        tot_roots = set()
        if e == 1:
            tot_roots.update(prime_modulo_method(p))
        else:
            for root in prime_modulo_method(p):
                diff = diff_method(root, p)
                if diff != 0:
                    ppow = p
                    m_inv = mod_inverse(diff, p)
                    for j in range(1, e):
                        ppow *= p
                        root = (root - expr_val(root, ppow) * m_inv) % ppow
                    tot_roots.add(root)
                else:
                    new_base = p
                    roots_in_base = {root}
                    while new_base < pow(p, e):
                        new_base *= p
                        new_roots = set()
                        for k in roots_in_base:
                            if expr_val(k, new_base) != 0:
                                continue
                            while k not in new_roots:
                                new_roots.add(k)
                                k = (k + (new_base // p)) % new_base
                        roots_in_base = new_roots
                    tot_roots = tot_roots | roots_in_base
        if tot_roots == set():
            return []
        dd[pow(p, e)] = tot_roots
    a = []
    m = []
    for x, y in dd.items():
        m.append(x)
        a.append(list(y))
    return sorted(set(crt(m, list(i))[0] for i in cartes(*a)))
示例#28
0
def part2():
    with open("13.txt") as f:
        data = f.read().splitlines()
        busses = []
        for n, i in enumerate(data[1].split(',')):
            if i != 'x':
                busses.append((int(i), n))
    # Solution is finding t in (t%i) + n = 0 for all i,n
    crt_sol = crt(*zip(*busses))
    return crt_sol[1] - crt_sol[0]
示例#29
0
def part2():
    ids_2 = [int(i) if i.isnumeric() else i for i in data[1].split(",")]
    ts = [-idx for idx, i in enumerate(ids_2) if i != 'x']
    print(ids, ts)
    # ids are moduli (the ms)
    # ts are residuals (the as)
    # negate residuals because for example in 7,13,x,x,59,x,31,19
    # you want 13 to be 1 *ahead*, 59 to be 4 ahead etc.
    # so you need them to be = -1 % ids[1], -4 % ids[2] etc.
    return crt(ids, ts)[0]
示例#30
0
def task2(input):
    ids = [(int(x), i) for i, x in enumerate(input[1].split(",")) if x != "x"]

    # Straightforward application of the Chinese Remainder Theorem
    primes = [x[0] for x in ids]
    remainders = [x[0] - x[1] for x in ids]

    N, _ = crt(primes, remainders)

    return N
示例#31
0
def test_crt():
    def mcrt(m, v, r, symmetric=False):
        assert crt(m, v, symmetric)[0] == r
        mm, e, s = crt1(m)
        assert crt2(m, v, mm, e, s, symmetric) == (r, mm)

    mcrt([2, 3, 5], [0, 0, 0], 0)
    mcrt([2, 3, 5], [1, 1, 1], 1)

    mcrt([2, 3, 5], [-1, -1, -1], -1, True)
    mcrt([2, 3, 5], [-1, -1, -1], 2*3*5 - 1, False)

    assert crt([656, 350], [811, 133], symmetric=True) == (-56917, 114800)
示例#32
0
 def mcrt(m, v, r, symmetric=False):
     assert crt(m, v, symmetric)[0] == r
     mm, e, s = crt1(m)
     assert crt2(m, v, mm, e, s, symmetric) == (r, mm)
示例#33
0
def test_crt():
    assert crt([2, 3, 5], [0, 0, 0]) == 0
    assert crt([2, 3, 5], [1, 1, 1]) == 1

    assert crt([2, 3, 5], [-1, -1, -1], True) == -1
    assert crt([2, 3, 5], [-1, -1, -1], False) == 2*3*5 - 1