aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorReiner Herrmann <reiner@reiner-h.de>2019-12-09 20:14:05 +0100
committerReiner Herrmann <reiner@reiner-h.de>2019-12-09 20:23:02 +0100
commit8be0c0f98f097dc09318f4db231fe22812f115c8 (patch)
tree15db7fefb3a2d9a17419ca02ee8531089e99367e
parent4b2db1e29345fcd722bcdc266d06acade53445fc (diff)
day9
-rw-r--r--input91
-rw-r--r--src/main.rs144
2 files changed, 106 insertions, 39 deletions
diff --git a/input9 b/input9
new file mode 100644
index 0000000..b9c19d2
--- /dev/null
+++ b/input9
@@ -0,0 +1 @@
+1102,34463338,34463338,63,1007,63,34463338,63,1005,63,53,1102,3,1,1000,109,988,209,12,9,1000,209,6,209,3,203,0,1008,1000,1,63,1005,63,65,1008,1000,2,63,1005,63,902,1008,1000,0,63,1005,63,58,4,25,104,0,99,4,0,104,0,99,4,17,104,0,99,0,0,1101,309,0,1024,1101,0,24,1002,1102,388,1,1029,1102,1,21,1019,1101,0,33,1015,1102,1,304,1025,1101,344,0,1027,1101,25,0,1003,1102,1,1,1021,1101,29,0,1012,1101,0,23,1005,1102,1,32,1007,1102,38,1,1000,1101,30,0,1016,1102,1,347,1026,1101,0,26,1010,1101,0,39,1004,1102,1,36,1011,1101,0,393,1028,1101,0,37,1013,1101,0,35,1008,1101,34,0,1001,1101,0,495,1022,1102,1,28,1018,1101,0,0,1020,1102,1,22,1006,1101,488,0,1023,1102,31,1,1009,1102,1,20,1017,1101,0,27,1014,109,10,21102,40,1,4,1008,1014,37,63,1005,63,205,1001,64,1,64,1106,0,207,4,187,1002,64,2,64,109,-18,1207,8,37,63,1005,63,227,1001,64,1,64,1106,0,229,4,213,1002,64,2,64,109,17,1207,-7,25,63,1005,63,247,4,235,1106,0,251,1001,64,1,64,1002,64,2,64,109,-8,1202,6,1,63,1008,63,29,63,1005,63,275,1001,64,1,64,1106,0,277,4,257,1002,64,2,64,109,25,1205,-6,293,1001,64,1,64,1105,1,295,4,283,1002,64,2,64,109,-4,2105,1,2,4,301,1106,0,313,1001,64,1,64,1002,64,2,64,109,-9,1208,-4,31,63,1005,63,335,4,319,1001,64,1,64,1105,1,335,1002,64,2,64,109,16,2106,0,-2,1106,0,353,4,341,1001,64,1,64,1002,64,2,64,109,-13,2102,1,-8,63,1008,63,38,63,1005,63,373,1105,1,379,4,359,1001,64,1,64,1002,64,2,64,109,9,2106,0,3,4,385,1105,1,397,1001,64,1,64,1002,64,2,64,109,-11,21107,41,42,0,1005,1014,415,4,403,1106,0,419,1001,64,1,64,1002,64,2,64,109,14,1206,-7,431,1106,0,437,4,425,1001,64,1,64,1002,64,2,64,109,-23,2107,37,-5,63,1005,63,455,4,443,1105,1,459,1001,64,1,64,1002,64,2,64,109,10,21107,42,41,-2,1005,1013,475,1105,1,481,4,465,1001,64,1,64,1002,64,2,64,2105,1,8,1001,64,1,64,1106,0,497,4,485,1002,64,2,64,109,-6,21108,43,41,8,1005,1017,517,1001,64,1,64,1106,0,519,4,503,1002,64,2,64,109,5,2101,0,-9,63,1008,63,23,63,1005,63,541,4,525,1106,0,545,1001,64,1,64,1002,64,2,64,109,-13,1201,5,0,63,1008,63,20,63,1005,63,565,1105,1,571,4,551,1001,64,1,64,1002,64,2,64,109,16,1205,4,589,4,577,1001,64,1,64,1106,0,589,1002,64,2,64,109,-16,1202,4,1,63,1008,63,23,63,1005,63,615,4,595,1001,64,1,64,1106,0,615,1002,64,2,64,109,1,2101,0,6,63,1008,63,33,63,1005,63,639,1001,64,1,64,1105,1,641,4,621,1002,64,2,64,109,8,21101,44,0,8,1008,1018,44,63,1005,63,667,4,647,1001,64,1,64,1105,1,667,1002,64,2,64,109,-7,1201,1,0,63,1008,63,39,63,1005,63,689,4,673,1106,0,693,1001,64,1,64,1002,64,2,64,109,7,2102,1,-8,63,1008,63,24,63,1005,63,715,4,699,1105,1,719,1001,64,1,64,1002,64,2,64,109,5,2108,34,-7,63,1005,63,739,1001,64,1,64,1105,1,741,4,725,1002,64,2,64,109,-22,2108,25,10,63,1005,63,763,4,747,1001,64,1,64,1106,0,763,1002,64,2,64,109,31,1206,-4,781,4,769,1001,64,1,64,1105,1,781,1002,64,2,64,109,-10,21101,45,0,5,1008,1019,47,63,1005,63,805,1001,64,1,64,1105,1,807,4,787,1002,64,2,64,109,2,21108,46,46,-3,1005,1013,825,4,813,1106,0,829,1001,64,1,64,1002,64,2,64,109,-22,2107,40,10,63,1005,63,845,1105,1,851,4,835,1001,64,1,64,1002,64,2,64,109,17,1208,-7,36,63,1005,63,871,1001,64,1,64,1105,1,873,4,857,1002,64,2,64,109,16,21102,47,1,-9,1008,1018,47,63,1005,63,899,4,879,1001,64,1,64,1106,0,899,4,64,99,21102,1,27,1,21101,0,913,0,1105,1,920,21201,1,39657,1,204,1,99,109,3,1207,-2,3,63,1005,63,962,21201,-2,-1,1,21102,1,940,0,1105,1,920,21201,1,0,-1,21201,-2,-3,1,21101,955,0,0,1105,1,920,22201,1,-1,-2,1106,0,966,21202,-2,1,-2,109,-3,2105,1,0
diff --git a/src/main.rs b/src/main.rs
index 53060ce..ce5ce0b 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -167,32 +167,56 @@ enum ProgramState {
struct IntComputer {
ip : usize,
- mem : Vec<i32>,
- input : VecDeque<i32>,
- output : VecDeque<i32>,
+ mem : Vec<isize>,
+ base_address : isize,
+ input : VecDeque<isize>,
+ output : VecDeque<isize>,
suspend_on_output : bool,
}
impl IntComputer {
- fn new(program : &[i32]) -> IntComputer {
+ fn new(program : &[isize]) -> IntComputer {
IntComputer {
ip : 0,
mem : program.to_vec(),
+ base_address : 0,
input : VecDeque::new(),
output : VecDeque::new(),
suspend_on_output : false,
}
}
- fn get_operands(&self, inputs : &[i32], mode : i32) -> Vec<i32> {
+ fn read_mem(&mut self, i : usize) -> isize {
+ if i >= self.mem.len() {
+ self.mem.resize(i+1, 0);
+ }
+ self.mem[i]
+ }
+
+ fn write_mem(&mut self, i : isize, val : isize, mode : isize) {
+ let pos = match mode {
+ 0 => i,
+ 1 => panic!("writing not supported in immediate mode"),
+ 2 => self.base_address + i,
+ _ => panic!("unimplemented mode")
+ } as usize;
+ if pos >= self.mem.len() {
+ self.mem.resize(pos+1, 0);
+ }
+ self.mem[pos] = val;
+ }
+
+ fn get_operands(&mut self, count : usize, mode : isize) -> Vec<isize> {
+ let inputs = self.mem[self.ip+1..=self.ip+count].to_vec();
let mut tmp = mode;
let mut ops = Vec::new();
for i in inputs {
let m = tmp % 10;
tmp /= 10;
match m {
- 0 => ops.push(self.mem[*i as usize]),
- 1 => ops.push(*i),
+ 0 => ops.push(self.read_mem(i as usize)),
+ 1 => ops.push(i),
+ 2 => ops.push(self.read_mem((self.base_address + i) as usize)),
_ => panic!("invalid mode")
}
}
@@ -215,24 +239,25 @@ impl IntComputer {
match opcode {
1 => { /* add */
- let ops = self.get_operands(&self.mem[self.ip+1..=self.ip+2], mode);
- let dst = self.mem[self.ip+3] as usize;
- self.mem[dst] = ops[0] + ops[1];
+ let ops = self.get_operands(2, mode);
+ let dst = self.mem[self.ip+3] as isize;
+ self.write_mem(dst, ops[0] + ops[1], mode/100);
self.ip += 4;
}
2 => { /* multiply */
- let ops = self.get_operands(&self.mem[self.ip+1..=self.ip+2], mode);
- let dst = self.mem[self.ip+3] as usize;
- self.mem[dst] = ops[0] * ops[1];
+ let ops = self.get_operands(2, mode);
+ let dst = self.mem[self.ip+3] as isize;
+ self.write_mem(dst, ops[0] * ops[1], mode/100);
self.ip += 4;
}
3 => { /* read stdin */
- let dst = self.mem[self.ip+1] as usize;
- self.mem[dst] = self.input.pop_front().expect("not enough input available");
+ let dst = self.mem[self.ip+1] as isize;
+ let input = self.input.pop_front().expect("not enough input available");
+ self.write_mem(dst, input, mode);
self.ip += 2;
}
4 => { /* write stdout */
- let ops = self.get_operands(&[self.mem[self.ip+1]], mode);
+ let ops = self.get_operands(1, mode);
self.output.push_back(ops[0]);
self.ip += 2;
if self.suspend_on_output {
@@ -240,7 +265,7 @@ impl IntComputer {
}
}
5 => { /* jump-if-true */
- let ops = self.get_operands(&self.mem[self.ip+1..=self.ip+2], mode);
+ let ops = self.get_operands(2, mode);
if ops[0] != 0 {
self.ip = ops[1] as usize;
} else {
@@ -248,7 +273,7 @@ impl IntComputer {
}
}
6 => { /* jump-if-false */
- let ops = self.get_operands(&self.mem[self.ip+1..=self.ip+2], mode);
+ let ops = self.get_operands(2, mode);
if ops[0] == 0 {
self.ip = ops[1] as usize;
} else {
@@ -256,25 +281,30 @@ impl IntComputer {
}
}
7 => { /* less-than */
- let ops = self.get_operands(&self.mem[self.ip+1..=self.ip+2], mode);
- let dst = self.mem[self.ip+3] as usize;
+ let ops = self.get_operands(2, mode);
+ let dst = self.mem[self.ip+3] as isize;
if ops[0] < ops[1] {
- self.mem[dst] = 1;
+ self.write_mem(dst, 1, mode/100);
} else {
- self.mem[dst] = 0;
+ self.write_mem(dst, 0, mode/100);
}
self.ip += 4;
}
8 => { /* equals */
- let ops = self.get_operands(&self.mem[self.ip+1..=self.ip+2], mode);
- let dst = self.mem[self.ip+3] as usize;
+ let ops = self.get_operands(2, mode);
+ let dst = self.mem[self.ip+3] as isize;
if ops[0] == ops[1] {
- self.mem[dst] = 1;
+ self.write_mem(dst, 1, mode/100);
} else {
- self.mem[dst] = 0;
+ self.write_mem(dst, 0, mode/100);
}
self.ip += 4;
}
+ 9 => { /* adjust relative base */
+ let ops = self.get_operands(1, mode);
+ self.base_address += ops[0];
+ self.ip += 2;
+ }
99 => return ProgramState::HALTED,
_ => panic!("invalid opcode")
}
@@ -286,9 +316,9 @@ impl IntComputer {
fn day2() {
let input = read_file("input2");
let input = input.trim_end();
- let mut program : Vec<i32> = input.split(',')
- .map(|x| x.parse::<i32>().unwrap())
- .collect();
+ let mut program : Vec<isize> = input.split(',')
+ .map(|x| x.parse::<isize>().unwrap())
+ .collect();
program[1] = 12;
program[2] = 2;
@@ -462,9 +492,9 @@ fn day4() {
fn day5() {
let input = read_file("input5");
let input = input.trim_end();
- let program : Vec<i32> = input.split(',')
- .map(|x| x.parse::<i32>().unwrap())
- .collect();
+ let program : Vec<isize> = input.split(',')
+ .map(|x| x.parse::<isize>().unwrap())
+ .collect();
let mut computer = IntComputer::new(&program);
computer.input.push_back(1);
computer.run_program();
@@ -492,7 +522,7 @@ fn day6() {
println!("6b: {}", orbit_map.count_transfers(orbit_map.map["YOU"], orbit_map.map["SAN"]));
}
-fn permutations(elements : Vec<i32>) -> Vec<Vec<i32>> {
+fn permutations(elements : Vec<isize>) -> Vec<Vec<isize>> {
let mut result = Vec::new();
if elements.len() == 1 {
result.push(elements);
@@ -510,7 +540,7 @@ fn permutations(elements : Vec<i32>) -> Vec<Vec<i32>> {
result
}
-fn max_thruster_signal(program : &[i32]) -> i32 {
+fn max_thruster_signal(program : &[isize]) -> isize {
let phase_settings = permutations(vec![0, 1, 2, 3, 4]);
let mut signals = Vec::new();
@@ -529,7 +559,7 @@ fn max_thruster_signal(program : &[i32]) -> i32 {
*signals.iter().max().unwrap()
}
-fn max_thruster_signal_feedback(program : &[i32]) -> i32 {
+fn max_thruster_signal_feedback(program : &[isize]) -> isize {
let phase_settings = permutations(vec![5, 6, 7, 8, 9]);
let mut signals = Vec::new();
@@ -566,9 +596,9 @@ fn max_thruster_signal_feedback(program : &[i32]) -> i32 {
fn day7() {
let input = read_file("input7");
let input = input.trim_end();
- let program : Vec<i32> = input.split(',')
- .map(|x| x.parse::<i32>().unwrap())
- .collect();
+ let program : Vec<isize> = input.split(',')
+ .map(|x| x.parse::<isize>().unwrap())
+ .collect();
println!("7a: {}", max_thruster_signal(&program));
@@ -621,8 +651,26 @@ fn day8() {
}
}
+fn day9() {
+ let input = read_file("input9");
+ let input = input.trim_end();
+ let program : Vec<isize> = input.split(',')
+ .map(|x| x.parse::<isize>().unwrap())
+ .collect();
+
+ let mut computer = IntComputer::new(&program);
+ computer.input.push_back(1);
+ computer.run_program();
+ println!("9a: {}", computer.output[0]);
+
+ let mut computer = IntComputer::new(&program);
+ computer.input.push_back(2);
+ computer.run_program();
+ println!("9b: {}", computer.output[0]);
+}
+
fn main() {
- day8();
+ day9();
}
#[cfg(test)]
@@ -733,4 +781,22 @@ mod tests {
let program = vec![3,52,1001,52,-5,52,3,53,1,52,56,54,1007,54,5,55,1005,55,26,1001,54,-5,54,1105,1,12,1,53,54,53,1008,54,0,55,1001,55,1,55,2,53,55,53,4,53,1001,56,-1,56,1005,56,6,99,0,0,0,0,10];
assert_eq!(max_thruster_signal_feedback(&program), 18216);
}
+
+ #[test]
+ fn test_day9() {
+ let program = vec![109,1,204,-1,1001,100,1,100,1008,100,16,101,1006,101,0,99];
+ let mut computer = IntComputer::new(&program);
+ computer.run_program();
+ assert!(computer.output.iter().eq(program.iter()));
+
+ let program = vec![1102,34915192,34915192,7,4,7,99,0];
+ let mut computer = IntComputer::new(&program);
+ computer.run_program();
+ assert_eq!(computer.output[0], 1219070632396864);
+
+ let program = vec![104,1125899906842624,99];
+ let mut computer = IntComputer::new(&program);
+ computer.run_program();
+ assert_eq!(computer.output[0], 1125899906842624);
+ }
}