בהצלחה
יום 7
2 לייקים
חלק 1
import operator
def int_input(inputs=None):
if inputs == None or inputs == []:
return int(input())
else:
return inputs.pop(0)
def intcode_computer(instructions, user_inputs=None, pass_print=False):
temp = instructions.copy()
STATES = {
1: {'func': operator.add, 'inputs': 3, 'index': 4, 'type': 0},
2: {'func': operator.mul, 'inputs': 3, 'index': 4, 'type': 0},
3: {'func': int_input, 'inputs': 1, 'index': 2, 'type': 1},
4: {'func': print, 'inputs': 1, 'index': 2, 'type': 2},
5: {'func': operator.truth, 'inputs': 2, 'index': 3, 'type': 3},
6: {'func': operator.not_, 'inputs': 2, 'index': 3, 'type': 3},
7: {'func': operator.lt, 'inputs': 3, 'index': 4, 'type': 4},
8: {'func': operator.eq, 'inputs': 3, 'index': 4, 'type': 4},
}
outputs = []
index = 0
while True:
opcode = str(temp[index]).zfill(5)
state = int(opcode[-2:])
if state != 99:
inputs = [temp[index + i + 1] for i in range(STATES[state]['inputs'])]
for pos in range(len(inputs) - 1):
if int(opcode[-3 - pos]) == 0:
inputs[pos] = temp[inputs[pos]]
if STATES[state]['type'] == 0:
temp[inputs[-1]] = STATES[state]['func'](*inputs[:-1])
elif STATES[state]['type'] == 1:
if user_inputs is not None:
inputs = user_inputs + inputs
temp[inputs[-1]] = STATES[state]['func'](inputs[:-1])
if user_inputs is not None and user_inputs != []:
user_inputs.pop(0)
elif STATES[state]['type'] == 2:
if int(opcode[-3]) == 0:
inputs[0] = temp[inputs[0]]
if not pass_print:
STATES[state]['func'](inputs[0])
outputs.append(inputs[0])
elif STATES[state]['type'] == 4:
if STATES[state]['func'](*inputs[:-1]):
temp[inputs[-1]] = 1
else:
temp[inputs[-1]] = 0
index += STATES[state]['index']
if STATES[state]['type'] == 3:
if STATES[state]['func'](*inputs[:-1]):
if int(opcode[-4]) == 0:
index = temp[inputs[-1]]
else:
index = inputs[-1]
else:
if outputs:
return outputs
else:
return temp
def calc_signal(software_input, sequence_list, pass_print=False):
output = 0
for digit in sequence_list:
inputs = [digit, output]
output = intcode_computer(software_input, inputs, pass_print)[0]
return output
def find_highest_signal(software_input, range_start, range_end, pass_print=False):
all_sequences = [[d0, d1, d2, d3, d4]
for d0 in range(range_start, range_end)
for d1 in range(range_start, range_end)
if d1 != d0
for d2 in range(range_start, range_end)
if d0 != d2 != d1
for d3 in range(range_start, range_end)
if d0 != d3 != d1 and d3 != d2
for d4 in range(range_start, range_end)
if d0 != d4 != d1 and d2 != d4 != d3
]
max_signal = 0
for sequence in all_sequences:
signal = calc_signal(software_input, sequence, pass_print)
if signal > max_signal:
max_signal = signal
return max_signal
with open('Day 7.txt', 'r') as file_handler:
challenge_input = list(map(int, file_handler.read().split(',')))
find_highest_signal(challenge_input, 0, 5, pass_print=True)
הפעם הם ניצחו אותי. אני פשוט לא מבין מה רוצים בחלק 2 וויתרתי לבנתיים.
אחזור לזה בהמשך עם ראש נקי.
לייק 1
חלק 1
#day7
#part 1
import itertools
import operator
PRO_CODE = list(range(1, 9))
def get_intcode_program(intcode):
with open(intcode, "r") as intcode_program:
intcode_program_read = intcode_program.read()
intcode_program_read = list(map(int, intcode_program_read.split(",")))
return intcode_program_read
def opcode_3_4(intcode_pro, code, signal):
if intcode_pro[code] % 100 == 3:
intcode_pro[intcode_pro[code + 1]] = signal
return True
elif intcode_pro[code] % 1000 == 4:
return False
elif intcode_pro[code] % 1000 == 104:
return False
return True
def opcode_1_2(int_code_pro, code, a, b):
if code == 1:
return operator.add(int_code_pro[a], int_code_pro[b])
elif code == 2:
return operator.mul(int_code_pro[a], int_code_pro[b])
def opcode_5_6(int_code_pro, code, a, b):
if int_code_pro[code] % 100 == 5:
if int_code_pro[a] != 0:
return int_code_pro[b]
elif int_code_pro[code] % 100 == 6:
if int_code_pro[a] == 0:
return int_code_pro[b]
return code + 3
def opcode_7_8(int_code_pro, code, a, b):
if int_code_pro[code] % 100 == 7:
if int_code_pro[a] < int_code_pro[b]:
return 1
elif int_code_pro[code] % 100 == 8:
if int_code_pro[a] == int_code_pro[b]:
return 1
return 0
def retrieve_parameters_mode_and_run(int_code_pro, pos, number):
number = str(number).zfill(5)
if number[2] == "0":
a = int_code_pro[pos + 1]
else:
a = pos + 1
if number[1] == "0":
b = int_code_pro[pos + 2]
else:
b = pos + 2
return a, b
def run_code(intcode_pro, signal, signal2):
code = 0
counti = 0
while code < len(intcode_pro):
if intcode_pro[code] % 100 in PRO_CODE[0:2]:
a, b = retrieve_parameters_mode_and_run(intcode_pro, code, intcode_pro[code])
intcode_pro[intcode_pro[code + 3]] = opcode_1_2(intcode_pro, intcode_pro[code] % 100, a, b)
code += 4
elif intcode_pro[code] % 100 in PRO_CODE[2:4]:
if True:
if counti == 1:
signal = signal2
counti = 1
if not opcode_3_4(intcode_pro, code, signal):
if intcode_pro[code + 2] == 99:
if intcode_pro[code] == 4:
return (intcode_pro[intcode_pro[code + 1]], intcode_pro)
return (intcode_pro[code + 1], intcode_pro)
print("Error")
return False
code += 2
elif intcode_pro[code] % 100 in PRO_CODE[4:6]:
a, b = retrieve_parameters_mode_and_run(intcode_pro, code, intcode_pro[code])
code = opcode_5_6(intcode_pro, code, a, b)
elif intcode_pro[code] % 100 in PRO_CODE[6:8]:
a, b = retrieve_parameters_mode_and_run(intcode_pro, code, intcode_pro[code])
value = opcode_7_8(intcode_pro, code, a, b)
intcode_pro[intcode_pro[code + 3]] = value
code += 4
intcode_prog = get_intcode_program("resources//day7.txt")
all_possibilites = itertools.permutations("01234", 5)
maximum = 0
for possible in all_possibilites:
output = 0
for digit in possible:
output, intcode_prog = run_code(intcode_prog, int(digit), output)
if output > maximum:
maximum = output
print(f"answer part 1 : {maximum}")
לייק 1
חלק 2 יחכה למחר כנראה. בינתיים זה נחמד מאוד
חלק 1
from itertools import permutations
# *************************************** IntCode Computer ************************************************
def get_input(path):
with open(path, 'r') as puzzle_input:
return puzzle_input.read().split(',')
def run_input(puzzle_input, op_dict, inputs):
op_code = 0
i = 0
while i < len(puzzle_input) and puzzle_input[i] != '99':
op_code = puzzle_input[i]
puzzle_input, to_increase, to_set = handle_op_code(op_code, i, puzzle_input, op_dict, inputs)
if to_increase:
i += int(to_increase)
else:
i = int(to_set)
if puzzle_input == -1:
return -1
return puzzle_input
def handle_op_code(op_code, op_code_idx, puzzle_input, op_dict, inputs):
op = get_operation(op_code)
op_code = op_code.zfill(5)
mode1 = op_code[2]
mode2 = op_code[1]
mode3 = op_code[0]
if op == 99:
return puzzle_input, _, 0
elif op == -1:
return puzzle_input, _, 0
elif op == 3:
return handle_three(op_code_idx, puzzle_input, inputs), 2, 0
elif op == 4:
if int(op_code.zfill(5)[2]):
mode = 1
else:
mode = 0
return handle_four(op_code_idx, puzzle_input, mode), 2, 0
elif op == 5:
to_set = handle_five(op_code_idx, puzzle_input, mode1, mode2, mode3)
return puzzle_input, 0, to_set
elif op == 6:
to_set = handle_six(op_code_idx, puzzle_input, mode1, mode2, mode3)
return puzzle_input, 0, to_set
elif op == 7:
return handle_seven(op_code_idx, puzzle_input, mode1, mode2, mode3), 4, 0
elif op == 8:
return handle_eight(op_code_idx, puzzle_input, mode1, mode2, mode3), 4, 0
else:
return handle_math_ops(op_dict, op, op_code_idx, puzzle_input, mode1, mode2, mode3), 4,0
def get_operation(op_code):
if op_code[-1] == '1':
return '+'
elif op_code[-1] == '2':
return '*'
elif op_code[-1] == '3':
return 3
elif op_code[-1] == '4':
return 4
elif op_code[-1] == '5':
return 5
elif op_code[-1] == '6':
return 6
elif op_code[-1] == '7':
return 7
elif op_code[-1] == '8':
return 8
elif op_code[-1] == '9':
return 99
else:
return -1
def get_args(op_code_idx, puzzle_input, modes, num_args):
args = []
if num_args == 2:
for i in range(len(modes)):
if not int(modes[i]):
args.append(int(puzzle_input[int(puzzle_input[op_code_idx + i + 1])]))
else:
args.append(int(puzzle_input[op_code_idx + i + 1]))
args.append(-1)
else:
for i in range(len(modes) - 1):
if not int(modes[i]):
args.append(int(puzzle_input[int(puzzle_input[op_code_idx + i + 1])]))
else:
args.append(int(puzzle_input[op_code_idx + i + 1]))
args.append(op_code_idx + 3)
return args
def handle_three(op_code_idx, puzzle_input, inputs):
integer = inputs[0]
inputs.pop(0)
puzzle_input[int(puzzle_input[op_code_idx + 1])] = integer
return puzzle_input
def handle_four(op_code_idx, puzzle_input, mode):
if mode:
return puzzle_input[op_code_idx + 1]
else:
return puzzle_input[int(puzzle_input[op_code_idx + 1])]
def handle_five(op_code_idx, puzzle_input, mode1, mode2, mode3):
modes = [mode1, mode2]
arg1, arg2, _ = get_args(op_code_idx, puzzle_input, modes, len(modes))
if arg1:
return arg2
else:
return op_code_idx + 3
def handle_six(op_code_idx, puzzle_input, mode1, mode2, mode3):
modes = [mode1, mode2]
arg1, arg2, _ = get_args(op_code_idx, puzzle_input, modes, len(modes))
if not arg1:
return arg2
else:
return op_code_idx + 3
def handle_seven(op_code_idx, puzzle_input, mode1, mode2, mode3):
modes = [mode1, mode2, mode3]
arg1, arg2, arg3 = get_args(op_code_idx, puzzle_input, modes, len(modes))
if arg1 < arg2:
puzzle_input[int(puzzle_input[arg3])] = '1'
else:
puzzle_input[int(puzzle_input[arg3])] = '0'
return puzzle_input
def handle_eight(op_code_idx, puzzle_input, mode1, mode2, mode3):
modes = [mode1, mode2, mode3]
arg1, arg2, arg3 = get_args(op_code_idx, puzzle_input, modes, len(modes))
if arg1 == arg2:
puzzle_input[int(puzzle_input[arg3])] = '1'
else:
puzzle_input[int(puzzle_input[arg3])] = '0'
return puzzle_input
def handle_math_ops(op_dict, op, op_code_idx, puzzle_input, mode1='0', mode2='0', mode3='0'):
arg3 = int(puzzle_input[op_code_idx + 3])
arg2 = set_arg(op_code_idx + 2, puzzle_input, mode2)
arg1 = set_arg(op_code_idx + 1, puzzle_input, mode1)
operation_result = op_dict.get(op)(arg1, arg2)
puzzle_input[arg3] = str(op_dict.get(op)(arg1, arg2))
return puzzle_input
def set_arg(idx, puzzle_input, mode):
if mode == '0':
first_input_idx = int(puzzle_input[idx])
arg = int(puzzle_input[first_input_idx])
else:
arg = int(puzzle_input[idx])
return arg
def add(num1, num2):
return num1 + num2
def multiply(num1, num2):
return num1 * num2
# *************************************** IntCode Computer ************************************************
def get_permutations(numbers):
perm = permutations(numbers)
for i in list(perm):
yield i
def get_best(puzzle_input, op_dict):
results = []
perms = get_permutations(range(0, 5))
for perm in perms:
res = '0'
for i in range(5):
inputs = [str(perm[i]), res]
res = run_input(puzzle_input, op_dict, inputs)
results.append(res)
results = [int(result) for result in results]
return max(results)
def main():
puzzle_input = get_input('input.txt')
op_dict = op_dict = {'+': add, '*': multiply}
first_part_result = get_best(puzzle_input, op_dict)
print(f'First part result: {first_part_result}')
main()
לייק 1
כבר כמעט השארתי את הסוף של זה למחר ויצאתי לרוץ… ואז בזמן הריצה איכשהו עלה לי רעיון וזה עבד!
חלק 2
from itertools import permutations
# *************************************** IntCode Computer ************************************************
def get_input(path):
with open(path, 'r') as puzzle_input:
return puzzle_input.read().split(',')
def run_input(puzzle_input, op_dict, inputs, idx=0):
op_code = 0
i = idx
while i < len(puzzle_input) and puzzle_input[i] != '99':
op_code = puzzle_input[i]
puzzle_input, to_increase, to_set = handle_op_code(op_code, i, puzzle_input, op_dict, inputs)
if to_increase:
i += int(to_increase)
else:
i = int(to_set)
if puzzle_input == -1:
return -1
if type(puzzle_input) == str:
return puzzle_input, i
if puzzle_input[i] == '99':
return 99, i
def handle_op_code(op_code, op_code_idx, puzzle_input, op_dict, inputs):
op = get_operation(op_code)
op_code = op_code.zfill(5)
mode1 = op_code[2]
mode2 = op_code[1]
mode3 = op_code[0]
if op == 99:
return puzzle_input, _, 0
elif op == -1:
return puzzle_input, _, 0
elif op == 3:
return handle_three(op_code_idx, puzzle_input, inputs), 2, 0
elif op == 4:
if int(op_code.zfill(5)[2]):
mode = 1
else:
mode = 0
return handle_four(op_code_idx, puzzle_input, mode), 2, 0
elif op == 5:
to_set = handle_five(op_code_idx, puzzle_input, mode1, mode2, mode3)
return puzzle_input, 0, to_set
elif op == 6:
to_set = handle_six(op_code_idx, puzzle_input, mode1, mode2, mode3)
return puzzle_input, 0, to_set
elif op == 7:
return handle_seven(op_code_idx, puzzle_input, mode1, mode2, mode3), 4, 0
elif op == 8:
return handle_eight(op_code_idx, puzzle_input, mode1, mode2, mode3), 4, 0
else:
return handle_math_ops(op_dict, op, op_code_idx, puzzle_input, mode1, mode2, mode3), 4,0
def get_operation(op_code):
if op_code[-1] == '1':
return '+'
elif op_code[-1] == '2':
return '*'
elif op_code[-1] == '3':
return 3
elif op_code[-1] == '4':
return 4
elif op_code[-1] == '5':
return 5
elif op_code[-1] == '6':
return 6
elif op_code[-1] == '7':
return 7
elif op_code[-1] == '8':
return 8
elif op_code[-1] == '9':
return 99
else:
return -1
def get_args(op_code_idx, puzzle_input, modes, num_args):
args = []
if num_args == 2:
for i in range(len(modes)):
if not int(modes[i]):
args.append(int(puzzle_input[int(puzzle_input[op_code_idx + i + 1])]))
else:
args.append(int(puzzle_input[op_code_idx + i + 1]))
args.append(-1)
else:
for i in range(len(modes) - 1):
if not int(modes[i]):
args.append(int(puzzle_input[int(puzzle_input[op_code_idx + i + 1])]))
else:
args.append(int(puzzle_input[op_code_idx + i + 1]))
args.append(op_code_idx + 3)
return args
def handle_three(op_code_idx, puzzle_input, inputs):
integer = inputs[0]
inputs.pop(0)
puzzle_input[int(puzzle_input[op_code_idx + 1])] = integer
return puzzle_input
def handle_four(op_code_idx, puzzle_input, mode):
if mode:
return puzzle_input[op_code_idx + 1]
else:
return puzzle_input[int(puzzle_input[op_code_idx + 1])]
def handle_five(op_code_idx, puzzle_input, mode1, mode2, mode3):
modes = [mode1, mode2]
arg1, arg2, _ = get_args(op_code_idx, puzzle_input, modes, len(modes))
if arg1:
return arg2
else:
return op_code_idx + 3
def handle_six(op_code_idx, puzzle_input, mode1, mode2, mode3):
modes = [mode1, mode2]
arg1, arg2, _ = get_args(op_code_idx, puzzle_input, modes, len(modes))
if not arg1:
return arg2
else:
return op_code_idx + 3
def handle_seven(op_code_idx, puzzle_input, mode1, mode2, mode3):
modes = [mode1, mode2, mode3]
arg1, arg2, arg3 = get_args(op_code_idx, puzzle_input, modes, len(modes))
if arg1 < arg2:
puzzle_input[int(puzzle_input[arg3])] = '1'
else:
puzzle_input[int(puzzle_input[arg3])] = '0'
return puzzle_input
def handle_eight(op_code_idx, puzzle_input, mode1, mode2, mode3):
modes = [mode1, mode2, mode3]
arg1, arg2, arg3 = get_args(op_code_idx, puzzle_input, modes, len(modes))
if arg1 == arg2:
puzzle_input[int(puzzle_input[arg3])] = '1'
else:
puzzle_input[int(puzzle_input[arg3])] = '0'
return puzzle_input
def handle_math_ops(op_dict, op, op_code_idx, puzzle_input, mode1='0', mode2='0', mode3='0'):
arg3 = int(puzzle_input[op_code_idx + 3])
arg2 = set_arg(op_code_idx + 2, puzzle_input, mode2)
arg1 = set_arg(op_code_idx + 1, puzzle_input, mode1)
operation_result = op_dict.get(op)(arg1, arg2)
puzzle_input[arg3] = str(op_dict.get(op)(arg1, arg2))
return puzzle_input
def set_arg(idx, puzzle_input, mode):
if mode == '0':
first_input_idx = int(puzzle_input[idx])
arg = int(puzzle_input[first_input_idx])
else:
arg = int(puzzle_input[idx])
return arg
def add(num1, num2):
return num1 + num2
def multiply(num1, num2):
return num1 * num2
# *************************************** IntCode Computer ************************************************
def get_permutations(numbers):
perm = permutations(numbers)
for i in list(perm):
yield i
def part_two(puzzle_input, op_dict):
results = []
perms = get_permutations(range(5, 10))
for perm in perms:
res = '0'
i = 0
j = 0
flag = False
amplifiers_pos = [0, 0, 0, 0, 0]
puzzle_input_copies = []
for k in range(5):
puzzle_input_copies.append(puzzle_input.copy())
while res != 99:
if not flag:
inputs = [str(perm[i]), res]
else:
inputs = [res]
prev_res = res
res, j = run_input(puzzle_input_copies[i], op_dict, inputs, amplifiers_pos[i])
amplifiers_pos[i] = j
if (i + 1) % 5 == 0:
flag = True
i = (i + 1) % 5
results.append(prev_res)
results = [int(result) for result in results]
return max(results)
def main():
puzzle_input = get_input('input.txt')
op_dict = op_dict = {'+': add, '*': multiply}
second_part_result = part_two(puzzle_input, op_dict)
print(second_part_result)
main()
2 לייקים
אסגור ברביעי
לייק 1
וואי וואי, חלש פה הפעם
לא מת על הפתרון שלי, אבל עובד.
מסיבות של חוסר זמן לא צנזרתי דברים שאתם לא יודעים, אבל אין פה איזו טכניקה מטורפת שגורמת להכול להיות יותר קל.
import itertools
import operator
from copy import copy
from typing import (
Any, Callable, Dict, Iterable, Iterator, List, Optional, Tuple, Union,
)
from typing_extensions import TypedDict
Command = TypedDict(
'Command',
{
'size': int, 'function': Callable[..., Any],
'jump': bool, 'void': int, 'method': bool,
},
total=False,
)
ParsedCmds = Iterator[int]
vmethod = {'void': 1, 'method': True}
class IntcodeMachine:
OPCODES: Dict[int, Command] = {
1: {'size': 4, 'function': operator.add},
2: {'size': 4, 'function': operator.mul},
3: {'size': 2, 'function': lambda s: s.get_input(), 'method': True},
4: {'size': 2, 'function': lambda s, v: s.add_output(v), **vmethod},
5: {'size': 3, 'function': operator.truth, 'jump': True},
6: {'size': 3, 'function': operator.not_, 'jump': True},
7: {'size': 4, 'function': lambda x, y: bool(operator.lt(x, y))},
8: {'size': 4, 'function': lambda x, y: bool(operator.eq(x, y))},
}
def __init__(self, code: List[int], inputs: Iterable[int]) -> None:
self.eip = 0 # Instructions pointer
self.code = code
self._inputs = iter(inputs)
self._outputs_index = 0
self._outputs: List[int] = []
@property
def opcode(self) -> int:
return self.code[self.eip] % 100
@property
def is_halt(self) -> bool:
return self.opcode == 99
@property
def is_jump(self) -> bool:
return self.opcode_get('jump', False)
def add_inputs(self, inputs: Union[int, List[int]]) -> None:
if not isinstance(inputs, (list, tuple)):
inputs = [inputs]
self._inputs = itertools.chain(self._inputs, inputs)
def get_input(self) -> Optional[int]:
try:
return next(self._inputs)
except StopIteration:
return None
def add_output(self, outputs: Union[int, List[int]]) -> None:
if not isinstance(outputs, (list, tuple)):
outputs = [outputs]
self._outputs.extend(outputs)
def get_outputs(self) -> List[int]:
outputs = self._outputs[self._outputs_index:]
self._outputs_index = len(self._outputs)
return outputs
@property
def modes(self) -> Tuple[int, int, int]:
modes_part = self.code[self.eip] // 100
return modes_part % 10, modes_part // 10 % 10, modes_part // 100
def opcode_get(self, prop: str, default: Any = None) -> Any:
return self.OPCODES[self.opcode].get(prop, default)
@property
def argc(self) -> int:
return self.opcode_get('size', 2) - 2
@property
def args(self) -> List[int]:
offset = self.argc + self.opcode_get('void', 0)
params = self.code[self.eip + 1:self.eip + 1 + offset]
out = []
for param, mode in zip(params, self.modes):
out.append(param if mode else self.code[param])
if self.opcode_get('method'):
out.insert(0, self)
return out
@property
def write_address(self) -> Optional[int]:
if self.opcode_get('void'):
return None
write_to = self.code[self.eip + 1 + self.argc]
is_relative_jump = self.is_jump and self.modes[self.argc] == 0
return self.code[write_to] if is_relative_jump else write_to
def __call__(self) -> List[int]:
while self.opcode != 99:
op_size = self.opcode_get('size')
args, write_to = self.args, self.write_address
returns = self.opcode_get('function')(*args)
if returns is None and self.opcode == 3:
return self.get_outputs() # Halt until you get input
if write_to is not None and not self.is_jump:
self.code[write_to] = returns
should_jump = self.is_jump and returns
self.eip = write_to if should_jump else (self.eip + op_size)
return self.get_outputs()
def get_input() -> List[int]:
with open('input.txt', 'r') as challenge_input:
return list(map(int, challenge_input.read().strip().split(',')))
# Part 1
program = get_input()
outputs = []
for phases in itertools.permutations(list(range(5))):
current_input = 0
for phase in phases:
current_machine = IntcodeMachine(program, [phase, current_input])
current_input = current_machine()[-1]
program = current_machine.code
outputs.append(current_input)
print(max(outputs))
# Part 2
program = get_input()
max_output = 0
for phases in itertools.permutations(list(range(5, 10))):
machines = [IntcodeMachine(copy(get_input()), [phase]) for phase in phases]
next_input = 0
i = 0
while not machines[-1].is_halt:
machines[i].add_inputs(next_input)
next_input = machines[i]()[-1]
i = (i + 1) % len(machines)
max_output = max(max_output, next_input)
print(max_output)
לייק 1
תאמין או לא - מסתבר שהקטע עם הריצה קרה גם לי!
קצת באיחור, אבל פתרתי. עובר ל-8
Advent of Code, Day 7
# ADVENT OF CODE, DAY 7
from itertools import permutations
def get_intcode():
with open('input.txt', 'r') as file:
intcode = file.read().split(',')
intcode = intcode_items_to_int(intcode)
return intcode
def intcode_items_to_int(intcode):
for i, num in enumerate(intcode):
intcode[i] = int(intcode[i])
return intcode
def read_instruction(code):
opcode = int(code) % 100
parameters = str(int(code) // 100).zfill(3)
return opcode, parameters
def run_intcode(amp_memory, phase, intcode):
i = 0
j = 0
is_phase = True
is_ended = False
current_output = 0
while i < len(intcode):
opcode, parameters = read_instruction(intcode[i])
if opcode == 1 or opcode == 2:
if parameters[2] == '0':
num1 = intcode[intcode[i + 1]]
elif parameters[2] == '1':
num1 = intcode[i + 1]
if parameters[1] == '0':
num2 = intcode[intcode[i + 2]]
elif parameters[1] == '1':
num2 = intcode[i + 2]
if opcode == 1:
intcode[intcode[i + 3]] = num1 + num2
else:
intcode[intcode[i + 3]] = num1 * num2
i += 4
if opcode == 3:
if is_phase:
intcode[intcode[i + 1]] = phase
is_phase = False
else:
intcode[intcode[i + 1]] = amp_memory[j]
j += 1
i += 2
if opcode == 4:
if parameters[2] == '0':
current_output = intcode[intcode[i + 1]]
elif parameters[2] == '1':
current_output = intcode[i + 1]
if j == len(amp_memory):
return intcode, current_output, is_ended
i += 2
if opcode == 5 or opcode == 6:
if parameters[2] == '0':
num1 = intcode[intcode[i + 1]]
elif parameters[2] == '1':
num1 = intcode[i + 1]
if opcode == 5:
if num1 != 0:
if parameters[1] == '0':
i = intcode[intcode[i + 2]]
if parameters[1] == '1':
i = intcode[i + 2]
else:
i += 3
if opcode == 6:
if num1 == 0:
if parameters[1] == '0':
i = intcode[intcode[i + 2]]
if parameters[1] == '1':
i = intcode[i + 2]
else:
i += 3
if opcode == 7 or opcode ==8:
if parameters[2] == '0':
num1 = intcode[intcode[i + 1]]
elif parameters[2] == '1':
num1 = intcode[i + 1]
if parameters[1] == '0':
num2 = intcode[intcode[i + 2]]
elif parameters[1] == '1':
num2 = intcode[i + 2]
if opcode == 7:
if num1 < num2:
intcode[intcode[i + 3]] = 1
else:
intcode[intcode[i + 3]] = 0
if opcode == 8:
if num1 == num2:
intcode[intcode[i + 3]] = 1
else:
intcode[intcode[i + 3]] = 0
i += 4
if opcode == 99:
is_ended = True
return intcode, current_output, is_ended
def feedback_loop(phases):
options = list(permutations(phases))
max_thrusters = 0
correct_phases = []
current_amp = 'a'
for option in options:
amp_a = [0]
amp_b = []
amp_c = []
amp_d = []
amp_e = []
is_complete = False
j = 0
while not is_complete:
for phase in option:
intcode = get_intcode()
if current_amp == 'a':
intcode, output_value, _ = run_intcode(amp_a, phase, intcode)
amp_b.append(output_value)
current_amp = 'b'
elif current_amp == 'b':
intcode, output_value, _ = run_intcode(amp_b, phase, intcode)
amp_c.append(output_value)
current_amp = 'c'
elif current_amp == 'c':
intcode, output_value, _ = run_intcode(amp_c, phase, intcode)
amp_d.append(output_value)
current_amp = 'd'
elif current_amp == 'd':
intcode, output_value, _ = run_intcode(amp_d, phase, intcode)
amp_e.append(output_value)
current_amp = 'e'
elif current_amp == 'e':
intcode, output_value, is_complete = run_intcode(amp_e, phase, intcode)
amp_a.append(output_value)
current_amp = 'a'
if amp_a[-1] > max_thrusters:
max_thrusters = amp_a[-1]
correct_phases = option
return (max_thrusters, correct_phases)
# PART 1
print(feedback_loop([0, 1, 2, 3, 4]))
# PART 2
print(feedback_loop([5, 6, 7, 8, 9]))
2 לייקים