mirror of
https://github.com/Noratrieb/advent-of-code.git
synced 2026-01-16 18:45:02 +01:00
more
This commit is contained in:
parent
43d4458c1a
commit
a7e9248e9c
1 changed files with 81 additions and 20 deletions
|
|
@ -1,6 +1,6 @@
|
||||||
use std::collections::VecDeque;
|
use std::collections::VecDeque;
|
||||||
|
|
||||||
use helper::{Day, Variants};
|
use helper::{Day, IteratorExt, Variants};
|
||||||
|
|
||||||
pub fn main() {
|
pub fn main() {
|
||||||
helper::main::<Day10>(include_str!("../input.txt"));
|
helper::main::<Day10>(include_str!("../input.txt"));
|
||||||
|
|
@ -242,6 +242,14 @@ fn part1(input: &str) -> u64 {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn surroundings(pos: usize, width: usize, len: usize, byte: u8) -> impl Iterator<Item = usize> {
|
fn surroundings(pos: usize, width: usize, len: usize, byte: u8) -> impl Iterator<Item = usize> {
|
||||||
|
surroundings_opt(pos, width, len, byte).flatten()
|
||||||
|
}
|
||||||
|
fn surroundings_opt(
|
||||||
|
pos: usize,
|
||||||
|
width: usize,
|
||||||
|
len: usize,
|
||||||
|
byte: u8,
|
||||||
|
) -> impl Iterator<Item = Option<usize>> {
|
||||||
[
|
[
|
||||||
// TODO: also use these filters in part 1
|
// TODO: also use these filters in part 1
|
||||||
left(pos, width).filter(|_| points_to(byte, Direction::Left)),
|
left(pos, width).filter(|_| points_to(byte, Direction::Left)),
|
||||||
|
|
@ -250,13 +258,17 @@ fn surroundings(pos: usize, width: usize, len: usize, byte: u8) -> impl Iterator
|
||||||
bottom(pos, len, width).filter(|_| points_to(byte, Direction::Bottom)),
|
bottom(pos, len, width).filter(|_| points_to(byte, Direction::Bottom)),
|
||||||
]
|
]
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.flatten()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Copy)]
|
#[derive(Clone, Copy, PartialEq, Eq)]
|
||||||
enum State {
|
enum State {
|
||||||
Empty,
|
Empty,
|
||||||
Path,
|
Path,
|
||||||
|
Outside,
|
||||||
|
OpenLeft,
|
||||||
|
OpenRight,
|
||||||
|
OpenTop,
|
||||||
|
OpenBottom,
|
||||||
}
|
}
|
||||||
|
|
||||||
fn part2(input: &str) -> u64 {
|
fn part2(input: &str) -> u64 {
|
||||||
|
|
@ -279,31 +291,67 @@ fn part2(input: &str) -> u64 {
|
||||||
|
|
||||||
tiles[target] = State::Path;
|
tiles[target] = State::Path;
|
||||||
|
|
||||||
let mut a = start_surroundings.next().unwrap();
|
let mut ab = start_surroundings.collect_array::<2>().unwrap();
|
||||||
let mut b = start_surroundings.next().unwrap();
|
ab.iter().for_each(|&a| tiles[a] = State::Path);
|
||||||
tiles[a] = State::Path;
|
|
||||||
tiles[b] = State::Path;
|
|
||||||
let mut value = highest_value - 1;
|
let mut value = highest_value - 1;
|
||||||
|
|
||||||
while value > 0 {
|
while value > 0 {
|
||||||
a = surroundings(a, width, bytes.len(), bytes[a])
|
ab = ab.map(|a| {
|
||||||
.find(|&pos| step_map[pos].1 && step_map[pos].0 == value - 1)
|
surroundings(a, width, bytes.len(), bytes[a])
|
||||||
.unwrap();
|
.find(|&pos| step_map[pos].1 && step_map[pos].0 == value - 1)
|
||||||
b = surroundings(b, width, bytes.len(), bytes[b])
|
.unwrap()
|
||||||
.find(|&pos| step_map[pos].1 && step_map[pos].0 == value - 1)
|
});
|
||||||
.unwrap();
|
|
||||||
value -= 1;
|
value -= 1;
|
||||||
|
|
||||||
tiles[a] = State::Path;
|
ab.iter().for_each(|&a| tiles[a] = State::Path);
|
||||||
tiles[b] = State::Path;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
print(&tiles, width, |i, state| match state {
|
print_tiles(&tiles, width, &bytes);
|
||||||
State::Empty => print!("{}", bytes[i] as char),
|
|
||||||
State::Path => print!("\x1B[1;31m{}\x1B[1;0m", bytes[i] as char),
|
|
||||||
});
|
|
||||||
|
|
||||||
0
|
// Cellular automata!
|
||||||
|
let mut changed = true;
|
||||||
|
while changed {
|
||||||
|
changed = false;
|
||||||
|
std::thread::sleep(std::time::Duration::from_secs(1));
|
||||||
|
|
||||||
|
for i in 0..tiles.len() {
|
||||||
|
let before = tiles[i];
|
||||||
|
if before != State::Empty {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
for around in surroundings_opt(i, width, bytes.len(), bytes[i]) {
|
||||||
|
// TODO: squeeeeze
|
||||||
|
match around {
|
||||||
|
None => {
|
||||||
|
tiles[i] = State::Outside;
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
Some(around) => {
|
||||||
|
if tiles[around] == State::Outside {
|
||||||
|
tiles[i] = State::Outside;
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
print_tiles(&tiles, width, &bytes);
|
||||||
|
}
|
||||||
|
|
||||||
|
tiles.iter().filter(|&&state| state == State::Empty).count() as u64
|
||||||
|
}
|
||||||
|
|
||||||
|
fn print_tiles(tiles: &[State], width: usize, bytes: &[u8]) {
|
||||||
|
print(&tiles, width, |i, state| {
|
||||||
|
let c = fancy_char(bytes[i]);
|
||||||
|
match state {
|
||||||
|
State::Empty => print!("{c}"),
|
||||||
|
State::Path => print!("\x1B[1;31m{c}\x1B[1;0m"),
|
||||||
|
State::Outside => print!("\x1B[1;34m{c}\x1B[1;0m"),
|
||||||
|
_ => print!("\x1B[1;33m{c}\x1B[1;0m"),
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
fn print<T>(slice: &[T], width: usize, mut cell: impl FnMut(usize, &T)) {
|
fn print<T>(slice: &[T], width: usize, mut cell: impl FnMut(usize, &T)) {
|
||||||
|
|
@ -318,6 +366,19 @@ fn print<T>(slice: &[T], width: usize, mut cell: impl FnMut(usize, &T)) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn fancy_char(byte: u8) -> char {
|
||||||
|
match byte {
|
||||||
|
VERTICAL => '│',
|
||||||
|
HORIZONTAL => '─',
|
||||||
|
BOTTOM_LEFT => '└',
|
||||||
|
BOTTOM_RIGHT => '┘',
|
||||||
|
TOP_RIGHT => '┐',
|
||||||
|
TOP_LEFT => '┌',
|
||||||
|
S => '+',
|
||||||
|
_ => '■',
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
helper::tests! {
|
helper::tests! {
|
||||||
day10 Day10;
|
day10 Day10;
|
||||||
part1 {
|
part1 {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue