From 4d60fb3e2343da1e4a9f78b8bddc554c86fd06a9 Mon Sep 17 00:00:00 2001 From: Vladan Popovic Date: Tue, 14 Jan 2020 15:31:14 +0100 Subject: [PATCH] Day 7 --- src/day5.rs | 61 +++++++++++------------ src/day7.rs | 139 ++++++++++++++++++++++++++++++++++++++++++++++++++++ src/main.rs | 8 ++- 3 files changed, 176 insertions(+), 32 deletions(-) create mode 100644 src/day7.rs diff --git a/src/day5.rs b/src/day5.rs index aafbb03..2506f72 100644 --- a/src/day5.rs +++ b/src/day5.rs @@ -33,9 +33,10 @@ fn set_param(input: &mut Vec, mode: i32, idx: i32, value: i32) -> () { } } -fn compute_intcode_extended(p: &mut Vec, input: i32) -> (Vec, Vec) { +pub fn compute_intcode_extended(p: &mut Vec, inp: Vec) -> (Vec, Vec) { let mut idx = 0; let mut output: Vec = Vec::new(); + let mut input = inp.into_iter(); while idx < p.len() - 1 { let (opcode, m1, m2, m3) = get_modes(p[idx]); @@ -56,7 +57,7 @@ fn compute_intcode_extended(p: &mut Vec, input: i32) -> (Vec, Vec } 3 => { let new_idx: usize = p[idx as usize + 1].try_into().unwrap(); - p[new_idx] = input; + p[new_idx] = input.next().expect("no next input!"); idx += 2; } 4 => { @@ -110,134 +111,134 @@ pub fn main() -> std::io::Result<()> { .map(|x| x.parse().ok().expect(&format!("{} not a number", x))) .collect(); - let (_, output) = compute_intcode_extended(&mut input.clone(), 1); + let (_, output) = compute_intcode_extended(&mut input.clone(), vec![1]); println!("part 1 = {}", output.last().unwrap()); - let (_, output) = compute_intcode_extended(&mut input.clone(), 5); + let (_, output) = compute_intcode_extended(&mut input.clone(), vec![5]); println!("part 2 = {}", output[0]); Ok(()) } #[test] fn test_halt() { - let (result, _) = compute_intcode_extended(&mut vec![99], 1); + let (result, _) = compute_intcode_extended(&mut vec![99], vec![1]); assert_eq!(result, vec![99]); } #[test] fn test_write_to_memory() { - let (result, _) = compute_intcode_extended(&mut vec![3, 3, 99, 0], 20); + let (result, _) = compute_intcode_extended(&mut vec![3, 3, 99, 0], vec![20]); assert_eq!(20, result[3]); } #[test] fn test_write_to_output() { - let (_, output) = compute_intcode_extended(&mut vec![4, 2, 99], 1); + let (_, output) = compute_intcode_extended(&mut vec![4, 2, 99], vec![1]); assert_eq!(99, output[0]); } #[test] fn test_add() { - let (result, _) = compute_intcode_extended(&mut vec![1, 2, 2, 0, 99], 1); + let (result, _) = compute_intcode_extended(&mut vec![1, 2, 2, 0, 99], vec![1]); assert_eq!(4, result[0]); } #[test] fn test_mul() { - let (result, _) = compute_intcode_extended(&mut vec![2, 2, 4, 0, 99], 1); + let (result, _) = compute_intcode_extended(&mut vec![2, 2, 4, 0, 99], vec![1]); assert_eq!(396, result[0]); } #[test] fn test_immediate_mode() { - let (result, output) = compute_intcode_extended(&mut vec![1102, 2, 4, 0, 99], 1); + let (result, _) = compute_intcode_extended(&mut vec![1102, 2, 4, 0, 99], vec![1]); assert_eq!(8, result[0]); } #[test] fn test_position_mode_equal() { - let (result, output) = - compute_intcode_extended(&mut vec![3, 9, 8, 9, 10, 9, 4, 9, 99, -1, 8], 8); + let (_, output) = + compute_intcode_extended(&mut vec![3, 9, 8, 9, 10, 9, 4, 9, 99, -1, 8], vec![8]); assert_eq!(1, output[0]); } #[test] fn test_position_mode_not_equal() { - let (result, output) = - compute_intcode_extended(&mut vec![3, 9, 8, 9, 10, 9, 4, 9, 99, -1, 8], 10); + let (_, output) = + compute_intcode_extended(&mut vec![3, 9, 8, 9, 10, 9, 4, 9, 99, -1, 8], vec![10]); assert_eq!(0, output[0]); } #[test] fn test_position_mode_less_than() { - let (result, output) = - compute_intcode_extended(&mut vec![3, 9, 7, 9, 10, 9, 4, 9, 99, -1, 8], 3); + let (_, output) = + compute_intcode_extended(&mut vec![3, 9, 7, 9, 10, 9, 4, 9, 99, -1, 8], vec![3]); assert_eq!(1, output[0]); } #[test] fn test_position_mode_greater_than() { - let (result, output) = - compute_intcode_extended(&mut vec![3, 9, 7, 9, 10, 9, 4, 9, 99, -1, 8], 10); + let (_, output) = + compute_intcode_extended(&mut vec![3, 9, 7, 9, 10, 9, 4, 9, 99, -1, 8], vec![10]); assert_eq!(0, output[0]); } #[test] fn test_immediate_mode_equal() { - let (result, output) = compute_intcode_extended(&mut vec![3, 3, 1108, -1, 8, 3, 4, 3, 99], 8); + let (_, output) = compute_intcode_extended(&mut vec![3, 3, 1108, -1, 8, 3, 4, 3, 99], vec![8]); assert_eq!(1, output[0]); } #[test] fn test_immediate_mode_not_equal() { - let (result, output) = compute_intcode_extended(&mut vec![3, 3, 1108, -1, 8, 3, 4, 3, 99], 10); + let (_, output) = compute_intcode_extended(&mut vec![3, 3, 1108, -1, 8, 3, 4, 3, 99], vec![10]); assert_eq!(0, output[0]); } #[test] fn test_immediate_mode_less_than() { - let (result, output) = compute_intcode_extended(&mut vec![3, 3, 1107, -1, 8, 3, 4, 3, 99], 3); + let (_, output) = compute_intcode_extended(&mut vec![3, 3, 1107, -1, 8, 3, 4, 3, 99], vec![3]); assert_eq!(1, output[0]); } #[test] fn test_immediate_mode_greater_than() { - let (result, output) = compute_intcode_extended(&mut vec![3, 3, 1107, -1, 8, 3, 4, 3, 99], 10); + let (_, output) = compute_intcode_extended(&mut vec![3, 3, 1107, -1, 8, 3, 4, 3, 99], vec![10]); assert_eq!(0, output[0]); } #[test] fn test_position_jump_zero() { - let (result, output) = compute_intcode_extended( + let (_, output) = compute_intcode_extended( &mut vec![3, 12, 6, 12, 15, 1, 13, 14, 13, 4, 13, 99, -1, 0, 1, 9], - 0, + vec![0], ); assert_eq!(0, output[0]); } #[test] fn test_position_jump_one() { - let (result, output) = compute_intcode_extended( + let (_, output) = compute_intcode_extended( &mut vec![3, 12, 6, 12, 15, 1, 13, 14, 13, 4, 13, 99, -1, 0, 1, 9], - 100, + vec![100], ); assert_eq!(1, output[0]); } #[test] fn test_immediate_jump_zero() { - let (result, output) = compute_intcode_extended( + let (_, output) = compute_intcode_extended( &mut vec![3, 3, 1105, -1, 9, 1101, 0, 0, 12, 4, 12, 99, 1], - 0, + vec![0], ); assert_eq!(0, output[0]); } #[test] fn test_immediate_jump_one() { - let (result, output) = compute_intcode_extended( + let (_, output) = compute_intcode_extended( &mut vec![3, 3, 1105, -1, 9, 1101, 0, 0, 12, 4, 12, 99, 1], - 100, + vec![100], ); assert_eq!(1, output[0]); } diff --git a/src/day7.rs b/src/day7.rs new file mode 100644 index 0000000..c4dc5af --- /dev/null +++ b/src/day7.rs @@ -0,0 +1,139 @@ +use crate::day5::compute_intcode_extended; + +pub fn permutations(start: usize, size: usize) -> Permutations { + Permutations { + idxs: (start..size).collect(), + swaps: vec![start; size], + i: 0, + } +} + +pub struct Permutations { + idxs: Vec, + swaps: Vec, + i: usize, +} + +impl Iterator for Permutations { + type Item = Vec; + + fn next(&mut self) -> Option { + if self.i > 0 { + loop { + if self.i >= self.swaps.len() { + return None; + } + if self.swaps[self.i] < self.i { + break; + } + self.swaps[self.i] = 0; + self.i += 1; + } + self.idxs.swap(self.i, (self.i & 1) * self.swaps[self.i]); + self.swaps[self.i] += 1; + } + self.i = 1; + Some(self.idxs.clone()) + } +} + +fn compute_thruster(input: &mut Vec, settings: Vec) -> i32 { + let mut signal = 0; + for phase in settings { + signal = compute_intcode_extended(input, vec![phase as i32, signal]).1[0]; + } + signal +} + +fn part1() -> i32 { + let input: Vec = std::include_str!("../day7-input.txt") + .trim() + .split(",") + .map(|x| x.parse().ok().expect(&format!("{} not a number", x))) + .collect(); + + let mut max_thruster = std::i32::MIN; + for settings in permutations(0, 5).collect::>() { + let thrust = compute_thruster(&mut input.clone(), settings); + max_thruster = max_thruster.max(thrust); + } + max_thruster +} + +fn compute_feedback(input: &mut Vec, mut settings: Vec) -> Vec { + settings.push(0); + println!("{:?}", settings); + let signal = compute_intcode_extended(input, settings).1; + println!("{:?}", signal); + signal +} + +fn part2() -> i32 { + let mut input: Vec = std::include_str!("../day7-input.txt") + .trim() + .split(",") + .map(|x| x.parse().ok().expect(&format!("{} not a number", x))) + .collect(); + + let mut max_thruster = std::i32::MIN; + for settings in permutations(5, 5).collect::>() { + let thrust = compute_thruster(&mut input, settings); + max_thruster = max_thruster.max(thrust); + } + max_thruster +} + +pub fn main() { + println!("part1 = {}", part1()); + println!("part2 = {}", part2()); +} + +#[test] +fn test_compute_thruster_1() { + let mut input = vec![ + 3, 15, 3, 16, 1002, 16, 10, 16, 1, 16, 15, 15, 4, 15, 99, 0, 0, + ]; + let settings = vec![4, 3, 2, 1, 0]; + assert_eq!(compute_thruster(&mut input, settings), 43210); +} + +#[test] +fn test_compute_thruster_2() { + let mut input = vec![ + 3, 23, 3, 24, 1002, 24, 10, 24, 1002, 23, -1, 23, 101, 5, 23, 23, 1, 24, 23, 23, 4, 23, 99, + 0, 0, + ]; + let settings = vec![0, 1, 2, 3, 4]; + assert_eq!(compute_thruster(&mut input, settings), 54321); +} + +#[test] +fn test_compute_thruster_3() { + let mut input = vec![ + 3, 31, 3, 32, 1002, 32, 10, 32, 1001, 31, -2, 31, 1007, 31, 0, 33, 1002, 33, 7, 33, 1, 33, + 31, 31, 1, 32, 31, 31, 4, 31, 99, 0, 0, 0, + ]; + let settings = vec![1, 0, 4, 3, 2]; + assert_eq!(compute_thruster(&mut input, settings), 65210); +} + +#[test] +fn test_compute_feedback_1() { + let mut input = vec![ + 3, 26, 1001, 26, -4, 26, 3, 27, 1002, 27, 2, 27, 1, 27, 26, 27, 4, 27, 1001, 28, -1, 28, + 1005, 28, 6, 99, 0, 0, 5, + ]; + let settings = vec![5, 6, 7, 8, 9]; + assert_eq!(compute_feedback(&mut input, settings), [139629729]); +} + +#[test] +fn test_compute_feedback_2() { + let mut input = 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, + ]; + let settings = vec![9, 7, 8, 5, 6]; + assert_eq!(compute_feedback(&mut input, settings), [18216]); +} diff --git a/src/main.rs b/src/main.rs index b6f489a..b98a548 100644 --- a/src/main.rs +++ b/src/main.rs @@ -5,10 +5,14 @@ mod day3; mod day4; mod day5; mod day6; +mod day7; fn main() -> std::io::Result<()> { - println!("========================= DAY 6"); - day6::main()?; + println!("========================= DAY 7"); + day7::main(); + + //println!("========================= DAY 6"); + //day6::main()?; //println!("========================= DAY 5"); //day5::main()?;