2022 day 16 part 2 wip

This commit is contained in:
Maciej Jur 2022-12-16 20:42:57 +01:00
parent f7d3b032c1
commit 46351760bf
3 changed files with 151 additions and 31 deletions

124
2022/rust/Cargo.lock generated
View file

@ -11,12 +11,129 @@ dependencies = [
"memchr", "memchr",
] ]
[[package]]
name = "autocfg"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
[[package]]
name = "cfg-if"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
name = "crossbeam-channel"
version = "0.5.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c2dd04ddaf88237dc3b8d8f9a3c1004b506b54b3313403944054d23c0870c521"
dependencies = [
"cfg-if",
"crossbeam-utils",
]
[[package]]
name = "crossbeam-deque"
version = "0.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "715e8152b692bba2d374b53d4875445368fdf21a94751410af607a5ac677d1fc"
dependencies = [
"cfg-if",
"crossbeam-epoch",
"crossbeam-utils",
]
[[package]]
name = "crossbeam-epoch"
version = "0.9.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "01a9af1f4c2ef74bb8aa1f7e19706bc72d03598c8a570bb5de72243c7a9d9d5a"
dependencies = [
"autocfg",
"cfg-if",
"crossbeam-utils",
"memoffset",
"scopeguard",
]
[[package]]
name = "crossbeam-utils"
version = "0.8.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4fb766fa798726286dbbb842f174001dab8abc7b627a1dd86e0b7222a95d929f"
dependencies = [
"cfg-if",
]
[[package]]
name = "either"
version = "1.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "90e5c1c8368803113bf0c9584fc495a58b86dc8a29edbf8fe877d21d9507e797"
[[package]]
name = "hermit-abi"
version = "0.1.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33"
dependencies = [
"libc",
]
[[package]]
name = "libc"
version = "0.2.138"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "db6d7e329c562c5dfab7a46a2afabc8b987ab9a4834c9d1ca04dc54c1546cef8"
[[package]] [[package]]
name = "memchr" name = "memchr"
version = "2.5.0" version = "2.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d"
[[package]]
name = "memoffset"
version = "0.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5de893c32cde5f383baa4c04c5d6dbdd735cfd4a794b0debdb2bb1b421da5ff4"
dependencies = [
"autocfg",
]
[[package]]
name = "num_cpus"
version = "1.14.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f6058e64324c71e02bc2b150e4f3bc8286db6c83092132ffa3f6b1eab0f9def5"
dependencies = [
"hermit-abi",
"libc",
]
[[package]]
name = "rayon"
version = "1.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6db3a213adf02b3bcfd2d3846bb41cb22857d131789e01df434fb7e7bc0759b7"
dependencies = [
"either",
"rayon-core",
]
[[package]]
name = "rayon-core"
version = "1.10.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cac410af5d00ab6884528b4ab69d1e8e146e8d471201800fa1b4524126de6ad3"
dependencies = [
"crossbeam-channel",
"crossbeam-deque",
"crossbeam-utils",
"num_cpus",
]
[[package]] [[package]]
name = "regex" name = "regex"
version = "1.7.0" version = "1.7.0"
@ -38,5 +155,12 @@ checksum = "456c603be3e8d448b072f410900c09faf164fbce2d480456f50eea6e25f9c848"
name = "rust" name = "rust"
version = "0.1.0" version = "0.1.0"
dependencies = [ dependencies = [
"rayon",
"regex", "regex",
] ]
[[package]]
name = "scopeguard"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"

View file

@ -7,3 +7,4 @@ edition = "2021"
[dependencies] [dependencies]
regex = "1.7.0" regex = "1.7.0"
rayon = "1.6.1"

View file

