From 571c0c251165584c653878daf0861dda7fc52037 Mon Sep 17 00:00:00 2001 From: Kienan Stewart Date: Sun, 15 May 2022 07:38:18 -0400 Subject: [PATCH] Day 7 --- day7/Cargo.lock | 30 +++++++++++ day7/Cargo.toml | 10 ++++ day7/src/#main.rs# | 132 +++++++++++++++++++++++++++++++++++++++++++++ day7/src/.#main.rs | 1 + day7/src/main.rs | 132 +++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 305 insertions(+) create mode 100644 day7/Cargo.lock create mode 100644 day7/Cargo.toml create mode 100644 day7/src/#main.rs# create mode 120000 day7/src/.#main.rs create mode 100644 day7/src/main.rs diff --git a/day7/Cargo.lock b/day7/Cargo.lock new file mode 100644 index 0000000..2b9779a --- /dev/null +++ b/day7/Cargo.lock @@ -0,0 +1,30 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "day7" +version = "0.1.0" +dependencies = [ + "icc", + "itertools", +] + +[[package]] +name = "either" +version = "1.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457" + +[[package]] +name = "icc" +version = "1.0.0" + +[[package]] +name = "itertools" +version = "0.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a9a9d19fa1e79b6215ff29b9d6880b706147f16e9b1dbb1e4e5947b5b02bc5e3" +dependencies = [ + "either", +] diff --git a/day7/Cargo.toml b/day7/Cargo.toml new file mode 100644 index 0000000..4c058ed --- /dev/null +++ b/day7/Cargo.toml @@ -0,0 +1,10 @@ +[package] +name = "day7" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +icc = { path = "../icc", version = "1.0.0"} +itertools = "0.10.3" \ No newline at end of file diff --git a/day7/src/#main.rs# b/day7/src/#main.rs# new file mode 100644 index 0000000..7599d41 --- /dev/null +++ b/day7/src/#main.rs# @@ -0,0 +1,132 @@ +use std::collections::VecDeque; +use itertools::Itertools; + +fn main() { + let program = vec![3,8,1001,8,10,8,105,1,0,0,21,38,63,88,97,118,199,280,361,442,99999,3,9,1002,9,3,9,101,2,9,9,1002,9,4,9,4,9,99,3,9,101,3,9,9,102,5,9,9,101,3,9,9,1002,9,3,9,101,3,9,9,4,9,99,3,9,1002,9,2,9,1001,9,3,9,102,3,9,9,101,2,9,9,1002,9,4,9,4,9,99,3,9,102,2,9,9,4,9,99,3,9,102,4,9,9,101,5,9,9,102,2,9,9,101,5,9,9,4,9,99,3,9,1002,9,2,9,4,9,3,9,101,1,9,9,4,9,3,9,102,2,9,9,4,9,3,9,101,1,9,9,4,9,3,9,101,2,9,9,4,9,3,9,1001,9,2,9,4,9,3,9,102,2,9,9,4,9,3,9,102,2,9,9,4,9,3,9,101,1,9,9,4,9,3,9,102,2,9,9,4,9,99,3,9,101,1,9,9,4,9,3,9,102,2,9,9,4,9,3,9,1001,9,2,9,4,9,3,9,1001,9,2,9,4,9,3,9,1001,9,1,9,4,9,3,9,1001,9,1,9,4,9,3,9,1001,9,2,9,4,9,3,9,102,2,9,9,4,9,3,9,1002,9,2,9,4,9,3,9,1001,9,1,9,4,9,99,3,9,1002,9,2,9,4,9,3,9,1002,9,2,9,4,9,3,9,102,2,9,9,4,9,3,9,1002,9,2,9,4,9,3,9,1001,9,1,9,4,9,3,9,102,2,9,9,4,9,3,9,102,2,9,9,4,9,3,9,101,1,9,9,4,9,3,9,102,2,9,9,4,9,3,9,102,2,9,9,4,9,99,3,9,102,2,9,9,4,9,3,9,101,1,9,9,4,9,3,9,1002,9,2,9,4,9,3,9,1002,9,2,9,4,9,3,9,102,2,9,9,4,9,3,9,1002,9,2,9,4,9,3,9,1001,9,2,9,4,9,3,9,101,2,9,9,4,9,3,9,1001,9,2,9,4,9,3,9,101,1,9,9,4,9,99,3,9,101,1,9,9,4,9,3,9,101,1,9,9,4,9,3,9,101,1,9,9,4,9,3,9,102,2,9,9,4,9,3,9,1001,9,1,9,4,9,3,9,1001,9,2,9,4,9,3,9,101,2,9,9,4,9,3,9,102,2,9,9,4,9,3,9,1001,9,1,9,4,9,3,9,1001,9,2,9,4,9,99]; + + let mut max_storage = 0; + let mut max_settings: Vec = Vec::new(); + + { + let settings = vec![0, 1, 2, 3, 4]; + // Cheese. + for permutation in settings.into_iter().permutations(5) { + //println!("{:?}", permutation); + let storage = run_amplifiers(&program, permutation.clone()); + if storage > max_storage { + max_storage = storage; + max_settings = permutation.clone(); + } + } + println!("[Part 1] Settings {:?} produced a value of {}", max_settings, max_storage); + } + + { + let settings = vec![5, 6, 7, 8, 9]; + for permutation in settings.into_iter().permutations(5) { + let storage = run_feedback_amplifiers(&program, permutation.clone()); + if storage > max_storage { + max_storage = storage; + max_settings = permutation.clone(); + } + } + println!("[Part 2] Settings {:?} produced a value of {}", max_settings, max_storage); + } +} + +fn run_amplifiers(program: &Vec, settings: Vec) -> i32 { + let mut storage: i32 = 0; + for setting in settings { + let mut input = VecDeque::from([setting, storage]); + let mut output: Vec = Vec::new(); + icc::simulate(&mut program.clone(), &mut input, &mut output, 0); + storage = output[0]; + } + return storage; +} + +fn run_feedback_amplifiers(program: &Vec, settings: Vec) -> i32 { + let amplifiers = [ + // program, input signal, entrypoint, setting + (&mut program.clone(), &mut 0, &mut 0usize, &mut icc::Status::Running), + (&mut program.clone(), &mut 0, &mut 0usize, &mut icc::Status::Running), + (&mut program.clone(), &mut 0, &mut 0usize, &mut icc::Status::Running), + (&mut program.clone(), &mut 0, &mut 0usize, &mut icc::Status::Running), + (&mut program.clone(), &mut 0, &mut 0usize, &mut icc::Status::Running), + ]; + let mut iter: i32 = 0; + loop { + for (index, setting) in settings.iter().enumerate() { + match amplifiers[index].3 { + icc::Status::Finished => { + if index == 4 { + // the output of amplifier 4 is stored on the input of amplifier 0 + return *amplifiers[0].1; + } + continue; + }, + _ => {} + } + println!("[Iter {}] Running amplifier {} from instruction {}", iter, index, *amplifiers[index].2); + let mut input = if iter == 0 { + VecDeque::from([*setting, *amplifiers[index].1]) + } else { + VecDeque::from([*amplifiers[index].1]) + }; + let mut output: Vec = Vec::new(); + let result = icc::simulate(amplifiers[index].0, &mut input, &mut output, *amplifiers[index].2); + match result.status { + icc::Status::WaitingForInput => { + println!("[Iter {}] Amplifier {} is waiting for input", iter, index); + }, + _ => {}, + } + let amp_index = (index+1) % settings.len(); + *amplifiers[amp_index].1 = output[0]; + println!("[Iter {}] Amplifier {}->{}: {}", iter, index, amp_index, output[0]); + *amplifiers[index].2 = result.instruction; + *amplifiers[index].3 = result.status; + } + iter += 1; + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn example_1() { + let program = 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!(run_amplifiers(&program, settings), 43210); + } + + #[test] + fn example_2() { + let program = 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!(run_amplifiers(&program, settings), 54321); + } + + #[test] + fn example_3() { + let program = 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!(run_amplifiers(&program, settings), 65210); + } + + #[test] + fn part2_example_1() { + let program = 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![9,8,7,6,5]; + assert_eq!(run_feedback_amplifiers(&program, settings), 139629729); + } + + #[test] + fn part2_example_2() { + 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]; + let settings = vec![9,7,8,5,6]; + assert_eq!(run_feedback_amplifiers(&program, settings), 18216); + } +} diff --git a/day7/src/.#main.rs b/day7/src/.#main.rs new file mode 120000 index 0000000..2c965d9 --- /dev/null +++ b/day7/src/.#main.rs @@ -0,0 +1 @@ +kienan@monolith.244424:1652264161 \ No newline at end of file diff --git a/day7/src/main.rs b/day7/src/main.rs new file mode 100644 index 0000000..7599d41 --- /dev/null +++ b/day7/src/main.rs @@ -0,0 +1,132 @@ +use std::collections::VecDeque; +use itertools::Itertools; + +fn main() { + let program = vec![3,8,1001,8,10,8,105,1,0,0,21,38,63,88,97,118,199,280,361,442,99999,3,9,1002,9,3,9,101,2,9,9,1002,9,4,9,4,9,99,3,9,101,3,9,9,102,5,9,9,101,3,9,9,1002,9,3,9,101,3,9,9,4,9,99,3,9,1002,9,2,9,1001,9,3,9,102,3,9,9,101,2,9,9,1002,9,4,9,4,9,99,3,9,102,2,9,9,4,9,99,3,9,102,4,9,9,101,5,9,9,102,2,9,9,101,5,9,9,4,9,99,3,9,1002,9,2,9,4,9,3,9,101,1,9,9,4,9,3,9,102,2,9,9,4,9,3,9,101,1,9,9,4,9,3,9,101,2,9,9,4,9,3,9,1001,9,2,9,4,9,3,9,102,2,9,9,4,9,3,9,102,2,9,9,4,9,3,9,101,1,9,9,4,9,3,9,102,2,9,9,4,9,99,3,9,101,1,9,9,4,9,3,9,102,2,9,9,4,9,3,9,1001,9,2,9,4,9,3,9,1001,9,2,9,4,9,3,9,1001,9,1,9,4,9,3,9,1001,9,1,9,4,9,3,9,1001,9,2,9,4,9,3,9,102,2,9,9,4,9,3,9,1002,9,2,9,4,9,3,9,1001,9,1,9,4,9,99,3,9,1002,9,2,9,4,9,3,9,1002,9,2,9,4,9,3,9,102,2,9,9,4,9,3,9,1002,9,2,9,4,9,3,9,1001,9,1,9,4,9,3,9,102,2,9,9,4,9,3,9,102,2,9,9,4,9,3,9,101,1,9,9,4,9,3,9,102,2,9,9,4,9,3,9,102,2,9,9,4,9,99,3,9,102,2,9,9,4,9,3,9,101,1,9,9,4,9,3,9,1002,9,2,9,4,9,3,9,1002,9,2,9,4,9,3,9,102,2,9,9,4,9,3,9,1002,9,2,9,4,9,3,9,1001,9,2,9,4,9,3,9,101,2,9,9,4,9,3,9,1001,9,2,9,4,9,3,9,101,1,9,9,4,9,99,3,9,101,1,9,9,4,9,3,9,101,1,9,9,4,9,3,9,101,1,9,9,4,9,3,9,102,2,9,9,4,9,3,9,1001,9,1,9,4,9,3,9,1001,9,2,9,4,9,3,9,101,2,9,9,4,9,3,9,102,2,9,9,4,9,3,9,1001,9,1,9,4,9,3,9,1001,9,2,9,4,9,99]; + + let mut max_storage = 0; + let mut max_settings: Vec = Vec::new(); + + { + let settings = vec![0, 1, 2, 3, 4]; + // Cheese. + for permutation in settings.into_iter().permutations(5) { + //println!("{:?}", permutation); + let storage = run_amplifiers(&program, permutation.clone()); + if storage > max_storage { + max_storage = storage; + max_settings = permutation.clone(); + } + } + println!("[Part 1] Settings {:?} produced a value of {}", max_settings, max_storage); + } + + { + let settings = vec![5, 6, 7, 8, 9]; + for permutation in settings.into_iter().permutations(5) { + let storage = run_feedback_amplifiers(&program, permutation.clone()); + if storage > max_storage { + max_storage = storage; + max_settings = permutation.clone(); + } + } + println!("[Part 2] Settings {:?} produced a value of {}", max_settings, max_storage); + } +} + +fn run_amplifiers(program: &Vec, settings: Vec) -> i32 { + let mut storage: i32 = 0; + for setting in settings { + let mut input = VecDeque::from([setting, storage]); + let mut output: Vec = Vec::new(); + icc::simulate(&mut program.clone(), &mut input, &mut output, 0); + storage = output[0]; + } + return storage; +} + +fn run_feedback_amplifiers(program: &Vec, settings: Vec) -> i32 { + let amplifiers = [ + // program, input signal, entrypoint, setting + (&mut program.clone(), &mut 0, &mut 0usize, &mut icc::Status::Running), + (&mut program.clone(), &mut 0, &mut 0usize, &mut icc::Status::Running), + (&mut program.clone(), &mut 0, &mut 0usize, &mut icc::Status::Running), + (&mut program.clone(), &mut 0, &mut 0usize, &mut icc::Status::Running), + (&mut program.clone(), &mut 0, &mut 0usize, &mut icc::Status::Running), + ]; + let mut iter: i32 = 0; + loop { + for (index, setting) in settings.iter().enumerate() { + match amplifiers[index].3 { + icc::Status::Finished => { + if index == 4 { + // the output of amplifier 4 is stored on the input of amplifier 0 + return *amplifiers[0].1; + } + continue; + }, + _ => {} + } + println!("[Iter {}] Running amplifier {} from instruction {}", iter, index, *amplifiers[index].2); + let mut input = if iter == 0 { + VecDeque::from([*setting, *amplifiers[index].1]) + } else { + VecDeque::from([*amplifiers[index].1]) + }; + let mut output: Vec = Vec::new(); + let result = icc::simulate(amplifiers[index].0, &mut input, &mut output, *amplifiers[index].2); + match result.status { + icc::Status::WaitingForInput => { + println!("[Iter {}] Amplifier {} is waiting for input", iter, index); + }, + _ => {}, + } + let amp_index = (index+1) % settings.len(); + *amplifiers[amp_index].1 = output[0]; + println!("[Iter {}] Amplifier {}->{}: {}", iter, index, amp_index, output[0]); + *amplifiers[index].2 = result.instruction; + *amplifiers[index].3 = result.status; + } + iter += 1; + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn example_1() { + let program = 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!(run_amplifiers(&program, settings), 43210); + } + + #[test] + fn example_2() { + let program = 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!(run_amplifiers(&program, settings), 54321); + } + + #[test] + fn example_3() { + let program = 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!(run_amplifiers(&program, settings), 65210); + } + + #[test] + fn part2_example_1() { + let program = 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![9,8,7,6,5]; + assert_eq!(run_feedback_amplifiers(&program, settings), 139629729); + } + + #[test] + fn part2_example_2() { + 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]; + let settings = vec![9,7,8,5,6]; + assert_eq!(run_feedback_amplifiers(&program, settings), 18216); + } +}