[rs] Parallelize 2022_16 part 2
This commit is contained in:
parent
4f9de30212
commit
efaaef4e6a
3 changed files with 193 additions and 53 deletions
120
rs/Cargo.lock
generated
120
rs/Cargo.lock
generated
|
|
@ -7,8 +7,15 @@ name = "aoc-rs"
|
|||
version = "0.0.0"
|
||||
dependencies = [
|
||||
"clap",
|
||||
"rayon",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "autocfg"
|
||||
version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
|
||||
|
||||
[[package]]
|
||||
name = "bitflags"
|
||||
version = "1.3.2"
|
||||
|
|
@ -21,6 +28,12 @@ version = "1.0.77"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e9f73505338f7d905b19d18738976aae232eb46b8efc15554ffc56deb5d9ebe4"
|
||||
|
||||
[[package]]
|
||||
name = "cfg-if"
|
||||
version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
||||
|
||||
[[package]]
|
||||
name = "clap"
|
||||
version = "4.0.29"
|
||||
|
|
@ -58,6 +71,55 @@ dependencies = [
|
|||
"os_str_bytes",
|
||||
]
|
||||
|
||||
[[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 = "errno"
|
||||
version = "0.2.8"
|
||||
|
|
@ -85,6 +147,15 @@ version = "0.4.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2540771e65fc8cb83cd6e8a237f70c319bd5c29f78ed1084ba5d50eeac86f7f9"
|
||||
|
||||
[[package]]
|
||||
name = "hermit-abi"
|
||||
version = "0.1.19"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hermit-abi"
|
||||
version = "0.2.6"
|
||||
|
|
@ -110,7 +181,7 @@ version = "0.4.1"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "927609f78c2913a6f6ac3c27a4fe87f43e2a35367c0c4b0f8265e8f49a104330"
|
||||
dependencies = [
|
||||
"hermit-abi",
|
||||
"hermit-abi 0.2.6",
|
||||
"io-lifetimes",
|
||||
"rustix",
|
||||
"windows-sys",
|
||||
|
|
@ -128,6 +199,25 @@ version = "0.1.3"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8f9f08d8963a6c613f4b1a78f4f4a4dbfadf8e6545b2d72861731e4858b8b47f"
|
||||
|
||||
[[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 0.1.19",
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "once_cell"
|
||||
version = "1.16.0"
|
||||
|
|
@ -182,6 +272,28 @@ dependencies = [
|
|||
"proc-macro2",
|
||||
]
|
||||
|
||||
[[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]]
|
||||
name = "rustix"
|
||||
version = "0.36.4"
|
||||
|
|
@ -196,6 +308,12 @@ dependencies = [
|
|||
"windows-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "scopeguard"
|
||||
version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"
|
||||
|
||||
[[package]]
|
||||
name = "strsim"
|
||||
version = "0.10.0"
|
||||
|
|
|
|||
|
|
@ -5,3 +5,4 @@ edition = "2021"
|
|||
|
||||
[dependencies]
|
||||
clap = { version = "4.0.29", features = ["derive", "deprecated"] }
|
||||
rayon = "1.6.1"
|
||||
|
|
|
|||
|
|
@ -1,6 +1,10 @@
|
|||
use std::collections::HashMap;
|
||||
use std::mem;
|
||||
|
||||
use rayon::prelude::{
|
||||
IndexedParallelIterator, IntoParallelRefIterator, IntoParallelRefMutIterator, ParallelIterator,
|
||||
};
|
||||
|
||||
fn parse_valve(line: &str) -> (&str, u32, Vec<&str>) {
|
||||
let (name, rest) = line
|
||||
.strip_prefix("Valve ")
|
||||
|
|
@ -168,47 +172,23 @@ impl Dp2 {
|
|||
let id = self.powers * (self.valves * own_id + el_id) + open.0 as usize;
|
||||
self.elems[id]
|
||||
}
|
||||
|
||||
fn set(&mut self, own_id: usize, el_id: usize, open: OpenSet, score: u32) {
|
||||
let id = self.powers * (self.valves * own_id + el_id) + open.0 as usize;
|
||||
self.elems[id] = score;
|
||||
}
|
||||
|
||||
fn clear(&mut self) {
|
||||
self.elems.fill(0);
|
||||
}
|
||||
}
|
||||
|
||||
fn solve_part_2(names: &HashMap<&str, usize>, valves: &[Valve], powerset: &[OpenSet]) -> u32 {
|
||||
// DP state consists of:
|
||||
// - The own valve
|
||||
// - The elephant valve
|
||||
// - The set of open/closed valves
|
||||
|
||||
let mut prev = Dp2::new(valves, powerset);
|
||||
let mut curr = Dp2::new(valves, powerset);
|
||||
|
||||
// Given valve v in minute t with set s, you can either...
|
||||
// - I move, elephant moves
|
||||
// - I move, elephant opens valve
|
||||
// - I open valve, elephant moves
|
||||
// - I open valve, elephant opens valve (if not in same room)
|
||||
|
||||
for minute in 1..=26 {
|
||||
eprintln!("Minute {minute}");
|
||||
|
||||
mem::swap(&mut curr, &mut prev);
|
||||
curr.clear();
|
||||
|
||||
for (own_id, own_valve) in valves.iter().enumerate() {
|
||||
for (el_id, el_valve) in valves.iter().enumerate() {
|
||||
for open in powerset {
|
||||
fn part_2_score(
|
||||
minute: u32,
|
||||
prev: &Dp2,
|
||||
own_id: usize,
|
||||
own_valve: &Valve,
|
||||
el_id: usize,
|
||||
el_valve: &Valve,
|
||||
open: OpenSet,
|
||||
) -> u32 {
|
||||
let mut score = 0;
|
||||
|
||||
// Both move
|
||||
for own_next in &own_valve.next {
|
||||
for el_next in &el_valve.next {
|
||||
score = score.max(prev.get(*own_next, *el_next, *open));
|
||||
score = score.max(prev.get(*own_next, *el_next, open));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -242,10 +222,51 @@ fn solve_part_2(names: &HashMap<&str, usize>, valves: &[Valve], powerset: &[Open
|
|||
score = score.max(room_but_valves_open + pressure_until_end);
|
||||
}
|
||||
|
||||
curr.set(own_id, el_id, *open, score);
|
||||
score
|
||||
}
|
||||
|
||||
fn solve_part_2(names: &HashMap<&str, usize>, valves: &[Valve], powerset: &[OpenSet]) -> u32 {
|
||||
// DP state consists of:
|
||||
// - The own valve
|
||||
// - The elephant valve
|
||||
// - The set of open/closed valves
|
||||
|
||||
let mut prev = Dp2::new(valves, powerset);
|
||||
let mut curr = Dp2::new(valves, powerset);
|
||||
|
||||
// Given valve v in minute t with set s, you can either...
|
||||
// - I move, elephant moves
|
||||
// - I move, elephant opens valve
|
||||
// - I open valve, elephant moves
|
||||
// - I open valve, elephant opens valve (if not in same room)
|
||||
|
||||
let mut variations = vec![];
|
||||
for (own_id, own_valve) in valves.iter().enumerate() {
|
||||
for (el_id, el_valve) in valves.iter().enumerate() {
|
||||
for open in powerset {
|
||||
variations.push((own_id, own_valve, el_id, el_valve, open));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Just to check whether the variations are in the correct order because I'm
|
||||
// zipping them to curr.elems later.
|
||||
for (i, (own_id, _, el_id, _, open)) in variations.iter().enumerate() {
|
||||
let id = curr.powers * (curr.valves * own_id + el_id) + open.0 as usize;
|
||||
assert_eq!(i, id);
|
||||
}
|
||||
|
||||
for minute in 1..=26 {
|
||||
eprintln!("Minute {minute}");
|
||||
|
||||
mem::swap(&mut curr, &mut prev);
|
||||
|
||||
curr.elems
|
||||
.par_iter_mut()
|
||||
.zip(variations.par_iter())
|
||||
.for_each(|(score, (own_id, own_valve, el_id, el_valve, open))| {
|
||||
*score = part_2_score(minute, &prev, *own_id, own_valve, *el_id, el_valve, **open);
|
||||
});
|
||||
}
|
||||
|
||||
curr.get(names["AA"], names["AA"], OpenSet::ALL_CLOSED)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue