diff options
author | Justin Wernick <justin@worthe-it.co.za> | 2019-12-12 00:37:55 +0200 |
---|---|---|
committer | Justin Wernick <justin@worthe-it.co.za> | 2019-12-12 00:37:55 +0200 |
commit | 22fc69709731ba039f321c48670584c50f48d9ab (patch) | |
tree | 4cc6aadb925285f1081d1d953f58c2304b186293 | |
parent | 003a62f1c38344c5a647170bd2472c4eab39cf75 (diff) |
Day 7 part 1 (it's dirty and doesn't solve part 2 yet)
-rw-r--r-- | Cargo.lock | 1 | ||||
-rw-r--r-- | Cargo.toml | 3 | ||||
-rw-r--r-- | inputs/day_7.txt | 1 | ||||
-rw-r--r-- | src/bin/day_7.rs | 91 |
4 files changed, 95 insertions, 1 deletions
@@ -12,6 +12,7 @@ dependencies = [ name = "aoc2019" version = "0.1.0" dependencies = [ + "archery 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "derive_more 0.99.2 (registry+https://github.com/rust-lang/crates.io-index)", "im 14.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "rpds 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -8,4 +8,5 @@ edition = "2018" structopt = "0.3.5" derive_more = "0.99.2" im = "14.0.0" -rpds = "0.7.0"
\ No newline at end of file +rpds = "0.7.0" +archery = "0.3.0"
\ No newline at end of file diff --git a/inputs/day_7.txt b/inputs/day_7.txt new file mode 100644 index 0000000..b21d6af --- /dev/null +++ b/inputs/day_7.txt @@ -0,0 +1 @@ +3,8,1001,8,10,8,105,1,0,0,21,46,59,84,93,110,191,272,353,434,99999,3,9,101,2,9,9,102,3,9,9,1001,9,5,9,102,4,9,9,1001,9,4,9,4,9,99,3,9,101,3,9,9,102,5,9,9,4,9,99,3,9,1001,9,4,9,1002,9,2,9,101,2,9,9,102,2,9,9,1001,9,3,9,4,9,99,3,9,1002,9,2,9,4,9,99,3,9,102,2,9,9,1001,9,5,9,1002,9,3,9,4,9,99,3,9,102,2,9,9,4,9,3,9,102,2,9,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,101,2,9,9,4,9,3,9,101,2,9,9,4,9,3,9,1001,9,1,9,4,9,3,9,101,2,9,9,4,9,99,3,9,102,2,9,9,4,9,3,9,1002,9,2,9,4,9,3,9,1002,9,2,9,4,9,3,9,1001,9,1,9,4,9,3,9,1001,9,2,9,4,9,3,9,101,1,9,9,4,9,3,9,1001,9,2,9,4,9,3,9,1002,9,2,9,4,9,3,9,1001,9,1,9,4,9,3,9,1001,9,2,9,4,9,99,3,9,101,1,9,9,4,9,3,9,1001,9,1,9,4,9,3,9,101,1,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,1002,9,2,9,4,9,3,9,1001,9,1,9,4,9,3,9,102,2,9,9,4,9,3,9,101,1,9,9,4,9,99,3,9,1001,9,1,9,4,9,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,1001,9,2,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,1001,9,1,9,4,9,3,9,102,2,9,9,4,9,99,3,9,102,2,9,9,4,9,3,9,1002,9,2,9,4,9,3,9,1002,9,2,9,4,9,3,9,1001,9,1,9,4,9,3,9,101,1,9,9,4,9,3,9,102,2,9,9,4,9,3,9,1002,9,2,9,4,9,3,9,101,2,9,9,4,9,3,9,1002,9,2,9,4,9,3,9,1001,9,2,9,4,9,99 diff --git a/src/bin/day_7.rs b/src/bin/day_7.rs new file mode 100644 index 0000000..d412734 --- /dev/null +++ b/src/bin/day_7.rs @@ -0,0 +1,91 @@ +use aoc2019::*; +use rpds::list; +use rpds::list::List; +use std::io; +use std::io::prelude::*; +use std::process; +use structopt::StructOpt; + +#[derive(Debug, StructOpt)] +#[structopt(name = "Day 7: Amplification Circuit")] +/// Executes an Intcode program on 5 amplifiers, and finds the input that gives the max output +/// +/// See https://adventofcode.com/2019/day/7 for details. +struct Opt { + #[structopt(short = "f", long = "feedback-loop")] + feedback_loop_mode: bool, +} + +fn main() { + let stdin = io::stdin(); + let opt = Opt::from_args(); + + let program: IntcodeProgram = stdin + .lock() + .split(b',') + .map(|x| exit_on_failed_assertion(x, "Error reading input")) + .map(|x| exit_on_failed_assertion(String::from_utf8(x), "Input was not valid UTF-8")) + .map(|x| exit_on_failed_assertion(x.trim().parse::<Intcode>(), "Invalid number")) + .collect::<IntcodeProgram>(); + + let result = exit_on_failed_assertion(find_max_power(&program), "Program errored"); + println!("{}", result); +} + +fn exit_on_failed_assertion<A, E: std::error::Error>(data: Result<A, E>, message: &str) -> A { + match data { + Ok(data) => data, + Err(e) => { + eprintln!("{}: {}", message, e); + process::exit(1); + } + } +} + +fn find_max_power(program: &IntcodeProgram) -> Result<Intcode, IntcodeProgramError> { + PhaseSetting::all() + .map(|phase| run_amplifiers(program, phase)) + .collect::<Result<Vec<Intcode>, _>>() + .map(|powers| powers.into_iter().max().unwrap_or(0)) +} + +fn run_amplifiers( + program: &IntcodeProgram, + phase: PhaseSetting, +) -> Result<Intcode, IntcodeProgramError> { + run_amp(program, phase, 0, 0) + .and_then(|pipe| run_amp(program, phase, 1, pipe)) + .and_then(|pipe| run_amp(program, phase, 2, pipe)) + .and_then(|pipe| run_amp(program, phase, 3, pipe)) + .and_then(|pipe| run_amp(program, phase, 4, pipe)) +} + +fn run_amp( + program: &IntcodeProgram, + phase: PhaseSetting, + n: usize, + input: Intcode, +) -> Result<Intcode, IntcodeProgramError> { + program + .with_input(list![phase.0[n], input]) + .execute() + .and_then(|output_vec| output_vec.get(0).cloned().ok_or(IntcodeProgramError)) +} + +#[derive(Debug, Clone, Copy)] +struct PhaseSetting([Intcode; 5]); + +impl PhaseSetting { + fn all() -> impl Iterator<Item = PhaseSetting> { + (0..=4) + .flat_map(move |a| { + (0..=4).flat_map(move |b| { + (0..=4).flat_map(move |c| { + (0..=4) + .flat_map(move |d| (0..=4).map(move |e| PhaseSetting([a, b, c, d, e]))) + }) + }) + }) + .filter(|phase| (0..=4).all(|x| phase.0.contains(&x))) + } +} |