[New-bugs-announce] [issue39000] Range causing unstable output(Windows64)
Sean Moss
report at bugs.python.org
Sun Dec 8 15:09:03 EST 2019
New submission from Sean Moss <smoss117 at gmail.com>:
I was doing this year's Advent of Code and found that the following program produces unstable output when run using the given file as input:
"""
from itertools import permutations
import gc
def runProgram(amp_input, program, counter):
while program[counter] != 99:
# print('*' * 99)
instruction = str(program[counter])
opcode = instruction[-2:]
value1 = program[counter + 1]
# print('2:{}'.format(counter))
try:
if opcode in ['01', '02', '1', '2', '5', '05', '6', '06', '7', '07', '8', '08']:
value1 = program[counter + 1]
value2 = program[counter + 2]
param_modes = instruction[::-1][2:]
# print('{} {} {} {}'.format(instruction, value1, value2, value3))
param_modes += '0' * (3 - len(param_modes))
# print(param_modes)
if param_modes[0] == '0':
value1 = program[value1]
if param_modes[1] == '0':
value2 = program[value2]
# print('{} {} {} {}'.format(instruction, value1, value2, value3))
if opcode in ['01', '02', '1', '2', '7', '07', '8', '08']:
value3 = program[counter + 3]
if opcode.endswith('1'):
program[value3] = value1 + value2
elif opcode.endswith('2'):
program[value3] = value1 * value2
elif opcode in ['7', '07']:
program[value3] = 1 if value1 < value2 else 0
elif opcode in ['8', '08']:
program[value3] = 1 if value1 == value2 else 0
counter += 4
elif opcode in ['5', '05']:
if value1 != 0:
counter = value2
else:
counter += 3
elif opcode in ['6', '06']:
if value1 == 0:
counter = value2
else:
counter += 3
elif opcode in ['03', '3']:
program[value1] = amp_input.pop(0)
counter += 2
elif opcode in ['4', '04']:
# print('{} {}'.format(instruction, value1))
if instruction != '104':
value1 = program[value1]
# print('Output value: {}'.format(value1))
counter += 2
return value1, counter
else:
print("Something broke at {}".format(counter))
print("program state {}".format(program))
print(instruction)
return False
except Exception as e:
print("Out of bounds at {}".format(counter))
print("program state {}".format(program))
print(instruction)
print(e)
print(len(program))
return
return program, True
outputs = []
max_output = 0
# initial_program = list(map(int, open('input7.txt').read().split(',')))
amp_ids = ['A', 'B', 'C', 'D', 'E']
permutation = [5, 6, 7, 8, 9]
# for permutation in permutations([5, 6, 7, 8, 9]):
amp_programs = {amp_id: [list(map(int, open('input7.txt').read().split(',')))[:], 0] for amp_id in ['A', 'B', 'C', 'D', 'E']}
loops = 0
prev_output = 0
for x in range(0, 5):
gc.collect()
new_output, outer_counter = runProgram([permutation[x], prev_output], amp_programs[amp_ids[x]][0], amp_programs[amp_ids[x]][1])
if outer_counter is not True:
prev_output = new_output
amp_programs[amp_ids[x]][1] = outer_counter
# print(new_output)
while amp_programs['E'][1] is not True:
gc.collect()
for amp_id in amp_programs.keys():
amp = amp_programs[amp_id]
# print(prev_output)
# print('1:{}'.format(amp[1]))
new_output, outer_counter = runProgram([prev_output], amp[0], amp[1])
if outer_counter is not True:
prev_output = new_output
amp[1] = outer_counter
# print('{}, {}'.format(amp[1], outer_counter))
# outputs.append(prev_output)
# print(prev_output)
outputs.append(prev_output)
# if prev_output > max_output:
# max_output = prev_output
print(max(outputs))
# print(outputs)
"""
However when this program is run on the same input it produces stable input:
"""
from itertools import permutations
def runProgram(amp_input, program, counter):
while program[counter] != 99:
# print('*' * 99)
instruction = str(program[counter])
opcode = instruction[-2:]
value1 = program[counter + 1]
# print('2:{}'.format(counter))
try:
if opcode in ['01', '02', '1', '2', '5', '05', '6', '06', '7', '07', '8', '08']:
value1 = program[counter + 1]
value2 = program[counter + 2]
param_modes = instruction[::-1][2:]
# print('{} {} {} {}'.format(instruction, value1, value2, value3))
param_modes += '0' * (3 - len(param_modes))
# print(param_modes)
if param_modes[0] == '0':
value1 = program[value1]
if param_modes[1] == '0':
value2 = program[value2]
# print('{} {} {} {}'.format(instruction, value1, value2, value3))
if opcode in ['01', '02', '1', '2', '7', '07', '8', '08']:
value3 = program[counter + 3]
if opcode.endswith('1'):
program[value3] = value1 + value2
elif opcode.endswith('2'):
program[value3] = value1 * value2
elif opcode in ['7', '07']:
program[value3] = 1 if value1 < value2 else 0
elif opcode in ['8', '08']:
program[value3] = 1 if value1 == value2 else 0
counter += 4
elif opcode in ['5', '05']:
if value1 != 0:
counter = value2
else:
counter += 3
elif opcode in ['6', '06']:
if value1 == 0:
counter = value2
else:
counter += 3
elif opcode in ['03', '3']:
program[value1] = amp_input.pop(0)
counter += 2
elif opcode in ['4', '04']:
# print('{} {}'.format(instruction, value1))
if instruction != '104':
value1 = program[value1]
# print('Output value: {}'.format(value1))
counter += 2
return value1, counter
else:
print("Something broke at {}".format(counter))
print("program state {}".format(program))
print(instruction)
return False
except Exception as e:
print("Out of bounds at {}".format(counter))
print("program state {}".format(program))
print(instruction)
print(e)
print(len(program))
return
return program, True
outputs = []
max_output = 0
# initial_program = list(map(int, open('input7.txt').read().split(',')))
amp_ids = ['A', 'B', 'C', 'D', 'E']
permutation = [5, 6, 7, 8, 9]
# for permutation in permutations([5, 6, 7, 8, 9]):
amp_programs = {amp_id: [list(map(int, open('input7.txt').read().split(',')))[:], 0] for amp_id in ['A', 'B', 'C', 'D', 'E']}
loops = 0
prev_output = 0
for amp, perm in zip(amp_programs.values(), permutation):
new_output, outer_counter = runProgram([perm, prev_output], amp[0], amp[1])
if outer_counter is not True:
prev_output = new_output
amp[1] = outer_counter
# print(new_output)
while amp_programs['E'][1] is not True:
for amp_id in amp_programs.keys():
amp = amp_programs[amp_id]
# print(prev_output)
# print('1:{}'.format(amp[1]))
new_output, outer_counter = runProgram([prev_output], amp[0], amp[1])
if outer_counter is not True:
prev_output = new_output
amp[1] = outer_counter
# print('{}, {}'.format(amp[1], outer_counter))
# outputs.append(prev_output)
# print(prev_output)
outputs.append(prev_output)
# if prev_output > max_output:
# max_output = prev_output
print(max(outputs))
# print(outputs)
"""
The only difference is that the second program uses the zip function to iterate while the first uses the range function to iterate. Again this is not a case of divergent output, it's that the first program doesn't always have the same output, the second program always has the same output.
----------
components: Library (Lib)
files: input7.txt
messages: 358022
nosy: Sean Moss
priority: normal
severity: normal
status: open
title: Range causing unstable output(Windows64)
type: behavior
versions: Python 3.5
Added file: https://bugs.python.org/file48766/input7.txt
_______________________________________
Python tracker <report at bugs.python.org>
<https://bugs.python.org/issue39000>
_______________________________________
More information about the New-bugs-announce
mailing list