This commit is contained in:
Moritz Hölting 2023-12-14 19:45:04 +01:00
parent 16987a4bf8
commit d93dc91117
5 changed files with 419 additions and 0 deletions

7
Cargo.lock generated
View File

@ -159,6 +159,13 @@ dependencies = [
"rayon",
]
[[package]]
name = "day-14"
version = "0.0.0"
dependencies = [
"indoc",
]
[[package]]
name = "deprecate-until"
version = "0.1.1"

7
day-14/Cargo.toml Normal file
View File

@ -0,0 +1,7 @@
[package]
name = "day-14"
version = "0.0.0"
edition = "2021"
[dev-dependencies]
indoc.workspace = true

100
day-14/src/bin/input.txt Normal file
View File

@ -0,0 +1,100 @@
O.O#..O.#...#..O.O#..O#...O..O.#...O#.OO.O...#....#.O.##..####.OOO....OO......##..........#O.#O.O.#.
..O.#..#O...#..#.....O..O..OO..#.O..O#..#O#...#......O.O.O......#..OO##...O..#.O.O..#...#O....O.OO..
....O#O#.O#...#..O.O#..#.....O....#.....OOO#OO.#....#...#.O.OOOO..#O.O##....##..O.....##.OOO.#..##..
OO...OO...#..OOO..#....O.#.......##O....#..O.O#..#.O.#..O.#O.#.#..#....#...O.......O#O.....OOO###...
..#...#...O.O....#..O.....#...OO.##O...#O...#.#.O#O.OO.OO.O...#O#...#.#...#.....O..#..O##.##.OO..#.O
..#.#.O.#OO#...#.#O##O.OO..#......#OO....O........#OO#..O.O.....#.....O.O..O.#O#..O......O....O.##.#
.....O..O......O...#.#.#.....#OOO##O.#O...O...O.O..#...#O##.OO......O......OO..O#..##......#OO#..O..
...#...O.#O.......#.O....#..#.....#.O.#.....#..O..#.....O#..O#.O.O......O###O#..O...OO..##........##
.......#O..O..O........#...#....O..#...#.....#.....#.#O.#.O...O#.....OO.O........#O#O.O..#.....O#O..
OOO....OO..#O.O#....O#O....OO...O.O...O..O.#..O#........OO....#...#.....OO..O#....##OO#.O#O........O
#.#......O..O...O###O.OO..##......#........O........O......O..O..O.....O.##.O...O..O..OO.O##O.O..#O.
...O.............#.OO.O#.#.....O.O#..OO#.............O..OO.#.O.#O#.O....#..#........O.#.O.......O#..
.............OO#.....O.O..O..O...O.O..#..#.#..O....OO#..OO..#.O..O#.....#.#....O.O...#.#O....#...O.#
..O..#O.#.#OOO.....#O..OO.##....O..##.O.....O....O..#.#...O.O..O##...O...O..#..O.#O.##.......O...#..
...O#.....O#O...O....OOO...#.#....##O.....OOO.##...OO.........#.#.#..O....#O#.OO.O........O.........
.......#........#....OO........O...OO.##...O.#.....#....O..OO.O.#...OO..O...O..O....O.#....#.......#
..#....#...##O..#....O#..O.O....#....#..###.#.O.....###..OO....#...OO.OOO#O...##...O.#O#...O...O.O..
O#..O#...OO..#.......#....OOO...OO.O...OO...##.O..O##.O......#....#O.O..O#OOO.#.O#O.......OO...OO...
OO.#.#...#..O.#.#.OO..OO.#O.#..O....OOO.#.....O.OO....O.#.#..##.....O.#...O......#OO#..O.O..#.....#.
O.....O..O..........O....O..#..#...........#.#O.......#....O.#..##....#O#...#O.O...O#O..#O#..OO.#.O.
.#.##....O.#...OO##O.#..O..OO........O...O......O#OO..OO.O...#..#.O#O.......O#...O.O#..#OOO.O...OO#.
..O..#OO#O#.O..O..#......#.O..#...O..O..O...##O.O..##.....#O.O.OOO.O..O...O...O..O..O....#......#OO.
...OOOO.#.#.O.OO#......#.#.O..O.#...O..O..#......#....##O.#.O.#O#O....###.#..#.....O#.O........O....
..OO#.........OOO..........O...O..###...##...O........#....O.O#O....#...............#...O..O.O...#..
.O......#O.OO.....O..#........O#OO.....O....O.O#.O.O...O....#..O#O....#.....O...O#O.O..#.OO..##.#.#.
....O.O#..#...O#.O.O.#......OO..O#..#..#..##...O.#..###.O#.O..O#....O.#..O.O#..##O#....#O.OO#.#.....
O##..#.....##...O......#..O....#O..#O...O.........O..OO......#.#OO##...#.....#......O.....O#..O..#..
.##.O#O#O...O..#...........#OO....O.#.O.O.#.#O.#..#...O........O...#...#..OOO..##..O......O##O#.....
...O...O#.....#O..#..#..O.#.##O..........#.O..###.O..O#O....O...O#O....OO.O..#.#.O#O#.....#.#.O.OO#O
...O..#O.#O......O....O...O..O#......OO...#..O.OO.O.#..#..#......OOO..#.....OO....O..#.#O......O....
.....#...##.....O#..O.....#O.#..OO..#.#..##....#.O.#......#.#O.O..O.O.......O......O#.O#O#...OO...#.
......##.O#....O#.....O......#OO#...O....O#....#....O...#..#.#....OO...##OO..#.....##..O..O.O...O..O
OO##..#...OO.......O...#..#..O.....O..OO.OO.#..#.#O.#O..#O.##..............O...O.#O..#..#.O......##.
..O.#.....O#O......O#O#..O.O.....#...OO.#.O.#....#.###....#.#...........O#O.....OO.#..O...#..OO...#O
#..O..O..O#..O...#O.#...###..O..#.O#.#OO.......OO..........O..OOO...#....OO......O..OO#.OO#...O.O.O.
O.O..O..##..O...O.#O#.O.#.O..#O.OO#.OO..O..#...O.........#OO.......O...OO..####O...O..O...#OOO..O.O.
O..#.O.#.OOO...#O.....O#O.#O#.OO...#OO.#.##.........O..O#O#.#.O#...O..O....O..#O...O#O...O..O.O.....
O.O..O...#.O#.#...O..#.O.#.O##.O..#..#...OO#...##.O.#.##.OOO.#.........O.O....#..O.O.....#......OOO.
O..#O.#....OO#..O.##........O...#.#.....OO.....#O...OO........OO.#OO.....#.......O.#..OO#..O.#O#....
.OO..O.#..#...O.O.OOO#.O...O.O..OO.#O#..OO..#.....#.#..O....O.#O.##...O..O.....#...##...O.O#O...O..O
#....O.#......OO....#..O#.OOO..O.#...O.........###O.....##..O..O.O.O.O....##.....O...O.O..O.O.....O.
#...OO...O....##O........O.O..OO..#.....#.....OO...O...O.....#..O...#.....#.#...#...................
...O....O..OO.OO.......##...#OOO.....O..OO.O#.#........O..O.O....O.#.O#...#.#.........#......O....#.
O.........#..#..##..OO#....#..OO#O....O.O...O...................O.....O..OO.O.O.O..O.#...#...O.#.#O.
....#.O#.O..#..#..#...#OO.#.......O.#....O...O...#.##...O...O....O#.O.....O#....#.#......#.#..O.O.O.
#O##.#.....#.##O..#...O...###.OO......#......#O....#..#..O........#.O..O.....O#..O...OO#..OO.#.OO.OO
.O#.###O.O.#...####O....#.##O.O##.#..#.#..O........###.#....##O....O.O....OO.O...O.#O...OOO##...#.O.
....O..O....O............O.O......OO.##..#OO..#O...#.O.O..#..#O.O.........##.#..#..OO.....O.......#.
O....##.#O...O.OO..O#..O...#...O.OO.#..O.#......#.O..#.#..........O###...OOO.O..#.......O.O.O......O
.#......##...O.....#.O.....O.#.......O#O...O#.O.......O..#O..O#...O..O..OO#..#.O#...O.#.#.O...#.#.OO
...O.#.O.#......##..O..........OOO.....O.O......O.....O..#.O..#...#.OOO...O..#..#...#......O...#...O
..O..OO...#..#O....OO...#O...O#..O##....O#....#..#.#...#...........###...........#...OO...OO........
OO....O...#OO..O..O.O.O..#.O.....O.#...O........OO...#......O.#....O..O.#.##.........OO.O#...O.OO...
.#.....O.O#O..O.....#.#...O.O##O.......#..O#.#.#.OO#.O.O.#O#..OO..O.#O..O.OOOO......O....O...#..#...
#......O..#...O..#.O....#..OO...#.........O.O...#..O......O.O.O.#.O.......O..##..O#.#..O..#....OO.#.
.O..##O#O.O.O....#...#..O#.#.#.......O........#..#OO.OO..O..O.#...O..OOOO.....O#....O####.......#...
.#OO#.O.#..........OO..O.......O#....#.OO#...##......####...O...OOO...#....O.#..O.......#..O.O......
....O..#........#OO.......O.#..O...O..O..#.O....#.O.O.O..OO.O#O.O..O.###..O.#.#.......#.#...O#...O..
OO....O#O.O.#.#.##O#.#O#....#....O.O.......O.O.OO....O#.....O.O.OO#.##.O.#..##O..O..O#O......O...O#O
.#...#O..##.##.OO....##.....#O...#.O.O..#.....##......OO#OO.#...O...#..O....O#.#.O..O.#.......O.#.#O
O.#OO#OOO..O.#..OO..O......#O...O....##..#..#O...OO#.#.OO........O.#...O..O#OOO.O....##.O.O........#
.###..O.O...O#O..OO.O....#...OO.OO.O..OO..O.O.O.........#.O#...#...#..O..#..O..OO..#.O.....OO#......
.O#...O#..#.....O......O##..O.O.O..#..#.#.....#...#....#..#...O.O#..O...O..#...O......#.#...O.....O.
.O#..OO#.O.O...#O...O.....#....##..####.....O..O.....O...#O..#.......#OOO#.#....O.......O.#O.#..O#..
......O.O#....O.......O.O...O..O#..O...#....#O..##OO.#O......OOO.....#.#O.O#.O#.O....O#O#O..###.#...
#.O....#O......OOO......##.O.OO....#O...#OO...OO.##...O.O..#OO..OOO#..#.O.........O#...O........#...
.O....#.......O#.O..##...O##OO......#..O.O#O.O.#...........#OO........O...O....#.............#.#..O.
....#O.#..#.#..........OO...O..........O....O#...#OO.......O...O.#OO..OOO....O.O#..O.O.###..O.O#...O
O...#..OO....O.......#.OO...O........O.OO..#..#..#.#.O..O.#....O.O......OO..OO.O..#..OOO#..OOO......
.OO#.O.....O..#...O.....O....O#........#....#.....O..#..###...#.O.......OO......O..O.OO..O..#.O#O#..
O....O...##.#....#O..O.#......................O..O#OOO..##....#.#..O.O.....O#..O.O.O...#.#.OOO...O..
.......O..OO.O..O#.OO.#.O..#O....#.OOO.........##......#.O#.O..O....O....O.....#O.O...O.#.......O.#O
....O##.#...O.##...O#...OOOO...OO...#.O.#...O.#O.......#.O.....##....O.#O....#......##.O....O.OO#..O
OO...O#O#O#.#OO.#O.O..#.#.#.#.............#.O........#...O..O......O#.#OO.O...#.O..O...O#.O....O#..O
.#..O..#.OO.#O...O#.O.#.#..#.......#.......#O...#..#O#....O...#....OO.....O......O..#.....O..O..#.O#
...OO....O.#....#.O.#..#.#O.#.#O.....O..O##.......O..#O.#.O...OOO#O.#......O....#......#......O##...
...##.O.O.....##....O.....#O..O........#.#.O#O....O#..O...O#OO...O....O..O.O.#.#..#OO...O..#....OO..
O...#OO.O.OO#..O....##O...#....#...#.O.O..O.........#..##.#O.#.OO..OO...#...O.O#.OO..#.O.OO#.#..##OO
..O.O#..O..#O...O.#.O.#....#....#.#O...O..O#O....#...#..#..##......#.O..........OOO........O.#......
.....#....#....OO....#....O.#O..O...O#O..#...###....O.....O........##.#.#..#.O.OO.#O.O.O..#...O#O..O
.OO.....O.O.....#....O.O....O......O#O....O#.#..O....O.#............#..O.#.....OO....O...O....O.#.O.
.........O#OO.#O.....O......O...#..#O..O.#...O.O..OO.........#.O#OO.#.OO.........#.OO..O.O#O..O.O#..
#...O...O....#O.###.....O.OO..O..OO.O#O....#O..#O..OO..O..#........O...#.....#..#...OO..O....#.....O
......O.O.OO#.O.......O#O.OO.#..O....O...#.O#..#....O.#....#..#O...#.OO.O#........#......O....O.O...
..#...##...#.O.O..#...O#.....##.......OO..O.#....O.O#O#..O...O#..OO...##O...O..O.....#.#...O.O......
OOO.O.O#O......#..OO.O...OO...O............O..O#..##O...###.#......O#..#.O..O.OOO...#..O#......#OO.#
O###.......#.O.O.#.....#.OO..O.O...#..O#O..#O.O.#.O..O.O..O#.#....#..#...O#..###.#..O#.O.........OO.
.......#O#OO#...#.#...#.O...O.....O.O#.....O.O.O##.#...#O.#....OO...O.OO..O....O.O..#..#.....O...#..
.O..###..OO#O.#.#OO.O#...#..O#...O.....O#.O......O...OO..O..O.....O..##.....OO.....O......O........O
..O..#.O.#..OO.O#..O#..O.....OO#O#....OO.OO#O...O...O.O......OO.#O#....O..#O.#.OO##.#....#O#.#......
O.#O.O.O.O...OO.....O.#...##..#....O....O..#..#O#..O#.#.OO.#O..........#...O..##..O.##.O.O...#.#O..#
......O#...O.#..O#.O.........#.#....O.O....O.#..O..O##.#..O....#..#O#.OO.........#.O##O.....OO.OO.O.
#....#.#O.O.O............O.O.#.O..O.........O..O........O......O.....OO.OO..OO.#....OO.OO.#....#..##
.......#...O.O.#.O.....#.O#.#..O..O...O.O.#O..#...##.........O..#.OO..O........#.....#.......OO.....
...#....O...O...#O.OO...#....#..O.#.O.#......##.#.#.OO.O.O...#..#..O........O.##..O...O#O...OO.O....
.......OO...O..O...........O###......#....O.......O..O.....O#...#.O.#.#......O..O.....#.#OO.......O.
.#..#.....#.O..O..O.....##..O.........O#.##O....OO...O...#..O.O.##OO......O.#..O....O..O.#.O.O...O.O
.O....O...O....#.O......#..##O.#..O..O.....O...OO..###....#..#..#..........#.#.#.#.#........O...O.O.
.OOO.#.#O....O.#...OO#.##...#...O.#...OO..###..OO.#.O....O..OO#..O..O....O#.#.O####..O....O..O#O....
.OO.OO#......#....#..##O#O...OO....#....O......OO..OOO.....##.......O#.#.O.#O......O..#.#O..O.O..#..

