Ejemplo n.º 1
0
    return a, b

# f(x) = ax + b
# Returns the position of card x after applying the shuffle
def apply_shuffle(a, b, x, size):
    return (a * x + b) % size

# Returns which card will be on position x after applying the shuffle
def apply_shuffle_inverted(a, b, x, size):
    return ((x - b) * modular_inverse(a, size)) % size

# g(f(x)) = cf(x) + d = cax + cb + d
def combine_functions(a, b, c, d, size):
    return (c * a) % size, (c * b + d) % size

def modular_inverse(x, size):
    ret, _ = modular_exponentiation(x, 0, size - 2, size)
    return ret

def modular_exponentiation(a, b, iterations, size):
    if iterations == 1:
        return a, b
    elif iterations % 2 == 0:
        a, b = combine_functions(a, b, a, b, size)
        return modular_exponentiation(a, b, iterations / 2, size)
    else:
        c, d = modular_exponentiation(a, b, iterations - 1, size)
        return combine_functions(a, b, c, d, size)

aoc.run_lines(main, "day22.txt")
Ejemplo n.º 2
0
        resources[ORE] = TRILLION
        resources[FUEL] = -part2
        nanofactory(reactions, resources)
        ore_remaining = resources[ORE]
        if ore_remaining <= 0:
            part2 -= 1
            break
        else:
            part2 += max(1, int(ore_remaining / ore_per_fuel))

    return part1, part2

def nanofactory(reactions, resources):
    while any(r != ORE and resources[r] < 0 for r in resources):
        for target in resources:
            if resources[target] < 0:
                new_resources = False
                for reaction in reactions:
                    if target in reaction[1]:
                        reaction_count = max(1, int(-resources[target] / reaction[1][target]))
                        for item in reaction[0]:
                            if item not in resources:
                                new_resources = True
                            resources[item] -= reaction[0][item] * reaction_count
                        for item in reaction[1]:
                            resources[item] += reaction[1][item] * reaction_count
                if new_resources:
                    break

aoc.run_lines(main, "day14.txt")
Ejemplo n.º 3
0
    return part1, part2

def run_program(program, instruction_to_flip):
    seen_instructions = []
    nop_jmp_counter = 0
    program_pointer = 0
    acc = 0
    while program_pointer not in seen_instructions and program_pointer < len(program):
        seen_instructions.append(program_pointer)
        instruction = program[program_pointer][0]
        value = program[program_pointer][1]
        program_pointer += 1

        if nop_jmp_counter == instruction_to_flip:
            if instruction == "nop":
                instruction = "jmp"
            elif instruction == "jmp":
                instruction = "nop"
        
        if instruction == "acc":
            acc += value
        elif instruction == "jmp":
            program_pointer += value - 1
            nop_jmp_counter += 1
        elif instruction == "nop":
            nop_jmp_counter += 1
    
    return acc, program_pointer >= len(program)

aoc.run_lines(main, "day08.txt")