From 22fc69709731ba039f321c48670584c50f48d9ab Mon Sep 17 00:00:00 2001 From: Justin Wernick Date: Thu, 12 Dec 2019 00:37:55 +0200 Subject: Day 7 part 1 (it's dirty and doesn't solve part 2 yet) --- src/bin/day_7.rs | 91 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 91 insertions(+) create mode 100644 src/bin/day_7.rs (limited to 'src/bin') 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::(), "Invalid number")) + .collect::(); + + let result = exit_on_failed_assertion(find_max_power(&program), "Program errored"); + println!("{}", result); +} + +fn exit_on_failed_assertion(data: Result, message: &str) -> A { + match data { + Ok(data) => data, + Err(e) => { + eprintln!("{}: {}", message, e); + process::exit(1); + } + } +} + +fn find_max_power(program: &IntcodeProgram) -> Result { + PhaseSetting::all() + .map(|phase| run_amplifiers(program, phase)) + .collect::, _>>() + .map(|powers| powers.into_iter().max().unwrap_or(0)) +} + +fn run_amplifiers( + program: &IntcodeProgram, + phase: PhaseSetting, +) -> Result { + 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 { + 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 { + (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))) + } +} -- cgit v1.2.3