109
day-14/src/bin/part1.rs Normal file
View File

@ -0,0 +1,109 @@
use std::cmp::Ordering;
fn main() {
println!("{}", part1(include_str!("./input.txt")));
}
fn part1(input: &str) -> usize {
let slid_lines = slide_north(input);
slid_lines
.iter()
.enumerate()
.map(|(i, line)| line.iter().filter(|c| **c == 'O').count() * (slid_lines.len() - i))
.sum()
}
fn slide_north(input: &str) -> Vec<Vec<char>> {
let lines = input.lines().collect::<Vec<_>>();
let columns = (0..lines[0].len())
.map(|i| {
let mut column = lines
.iter()
.map(|row| row.chars().nth(i).unwrap())
.collect::<Vec<_>>();
// bubble sort
for n in (1..column.len()).rev() {
for j in 0..n {
if sort_slide_north(&column[j], &column[j + 1]) == Ordering::Greater {
column.swap(j, j + 1);
}
}
}
column
})
.collect::<Vec<_>>();
(0..columns[0].len())
.map(|i| {
columns
.iter()
.map(|column| *column.get(i).unwrap())
.collect::<Vec<_>>()
})
.collect::<Vec<_>>()
}
fn sort_slide_north(a: &char, b: &char) -> Ordering {
if a == &'#' || b == &'#' {
Ordering::Equal
} else if a == &'.' && b == &'O' {
Ordering::Greater
} else if a == &'O' && b == &'.' {
Ordering::Less
} else {
a.cmp(b)
}
}
#[cfg(test)]
mod tests {
use super::*;
use indoc::indoc;
const INPUT: &str = indoc!(
"
O....#....
O.OO#....#
.....##...
OO.#O....O
.O.....O#.
O.#..O.#.#
..O..#O..O
.......O..
#....###..
#OO..#....
"
);
#[test]
fn test_part1() {
assert_eq!(part1(INPUT), 136);
}
#[test]
fn test_slide_north() {
assert_eq!(
slide_north(INPUT)
.iter()
.map(|line| line.iter().collect::<String>())
.collect::<Vec<_>>()
.join("\n"),
indoc!(
"
OOOO.#.O..
OO..#....#
OO..O##..O
O..#.OO...
........#.
..#....#.#
..O..#.O.O
..O.......
#....###..
#....#...."
)
);
}
}

