summaryrefslogtreecommitdiff
path: root/src/bin/day_13.rs
diff options
context:
space:
mode:
authorJustin Wernick <justin@worthe-it.co.za>2019-12-21 11:57:34 +0200
committerJustin Wernick <justin@worthe-it.co.za>2019-12-21 11:57:34 +0200
commit47eabec40889d650834a244cb1951eca14c3e5ad (patch)
tree6bd8a9a928b69ac647d128de6a583e90dbce24d5 /src/bin/day_13.rs
parent4316344e335cd69714799ed204d2448d81877b7d (diff)
Day 13 part 1
Diffstat (limited to 'src/bin/day_13.rs')
-rw-r--r--src/bin/day_13.rs70
1 files changed, 70 insertions, 0 deletions
diff --git a/src/bin/day_13.rs b/src/bin/day_13.rs
new file mode 100644
index 0000000..a7d6128
--- /dev/null
+++ b/src/bin/day_13.rs
@@ -0,0 +1,70 @@
+use aoc2019::*;
+use rpds::vector::Vector;
+use rpds::RedBlackTreeMap;
+use std::io;
+use std::io::prelude::*;
+use std::process;
+use structopt::StructOpt;
+
+#[derive(Debug, StructOpt)]
+#[structopt(name = "Day 13: Care Package")]
+/// Executes an Intcode game
+///
+/// The program is read from stdin as a series of comma-separated
+/// values. Newlines are ignored.
+///
+/// See https://adventofcode.com/2019/day/13 for details.
+struct Opt {
+ #[structopt(short = "i", long = "input")]
+ input: Vec<Intcode>,
+}
+
+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>()
+ .with_input(opt.input.into_iter().collect());
+
+ let result = exit_on_failed_assertion(program.execute(), "Program errored");
+
+ println!("{}", count_blocks(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 render_screen(output: Vector<Intcode>) -> RedBlackTreeMap<(Intcode, Intcode), Intcode> {
+ (0..output.len() / 3)
+ .map(|i| i * 3)
+ .map(|i| {
+ (
+ output[i].clone(),
+ output[i + 1].clone(),
+ output[i + 2].clone(),
+ )
+ })
+ .fold(RedBlackTreeMap::new(), |acc, (x, y, tile)| {
+ acc.insert((x, y), tile)
+ })
+}
+
+fn count_blocks(output: Vector<Intcode>) -> usize {
+ render_screen(output)
+ .values()
+ .filter(|val| **val == Intcode::from(2))
+ .count()
+}