day 10 (only part 1) + 11
This commit is contained in:
parent
5abf4a2916
commit
ff54ef107a
14
Cargo.lock
generated
14
Cargo.lock
generated
@ -34,6 +34,20 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
name = "day1"
|
name = "day1"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "day10"
|
||||||
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"itertools 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "day11"
|
||||||
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"shared 0.1.0",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "day2"
|
name = "day2"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
|
@ -9,5 +9,7 @@ members = [
|
|||||||
"day7",
|
"day7",
|
||||||
"day8",
|
"day8",
|
||||||
"day9",
|
"day9",
|
||||||
|
"day10",
|
||||||
|
"day11",
|
||||||
"shared",
|
"shared",
|
||||||
]
|
]
|
||||||
|
10
day10/Cargo.toml
Normal file
10
day10/Cargo.toml
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
[package]
|
||||||
|
name = "day10"
|
||||||
|
version = "0.1.0"
|
||||||
|
authors = ["Stefan Bühler <stbuehler@web.de>"]
|
||||||
|
edition = "2018"
|
||||||
|
|
||||||
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
itertools = "0.8.2"
|
26
day10/src/input.txt
Normal file
26
day10/src/input.txt
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
#.#.###.#.#....#..##.#....
|
||||||
|
.....#..#..#..#.#..#.....#
|
||||||
|
.##.##.##.##.##..#...#...#
|
||||||
|
#.#...#.#####...###.#.#.#.
|
||||||
|
.#####.###.#.#.####.#####.
|
||||||
|
#.#.#.##.#.##...####.#.##.
|
||||||
|
##....###..#.#..#..#..###.
|
||||||
|
..##....#.#...##.#.#...###
|
||||||
|
#.....#.#######..##.##.#..
|
||||||
|
#.###.#..###.#.#..##.....#
|
||||||
|
##.#.#.##.#......#####..##
|
||||||
|
#..##.#.##..###.##.###..##
|
||||||
|
#..#.###...#.#...#..#.##.#
|
||||||
|
.#..#.#....###.#.#..##.#.#
|
||||||
|
#.##.#####..###...#.###.##
|
||||||
|
#...##..#..##.##.#.##..###
|
||||||
|
#.#.###.###.....####.##..#
|
||||||
|
######....#.##....###.#..#
|
||||||
|
..##.#.####.....###..##.#.
|
||||||
|
#..#..#...#.####..######..
|
||||||
|
#####.##...#.#....#....#.#
|
||||||
|
.#####.##.#.#####..##.#...
|
||||||
|
#..##..##.#.##.##.####..##
|
||||||
|
.##..####..#..####.#######
|
||||||
|
#.#..#.##.#.######....##..
|
||||||
|
.#.##.##.####......#.##.##
|
107
day10/src/main.rs
Normal file
107
day10/src/main.rs
Normal file
@ -0,0 +1,107 @@
|
|||||||
|
use itertools::Itertools;
|
||||||
|
|
||||||
|
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
|
||||||
|
pub struct Position {
|
||||||
|
pub x: usize,
|
||||||
|
pub y: usize,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
|
||||||
|
pub struct Field {
|
||||||
|
rows: usize,
|
||||||
|
columns: usize,
|
||||||
|
astroids: Vec<bool>,
|
||||||
|
}
|
||||||
|
|
||||||
|
fn gcd(mut x: isize, mut y: isize) -> isize {
|
||||||
|
loop {
|
||||||
|
if y == 0 { return x; }
|
||||||
|
x = x % y;
|
||||||
|
if x == 0 { return y; }
|
||||||
|
y = y % x;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Field {
|
||||||
|
pub fn parse(input: &str) -> Self {
|
||||||
|
let lines = input.lines().collect::<Vec<_>>();
|
||||||
|
let rows = lines.len();
|
||||||
|
let columns = lines[0].len();
|
||||||
|
let mut astroids = Vec::new();
|
||||||
|
for line in lines {
|
||||||
|
assert_eq!(columns, line.len());
|
||||||
|
for cell in line.chars() {
|
||||||
|
astroids.push(match cell {
|
||||||
|
'#' => true,
|
||||||
|
'.' => false,
|
||||||
|
_ => panic!("Unexpected cell: {:?}", cell),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Self {
|
||||||
|
rows,
|
||||||
|
columns,
|
||||||
|
astroids,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn sees(&self, a: Position, b: Position) -> bool {
|
||||||
|
if a == b { return true; }
|
||||||
|
let diff_x = b.x as isize - a.x as isize;
|
||||||
|
let diff_y = b.y as isize - a.y as isize;
|
||||||
|
let d = gcd(diff_x, diff_y).abs();
|
||||||
|
let diff_x = diff_x / d;
|
||||||
|
let diff_y = diff_y / d;
|
||||||
|
let mut pos = a;
|
||||||
|
loop {
|
||||||
|
pos.x = (pos.x as isize + diff_x) as usize;
|
||||||
|
pos.y = (pos.y as isize + diff_y) as usize;
|
||||||
|
if pos == b { return true; }
|
||||||
|
if self[pos] { return false; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn all_astroids(&self) -> impl Iterator<Item = Position> + '_ {
|
||||||
|
(0..self.columns).cartesian_product(0..self.rows).map(|(x, y)| Position { x, y }).filter(move |pos| self[*pos])
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn best_monitoring_station(&self) -> (Position, usize) {
|
||||||
|
self.all_astroids().map(|monitor| {
|
||||||
|
// can see itself, but only count "others"
|
||||||
|
(monitor, self.all_astroids().filter(|astroid| self.sees(monitor, *astroid)).count() - 1)
|
||||||
|
}).max_by_key(|(_, n)| *n).unwrap()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl std::ops::Index<Position> for Field {
|
||||||
|
type Output = bool;
|
||||||
|
|
||||||
|
fn index(&self, index: Position) -> &Self::Output {
|
||||||
|
assert!(index.x < self.columns);
|
||||||
|
assert!(index.y < self.rows);
|
||||||
|
&self.astroids[index.y * self.columns + index.x]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let input = include_str!("input.txt");
|
||||||
|
println!("Best monitoring station sees astroids: {}", Field::parse(input).best_monitoring_station().1);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod day10test {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn examples1() {
|
||||||
|
assert_eq!(
|
||||||
|
Field::parse(".#..#
|
||||||
|
.....
|
||||||
|
#####
|
||||||
|
....#
|
||||||
|
...##").best_monitoring_station(),
|
||||||
|
(Position { x: 3, y: 4 }, 8),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
10
day11/Cargo.toml
Normal file
10
day11/Cargo.toml
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
[package]
|
||||||
|
name = "day11"
|
||||||
|
version = "0.1.0"
|
||||||
|
authors = ["Stefan Bühler <stbuehler@web.de>"]
|
||||||
|
edition = "2018"
|
||||||
|
|
||||||
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
shared = { path = "../shared" }
|
1
day11/src/input.txt
Normal file
1
day11/src/input.txt
Normal file
@ -0,0 +1 @@
|
|||||||
|
3,8,1005,8,309,1106,0,11,0,0,0,104,1,104,0,3,8,102,-1,8,10,101,1,10,10,4,10,1008,8,1,10,4,10,1001,8,0,29,3,8,102,-1,8,10,101,1,10,10,4,10,1008,8,0,10,4,10,102,1,8,51,3,8,102,-1,8,10,1001,10,1,10,4,10,108,0,8,10,4,10,1002,8,1,72,1,1104,8,10,2,1105,15,10,2,1106,0,10,3,8,1002,8,-1,10,1001,10,1,10,4,10,1008,8,1,10,4,10,101,0,8,107,3,8,102,-1,8,10,1001,10,1,10,4,10,108,1,8,10,4,10,101,0,8,128,2,6,8,10,3,8,102,-1,8,10,101,1,10,10,4,10,1008,8,0,10,4,10,102,1,8,155,1006,0,96,2,108,10,10,1,101,4,10,3,8,1002,8,-1,10,101,1,10,10,4,10,1008,8,0,10,4,10,1002,8,1,188,2,1,5,10,3,8,102,-1,8,10,101,1,10,10,4,10,1008,8,0,10,4,10,102,1,8,214,2,6,18,10,1006,0,78,1,105,1,10,3,8,1002,8,-1,10,1001,10,1,10,4,10,1008,8,1,10,4,10,102,1,8,247,2,103,8,10,2,1002,10,10,2,106,17,10,1,1006,15,10,3,8,102,-1,8,10,101,1,10,10,4,10,1008,8,1,10,4,10,101,0,8,285,1,1101,18,10,101,1,9,9,1007,9,992,10,1005,10,15,99,109,631,104,0,104,1,21102,387507921664,1,1,21102,1,326,0,1106,0,430,21102,932826591260,1,1,21102,337,1,0,1106,0,430,3,10,104,0,104,1,3,10,104,0,104,0,3,10,104,0,104,1,3,10,104,0,104,1,3,10,104,0,104,0,3,10,104,0,104,1,21101,206400850983,0,1,21101,0,384,0,1105,1,430,21102,3224464603,1,1,21102,395,1,0,1106,0,430,3,10,104,0,104,0,3,10,104,0,104,0,21102,838433657700,1,1,21102,418,1,0,1106,0,430,21101,825012007272,0,1,21101,429,0,0,1106,0,430,99,109,2,21202,-1,1,1,21101,40,0,2,21101,461,0,3,21102,1,451,0,1105,1,494,109,-2,2105,1,0,0,1,0,0,1,109,2,3,10,204,-1,1001,456,457,472,4,0,1001,456,1,456,108,4,456,10,1006,10,488,1102,1,0,456,109,-2,2106,0,0,0,109,4,1202,-1,1,493,1207,-3,0,10,1006,10,511,21101,0,0,-3,21202,-3,1,1,21201,-2,0,2,21102,1,1,3,21102,1,530,0,1106,0,535,109,-4,2106,0,0,109,5,1207,-3,1,10,1006,10,558,2207,-4,-2,10,1006,10,558,22101,0,-4,-4,1106,0,626,22102,1,-4,1,21201,-3,-1,2,21202,-2,2,3,21101,0,577,0,1106,0,535,22102,1,1,-4,21101,1,0,-1,2207,-4,-2,10,1006,10,596,21102,0,1,-1,22202,-2,-1,-2,2107,0,-3,10,1006,10,618,21201,-1,0,1,21102,618,1,0,105,1,493,21202,-2,-1,-2,22201,-4,-2,-4,109,-5,2105,1,0
|
107
day11/src/main.rs
Normal file
107
day11/src/main.rs
Normal file
@ -0,0 +1,107 @@
|
|||||||
|
use shared::intcode::{IntCode, SimulateStep};
|
||||||
|
use std::collections::{HashMap, HashSet};
|
||||||
|
|
||||||
|
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
|
||||||
|
pub enum Direction {
|
||||||
|
Up,
|
||||||
|
Right,
|
||||||
|
Down,
|
||||||
|
Left,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Direction {
|
||||||
|
pub fn turn_right(self) -> Self {
|
||||||
|
match self {
|
||||||
|
Self::Up => Self::Right,
|
||||||
|
Self::Right => Self::Down,
|
||||||
|
Self::Down => Self::Left,
|
||||||
|
Self::Left => Self::Up,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn turn_left(self) -> Self {
|
||||||
|
match self {
|
||||||
|
Self::Up => Self::Left,
|
||||||
|
Self::Right => Self::Up,
|
||||||
|
Self::Down => Self::Right,
|
||||||
|
Self::Left => Self::Down,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
|
||||||
|
pub struct Position {
|
||||||
|
pub x: isize,
|
||||||
|
pub y: isize,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl std::ops::Add<Direction> for Position {
|
||||||
|
type Output = Position;
|
||||||
|
|
||||||
|
fn add(mut self, rhs: Direction) -> Self::Output {
|
||||||
|
match rhs {
|
||||||
|
Direction::Up => self.y -= 1,
|
||||||
|
Direction::Right => self.x += 1,
|
||||||
|
Direction::Down => self.y += 1,
|
||||||
|
Direction::Left => self.x -= 1,
|
||||||
|
}
|
||||||
|
self
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn paint(mut ic: IntCode, start_white: bool) -> HashMap<Position, bool> {
|
||||||
|
let mut painted = HashMap::new();
|
||||||
|
let mut pos = Position { x: 0, y: 0 };
|
||||||
|
let mut direction = Direction::Up;
|
||||||
|
if start_white {
|
||||||
|
painted.insert(pos, true);
|
||||||
|
}
|
||||||
|
loop {
|
||||||
|
let is_white = painted.get(&pos).cloned().unwrap_or(false);
|
||||||
|
ic.next_input = Some(if is_white { 1 } else { 0 });
|
||||||
|
match ic.simulate_step() {
|
||||||
|
SimulateStep::WaitForInput => panic!("no further input until paint and movement done"),
|
||||||
|
SimulateStep::Finished => break,
|
||||||
|
SimulateStep::Output(n) => {
|
||||||
|
match n {
|
||||||
|
0 => { painted.insert(pos, false); },
|
||||||
|
1 => { painted.insert(pos, true); },
|
||||||
|
_ => panic!("invalid paint: {}", n),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
match ic.simulate_step().expect_output() {
|
||||||
|
0 => direction = direction.turn_left(),
|
||||||
|
1 => direction = direction.turn_right(),
|
||||||
|
n => panic!("invalid rotation: {}", n),
|
||||||
|
}
|
||||||
|
pos = pos + direction;
|
||||||
|
}
|
||||||
|
painted
|
||||||
|
}
|
||||||
|
|
||||||
|
fn visualize(painted: HashMap<Position, bool>) {
|
||||||
|
let painted_white: HashSet<Position> = painted.into_iter().filter_map(|(k, v)| if v { Some(k) } else { None }).collect();
|
||||||
|
let left = painted_white.iter().map(|p| p.x).min().unwrap();
|
||||||
|
let right = painted_white.iter().map(|p| p.x).max().unwrap();
|
||||||
|
let top = painted_white.iter().map(|p| p.y).min().unwrap();
|
||||||
|
let bottom = painted_white.iter().map(|p| p.y).max().unwrap();
|
||||||
|
for y in top..=bottom {
|
||||||
|
for x in left..=right {
|
||||||
|
if painted_white.contains(&Position { x, y }) {
|
||||||
|
print!("#");
|
||||||
|
} else {
|
||||||
|
print!(" ");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
println!("");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let ic = include_str!("input.txt").parse::<IntCode>().unwrap();
|
||||||
|
let painted = paint(ic.clone(), false);
|
||||||
|
println!("First try: Painted {} tiles.", painted.len());
|
||||||
|
let painted = paint(ic, true);
|
||||||
|
visualize(painted);
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user