diff options
| author | Reiner Herrmann <reiner@reiner-h.de> | 2019-12-05 12:30:36 +0100 |
|---|---|---|
| committer | Reiner Herrmann <reiner@reiner-h.de> | 2019-12-05 12:30:36 +0100 |
| commit | 4b988ac3aad1ddce7eceb9ee89015db9a83d9b05 (patch) | |
| tree | 2e3ac6c40a6d382449624e06af56217b3a1a749a | |
| parent | 80f3bb10589b2f56178943c84b1a1fc5eb593d4f (diff) | |
day5
| -rw-r--r-- | input5 | 1 | ||||
| -rw-r--r-- | src/main.rs | 151 |
2 files changed, 136 insertions, 16 deletions
@@ -0,0 +1 @@ +3,225,1,225,6,6,1100,1,238,225,104,0,1101,40,71,224,1001,224,-111,224,4,224,1002,223,8,223,101,7,224,224,1,224,223,223,1102,66,6,225,1102,22,54,225,1,65,35,224,1001,224,-86,224,4,224,102,8,223,223,101,6,224,224,1,224,223,223,1102,20,80,225,101,92,148,224,101,-162,224,224,4,224,1002,223,8,223,101,5,224,224,1,224,223,223,1102,63,60,225,1101,32,48,225,2,173,95,224,1001,224,-448,224,4,224,102,8,223,223,1001,224,4,224,1,224,223,223,1001,91,16,224,101,-79,224,224,4,224,1002,223,8,223,101,3,224,224,1,224,223,223,1101,13,29,225,1101,71,70,225,1002,39,56,224,1001,224,-1232,224,4,224,102,8,223,223,101,4,224,224,1,223,224,223,1101,14,59,225,102,38,143,224,1001,224,-494,224,4,224,102,8,223,223,101,3,224,224,1,224,223,223,1102,30,28,224,1001,224,-840,224,4,224,1002,223,8,223,101,4,224,224,1,223,224,223,4,223,99,0,0,0,677,0,0,0,0,0,0,0,0,0,0,0,1105,0,99999,1105,227,247,1105,1,99999,1005,227,99999,1005,0,256,1105,1,99999,1106,227,99999,1106,0,265,1105,1,99999,1006,0,99999,1006,227,274,1105,1,99999,1105,1,280,1105,1,99999,1,225,225,225,1101,294,0,0,105,1,0,1105,1,99999,1106,0,300,1105,1,99999,1,225,225,225,1101,314,0,0,106,0,0,1105,1,99999,107,677,226,224,1002,223,2,223,1005,224,329,1001,223,1,223,8,226,226,224,102,2,223,223,1006,224,344,101,1,223,223,7,226,677,224,1002,223,2,223,1005,224,359,101,1,223,223,1007,677,226,224,1002,223,2,223,1005,224,374,1001,223,1,223,1007,677,677,224,1002,223,2,223,1006,224,389,101,1,223,223,1008,226,226,224,1002,223,2,223,1005,224,404,1001,223,1,223,108,677,226,224,1002,223,2,223,1006,224,419,1001,223,1,223,1108,677,226,224,102,2,223,223,1006,224,434,1001,223,1,223,108,226,226,224,1002,223,2,223,1005,224,449,101,1,223,223,7,677,677,224,1002,223,2,223,1006,224,464,1001,223,1,223,8,226,677,224,1002,223,2,223,1005,224,479,1001,223,1,223,107,226,226,224,102,2,223,223,1006,224,494,101,1,223,223,1007,226,226,224,1002,223,2,223,1005,224,509,1001,223,1,223,1107,226,677,224,102,2,223,223,1005,224,524,1001,223,1,223,108,677,677,224,1002,223,2,223,1005,224,539,101,1,223,223,1107,677,226,224,102,2,223,223,1005,224,554,1001,223,1,223,107,677,677,224,1002,223,2,223,1005,224,569,101,1,223,223,8,677,226,224,102,2,223,223,1005,224,584,1001,223,1,223,7,677,226,224,102,2,223,223,1006,224,599,101,1,223,223,1008,677,677,224,1002,223,2,223,1005,224,614,101,1,223,223,1008,677,226,224,102,2,223,223,1006,224,629,1001,223,1,223,1108,677,677,224,102,2,223,223,1006,224,644,101,1,223,223,1108,226,677,224,1002,223,2,223,1005,224,659,1001,223,1,223,1107,226,226,224,102,2,223,223,1006,224,674,1001,223,1,223,4,223,99,226 diff --git a/src/main.rs b/src/main.rs index ec27262..7c490af 100644 --- a/src/main.rs +++ b/src/main.rs @@ -106,33 +106,109 @@ fn day1() { println!("1b: {}", sum2); } -fn run_program(input : Vec<usize>) -> Vec<usize> { - let mut mem = input.clone(); - for i in 0..mem.len()/4 { - let pos = i * 4; - let opcode = mem[pos]; - if opcode == 99 { - break; +fn get_operands(mem : &Vec<i32>, inputs : Vec<i32>, mode : i32) -> Vec<i32> { + let mut tmp = mode; + let mut ops = Vec::new(); + for i in inputs { + let m = tmp % 10; + tmp /= 10; + match m { + 0 => ops.push(mem[i as usize]), + 1 => ops.push(i), + _ => panic!("invalid mode") } + } + ops +} + +fn run_program_io(input : Vec<i32>, stdin : &Vec<&str>, stdout : &mut Vec<i32>) -> Vec<i32> { + let mut stdin_iter = stdin.iter(); + let mut mem = input.clone(); + let mut ip = 0; + loop { + let instruction = mem[ip]; + let opcode = instruction % 100; + let mode = instruction / 100; - let op1 = mem[pos+1]; - let op2 = mem[pos+2]; - let op3 = mem[pos+3]; match opcode { - 1 => { mem[op3] = mem[op1] + mem[op2]; } - 2 => { mem[op3] = mem[op1] * mem[op2]; } + 1 => { /* add */ + let ops = get_operands(&mem, mem[ip+1..ip+3].to_vec(), mode); + let dst = mem[ip+3] as usize; + mem[dst] = ops[0] + ops[1]; + ip += 4; + } + 2 => { /* multiply */ + let ops = get_operands(&mem, mem[ip+1..ip+3].to_vec(), mode); + let dst = mem[ip+3] as usize; + mem[dst] = ops[0] * ops[1]; + ip += 4; + } + 3 => { /* read stdin */ + let input = stdin_iter.next().unwrap(); + let dst = mem[ip+1] as usize; + mem[dst] = input.parse::<i32>().unwrap(); + ip += 2; + } + 4 => { /* write stdout */ + let ops = get_operands(&mem, mem[ip+1..ip+2].to_vec(), mode); + stdout.push(ops[0]); + ip += 2; + } + 5 => { /* jump-if-true */ + let ops = get_operands(&mem, mem[ip+1..ip+3].to_vec(), mode); + if ops[0] != 0 { + ip = ops[1] as usize; + } else { + ip += 3; + } + } + 6 => { /* jump-if-false */ + let ops = get_operands(&mem, mem[ip+1..ip+3].to_vec(), mode); + if ops[0] == 0 { + ip = ops[1] as usize; + } else { + ip += 3; + } + } + 7 => { /* less-than */ + let ops = get_operands(&mem, mem[ip+1..ip+3].to_vec(), mode); + let dst = mem[ip+3] as usize; + if ops[0] < ops[1] { + mem[dst] = 1; + } else { + mem[dst] = 0; + } + ip += 4; + } + 8 => { /* equals */ + let ops = get_operands(&mem, mem[ip+1..ip+3].to_vec(), mode); + let dst = mem[ip+3] as usize; + if ops[0] == ops[1] { + mem[dst] = 1; + } else { + mem[dst] = 0; + } + ip += 4; + } + 99 => break, _ => panic!("invalid opcode") } } mem } +fn run_program(input : Vec<i32>) -> Vec<i32> { + let stdin = Vec::new(); + let mut stdout = Vec::new(); + run_program_io(input, &stdin, &mut stdout) +} + fn day2() { let mut input = read_file("input2"); input.pop(); - let mut program : Vec<usize> = input.split(',') - .map(|x| x.parse::<usize>().unwrap()) - .collect(); + let mut program : Vec<i32> = input.split(',') + .map(|x| x.parse::<i32>().unwrap()) + .collect(); program[1] = 12; program[2] = 2; @@ -301,8 +377,31 @@ fn day4() { println!("4a: {}", count); } +fn day5() { + let mut input = read_file("input5"); + input.pop(); + let program : Vec<i32> = input.split(',') + .map(|x| x.parse::<i32>().unwrap()) + .collect(); + let mut stdout = Vec::new(); + let stdin = vec!["1"]; + run_program_io(program.clone(), &stdin, &mut stdout); + println!("5a:"); + for val in stdout { + println!("{}", val); + } + + let mut stdout = Vec::new(); + let stdin = vec!["5"]; + run_program_io(program.clone(), &stdin, &mut stdout); + println!("5b:"); + for val in stdout { + println!("{}", val); + } +} + fn main() { - day4(); + day5(); } #[cfg(test)] @@ -357,4 +456,24 @@ mod tests { assert!(!valid_password2(123444)); assert!(valid_password2(111122)); } + + #[test] + fn test_day5() { + let program = vec![3,21,1008,21,8,20,1005,20,22,107,8,21,20,1006,20,31,1106,0,36,98,0,0,1002,21,125,20,4,20,1105,1,46,104,999,1105,1,46,1101,1000,1,20,4,20,1105,1,46,98,99]; + + let stdin = vec!["4"]; + let mut stdout = Vec::new(); + run_program_io(program.clone(), &stdin, &mut stdout); + assert_eq!(stdout[0], 999); + + let stdin = vec!["8"]; + let mut stdout = Vec::new(); + run_program_io(program.clone(), &stdin, &mut stdout); + assert_eq!(stdout[0], 1000); + + let stdin = vec!["42"]; + let mut stdout = Vec::new(); + run_program_io(program.clone(), &stdin, &mut stdout); + assert_eq!(stdout[0], 1001); + } } |
