Added Solution for 2019 day 13
This commit is contained in:
parent
dd0de2a736
commit
72914e6246
6 changed files with 123 additions and 0 deletions
|
@ -99,6 +99,17 @@ pub mod intcode_processor {
|
|||
self.input.push_back(input);
|
||||
}
|
||||
|
||||
/// Clears the input and sets it to `input`
|
||||
pub fn reset_input(&mut self, input: RegVal) {
|
||||
self.input.clear();
|
||||
self.input.push_back(input);
|
||||
}
|
||||
|
||||
/// Return the number of items left in the input queue
|
||||
pub fn get_input_len(&self) -> usize {
|
||||
self.input.len()
|
||||
}
|
||||
|
||||
/// Get the value from memory address `address`.
|
||||
///
|
||||
/// ## Example
|
||||
|
|
9
2019/day13_care_package/Cargo.toml
Normal file
9
2019/day13_care_package/Cargo.toml
Normal file
|
@ -0,0 +1,9 @@
|
|||
[package]
|
||||
name = "day13_care_package"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
intcode_processor = { path = "../common/intcode_processor" }
|
40
2019/day13_care_package/challenge.txt
Normal file
40
2019/day13_care_package/challenge.txt
Normal file
|
@ -0,0 +1,40 @@
|
|||
As you ponder the solitude of space and the ever-increasing three-hour roundtrip for messages between you and Earth, you notice that the Space Mail Indicator Light is blinking. To help keep you sane, the Elves have sent you a care package.
|
||||
|
||||
It's a new game for the ship's [arcade cabinet](https://en.wikipedia.org/wiki/Arcade_cabinet)! Unfortunately, the arcade is *all the way* on the other end of the ship. Surely, it won't be hard to build your own - the care package even comes with schematics.
|
||||
|
||||
The arcade cabinet runs [Intcode](9) software like the game the Elves sent (your puzzle input). It has a primitive screen capable of drawing square *tiles* on a grid. The software draws tiles to the screen with output instructions: every three output instructions specify the `x` position (distance from the left), `y` position (distance from the top), and `tile id`. The `tile id` is interpreted as follows:
|
||||
|
||||
* `0` is an *empty* tile. No game object appears in this tile.
|
||||
* `1` is a *wall* tile. Walls are indestructible barriers.
|
||||
* `2` is a *block* tile. Blocks can be broken by the ball.
|
||||
* `3` is a *horizontal paddle* tile. The paddle is indestructible.
|
||||
* `4` is a *ball* tile. The ball moves diagonally and bounces off objects.
|
||||
|
||||
For example, a sequence of output values like `1,2,3,6,5,4` would draw a *horizontal paddle* tile (`1` tile from the left and `2` tiles from the top) and a *ball* tile (`6` tiles from the left and `5` tiles from the top).
|
||||
|
||||
Start the game. *How many block tiles are on the screen when the game exits?*
|
||||
|
||||
Your puzzle answer was `333`.
|
||||
|
||||
\--- Part Two ---
|
||||
----------
|
||||
|
||||
The game didn't run because you didn't put in any quarters. Unfortunately, you did not bring any quarters. Memory address `0` represents the number of quarters that have been inserted; set it to `2` to play for free.
|
||||
|
||||
The arcade cabinet has a [joystick](https://en.wikipedia.org/wiki/Joystick) that can move left and right. The software reads the position of the joystick with input instructions:
|
||||
|
||||
* If the joystick is in the *neutral position*, provide `0`.
|
||||
* If the joystick is *tilted to the left*, provide `-1`.
|
||||
* If the joystick is *tilted to the right*, provide `1`.
|
||||
|
||||
The arcade cabinet also has a [segment display](https://en.wikipedia.org/wiki/Display_device#Segment_displays) capable of showing a single number that represents the player's current score. When three output instructions specify `X=-1, Y=0`, the third output instruction is not a tile; the value instead specifies the new score to show in the segment display. For example, a sequence of output values like `-1,0,12345` would show `12345` as the player's current score.
|
||||
|
||||
Beat the game by breaking all the blocks. *What is your score after the last block is broken?*
|
||||
|
||||
Your puzzle answer was `16539`.
|
||||
|
||||
Both parts of this puzzle are complete! They provide two gold stars: \*\*
|
||||
|
||||
At this point, you should [return to your Advent calendar](/2019) and try another puzzle.
|
||||
|
||||
If you still want to see it, you can [get your puzzle input](13/input).
|
62
2019/day13_care_package/src/lib.rs
Normal file
62
2019/day13_care_package/src/lib.rs
Normal file
|
@ -0,0 +1,62 @@
|
|||
use std::collections::HashMap;
|
||||
|
||||
use intcode_processor::intcode_processor::{Cpu, OutputState};
|
||||
|
||||
pub fn run(input: &str) -> (usize, isize) {
|
||||
let mut cpu = Cpu::try_with_memory_from_str(input).unwrap();
|
||||
let mut cpu_2 = cpu.clone();
|
||||
let mut screen = HashMap::new();
|
||||
let mut screen_2 = HashMap::new();
|
||||
while let OutputState::Output(x) = cpu.run() {
|
||||
if let OutputState::Output(y) = cpu.run() {
|
||||
if let OutputState::Output(tile) = cpu.run() {
|
||||
screen.insert((x, y), tile);
|
||||
}
|
||||
}
|
||||
}
|
||||
let first = screen.iter().filter(|(_coords, tile)| **tile == 2).count();
|
||||
|
||||
cpu_2.set(0, 2);
|
||||
let second = play(&mut cpu_2, &mut screen_2);
|
||||
(first, second)
|
||||
}
|
||||
|
||||
fn play(cpu: &mut Cpu, screen: &mut HashMap<(isize, isize), isize>) -> isize {
|
||||
let mut res = 0;
|
||||
let mut ball_pos = 0;
|
||||
let mut pad_pos = 0;
|
||||
while let OutputState::Output(x) = cpu.run() {
|
||||
if let OutputState::Output(y) = cpu.run() {
|
||||
if let OutputState::Output(tile) = cpu.run() {
|
||||
if x == -1 && y == 0 {
|
||||
res = tile;
|
||||
} else {
|
||||
if tile == 4 {
|
||||
ball_pos = x;
|
||||
} else if tile == 3 {
|
||||
pad_pos = x;
|
||||
}
|
||||
screen.insert((x, y), tile);
|
||||
cpu.reset_input((ball_pos - pad_pos).signum());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
res
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use std::fs::read_to_string;
|
||||
|
||||
fn read_file(name: &str) -> String {
|
||||
read_to_string(name).expect(&format!("Unable to read file: {name}")[..]).trim().to_string()
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_challenge() {
|
||||
let challenge_input = read_file("tests/challenge_input");
|
||||
assert_eq!(run(&challenge_input), (333, 16539));
|
||||
}
|
||||
}
|
1
2019/day13_care_package/tests/challenge_input
Normal file
1
2019/day13_care_package/tests/challenge_input
Normal file
File diff suppressed because one or more lines are too long
Loading…
Add table
Add a link
Reference in a new issue