day(14): add solution
Signed-off-by: Matej Focko <mfocko@redhat.com>
This commit is contained in:
parent
0a4cc4c031
commit
fdbca4409c
2 changed files with 152 additions and 0 deletions
10
samples/day14.txt
Normal file
10
samples/day14.txt
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
O....#....
|
||||||
|
O.OO#....#
|
||||||
|
.....##...
|
||||||
|
OO.#O....O
|
||||||
|
.O.....O#.
|
||||||
|
O.#..O.#.#
|
||||||
|
..O..#O..O
|
||||||
|
.......O..
|
||||||
|
#....###..
|
||||||
|
#OO..#....
|
142
src/bin/day14.rs
Normal file
142
src/bin/day14.rs
Normal file
|
@ -0,0 +1,142 @@
|
||||||
|
use std::collections::HashMap;
|
||||||
|
|
||||||
|
use aoc_2023::*;
|
||||||
|
use indicatif::ProgressIterator;
|
||||||
|
use memoize::memoize;
|
||||||
|
|
||||||
|
type Output1 = usize;
|
||||||
|
type Output2 = Output1;
|
||||||
|
|
||||||
|
#[memoize]
|
||||||
|
fn slide_rocks(map: Vec<Vec<char>>) -> Vec<Vec<char>> {
|
||||||
|
let mut tilted: Vec<Vec<char>> = map.to_vec();
|
||||||
|
|
||||||
|
for x in 0..tilted[0].len() {
|
||||||
|
let mut next = 0;
|
||||||
|
for y in 0..tilted.len() {
|
||||||
|
match tilted[y][x] {
|
||||||
|
'#' | 'O' => {
|
||||||
|
next = y + 1;
|
||||||
|
}
|
||||||
|
'.' => {
|
||||||
|
while next < tilted.len() && tilted[next][x] == '.' {
|
||||||
|
next += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if next < tilted.len() && tilted[next][x] == 'O' {
|
||||||
|
tilted[y][x] = 'O';
|
||||||
|
tilted[next][x] = '.';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => unreachable!(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
tilted
|
||||||
|
}
|
||||||
|
|
||||||
|
#[memoize]
|
||||||
|
fn rotate_east(map: Vec<Vec<char>>) -> Vec<Vec<char>> {
|
||||||
|
let mut r = map.clone();
|
||||||
|
|
||||||
|
for y in 0..map.len() {
|
||||||
|
for (x, row) in r.iter_mut().enumerate().take(map[y].len()) {
|
||||||
|
row[map.len() - y - 1] = map[y][x];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
r
|
||||||
|
}
|
||||||
|
|
||||||
|
#[memoize]
|
||||||
|
fn run_cycle(map: Vec<Vec<char>>) -> Vec<Vec<char>> {
|
||||||
|
let mut map = map;
|
||||||
|
for _ in 0..4 {
|
||||||
|
map = slide_rocks(map);
|
||||||
|
map = rotate_east(map);
|
||||||
|
}
|
||||||
|
|
||||||
|
map
|
||||||
|
}
|
||||||
|
|
||||||
|
fn total_load(m: &[Vec<char>]) -> usize {
|
||||||
|
let rows = m.len();
|
||||||
|
|
||||||
|
m.iter()
|
||||||
|
.enumerate()
|
||||||
|
.map(|(y, l)| (rows - y) * l.iter().filter(|&&c| c == 'O').count())
|
||||||
|
.sum()
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Day14 {
|
||||||
|
map: Vec<Vec<char>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Solution<Output1, Output2> for Day14 {
|
||||||
|
fn new<P: AsRef<Path>>(pathname: P) -> Self {
|
||||||
|
let lines: Vec<String> = file_to_lines(pathname);
|
||||||
|
|
||||||
|
Self {
|
||||||
|
map: lines.iter().map(|l| l.chars().collect()).collect(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn part_1(&mut self) -> Output1 {
|
||||||
|
let tilted = slide_rocks(self.map.clone());
|
||||||
|
total_load(&tilted)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn part_2(&mut self) -> Output2 {
|
||||||
|
let mut map = self.map.clone();
|
||||||
|
|
||||||
|
let iterations = 1000000000;
|
||||||
|
let mut remaining = 0;
|
||||||
|
|
||||||
|
let mut seen: HashMap<Vec<Vec<char>>, usize> = HashMap::new();
|
||||||
|
for i in (0..iterations).progress() {
|
||||||
|
seen.insert(map.clone(), i);
|
||||||
|
map = run_cycle(map);
|
||||||
|
|
||||||
|
if let Some(&old_i) = seen.get(&map) {
|
||||||
|
remaining = (iterations - i - 1) % (i - old_i + 1);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for _ in 0..remaining {
|
||||||
|
map = run_cycle(map);
|
||||||
|
}
|
||||||
|
|
||||||
|
total_load(&map)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() -> Result<()> {
|
||||||
|
Day14::main()
|
||||||
|
}
|
||||||
|
|
||||||
|
test_sample!(day_14, Day14, 136, 64);
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod day_14_extended {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_rotate_east() {
|
||||||
|
let m = vec![
|
||||||
|
vec!['#', 'O', 'O'],
|
||||||
|
vec!['.', '#', 'O'],
|
||||||
|
vec!['.', '.', 'O'],
|
||||||
|
];
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
rotate_east(m),
|
||||||
|
vec![
|
||||||
|
vec!['.', '.', '#'],
|
||||||
|
vec!['.', '#', 'O'],
|
||||||
|
vec!['O', 'O', 'O'],
|
||||||
|
]
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue