2019: day13: finish

This commit is contained in:
Antoine Martin 2019-12-14 00:51:44 +01:00
parent 9f77b90f81
commit 03d248cf9c
5 changed files with 162 additions and 0 deletions

View file

@ -12,6 +12,7 @@ use aoc2019::day09;
use aoc2019::day10;
use aoc2019::day11;
use aoc2019::day12;
use aoc2019::day13;
fn aoc2019_all(c: &mut Criterion) {
c.bench_function("day01", |b| b.iter(|| day01::run().unwrap()));
@ -26,6 +27,7 @@ fn aoc2019_all(c: &mut Criterion) {
c.bench_function("day10", |b| b.iter(|| day10::run().unwrap()));
c.bench_function("day11", |b| b.iter(|| day11::run().unwrap()));
c.bench_function("day12", |b| b.iter(|| day12::run().unwrap()));
c.bench_function("day13", |b| b.iter(|| day13::run().unwrap()));
}
criterion_group! {

1
aoc2019/input/day13.txt Normal file

File diff suppressed because one or more lines are too long

156
aoc2019/src/day13.rs Normal file
View file

@ -0,0 +1,156 @@
use std::collections::HashMap;
use std::fmt::{self, Display, Write};
use aoc::err;
use aoc::Result;
use crate::intcode::{parse_memory, Intcode};
const INPUT: &str = include_str!("../input/day13.txt");
pub fn run() -> Result<String> {
let mut res = String::with_capacity(128);
let memory = parse_memory(INPUT)?;
writeln!(res, "part 1: {}", part1(memory.clone())?)?;
writeln!(res, "part 2: {}", part2(memory)?)?;
Ok(res)
}
fn part1(memory: Vec<i64>) -> Result<usize> {
let mut intcode = Intcode::with_memory(memory);
intcode.run()?;
let mut map = HashMap::new();
for c in intcode.output.chunks(3) {
let pos = (c[0], c[1]);
let tile = Tile::new(c[2])?;
map.insert(pos, tile);
}
Ok(map
.values()
.filter(|t| match t {
Tile::Block => true,
_ => false,
})
.count())
}
#[allow(dead_code)]
fn print_screen(screen: &[Vec<Tile>]) {
for line in screen {
for tile in line {
print!("{}", tile);
}
println!();
}
}
fn get_next_move(paddle_pos: (i64, i64), ball_pos: (i64, i64)) -> i64 {
if ball_pos.0 > paddle_pos.0 {
1
} else if ball_pos.0 == paddle_pos.0 {
0
} else {
-1
}
}
fn part2(mut memory: Vec<i64>) -> Result<i64> {
// put coin in
memory[0] = 2;
let mut intcode = Intcode::with_memory(memory);
let mut score = 0;
let mut paddle_pos = (0, 0);
let mut ball_pos = (0, 0);
loop {
let halted = intcode.run_and_wait()?;
for c in intcode.output.chunks(3) {
let pos = (c[0], c[1]);
match pos {
(-1, 0) => {
score = c[2];
}
_ => {
let tile = Tile::new(c[2])?;
match tile {
Tile::Paddle => paddle_pos = pos,
Tile::Ball => ball_pos = pos,
_ => {}
}
}
};
}
intcode.output.clear();
if halted {
break;
}
let mv = get_next_move(paddle_pos, ball_pos);
intcode.add_input(mv);
}
Ok(score)
}
#[derive(Clone, Copy)]
enum Tile {
Empty,
Wall,
Block,
Paddle,
Ball,
}
impl Tile {
fn new(n: i64) -> Result<Self> {
let tile = match n {
0 => Tile::Empty,
1 => Tile::Wall,
2 => Tile::Block,
3 => Tile::Paddle,
4 => Tile::Ball,
_ => return Err(err!("couldn't associate number with tile: {}", n)),
};
Ok(tile)
}
}
impl Display for Tile {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
Tile::Empty => write!(f, " "),
Tile::Wall => write!(f, "|"),
Tile::Block => write!(f, ""),
Tile::Paddle => write!(f, "_"),
Tile::Ball => write!(f, "O"),
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn part1_real() {
let memory = parse_memory(INPUT).unwrap();
assert_eq!(part1(memory).unwrap(), 298);
}
#[test]
fn part2_real() {
let memory = parse_memory(INPUT).unwrap();
assert_eq!(part2(memory).unwrap(), 13956);
}
}

View file

@ -12,3 +12,4 @@ pub mod day09;
pub mod day10;
pub mod day11;
pub mod day12;
pub mod day13;

View file

@ -13,6 +13,7 @@ use aoc2019::day09;
use aoc2019::day10;
use aoc2019::day11;
use aoc2019::day12;
use aoc2019::day13;
fn main() -> Result<()> {
let days: &[DayFunc] = &[
@ -28,6 +29,7 @@ fn main() -> Result<()> {
day10::run,
day11::run,
day12::run,
day13::run,
];
aoc::run(days)