File size: 2,257 Bytes
a4da721
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
def parse_input(file):
    with open(file, 'r') as f:
        lines = f.readlines()
    initial_values = [int(line.split(': ')[1]) for line in lines[:3]]
    program = list(map(int, lines[3].split(': ')[1].split(',')))
    return initial_values, program

def get_combo_value(operand, registers):
    if operand <= 3:
        return operand
    elif operand == 4:
        return registers['A']
    elif operand == 5:
        return registers['B']
    elif operand == 6:
        return registers['C']
    else:
        raise ValueError("Invalid combo operand")

def execute_program(registers, program):
    output = []
    ip = 0
    while ip < len(program):
        opcode = program[ip]
        operand = program[ip + 1]
        if opcode == 0:  # adv
            denominator = 2 ** get_combo_value(operand, registers)
            registers['A'] //= denominator
        elif opcode == 1:  # bxl
            registers['B'] ^= operand
        elif opcode == 2:  # bst
            registers['B'] = get_combo_value(operand, registers) % 8
        elif opcode == 3:  # jnz
            if registers['A'] != 0:
                ip = operand
                continue
        elif opcode == 4:  # bxc
            registers['B'] ^= registers['C']
        elif opcode == 5:  # out
            output.append(get_combo_value(operand, registers) % 8)
        elif opcode == 6:  # bdv
            denominator = 2 ** get_combo_value(operand, registers)
            registers['B'] = registers['A'] // denominator
        elif opcode == 7:  # cdv
            denominator = 2 ** get_combo_value(operand, registers)
            registers['C'] = registers['A'] // denominator
        ip += 2
    return output

def part1(file):
    initial_values, program = parse_input(file)
    registers = {'A': initial_values[0], 'B': initial_values[1], 'C': initial_values[2]}
    output = execute_program(registers, program)
    return ','.join(map(str, output))

def part2(file):
    _, program = parse_input(file)
    for a in range(1, 1000000):  # Arbitrary large number for search
        registers = {'A': a, 'B': 0, 'C': 0}
        output = execute_program(registers, program)
        if output == program:
            return a

file = "input.txt"
print(part1(file))
print(part2(file))