[Rust/2022/24] Add solution
This commit is contained in:
parent
e34ead249e
commit
e3f1cdbc20
7 changed files with 213 additions and 2 deletions
|
@ -1,13 +1,13 @@
|
|||
# AdventOfCode
|
||||
[Advent of Code](https://adventofcode.com/) solutions in [<img height=12 src=".assets/rs.svg"> Rust](Rust), [<img height=12 src=".assets/hs.svg"> Haskell](Haskell), [<img height=12 src=".assets/py.svg"> Python](Python) and [<img height=12 src=".assets/apl.svg"> APL](APL)
|
||||
|
||||
## [2022](https://adventofcode.com/2022) ([<img height=18 src=".assets/rs.svg"> Rust](Rust/2022): 24/25 | [<img height=18 src=".assets/py.svg"> Python](Python/2022): 18/25 | [<img height=18 src=".assets/hs.svg"> Haskell](Haskell/2022): 9/25)
|
||||
## [2022](https://adventofcode.com/2022) ([<img height=18 src=".assets/rs.svg"> Rust](Rust/2022): 25/25 | [<img height=18 src=".assets/py.svg"> Python](Python/2022): 18/25 | [<img height=18 src=".assets/hs.svg"> Haskell](Haskell/2022): 9/25)
|
||||
|Mo|Tu|We|Th|Fr|Sa|Su|
|
||||
|-|-|-|-|-|-|-|
|
||||
||||[**1**](https://adventofcode.com/2022/day/1) [<img height=12 src=".assets/rs.svg">](Rust/2022/01.rs "Rust solution for 2022/01") [<img height=12 src=".assets/hs.svg">](Haskell/2022/01.hs "Haskell solution for 2022/01") [<img height=12 src=".assets/py.svg">](Python/2022/01.py "Python solution for 2022/01")|[**2**](https://adventofcode.com/2022/day/2) [<img height=12 src=".assets/rs.svg">](Rust/2022/02.rs "Rust solution for 2022/02") [<img height=12 src=".assets/hs.svg">](Haskell/2022/02.hs "Haskell solution for 2022/02") [<img height=12 src=".assets/py.svg">](Python/2022/02.py "Python solution for 2022/02")|[**3**](https://adventofcode.com/2022/day/3) [<img height=12 src=".assets/rs.svg">](Rust/2022/03.rs "Rust solution for 2022/03") [<img height=12 src=".assets/hs.svg">](Haskell/2022/03.hs "Haskell solution for 2022/03") [<img height=12 src=".assets/py.svg">](Python/2022/03.py "Python solution for 2022/03")|[**4**](https://adventofcode.com/2022/day/4) [<img height=12 src=".assets/rs.svg">](Rust/2022/04.rs "Rust solution for 2022/04") [<img height=12 src=".assets/hs.svg">](Haskell/2022/04.hs "Haskell solution for 2022/04") [<img height=12 src=".assets/py.svg">](Python/2022/04.py "Python solution for 2022/04")|
|
||||
|[**5**](https://adventofcode.com/2022/day/5) [<img height=12 src=".assets/rs.svg">](Rust/2022/05.rs "Rust solution for 2022/05") [<img height=12 src=".assets/hs.svg">](Haskell/2022/05.hs "Haskell solution for 2022/05") [<img height=12 src=".assets/py.svg">](Python/2022/05.py "Python solution for 2022/05")|[**6**](https://adventofcode.com/2022/day/6) [<img height=12 src=".assets/rs.svg">](Rust/2022/06.rs "Rust solution for 2022/06") [<img height=12 src=".assets/hs.svg">](Haskell/2022/06.hs "Haskell solution for 2022/06") [<img height=12 src=".assets/py.svg">](Python/2022/06.py "Python solution for 2022/06")|[**7**](https://adventofcode.com/2022/day/7) [<img height=12 src=".assets/rs.svg">](Rust/2022/07.rs "Rust solution for 2022/07") [<img height=12 src=".assets/hs.svg">](Haskell/2022/07.hs "Haskell solution for 2022/07") [<img height=12 src=".assets/py.svg">](Python/2022/07.py "Python solution for 2022/07")|[**8**](https://adventofcode.com/2022/day/8) [<img height=12 src=".assets/rs.svg">](Rust/2022/08.rs "Rust solution for 2022/08") [<img height=12 src=".assets/hs.svg">](Haskell/2022/08.hs "Haskell solution for 2022/08") [<img height=12 src=".assets/py.svg">](Python/2022/08.py "Python solution for 2022/08")|[**9**](https://adventofcode.com/2022/day/9) [<img height=12 src=".assets/rs.svg">](Rust/2022/09.rs "Rust solution for 2022/09") [<img height=12 src=".assets/hs.svg">](Haskell/2022/09.hs "Haskell solution for 2022/09") [<img height=12 src=".assets/py.svg">](Python/2022/09.py "Python solution for 2022/09")|[**10**](https://adventofcode.com/2022/day/10) [<img height=12 src=".assets/rs.svg">](Rust/2022/10.rs "Rust solution for 2022/10") [<img height=12 src=".assets/py.svg">](Python/2022/10.py "Python solution for 2022/10")|[**11**](https://adventofcode.com/2022/day/11) [<img height=12 src=".assets/rs.svg">](Rust/2022/11.rs "Rust solution for 2022/11") [<img height=12 src=".assets/py.svg">](Python/2022/11.py "Python solution for 2022/11")|
|
||||
|[**12**](https://adventofcode.com/2022/day/12) [<img height=12 src=".assets/rs.svg">](Rust/2022/12.rs "Rust solution for 2022/12") [<img height=12 src=".assets/py.svg">](Python/2022/12.py "Python solution for 2022/12")|[**13**](https://adventofcode.com/2022/day/13) [<img height=12 src=".assets/rs.svg">](Rust/2022/13.rs "Rust solution for 2022/13") [<img height=12 src=".assets/py.svg">](Python/2022/13.py "Python solution for 2022/13")|[**14**](https://adventofcode.com/2022/day/14) [<img height=12 src=".assets/rs.svg">](Rust/2022/14.rs "Rust solution for 2022/14") [<img height=12 src=".assets/py.svg">](Python/2022/14.py "Python solution for 2022/14")|[**15**](https://adventofcode.com/2022/day/15) [<img height=12 src=".assets/rs.svg">](Rust/2022/15.rs "Rust solution for 2022/15") [<img height=12 src=".assets/py.svg">](Python/2022/15.py "Python solution for 2022/15")|[**16**](https://adventofcode.com/2022/day/16) [<img height=12 src=".assets/rs.svg">](Rust/2022/16.rs "Rust solution for 2022/16") [<img height=12 src=".assets/py.svg">](Python/2022/16.py "Python solution for 2022/16")|[**17**](https://adventofcode.com/2022/day/17) [<img height=12 src=".assets/rs.svg">](Rust/2022/17.rs "Rust solution for 2022/17") [<img height=12 src=".assets/py.svg">](Python/2022/17.py "Python solution for 2022/17")|[**18**](https://adventofcode.com/2022/day/18) [<img height=12 src=".assets/rs.svg">](Rust/2022/18.rs "Rust solution for 2022/18") [<img height=12 src=".assets/py.svg">](Python/2022/18.py "Python solution for 2022/18")|
|
||||
|[**19**](https://adventofcode.com/2022/day/19) [<img height=12 src=".assets/rs.svg">](Rust/2022/19.rs "Rust solution for 2022/19")|[**20**](https://adventofcode.com/2022/day/20) [<img height=12 src=".assets/rs.svg">](Rust/2022/20.rs "Rust solution for 2022/20")|[**21**](https://adventofcode.com/2022/day/21) [<img height=12 src=".assets/rs.svg">](Rust/2022/21.rs "Rust solution for 2022/21")|[**22**](https://adventofcode.com/2022/day/22) [<img height=12 src=".assets/rs.svg">](Rust/2022/22.rs "Rust solution for 2022/22")|[**23**](https://adventofcode.com/2022/day/23) [<img height=12 src=".assets/rs.svg">](Rust/2022/23.rs "Rust solution for 2022/23")|[**24**](https://adventofcode.com/2022/day/24)|[**25**](https://adventofcode.com/2022/day/25) [<img height=12 src=".assets/rs.svg">](Rust/2022/25.rs "Rust solution for 2022/25")|
|
||||
|[**19**](https://adventofcode.com/2022/day/19) [<img height=12 src=".assets/rs.svg">](Rust/2022/19.rs "Rust solution for 2022/19")|[**20**](https://adventofcode.com/2022/day/20) [<img height=12 src=".assets/rs.svg">](Rust/2022/20.rs "Rust solution for 2022/20")|[**21**](https://adventofcode.com/2022/day/21) [<img height=12 src=".assets/rs.svg">](Rust/2022/21.rs "Rust solution for 2022/21")|[**22**](https://adventofcode.com/2022/day/22) [<img height=12 src=".assets/rs.svg">](Rust/2022/22.rs "Rust solution for 2022/22")|[**23**](https://adventofcode.com/2022/day/23) [<img height=12 src=".assets/rs.svg">](Rust/2022/23.rs "Rust solution for 2022/23")|[**24**](https://adventofcode.com/2022/day/24) [<img height=12 src=".assets/rs.svg">](Rust/2022/24.rs "Rust solution for 2022/24")|[**25**](https://adventofcode.com/2022/day/25) [<img height=12 src=".assets/rs.svg">](Rust/2022/25.rs "Rust solution for 2022/25")|
|
||||
|26|27|28|29|30|31||
|
||||
|
||||
## [2021](https://adventofcode.com/2021) ([<img height=18 src=".assets/rs.svg"> Rust](Rust/2021): 25/25 | [<img height=18 src=".assets/py.svg"> Python](Python/2021): 25/25 | [<img height=18 src=".assets/apl.svg"> APL](APL/2021): 17/25)
|
||||
|
|
192
Rust/2022/24.rs
Normal file
192
Rust/2022/24.rs
Normal file
|
@ -0,0 +1,192 @@
|
|||
#![feature(test)]
|
||||
|
||||
use std::{cmp::Ordering, collections::BinaryHeap};
|
||||
|
||||
use itertools::Itertools;
|
||||
use rustc_hash::FxHashSet;
|
||||
use smallvec::{smallvec, SmallVec};
|
||||
|
||||
#[derive(Debug)]
|
||||
struct Input {
|
||||
width: usize,
|
||||
height: usize,
|
||||
blizzards: Vec<Vec<Option<Direction>>>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
enum Direction {
|
||||
North,
|
||||
East,
|
||||
South,
|
||||
West,
|
||||
}
|
||||
|
||||
fn setup(input: &str) -> Input {
|
||||
let blizzards = input
|
||||
.lines()
|
||||
.skip(1)
|
||||
.take_while(|l| l.as_bytes()[1] != b'#')
|
||||
.map(|line| {
|
||||
line.bytes()
|
||||
.skip(1)
|
||||
.take_while(|&c| c != b'#')
|
||||
.map(|c| match c {
|
||||
b'.' => None,
|
||||
b'^' => Some(Direction::North),
|
||||
b'>' => Some(Direction::East),
|
||||
b'v' => Some(Direction::South),
|
||||
b'<' => Some(Direction::West),
|
||||
_ => panic!(),
|
||||
})
|
||||
.collect_vec()
|
||||
})
|
||||
.collect_vec();
|
||||
Input {
|
||||
width: blizzards[0].len(),
|
||||
height: blizzards.len(),
|
||||
blizzards,
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
||||
struct State {
|
||||
time: usize,
|
||||
position: usize,
|
||||
cnt: usize,
|
||||
dist: usize,
|
||||
}
|
||||
|
||||
impl PartialOrd for State {
|
||||
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
|
||||
Some(self.cmp(other))
|
||||
}
|
||||
}
|
||||
|
||||
impl Ord for State {
|
||||
fn cmp(&self, other: &Self) -> Ordering {
|
||||
other.dist.cmp(&self.dist)
|
||||
}
|
||||
}
|
||||
|
||||
impl State {
|
||||
fn init(input: &Input) -> Self {
|
||||
Self {
|
||||
time: 0,
|
||||
position: input.width * input.height,
|
||||
cnt: 0,
|
||||
dist: usize::MAX,
|
||||
}
|
||||
}
|
||||
|
||||
fn next(self, input: &Input, target: usize) -> impl Iterator<Item = Self> + '_ {
|
||||
let &Input {
|
||||
width: w,
|
||||
height: h,
|
||||
..
|
||||
} = input;
|
||||
|
||||
let mut out: SmallVec<[_; 7]> = smallvec![self.position];
|
||||
|
||||
match self.position {
|
||||
p if p == w * h => out.push(0),
|
||||
p if p == w * h + 1 => out.push(w * h - 1),
|
||||
p => {
|
||||
if p == 0 {
|
||||
out.push(w * h);
|
||||
}
|
||||
|
||||
if p == w * h - 1 {
|
||||
out.push(w * h + 1);
|
||||
}
|
||||
|
||||
if p >= w {
|
||||
out.push(p - w);
|
||||
}
|
||||
if p + w < w * h {
|
||||
out.push(p + w);
|
||||
}
|
||||
if p % w > 0 {
|
||||
out.push(p - 1);
|
||||
}
|
||||
if p % w < w - 1 {
|
||||
out.push(p + 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
out.into_iter()
|
||||
.filter(move |&p| {
|
||||
let (i, j) = (p / w, p % w);
|
||||
let t = self.time + 1;
|
||||
p >= w * h
|
||||
|| !matches!(
|
||||
input.blizzards[i][(j + w - t % w) % w],
|
||||
Some(Direction::East)
|
||||
) && !matches!(input.blizzards[i][(j + t) % w], Some(Direction::West))
|
||||
&& !matches!(
|
||||
input.blizzards[(i + h - t % h) % h][j],
|
||||
Some(Direction::South)
|
||||
)
|
||||
&& !matches!(input.blizzards[(i + t) % h][j], Some(Direction::North))
|
||||
})
|
||||
.map(move |p| {
|
||||
let time = self.time + 1;
|
||||
let cnt = self.cnt
|
||||
+ (self.cnt % 2) * (p == w * h) as usize
|
||||
+ ((self.cnt + 1) % 2) * (p == w * h + 1) as usize;
|
||||
|
||||
let start_to_goal = w + h;
|
||||
let (start, goal) = match p {
|
||||
p if p == w * h => (0, start_to_goal),
|
||||
p if p == w * h + 1 => (start_to_goal, 0),
|
||||
p => {
|
||||
let (i, j) = (p / w, p % w);
|
||||
(i + j + 1, start_to_goal - i - j - 2)
|
||||
}
|
||||
};
|
||||
|
||||
Self {
|
||||
time,
|
||||
cnt,
|
||||
position: p,
|
||||
dist: {
|
||||
if cnt != target {
|
||||
time + start * (cnt % 2)
|
||||
+ goal * ((cnt + 1) % 2)
|
||||
+ (target - cnt - 1) * start_to_goal
|
||||
} else {
|
||||
0
|
||||
}
|
||||
},
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
fn solve(input: &Input, target: usize) -> usize {
|
||||
let mut queue = BinaryHeap::from([State::init(input)]);
|
||||
let mut seen = FxHashSet::default();
|
||||
while let Some(state) = queue.pop() {
|
||||
if state.cnt == target {
|
||||
return state.time;
|
||||
}
|
||||
|
||||
for next in state.next(input, target) {
|
||||
if seen.insert(next) {
|
||||
queue.push(next);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
panic!()
|
||||
}
|
||||
|
||||
fn part1(input: &Input) -> usize {
|
||||
solve(input, 1)
|
||||
}
|
||||
|
||||
fn part2(input: &Input) -> usize {
|
||||
solve(input, 3)
|
||||
}
|
||||
|
||||
aoc::main!(2022, 24, ex: 1);
|
7
Rust/Cargo.lock
generated
7
Rust/Cargo.lock
generated
|
@ -23,6 +23,7 @@ dependencies = [
|
|||
"rayon",
|
||||
"regex",
|
||||
"rustc-hash",
|
||||
"smallvec",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -448,6 +449,12 @@ version = "1.2.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
|
||||
|
||||
[[package]]
|
||||
name = "smallvec"
|
||||
version = "1.11.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "942b4a808e05215192e39f4ab80813e599068285906cc91aa64f923db842bd5a"
|
||||
|
||||
[[package]]
|
||||
name = "tempfile"
|
||||
version = "3.8.0"
|
||||
|
|
|
@ -26,6 +26,7 @@ paste = "1.0.14"
|
|||
rayon = "1.8.0"
|
||||
regex = "1.10.2"
|
||||
rustc-hash = "1.1.0"
|
||||
smallvec = "1.11.1"
|
||||
|
||||
[dev-dependencies]
|
||||
proptest = "1.3.1"
|
||||
|
@ -196,5 +197,8 @@ path = "2022/22.rs"
|
|||
name = "2022_23"
|
||||
path = "2022/23.rs"
|
||||
[[bin]]
|
||||
name = "2022_24"
|
||||
path = "2022/24.rs"
|
||||
[[bin]]
|
||||
name = "2022_25"
|
||||
path = "2022/25.rs"
|
||||
|
|
6
examples/2022/24/1
Normal file
6
examples/2022/24/1
Normal file
|
@ -0,0 +1,6 @@
|
|||
#.######
|
||||
#>>.<^<#
|
||||
#.<..<<#
|
||||
#>v.><>#
|
||||
#<^v^^>#
|
||||
######.#
|
1
examples/2022/24/1.1
Normal file
1
examples/2022/24/1.1
Normal file
|
@ -0,0 +1 @@
|
|||
18
|
1
examples/2022/24/1.2
Normal file
1
examples/2022/24/1.2
Normal file
|
@ -0,0 +1 @@
|
|||
54
|
Loading…
Add table
Add a link
Reference in a new issue