@ -2,6 +2,8 @@ use std::cmp::Ordering;
use std::collections::{BinaryHeap, HashMap, HashSet}; use std::collections::{BinaryHeap, HashMap, HashSet};
use crate::utils; use crate::utils;
use rayon::prelude::*;
pub fn run() -> () { pub fn run() -> () {
let lines = utils::read_lines(utils::Source::Day(16)); let lines = utils::read_lines(utils::Source::Day(16));
@ -107,7 +109,7 @@ fn move_to_open<'data, 'a>(
let opened = { let mut opened = opened.clone(); opened.insert(curr); opened }; let opened = { let mut opened = opened.clone(); opened.insert(curr); opened };
let time_left = state.time_left - distance - 1; let time_left = state.time_left - distance - 1;
closed.iter() closed.par_iter()
.map(|&next| move_to_open(map, distances, &closed, &opened, MoveState { curr, next, time_left, released })) .map(|&next| move_to_open(map, distances, &closed, &opened, MoveState { curr, next, time_left, released }))
.max() .max()
.unwrap_or_else(|| released + release_pressure(map, &opened) * time_left) .unwrap_or_else(|| released + release_pressure(map, &opened) * time_left)
@ -142,56 +144,49 @@ fn parallel_to_open<'data, 'a>(
opened: &'a HashSet<&'data str>, opened: &'a HashSet<&'data str>,
state: ParallelMoveState, state: ParallelMoveState,
) -> u32 { ) -> u32 {
let p_distance = *distances.get(&(state.p_curr, state.p_next)).unwrap() - state.p_progress; let p_distance_left = *distances.get(&(state.p_curr, state.p_next)).unwrap() - state.p_progress;
let e_distance = *distances.get(&(state.e_curr, state.e_next)).unwrap() - state.e_progress; let e_distance_left = *distances.get(&(state.e_curr, state.e_next)).unwrap() - state.e_progress;
let distance = state.time_left.min(p_distance).min(e_distance); let distance = state.time_left.min(p_distance_left).min(e_distance_left);
let released = state.released + distance * release_pressure(map, opened); let released = state.released + distance * release_pressure(map, opened);
if distance == state.time_left { return released }; if distance == state.time_left { return released };
// opening
let released = released + release_pressure(map, opened); let released = released + release_pressure(map, opened);
let (closed, opened) = match (distance == p_distance, distance == e_distance) { let (closed, opened) = {
(true, true) => ( let mut closed = closed.clone();
{ let mut closed = closed.clone(); closed.remove(state.p_next); closed.remove(state.e_next); closed }, let mut opened = opened.clone();
{ let mut opened = opened.clone(); opened.insert(state.p_next); opened.insert(state.e_next); opened }, if distance == p_distance_left { closed.remove(state.p_next); opened.insert(state.p_next); };
), if distance == e_distance_left { closed.remove(state.e_next); opened.insert(state.e_next); };
(true, false) => ( (closed, opened)
{ let mut closed = closed.clone(); closed.remove(state.p_next); closed },
{ let mut opened = opened.clone(); opened.insert(state.p_next); opened },
),
(false, true) => (
{ let mut closed = closed.clone(); closed.remove(state.e_next); closed },
{ let mut opened = opened.clone(); opened.insert(state.e_next); opened },
),
_ => unreachable!(),
}; };
let time_left = state.time_left - distance - 1; let time_left = state.time_left - distance - 1;
match (distance == p_distance, distance == e_distance) { match (distance == p_distance_left, distance == e_distance_left) {
(true, true) => closed.iter() (true, true) => closed.par_iter()
.flat_map(|&p_next| closed.iter() .flat_map(|&p_next| closed.par_iter()
.filter(move |&&e_next| e_next != p_next) .filter(move |&&e_next| e_next != p_next)
.map(|&e_next| { parallel_to_open(map, distances, &closed, &opened, ParallelMoveState { .map(|&e_next| parallel_to_open(map, distances, &closed, &opened, ParallelMoveState {
p_curr: state.p_next, p_next, p_progress: 0, p_curr: state.p_next, p_next, p_progress: 0,
e_curr: state.e_next, e_next, e_progress: 0, e_curr: state.e_next, e_next, e_progress: 0,
time_left, released, time_left, released,
})}) }))
) )
.max() .max()
.unwrap_or_else(|| released + release_pressure(map, &opened) * time_left), .unwrap_or_else(|| released + release_pressure(map, &opened) * time_left),
(true, false) => closed.iter() (true, false) => closed.par_iter()
.map(|&next| { parallel_to_open(map, distances, &closed, &opened, ParallelMoveState { .map(|&next| parallel_to_open(map, distances, &closed, &opened, ParallelMoveState {
p_curr: state.p_next, p_next: next, p_progress: 0, p_curr: state.p_next, p_next: next, p_progress: 0,
e_curr: state.e_curr, e_next: state.e_next, e_progress: state.e_progress + 1, e_curr: state.e_curr, e_next: state.e_next, e_progress: state.e_progress + distance + 1,
time_left, released, time_left, released,
})}) }))
.max() .max()
.unwrap_or_else(|| released + release_pressure(map, &opened) * time_left), .unwrap_or_else(|| released + release_pressure(map, &opened) * time_left),
(false, true) => closed.iter() (false, true) => closed.par_iter()
.map(|&next| { parallel_to_open(map, distances, &closed, &opened, ParallelMoveState { .map(|&next| parallel_to_open(map, distances, &closed, &opened, ParallelMoveState {
p_curr: state.p_curr, p_next: state.p_next, p_progress: state.p_progress + 1, p_curr: state.p_curr, p_next: state.p_next, p_progress: state.p_progress + distance + 1,
e_curr: state.e_next, e_next: next, e_progress: 0, e_curr: state.e_next, e_next: next, e_progress: 0,
time_left, released, time_left, released,
})}) }))
.max() .max()
.unwrap_or_else(|| released + release_pressure(map, &opened) * time_left), .unwrap_or_else(|| released + release_pressure(map, &opened) * time_left),
_ => unreachable!() _ => unreachable!()