196
day-14/src/bin/part2.rs Normal file
View File

@ -0,0 +1,196 @@
use std::{cmp::Ordering, collections::HashMap};
const REPETITIONS: u32 = 1_000_000_000;
fn main() {
println!("{}", part2(include_str!("./input.txt")));
}
fn part2(input: &str) -> usize {
let mut lines = input
.lines()
.map(|l| l.chars().collect())
.collect::<Vec<Vec<_>>>();
let mut seen = HashMap::new();
seen.insert(lines.clone(), 0);
let mut stop_at = None;
for i in 1..REPETITIONS + 1 {
lines = cycle(lines);
// stop at correct iteration
if stop_at.is_some_and(|j| j == i) {
break;
}
// check if we've seen this before & calculate where to stop
if seen.contains_key(&lines) && stop_at.is_none() {
let repeat_period = i - seen.get(&lines).unwrap();
stop_at = Some(i + ((REPETITIONS - i) % repeat_period));
}
seen.insert(lines.clone(), i);
}
lines
.iter()
.enumerate()
.map(|(i, line)| line.iter().filter(|c| **c == 'O').count() * (lines.len() - i))
.sum()
}
fn cycle(matrix: Vec<Vec<char>>) -> Vec<Vec<char>> {
let north_lines = transmute(slide_rows_left(transmute(matrix)));
let west_lines = slide_rows_left(north_lines);
let south_lines = transmute(reverse_rows(slide_rows_left(reverse_rows(transmute(
west_lines,
)))));
reverse_rows(slide_rows_left(reverse_rows(south_lines)))
}
fn transmute<T: Copy>(matrix: Vec<Vec<T>>) -> Vec<Vec<T>> {
(0..matrix[0].len())
.map(|i| {
matrix
.iter()
.map(|row| *row.get(i).unwrap())
.collect::<Vec<_>>()
})
.collect::<Vec<_>>()
}
fn reverse_rows<T: Copy>(matrix: Vec<Vec<T>>) -> Vec<Vec<T>> {
matrix
.iter()
.map(|row| {
let mut row = row.clone();
row.reverse();
row
})
.collect::<Vec<_>>()
}
fn slide_rows_left(lines: Vec<Vec<char>>) -> Vec<Vec<char>> {
lines
.into_iter()
.map(|mut row| {
for n in (1..row.len()).rev() {
for i in 0..n {
if sort_slide_line(&row[i], &row[i + 1]) == Ordering::Greater {
row.swap(i, i + 1);
}
}
}
row
})
.collect()
}
fn sort_slide_line(a: &char, b: &char) -> Ordering {
if a == &'#' || b == &'#' {
Ordering::Equal
} else if a == &'.' && b == &'O' {
Ordering::Greater
} else if a == &'O' && b == &'.' {
Ordering::Less
} else {
a.cmp(b)
}
}
#[cfg(test)]
mod tests {
use super::*;
use indoc::indoc;
const INPUT: &str = indoc!(
"
O....#....
O.OO#....#
.....##...
OO.#O....O
.O.....O#.
O.#..O.#.#
..O..#O..O
.......O..
#....###..
#OO..#....
"
);
#[test]
fn test_part2() {
assert_eq!(part2(INPUT), 64);
}
#[test]
fn test_cycle() {
let lines = INPUT
.lines()
.map(|l| l.chars().collect())
.collect::<Vec<Vec<char>>>();
// one cycle
assert_eq!(
cycle(lines.clone()),
indoc!(
"
.....#....
....#...O#
...OO##...
.OO#......
.....OOO#.
.O#...O#.#
....O#....
......OOOO
#...O###..
#..OO#...."
)
.lines()
.map(|l| l.chars().collect())
.collect::<Vec<Vec<_>>>()
);
// two cycles
assert_eq!(
cycle(cycle(lines.clone())),
indoc!(
"
.....#....
....#...O#
.....##...
..O#......
.....OOO#.
.O#...O#.#
....O#...O
.......OOO
#..OO###..
#.OOO#...O"
)
.lines()
.map(|l| l.chars().collect())
.collect::<Vec<Vec<_>>>()
);
// three cycles
assert_eq!(
cycle(cycle(cycle(lines.clone()))),
indoc!(
"
.....#....
....#...O#
.....##...
..O#......
.....OOO#.
.O#...O#.#
....O#...O
.......OOO
#...O###.O
#.OOO#...O"
)
.lines()
.map(|l| l.chars().collect())
.collect::<Vec<Vec<_>>>()
);
}
}