Day 13
authorUmmon <greg.burri@gmail.com>
Sun, 15 Dec 2019 12:37:40 +0000 (13:37 +0100)
committerUmmon <greg.burri@gmail.com>
Sun, 15 Dec 2019 12:37:40 +0000 (13:37 +0100)
Cargo.toml
src/day13.rs [new file with mode: 0644]
src/main.rs

index 1a85341..40784cc 100644 (file)
@@ -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 (file)
index 0000000..246fba5
--- /dev/null
@@ -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<i64>, // 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
+}
index 3b877e9..1d13545 100644 (file)
@@ -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<String> = env::args().skip(1).collect();