@@ -12,6 +12,7 @@ class IntCode:
1212"06" :3 ,
1313"07" :4 ,
1414"08" :4 ,
15+ "09" :2 ,
1516"99" :1 ,
1617 }
1718
@@ -22,6 +23,7 @@ def __init__(self, instructions, reference=""):
2223# Current state
2324self .pointer = 0
2425self .state = "Running"
26+ self .relative_base = 0
2527
2628# Current instruction modes
2729self .modes = "000"
@@ -58,26 +60,71 @@ def get_instruction(self, opcode):
5860 ]
5961
6062def get_value (self ,param_position ):
63+ assert self .modes [2 - (param_position - 1 )]in "012"
64+ try :
65+ if self .modes [2 - (param_position - 1 )]== "0" :
66+ return self .instructions [
67+ self .instructions [self .pointer + param_position ]
68+ ]
69+ elif self .modes [2 - (param_position - 1 )]== "1" :
70+ return self .instructions [self .pointer + param_position ]
71+ else :
72+ return self .instructions [
73+ self .relative_base
74+ + self .instructions [self .pointer + param_position ]
75+ ]
76+ except :
77+ return 0
78+
79+ def set_value (self ,param_position ,value ):
80+ assert self .modes [2 - (param_position - 1 )]in "02"
6181if self .modes [2 - (param_position - 1 )]== "0" :
62- return self .instructions [self .instructions [self .pointer + param_position ]]
82+ try :
83+ self .instructions [
84+ self .instructions [self .pointer + param_position ]
85+ ]= value
86+ except :
87+ self .instructions += [0 ]* (
88+ self .instructions [self .pointer + param_position ]
89+ - len (self .instructions )
90+ + 1
91+ )
92+ self .instructions [
93+ self .instructions [self .pointer + param_position ]
94+ ]= value
6395else :
64- return self .instructions [self .pointer + param_position ]
96+ try :
97+ self .instructions [
98+ self .relative_base
99+ + self .instructions [self .pointer + param_position ]
100+ ]= value
101+ except :
102+ self .instructions += [0 ]* (
103+ self .relative_base
104+ + self .instructions [self .pointer + param_position ]
105+ - len (self .instructions )
106+ + 1
107+ )
108+ self .instructions [
109+ self .relative_base
110+ + self .instructions [self .pointer + param_position ]
111+ ]= value
65112
66113def op_01 (self ,instr ):
67- self .instructions [ instr [ 3 ]] = self .get_value (1 )+ self .get_value (2 )
114+ self .set_value ( 3 , self .get_value (1 )+ self .get_value (2 ) )
68115self .pointer += self .instr_length ["01" ]
69116self .state = "Running"
70117
71118def op_02 (self ,instr ):
72- self .instructions [ instr [ 3 ]] = self .get_value (1 )* self .get_value (2 )
119+ self .set_value ( 3 , self .get_value (1 )* self .get_value (2 ) )
73120self .pointer += self .instr_length ["02" ]
74121self .state = "Running"
75122
76123def op_03 (self ,instr ):
77124if len (self .inputs )== 0 :
78125self .state = "Paused"
79126return
80- self .instructions [ instr [ 1 ]] = self .inputs .pop (0 )
127+ self .set_value ( 1 , self .inputs .pop (0 ) )
81128self .pointer += self .instr_length ["03" ]
82129self .state = "Running"
83130
@@ -102,20 +149,25 @@ def op_06(self, instr):
102149
103150def op_07 (self ,instr ):
104151if self .get_value (1 )< self .get_value (2 ):
105- self .instructions [ instr [ 3 ]] = 1
152+ self .set_value ( 3 , 1 )
106153else :
107- self .instructions [ instr [ 3 ]] = 0
154+ self .set_value ( 3 , 0 )
108155self .pointer += self .instr_length ["07" ]
109156self .state = "Running"
110157
111158def op_08 (self ,instr ):
112159if self .get_value (1 )== self .get_value (2 ):
113- self .instructions [ instr [ 3 ]] = 1
160+ self .set_value ( 3 , 1 )
114161else :
115- self .instructions [ instr [ 3 ]] = 0
162+ self .set_value ( 3 , 0 )
116163self .pointer += self .instr_length ["08" ]
117164self .state = "Running"
118165
166+ def op_09 (self ,instr ):
167+ self .relative_base += self .get_value (1 )
168+ self .pointer += self .instr_length ["09" ]
169+ self .state = "Running"
170+
119171def op_99 (self ,instr ):
120172self .pointer += self .instr_length ["99" ]
121173self .state = "Stopped"
@@ -139,6 +191,7 @@ def export(self):
139191if self .reference != "" :
140192output += "Computer # " + str (self .reference )
141193output += "\n " + "Instructions: " + "," .join (map (str ,self .instructions ))
194+ output += "\n " + "Relative base: " + str (self .relative_base )
142195output += "\n " + "Inputs: " + "," .join (map (str ,self .all_inputs ))
143196output += "\n " + "Outputs: " + "," .join (map (str ,self .outputs ))
144197return output