use aoc2019::*; use std::io; use std::io::prelude::*; use std::process; use structopt::StructOpt; #[derive(Debug, StructOpt)] #[structopt(name = "Day 21: Springdroid Adventure")] /// Pilots a springdroid around! /// /// See https://adventofcode.com/2019/day/21 for details. struct Opt {} 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 walk_result = exit_on_failed_assertion( { let input = vec![ "NOT T T\n", "AND A T\n", "AND B T\n", "AND C T\n", "NOT T J\n", "AND D J\n", "WALK\n", ]; program .with_input( input .iter() .flat_map(|line| line.chars().map(|c| Intcode::from(c as u8))) .collect(), ) .execute() }, "Program failed", ); println!( "{}", walk_result .drop_last() .unwrap() .iter() .flat_map(|c| c.to_signed_bytes_be()) .map(|c| c as char) .collect::() ); println!("{}", walk_result.last().unwrap()); let run_result = exit_on_failed_assertion( { // (!A || !B || !C) && D && (E || H) let input = vec![ "OR E J\n", "OR H J\n", "AND D J\n", "NOT T T\n", "AND A T\n", "AND B T\n", "AND C T\n", "NOT T T\n", "AND T J\n", "RUN\n", ]; program .with_input( input .iter() .flat_map(|line| line.chars().map(|c| Intcode::from(c as u8))) .collect(), ) .execute() }, "Program failed", ); println!( "{}", run_result .drop_last() .unwrap() .iter() .flat_map(|c| c.to_signed_bytes_be()) .map(|c| c as char) .collect::() ); println!("{}", run_result.last().unwrap()); } fn exit_on_failed_assertion(data: Result, message: &str) -> A { match data { Ok(data) => data, Err(e) => { eprintln!("{}: {}", message, e); process::exit(1); } } }