day24 part 2
This commit is contained in:
parent
c0b03656c1
commit
c9e4d63abe
115
src/day24.rs
115
src/day24.rs
@ -1,6 +1,21 @@
|
|||||||
use aoc_runner_derive::aoc;
|
use aoc_runner_derive::aoc;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
|
||||||
|
#[derive(Debug, Copy, Clone, Ord, PartialOrd, Eq, PartialEq, Hash)]
|
||||||
|
struct Pos(isize, isize);
|
||||||
|
impl Pos {
|
||||||
|
fn step(self, dir: Direction) -> Self {
|
||||||
|
match dir {
|
||||||
|
Direction::E => Pos(self.0 + 2, self.1),
|
||||||
|
Direction::SE => Pos(self.0 + 1, self.1 -1),
|
||||||
|
Direction::SW => Pos(self.0 -1, self.1 -1),
|
||||||
|
Direction::W => Pos(self.0 -2, self.1),
|
||||||
|
Direction::NE => Pos(self.0 + 1, self.1 + 1),
|
||||||
|
Direction::NW => Pos(self.0 -1, self.1 + 1),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Copy, Clone)]
|
#[derive(Debug, Copy, Clone)]
|
||||||
enum Direction {
|
enum Direction {
|
||||||
E,
|
E,
|
||||||
@ -24,17 +39,6 @@ impl Direction {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn step(self) -> (isize, isize) {
|
|
||||||
match self {
|
|
||||||
Direction::E => (2, 0),
|
|
||||||
Direction::SE => (1, -1),
|
|
||||||
Direction::SW => (-1, -1),
|
|
||||||
Direction::W => (-2, 0),
|
|
||||||
Direction::NE => (1, 1),
|
|
||||||
Direction::NW => (-1, 1),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn iter(input: &[u8]) -> impl Iterator<Item = Direction> + '_ {
|
fn iter(input: &[u8]) -> impl Iterator<Item = Direction> + '_ {
|
||||||
struct Iter<'a>(&'a [u8]);
|
struct Iter<'a>(&'a [u8]);
|
||||||
impl<'a> Iterator for Iter<'a> {
|
impl<'a> Iterator for Iter<'a> {
|
||||||
@ -53,13 +57,26 @@ impl Direction {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
|
||||||
|
enum Tile {
|
||||||
|
Black,
|
||||||
|
White,
|
||||||
|
}
|
||||||
|
impl Tile {
|
||||||
|
fn flip(&mut self) {
|
||||||
|
*self = match *self {
|
||||||
|
Tile::Black => Tile::White,
|
||||||
|
Tile::White => Tile::Black,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[aoc(day24, part1)]
|
#[aoc(day24, part1)]
|
||||||
fn solve_d24_p1(input: &str) -> usize {
|
fn solve_d24_p1(input: &str) -> usize {
|
||||||
let mut tiles: HashMap<_, usize> = HashMap::new();
|
let mut tiles: HashMap<_, usize> = HashMap::new();
|
||||||
for pos in input.split('\n').map(|line| {
|
for pos in input.split('\n').map(|line| {
|
||||||
Direction::iter(line.as_bytes()).fold((0, 0), |pos, dir| {
|
Direction::iter(line.as_bytes()).fold(Pos(0, 0), |pos, dir| {
|
||||||
let (x_step, y_step) = dir.step();
|
pos.step(dir)
|
||||||
(pos.0 + x_step, pos.1 + y_step)
|
|
||||||
})
|
})
|
||||||
}) {
|
}) {
|
||||||
*tiles.entry(pos).or_default() += 1;
|
*tiles.entry(pos).or_default() += 1;
|
||||||
@ -70,3 +87,73 @@ fn solve_d24_p1(input: &str) -> usize {
|
|||||||
.filter(|×_flipped| times_flipped % 2 == 1)
|
.filter(|×_flipped| times_flipped % 2 == 1)
|
||||||
.count()
|
.count()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[aoc(day24, part2)]
|
||||||
|
fn solve_d24_p2(input: &str) -> usize {
|
||||||
|
let mut floor: HashMap<_, Tile> = HashMap::new();
|
||||||
|
for pos in input.split('\n').map(|line| {
|
||||||
|
Direction::iter(line.as_bytes()).fold(Pos(0, 0), |pos, dir| {
|
||||||
|
pos.step(dir)
|
||||||
|
})
|
||||||
|
}) {
|
||||||
|
floor.entry(pos).or_insert(Tile::White).flip()
|
||||||
|
}
|
||||||
|
|
||||||
|
for _ in 0..100 {
|
||||||
|
let mut tiles_visited = HashMap::new();
|
||||||
|
for &pos in floor.keys() {
|
||||||
|
run(&floor, &mut tiles_visited, pos);
|
||||||
|
}
|
||||||
|
for pos in tiles_visited
|
||||||
|
.into_iter()
|
||||||
|
.filter_map(|(k, should_flip)| if should_flip { Some(k) } else { None })
|
||||||
|
{
|
||||||
|
floor.entry(pos).or_insert(Tile::White).flip();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
floor.values().filter(|&&tile| tile == Tile::Black).count()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn run(
|
||||||
|
floor: &HashMap<Pos, Tile>,
|
||||||
|
tiles_visited: &mut HashMap<Pos, bool>,
|
||||||
|
pos: Pos,
|
||||||
|
) {
|
||||||
|
if tiles_visited.contains_key(&pos) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
let n = neighbors(floor, pos);
|
||||||
|
let black_tiles = n
|
||||||
|
.iter()
|
||||||
|
.copied()
|
||||||
|
.filter(|&tile| tile == Tile::Black)
|
||||||
|
.count();
|
||||||
|
let tile = floor.get(&pos).copied().unwrap_or(Tile::White);
|
||||||
|
if (tile == Tile::Black && (black_tiles == 0 || black_tiles > 2))
|
||||||
|
|| (tile == Tile::White && black_tiles == 2)
|
||||||
|
{
|
||||||
|
tiles_visited.insert(pos, true);
|
||||||
|
} else {
|
||||||
|
tiles_visited.insert(pos, false);
|
||||||
|
}
|
||||||
|
if black_tiles > 0 {
|
||||||
|
run(floor, tiles_visited, pos.step(Direction::E));
|
||||||
|
run(floor, tiles_visited, pos.step(Direction::SE));
|
||||||
|
run(floor, tiles_visited, pos.step(Direction::SW));
|
||||||
|
run(floor, tiles_visited, pos.step(Direction::W));
|
||||||
|
run(floor, tiles_visited, pos.step(Direction::NE));
|
||||||
|
run(floor, tiles_visited, pos.step(Direction::NW));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn neighbors(floor: &HashMap<Pos, Tile>, pos: Pos) -> [Tile; 6] {
|
||||||
|
[
|
||||||
|
floor.get(&pos.step(Direction::E)).copied().unwrap_or(Tile::White),
|
||||||
|
floor.get(&pos.step(Direction::SE)).copied().unwrap_or(Tile::White),
|
||||||
|
floor.get(&pos.step(Direction::SW)).copied().unwrap_or(Tile::White),
|
||||||
|
floor.get(&pos.step(Direction::W)).copied().unwrap_or(Tile::White),
|
||||||
|
floor.get(&pos.step(Direction::NE)).copied().unwrap_or(Tile::White),
|
||||||
|
floor.get(&pos.step(Direction::NW)).copied().unwrap_or(Tile::White),
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user