this repo has no description
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

at d09cbade53a0d3e704dcbf42bd5df4d55ab4d307 175 lines 5.8 kB view raw
1use std::fs; 2 3type IntCodes = Vec<isize>; 4 5#[derive(Clone)] 6struct IntCodeComp { 7 pos: usize, 8 rel_base: isize, 9 codes: IntCodes, 10 inputs: Vec<isize>, 11 done: bool, 12} 13 14impl IntCodeComp { 15 fn new(codes: IntCodes, rel_base: isize, inputs: Vec<isize>) -> IntCodeComp { 16 IntCodeComp{ codes, inputs, rel_base, pos: 0, done: false } 17 } 18 19 fn val_param(&mut self, t: char, v: isize) -> isize { 20 match t { 21 '0' => { // Position mode 22 self.grow(v as usize); 23 return self.codes[v as usize]; 24 }, 25 '1' => { // Absolute mode 26 return v; 27 }, 28 '2' => { // Relative mode 29 let dest = (self.rel_base + v) as usize; 30 self.grow(dest); 31 return self.codes[dest]; 32 }, 33 _ => unreachable!(), 34 } 35 } 36 37 fn write_param(&self, opcode: String, idx: usize) -> isize { 38 let param_type = opcode.chars().nth(4-idx).unwrap(); 39 let v = self.codes[self.pos+idx]; 40 41 match param_type { 42 '0' | '1' => v, 43 '2' => self.rel_base + v, 44 _ => unreachable!(), 45 } 46 } 47 48 fn n_params(&mut self, opcode: String, num: usize) -> Vec<isize> { 49 let out = (1..=num).fold(vec![], |mut out, i| { 50 let param_type = opcode.chars().nth(4-i).unwrap(); 51 let param = self.val_param(param_type, self.codes[self.pos+i]); 52 out.push(param); 53 out.clone() 54 }); 55 out 56 } 57 58 fn grow(&mut self, pos: usize) { 59 while self.codes.len() < pos+1 { 60 self.codes.push(0); 61 } 62 } 63 64 fn set_val(&mut self, dest: isize, val: isize) { 65 self.grow(dest as usize); 66 self.codes[dest as usize] = val; 67 } 68 69 fn set_pos(&mut self, dest: isize) { 70 self.grow(dest as usize); 71 self.pos = dest as usize; 72 } 73 74 fn advance_pos(&mut self, offset: usize) { 75 let new_pos = self.pos + offset; 76 self.grow(new_pos); 77 self.pos = new_pos; 78 } 79} 80 81impl Iterator for IntCodeComp { 82 type Item = isize; 83 84 fn next(&mut self) -> Option<Self::Item> { 85 if self.done { return None; } 86 loop { 87 if self.codes[self.pos] == 99 { return None; } 88 89 let opcode = format!("{:0>6}", self.codes[self.pos]); 90 match opcode.chars().nth(5) { 91 Some('1') => { // Add 92 let params = self.n_params(opcode.clone(), 2); 93 let dest = self.write_param(opcode.clone(), 3); 94 self.set_val(dest, params[0] + params[1]); 95 self.advance_pos(4); 96 }, 97 Some('2') => { // Mult 98 let params = self.n_params(opcode.clone(), 2); 99 let dest = self.write_param(opcode.clone(), 3); 100 self.set_val(dest, params[0] * params[1]); 101 self.advance_pos(4); 102 }, 103 Some('3') => { // Input 104 let dest = self.write_param(opcode.clone(), 3); 105 let v = match self.inputs.pop() { 106 Some(i) => i, 107 None => return None, 108 }; 109 self.set_val(dest, v); 110 self.advance_pos(2); 111 }, 112 Some('4') => { // Output 113 let x = *self.n_params(opcode, 1).first().unwrap(); 114 self.advance_pos(2); 115 return Some(x); 116 }, 117 Some('5') => { // Jump If True 118 let params = self.n_params(opcode, 2); 119 if params[0] > 0 { 120 self.set_pos(params[1]); 121 } else { 122 self.advance_pos(3); 123 } 124 }, 125 Some('6') => { // Jump If False 126 let params = self.n_params(opcode, 2); 127 if params[0] == 0 { 128 self.set_pos(params[1]); 129 } else { 130 self.advance_pos(3); 131 } 132 }, 133 Some('7') => { // Less Than 134 let params = self.n_params(opcode.clone(), 2); 135 let dest = self.write_param(opcode.clone(), 3); 136 if params[0] < params[1] { 137 self.set_val(dest, 1); 138 } else { 139 self.set_val(dest, 0); 140 } 141 self.advance_pos(4); 142 }, 143 Some('8') => { // Equals 144 let params = self.n_params(opcode.clone(), 2); 145 let dest = self.write_param(opcode.clone(), 3); 146 if params[0] == params[1] { 147 self.set_val(dest, 1); 148 } else { 149 self.set_val(dest, 0); 150 } 151 self.advance_pos(4); 152 }, 153 Some('9') => { // Relative Base Offset 154 let params = self.n_params(opcode, 1); 155 self.rel_base += params[0]; 156 self.advance_pos(2); 157 }, 158 Some(_) => return None, 159 None => return None, 160 } 161 } 162 } 163} 164 165fn main() { 166 let raw_contents = fs::read_to_string("input.txt").expect("Error reading the file."); 167 let contents = raw_contents.trim(); // get rid of trailing \n 168 169 let intcodes: IntCodes = contents.split(',').map(|x| x.parse().unwrap()).collect(); 170 171 // let comp = IntCodeComp::new(intcodes.clone(), 0, vec![2]); // Part 1 172 let comp = IntCodeComp::new(intcodes.clone(), 0, vec![2]); // Part 2 173 174 comp.for_each(|out| println!("{}", out)); 175}