Optimize 09
This commit is contained in:
parent
c6d69e2fc2
commit
257c7e5cb6
3 changed files with 61 additions and 54 deletions
73
Cargo.lock
generated
73
Cargo.lock
generated
|
|
@ -32,9 +32,9 @@ version = "0.0.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"cached",
|
"cached",
|
||||||
"derive_more",
|
|
||||||
"glam",
|
"glam",
|
||||||
"itertools",
|
"itertools",
|
||||||
|
"rayon",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
@ -82,6 +82,31 @@ version = "1.0.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "crossbeam-deque"
|
||||||
|
version = "0.8.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "9dd111b7b7f7d55b72c0a6ae361660ee5853c9af73f70c3c2ef6858b950e2e51"
|
||||||
|
dependencies = [
|
||||||
|
"crossbeam-epoch",
|
||||||
|
"crossbeam-utils",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "crossbeam-epoch"
|
||||||
|
version = "0.9.18"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e"
|
||||||
|
dependencies = [
|
||||||
|
"crossbeam-utils",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "crossbeam-utils"
|
||||||
|
version = "0.8.21"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "darling"
|
name = "darling"
|
||||||
version = "0.20.11"
|
version = "0.20.11"
|
||||||
|
|
@ -117,27 +142,6 @@ dependencies = [
|
||||||
"syn",
|
"syn",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "derive_more"
|
|
||||||
version = "2.1.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "10b768e943bed7bf2cab53df09f4bc34bfd217cdb57d971e769874c9a6710618"
|
|
||||||
dependencies = [
|
|
||||||
"derive_more-impl",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "derive_more-impl"
|
|
||||||
version = "2.1.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "6d286bfdaf75e988b4a78e013ecd79c581e06399ab53fbacd2d916c2f904f30b"
|
|
||||||
dependencies = [
|
|
||||||
"proc-macro2",
|
|
||||||
"quote",
|
|
||||||
"rustc_version",
|
|
||||||
"syn",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "either"
|
name = "either"
|
||||||
version = "1.13.0"
|
version = "1.13.0"
|
||||||
|
|
@ -229,12 +233,23 @@ dependencies = [
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rustc_version"
|
name = "rayon"
|
||||||
version = "0.4.1"
|
version = "1.11.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92"
|
checksum = "368f01d005bf8fd9b1206fb6fa653e6c4a81ceb1466406b81792d87c5677a58f"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"semver",
|
"either",
|
||||||
|
"rayon-core",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rayon-core"
|
||||||
|
version = "1.13.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "22e18b0f0062d30d4230b2e85ff77fdfe4326feb054b9783a3460d8435c8ab91"
|
||||||
|
dependencies = [
|
||||||
|
"crossbeam-deque",
|
||||||
|
"crossbeam-utils",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
@ -243,12 +258,6 @@ version = "1.0.22"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d"
|
checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "semver"
|
|
||||||
version = "1.0.27"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "d767eb0aabc880b29956c35734170f26ed551a859dbd361d140cdbeca61ab1e2"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "strsim"
|
name = "strsim"
|
||||||
version = "0.11.1"
|
version = "0.11.1"
|
||||||
|
|
|
||||||
|
|
@ -6,9 +6,9 @@ edition = "2021"
|
||||||
[dependencies]
|
[dependencies]
|
||||||
anyhow = "1.0.100"
|
anyhow = "1.0.100"
|
||||||
cached = "0.56.0"
|
cached = "0.56.0"
|
||||||
derive_more = { version = "2.1.0", features = ["deref"] }
|
|
||||||
glam = "0.30.9"
|
glam = "0.30.9"
|
||||||
itertools = "0.14.0"
|
itertools = "0.14.0"
|
||||||
|
rayon = "1.11.0"
|
||||||
|
|
||||||
[profile.release]
|
[profile.release]
|
||||||
debug = true
|
debug = true
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,7 @@
|
||||||
use aoc::*;
|
use aoc::*;
|
||||||
use derive_more::Deref;
|
|
||||||
use glam::I64Vec2;
|
use glam::I64Vec2;
|
||||||
use itertools::Itertools;
|
use itertools::Itertools;
|
||||||
use std::cmp::Reverse;
|
use rayon::prelude::*;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
|
||||||
const INPUT: &str = include_str!("../../input/09");
|
const INPUT: &str = include_str!("../../input/09");
|
||||||
|
|
@ -45,19 +44,19 @@ fn part2(input: &str) -> u64 {
|
||||||
.iter()
|
.iter()
|
||||||
.copied()
|
.copied()
|
||||||
.tuple_combinations()
|
.tuple_combinations()
|
||||||
|
.par_bridge()
|
||||||
.map(Rect::from)
|
.map(Rect::from)
|
||||||
.sorted_by_key(|r| {
|
.filter(|&r| polygon.contains_rect(r))
|
||||||
let area = r.uncompress(&uncompress).area();
|
.map(|r| r.uncompress(&uncompress).area())
|
||||||
Reverse(area)
|
.max()
|
||||||
})
|
|
||||||
.find(|&r| polygon.contains_rect(r))
|
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.uncompress(&uncompress)
|
|
||||||
.area()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
struct Polygon {
|
struct Polygon {
|
||||||
points: Vec<I64Vec2>,
|
points: Vec<I64Vec2>,
|
||||||
|
/// Contains vertical lines sorted by their x value in ascending order.
|
||||||
|
/// This is important for contains_point, as that assumes the lines are in this order.
|
||||||
|
/// This dramatically speeds up the raycast in contains_point, as the ray is cast in positive x direction.
|
||||||
cached_vertical_lines: Vec<Line>,
|
cached_vertical_lines: Vec<Line>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -72,7 +71,7 @@ impl Polygon {
|
||||||
fn parse(input: &str) -> Self {
|
fn parse(input: &str) -> Self {
|
||||||
let mut polygon = Self {
|
let mut polygon = Self {
|
||||||
points: input.lines().map(parse_line).collect(),
|
points: input.lines().map(parse_line).collect(),
|
||||||
cached_vertical_lines: vec![],
|
cached_vertical_lines: Default::default(),
|
||||||
};
|
};
|
||||||
polygon.cache_vertical_lines();
|
polygon.cache_vertical_lines();
|
||||||
polygon
|
polygon
|
||||||
|
|
@ -127,19 +126,20 @@ impl Polygon {
|
||||||
let xs = self
|
let xs = self
|
||||||
.cached_vertical_lines
|
.cached_vertical_lines
|
||||||
.iter()
|
.iter()
|
||||||
|
.take_while(|line| line.0.x < p.x)
|
||||||
.filter(|l| {
|
.filter(|l| {
|
||||||
let ymin = l.0.y.min(l.1.y);
|
let ymin = l.0.y.min(l.1.y);
|
||||||
let ymax = l.0.y.max(l.1.y);
|
let ymax = l.0.y.max(l.1.y);
|
||||||
ymin <= p.y && p.y <= ymax
|
ymin <= p.y && p.y <= ymax
|
||||||
})
|
})
|
||||||
.flat_map(|l| [l.0.x])
|
.map(|l| l.0.x)
|
||||||
.filter(|&x| x < p.x)
|
|
||||||
.chain([p.x])
|
.chain([p.x])
|
||||||
.sorted();
|
.sorted();
|
||||||
|
|
||||||
let line = |p| {
|
let line_with = |p: I64Vec2| {
|
||||||
self.cached_vertical_lines
|
self.cached_vertical_lines
|
||||||
.iter()
|
.iter()
|
||||||
|
.take_while(|line| line.0.x <= p.x)
|
||||||
.find(|line| line.contains(p))
|
.find(|line| line.contains(p))
|
||||||
.copied()
|
.copied()
|
||||||
};
|
};
|
||||||
|
|
@ -149,7 +149,7 @@ impl Polygon {
|
||||||
|
|
||||||
for x in xs {
|
for x in xs {
|
||||||
let check = I64Vec2::new(x, p.y);
|
let check = I64Vec2::new(x, p.y);
|
||||||
if let Some(line) = line(check) {
|
if let Some(line) = line_with(check) {
|
||||||
winding = line.winding();
|
winding = line.winding();
|
||||||
on_line = true;
|
on_line = true;
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -160,19 +160,17 @@ impl Polygon {
|
||||||
winding < 0 || on_line
|
winding < 0 || on_line
|
||||||
}
|
}
|
||||||
|
|
||||||
fn vertical_lines(&self) -> Vec<Line> {
|
fn cache_vertical_lines(&mut self) {
|
||||||
self.points
|
self.cached_vertical_lines = self
|
||||||
|
.points
|
||||||
.iter()
|
.iter()
|
||||||
.chain(self.points.first()) // close the loop
|
.chain(self.points.first()) // close the loop
|
||||||
.copied()
|
.copied()
|
||||||
.tuple_windows()
|
.tuple_windows()
|
||||||
.map(|(a, b)| Line(a, b))
|
.map(|(a, b)| Line(a, b))
|
||||||
.filter(|l| l.is_vertical())
|
.filter(|l| l.is_vertical())
|
||||||
.collect()
|
.sorted_by_key(|line| line.0.x)
|
||||||
}
|
.collect();
|
||||||
|
|
||||||
fn cache_vertical_lines(&mut self) {
|
|
||||||
self.cached_vertical_lines = self.vertical_lines();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue