|
| 1 | +# -------------------------------- Input data ---------------------------------------- # |
| 2 | +importos |
| 3 | + |
| 4 | +test_data= {} |
| 5 | + |
| 6 | +test=1 |
| 7 | +test_data[test]= { |
| 8 | +"input":"""Before: [3, 2, 1, 1] |
| 9 | +9 2 1 2 |
| 10 | +After: [3, 2, 2, 1]""", |
| 11 | +"expected": ["Unknown","Unknown"], |
| 12 | +} |
| 13 | + |
| 14 | +test="real" |
| 15 | +input_file=os.path.join( |
| 16 | +os.path.dirname(__file__), |
| 17 | +"Inputs", |
| 18 | +os.path.basename(__file__).replace(".py",".txt"), |
| 19 | +) |
| 20 | +test_data[test]= { |
| 21 | +"input":open(input_file,"r+").read().strip(), |
| 22 | +"expected": ["Unknown","Unknown"], |
| 23 | +} |
| 24 | + |
| 25 | +# -------------------------------- Control program execution ------------------------- # |
| 26 | + |
| 27 | +case_to_test="real" |
| 28 | +part_to_test=2 |
| 29 | + |
| 30 | +# -------------------------------- Initialize some variables ------------------------- # |
| 31 | + |
| 32 | +puzzle_input=test_data[case_to_test]["input"] |
| 33 | +puzzle_expected_result=test_data[case_to_test]["expected"][part_to_test-1] |
| 34 | +puzzle_actual_result="Unknown" |
| 35 | + |
| 36 | + |
| 37 | +# -------------------------------- Actual code execution ----------------------------- # |
| 38 | + |
| 39 | +registers= [0]*4 |
| 40 | + |
| 41 | +i=0 |
| 42 | +file_contents=puzzle_input.splitlines() |
| 43 | +nb_lines=len(file_contents) |
| 44 | + |
| 45 | +more_than_3_opcodes=0 |
| 46 | +opcodes_mapping= {i: []foriinrange(16)} |
| 47 | +whilei<nb_lines: |
| 48 | +iffile_contents[i]=="": |
| 49 | +i+=1 |
| 50 | +continue |
| 51 | +eliffile_contents[i][:4]!="Befo": |
| 52 | +i+=1 |
| 53 | +continue |
| 54 | + |
| 55 | +test_program=file_contents[i+6 :] |
| 56 | + |
| 57 | +before,operation,after=file_contents[i :i+3] |
| 58 | + |
| 59 | +numeric_opcode=int(operation.split(" ")[0]) |
| 60 | +a,b,c=map(int,operation.split(" ")[1:]) |
| 61 | + |
| 62 | +init=before[9:-1].split(", ") |
| 63 | +init= [int(x)forxininit] |
| 64 | + |
| 65 | +final=after[9:-1].split(", ") |
| 66 | +final= [int(x)forxinfinal] |
| 67 | + |
| 68 | +matching_opcodes= [] |
| 69 | + |
| 70 | +foropcodein [ |
| 71 | +"addr", |
| 72 | +"addi", |
| 73 | +"mulr", |
| 74 | +"muli", |
| 75 | +"banr", |
| 76 | +"bani", |
| 77 | +"borr", |
| 78 | +"bori", |
| 79 | +"setr", |
| 80 | +"seti", |
| 81 | +"gtir", |
| 82 | +"gtri", |
| 83 | +"gtrr", |
| 84 | +"eqir", |
| 85 | +"eqri", |
| 86 | +"eqrr", |
| 87 | + ]: |
| 88 | +registers=init.copy() |
| 89 | + |
| 90 | +ifopcode=="addr": |
| 91 | +registers[c]=registers[a]+registers[b] |
| 92 | +elifopcode=="addi": |
| 93 | +registers[c]=registers[a]+b |
| 94 | + |
| 95 | +elifopcode=="mulr": |
| 96 | +registers[c]=registers[a]*registers[b] |
| 97 | +elifopcode=="muli": |
| 98 | +registers[c]=registers[a]*b |
| 99 | + |
| 100 | +elifopcode=="banr": |
| 101 | +registers[c]=registers[a]®isters[b] |
| 102 | +elifopcode=="bani": |
| 103 | +registers[c]=registers[a]&b |
| 104 | + |
| 105 | +elifopcode=="borr": |
| 106 | +registers[c]=registers[a]|registers[b] |
| 107 | +elifopcode=="bori": |
| 108 | +registers[c]=registers[a]|b |
| 109 | + |
| 110 | +elifopcode=="setr": |
| 111 | +registers[c]=registers[a] |
| 112 | +elifopcode=="seti": |
| 113 | +registers[c]=a |
| 114 | + |
| 115 | +elifopcode=="gtir": |
| 116 | +registers[c]=1ifa>registers[b]else0 |
| 117 | +elifopcode=="gtri": |
| 118 | +registers[c]=1ifregisters[a]>belse0 |
| 119 | +elifopcode=="gtrr": |
| 120 | +registers[c]=1ifregisters[a]>registers[b]else0 |
| 121 | + |
| 122 | +elifopcode=="eqir": |
| 123 | +registers[c]=1ifa==registers[b]else0 |
| 124 | +elifopcode=="eqri": |
| 125 | +registers[c]=1ifregisters[a]==belse0 |
| 126 | +elifopcode=="eqrr": |
| 127 | +registers[c]=1ifregisters[a]==registers[b]else0 |
| 128 | + |
| 129 | +ifregisters==final: |
| 130 | +opcodes_mapping[numeric_opcode].append(opcode) |
| 131 | +matching_opcodes.append(opcode) |
| 132 | + |
| 133 | +iflen(matching_opcodes)>=3: |
| 134 | +more_than_3_opcodes+=1 |
| 135 | + |
| 136 | +i+=3 |
| 137 | + |
| 138 | +ifpart_to_test==1: |
| 139 | +puzzle_actual_result=more_than_3_opcodes |
| 140 | + |
| 141 | +else: |
| 142 | +opcodes_mapping= {i:set(opcodes_mapping[i])foriinopcodes_mapping} |
| 143 | + |
| 144 | +final_mapping= [0]*16 |
| 145 | + |
| 146 | +while0infinal_mapping: |
| 147 | +new_match= [iforiinopcodes_mappingiflen(opcodes_mapping[i])==1] |
| 148 | +numeric,alpha=new_match[0],opcodes_mapping[new_match[0]].pop() |
| 149 | + |
| 150 | +final_mapping[numeric]=alpha |
| 151 | + |
| 152 | +foriinopcodes_mapping: |
| 153 | +ifalphainopcodes_mapping[i]: |
| 154 | +opcodes_mapping[i].remove(alpha) |
| 155 | + |
| 156 | +registers= [0]*4 |
| 157 | +foroperationintest_program: |
| 158 | +opcode=final_mapping[int(operation.split(" ")[0])] |
| 159 | +a,b,c=map(int,operation.split(" ")[1:]) |
| 160 | + |
| 161 | +print(operation,opcode,a,b,c) |
| 162 | + |
| 163 | +ifopcode=="addr": |
| 164 | +registers[c]=registers[a]+registers[b] |
| 165 | +elifopcode=="addi": |
| 166 | +registers[c]=registers[a]+b |
| 167 | + |
| 168 | +elifopcode=="mulr": |
| 169 | +registers[c]=registers[a]*registers[b] |
| 170 | +elifopcode=="muli": |
| 171 | +registers[c]=registers[a]*b |
| 172 | + |
| 173 | +elifopcode=="banr": |
| 174 | +registers[c]=registers[a]®isters[b] |
| 175 | +elifopcode=="bani": |
| 176 | +registers[c]=registers[a]&b |
| 177 | + |
| 178 | +elifopcode=="borr": |
| 179 | +registers[c]=registers[a]|registers[b] |
| 180 | +elifopcode=="bori": |
| 181 | +registers[c]=registers[a]|b |
| 182 | + |
| 183 | +elifopcode=="setr": |
| 184 | +registers[c]=registers[a] |
| 185 | +elifopcode=="seti": |
| 186 | +registers[c]=a |
| 187 | + |
| 188 | +elifopcode=="gtir": |
| 189 | +registers[c]=1ifa>registers[b]else0 |
| 190 | +elifopcode=="gtri": |
| 191 | +registers[c]=1ifregisters[a]>belse0 |
| 192 | +elifopcode=="gtrr": |
| 193 | +registers[c]=1ifregisters[a]>registers[b]else0 |
| 194 | + |
| 195 | +elifopcode=="eqir": |
| 196 | +registers[c]=1ifa==registers[b]else0 |
| 197 | +elifopcode=="eqri": |
| 198 | +registers[c]=1ifregisters[a]==belse0 |
| 199 | +elifopcode=="eqrr": |
| 200 | +registers[c]=1ifregisters[a]==registers[b]else0 |
| 201 | + |
| 202 | +puzzle_actual_result=registers[0] |
| 203 | + |
| 204 | +# -------------------------------- Outputs / results --------------------------------- # |
| 205 | + |
| 206 | +print("Expected result : "+str(puzzle_expected_result)) |
| 207 | +print("Actual result : "+str(puzzle_actual_result)) |