@@ -11,103 +11,103 @@ pub enum State {
1111
1212pub struct Computer {
1313 pc : usize ,
14- base : i64 ,
15- code : Vec < i64 > ,
16- input : VecDeque < i64 > ,
14+ base : usize ,
15+ code : Vec < usize > ,
16+ input : VecDeque < usize > ,
1717}
1818
1919impl Computer {
2020 pub fn new ( input : & [ i64 ] ) -> Computer {
2121 let mut code = Vec :: with_capacity ( input. len ( ) + EXTRA ) ;
22- code. extend_from_slice ( input) ;
22+ code. extend ( input. iter ( ) . map ( | & i| i as usize ) ) ;
2323 code. resize ( input. len ( ) + EXTRA , 0 ) ;
2424
2525 Computer { pc : 0 , base : 0 , code, input : VecDeque :: new ( ) }
2626 }
2727
2828 pub fn input ( & mut self , value : i64 ) {
29- self . input . push_back ( value) ;
29+ self . input . push_back ( value as usize ) ;
3030 }
3131
3232 pub fn input_ascii ( & mut self , ascii : & str ) {
33- self . input . extend ( ascii. bytes ( ) . map ( |b| b as i64 ) ) ;
33+ self . input . extend ( ascii. bytes ( ) . map ( |b| b as usize ) ) ;
3434 }
3535
3636 /// Runs until either the program needs input, outputs a value or encounters the halt opcode.
3737 /// In the first two cases, the computer can be resumed by calling `run` again.
3838 pub fn run ( & mut self ) -> State {
3939 loop {
40- let code = self . code [ self . pc ] ;
40+ let op = self . code [ self . pc ] ;
4141
42- match code % 100 {
42+ match op % 100 {
4343 // Add
4444 1 => {
45- let first = self . address ( code / 100 , 1 ) ;
46- let second = self . address ( code / 1000 , 2 ) ;
47- let third = self . address ( code / 10000 , 3 ) ;
48- self . code [ third] = self . code [ first] + self . code [ second] ;
45+ let first = self . address ( op / 100 , 1 ) ;
46+ let second = self . address ( op / 1000 , 2 ) ;
47+ let third = self . address ( op / 10000 , 3 ) ;
48+ self . code [ third] = self . code [ first] . wrapping_add ( self . code [ second] ) ;
4949 self . pc += 4 ;
5050 }
5151 // Multiply
5252 2 => {
53- let first = self . address ( code / 100 , 1 ) ;
54- let second = self . address ( code / 1000 , 2 ) ;
55- let third = self . address ( code / 10000 , 3 ) ;
56- self . code [ third] = self . code [ first] * self . code [ second] ;
53+ let first = self . address ( op / 100 , 1 ) ;
54+ let second = self . address ( op / 1000 , 2 ) ;
55+ let third = self . address ( op / 10000 , 3 ) ;
56+ self . code [ third] = self . code [ first] . wrapping_mul ( self . code [ second] ) ;
5757 self . pc += 4 ;
5858 }
5959 // Read input channel
6060 3 => {
6161 let Some ( value) = self . input . pop_front ( ) else {
6262 break State :: Input ;
6363 } ;
64- let first = self . address ( code / 100 , 1 ) ;
64+ let first = self . address ( op / 100 , 1 ) ;
6565 self . code [ first] = value;
6666 self . pc += 2 ;
6767 }
6868 // Write output channel
6969 4 => {
70- let first = self . address ( code / 100 , 1 ) ;
70+ let first = self . address ( op / 100 , 1 ) ;
7171 let value = self . code [ first] ;
7272 self . pc += 2 ;
73- break State :: Output ( value) ;
73+ break State :: Output ( value as i64 ) ;
7474 }
7575 // Jump if true
7676 5 => {
77- let first = self . address ( code / 100 , 1 ) ;
78- let second = self . address ( code / 1000 , 2 ) ;
77+ let first = self . address ( op / 100 , 1 ) ;
78+ let second = self . address ( op / 1000 , 2 ) ;
7979 let value = self . code [ first] == 0 ;
80- self . pc = if value { self . pc + 3 } else { self . code [ second] as usize } ;
80+ self . pc = if value { self . pc + 3 } else { self . code [ second] } ;
8181 }
8282 // Jump if false
8383 6 => {
84- let first = self . address ( code / 100 , 1 ) ;
85- let second = self . address ( code / 1000 , 2 ) ;
84+ let first = self . address ( op / 100 , 1 ) ;
85+ let second = self . address ( op / 1000 , 2 ) ;
8686 let value = self . code [ first] == 0 ;
87- self . pc = if value { self . code [ second] as usize } else { self . pc + 3 } ;
87+ self . pc = if value { self . code [ second] } else { self . pc + 3 } ;
8888 }
8989 // Less than
9090 7 => {
91- let first = self . address ( code / 100 , 1 ) ;
92- let second = self . address ( code / 1000 , 2 ) ;
93- let third = self . address ( code / 10000 , 3 ) ;
94- let value = self . code [ first] < self . code [ second] ;
95- self . code [ third] = value as i64 ;
91+ let first = self . address ( op / 100 , 1 ) ;
92+ let second = self . address ( op / 1000 , 2 ) ;
93+ let third = self . address ( op / 10000 , 3 ) ;
94+ let value = ( self . code [ first] as i64 ) < ( self . code [ second] as i64 ) ;
95+ self . code [ third] = value as usize ;
9696 self . pc += 4 ;
9797 }
9898 // Equals
9999 8 => {
100- let first = self . address ( code / 100 , 1 ) ;
101- let second = self . address ( code / 1000 , 2 ) ;
102- let third = self . address ( code / 10000 , 3 ) ;
100+ let first = self . address ( op / 100 , 1 ) ;
101+ let second = self . address ( op / 1000 , 2 ) ;
102+ let third = self . address ( op / 10000 , 3 ) ;
103103 let value = self . code [ first] == self . code [ second] ;
104- self . code [ third] = value as i64 ;
104+ self . code [ third] = value as usize ;
105105 self . pc += 4 ;
106106 }
107107 // Adjust relative base
108108 9 => {
109- let first = self . address ( code / 100 , 1 ) ;
110- self . base + = self . code [ first] ;
109+ let first = self . address ( op / 100 , 1 ) ;
110+ self . base = self . base . wrapping_add ( self . code [ first] ) ;
111111 self . pc += 2 ;
112112 }
113113 _ => break State :: Halted ,
@@ -116,16 +116,13 @@ impl Computer {
116116 }
117117
118118 /// Calculates an address using one of the three possible address modes.
119- /// If the address exceeds the size of the `code` vector then it is extended with 0 values.
120119 #[ inline]
121- fn address ( & mut self , mode : i64 , offset : usize ) -> usize {
122- let index = match mode % 10 {
123- 0 => self . code [ self . pc + offset] as usize ,
120+ fn address ( & mut self , mode : usize , offset : usize ) -> usize {
121+ match mode % 10 {
122+ 0 => self . code [ self . pc + offset] ,
124123 1 => self . pc + offset,
125- 2 => ( self . base + self . code [ self . pc + offset] ) as usize ,
124+ 2 => self . base . wrapping_add ( self . code [ self . pc + offset] ) ,
126125 _ => unreachable ! ( ) ,
127- } ;
128-
129- index
126+ }
130127 }
131128}
0 commit comments