This commit is contained in:
Kienan Stewart 2022-05-15 07:38:18 -04:00
parent 9411a5231d
commit 571c0c2511
5 changed files with 305 additions and 0 deletions

30
day7/Cargo.lock generated Normal file
View File

@ -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",
]

10
day7/Cargo.toml Normal file
View File

@ -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"

132
day7/src/#main.rs# Normal file
View File

@ -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<i32> = 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<i32>, settings: Vec<i32>) -> i32 {
let mut storage: i32 = 0;
for setting in settings {
let mut input = VecDeque::from([setting, storage]);
let mut output: Vec<i32> = Vec::new();
icc::simulate(&mut program.clone(), &mut input, &mut output, 0);
storage = output[0];
}
return storage;
}
fn run_feedback_amplifiers(program: &Vec<i32>, settings: Vec<i32>) -> 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<i32> = 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);
}
}

1
day7/src/.#main.rs Symbolic link
View File

@ -0,0 +1 @@
kienan@monolith.244424:1652264161

132
day7/src/main.rs Normal file
View File

@ -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<i32> = 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<i32>, settings: Vec<i32>) -> i32 {
let mut storage: i32 = 0;
for setting in settings {
let mut input = VecDeque::from([setting, storage]);
let mut output: Vec<i32> = Vec::new();
icc::simulate(&mut program.clone(), &mut input, &mut output, 0);
storage = output[0];
}
return storage;
}
fn run_feedback_amplifiers(program: &Vec<i32>, settings: Vec<i32>) -> 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<i32> = 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);
}
}