From 5f5bb74b4d68a3bd4a34106bc1b26b52781ce116 Mon Sep 17 00:00:00 2001 From: Ummon Date: Sun, 15 Dec 2019 13:37:40 +0100 Subject: [PATCH] Day 13 --- Cargo.toml | 3 ++- src/day13.rs | 72 ++++++++++++++++++++++++++++++++++++++++++++++++++++ src/main.rs | 11 +++++++- 3 files changed, 84 insertions(+), 2 deletions(-) create mode 100644 src/day13.rs diff --git a/Cargo.toml b/Cargo.toml index 1a85341..40784cc 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,4 +10,5 @@ edition = "2018" itertools = "0.8" threadpool = "1.7" regex = "1" -num = "0.2" \ No newline at end of file +num = "0.2" +num_enum = "0.4" \ No newline at end of file diff --git a/src/day13.rs b/src/day13.rs new file mode 100644 index 0000000..246fba5 --- /dev/null +++ b/src/day13.rs @@ -0,0 +1,72 @@ +use super::intcode; +use std::convert::TryFrom; +use itertools::Itertools; +use num_enum::TryFromPrimitive; + +// Not neccesary, to try to parse enum. +#[derive(Debug, Eq, PartialEq, TryFromPrimitive)] +#[repr(u8)] +enum Tile { + Empty, + Wall, + Block, + Paddle, + Ball, +} + +pub fn count_nb_block(code: &[i64]) -> i32 { + let output = intcode::execute_op_code(code, &[]); + + output.iter().chunks(3).into_iter().map( + |tile_with_pos| { + let tile_with_pos: Vec<&i64> = tile_with_pos.collect(); + let tile = Tile::try_from(*tile_with_pos[2] as u8).unwrap(); + if tile == Tile::Block { 1 } else { 0 } + } + ).sum() +} + +struct State { + score: i64, + joystick: i64, // -1: move to left, 0: do not move, 1: move to right. + paddle_position_x: i64, + ball_position_x: i64, + buffer: Vec, // Used to buffer the input. +} + +impl intcode::IO for State { + fn read(&mut self) -> i64 { + self.joystick + } + + fn write(&mut self, value: i64) { + self.buffer.push(value); + if self.buffer.len() == 3 { + if self.buffer[0] == -1 { + self.score = self.buffer[2]; + } else { + let tile = Tile::try_from(self.buffer[2] as u8).unwrap(); + if tile == Tile::Ball { + self.ball_position_x = self.buffer[0]; + } else if tile == Tile::Paddle { + self.paddle_position_x = self.buffer[0]; + } + self.joystick = + if self.paddle_position_x > self.ball_position_x { + -1 + } else if self.paddle_position_x < self.ball_position_x { + 1 + } else { + 0 + }; + } + self.buffer.clear(); + } + } +} + +pub fn final_score(code: &[i64]) -> i64 { + let mut state = State { score: 0, joystick: 0, paddle_position_x: 0, ball_position_x: 0, buffer: Vec::new() }; + intcode::execute_op_code_with_custom_io(&code, &mut state); + state.score +} diff --git a/src/main.rs b/src/main.rs index 3b877e9..1d13545 100644 --- a/src/main.rs +++ b/src/main.rs @@ -13,6 +13,7 @@ mod day08; mod day10; mod day11; mod day12; +mod day13; fn day01() -> String { let masses = common::read_list_of_numbers("data/day01.input", "\n"); @@ -94,6 +95,13 @@ fn day12() -> String { format!("part1: {}, part2: {}", day12::final_energy(&coordinates, 1000), day12::find_same_state(&coordinates)) } +fn day13() -> String { + let code = common::read_list_of_numbers::<&str, i64>("data/day13.input", ","); + let mut modified_code = Vec::from(&code[..]); + modified_code[0] = 2; + format!("part1: {}, part2: {}", day13::count_nb_block(&code), day13::final_score(&modified_code)) +} + fn format_micros(t: u128) -> String { if t < 10_000 { format!("{} μs", t) @@ -124,7 +132,8 @@ fn main() { day09, day10, day11, - day12 + day12, + day13, ); let args: Vec = env::args().skip(1).collect(); -- 2.45.2