mirror of
https://github.com/bertptrs/adventofcode.git
synced 2025-12-25 21:00:31 +01:00
Directly infer matched pivot
This commit is contained in:
@@ -174,15 +174,30 @@ fn parse_input(input: &[u8]) -> IResult<&[u8], Vec<Scanner>> {
|
|||||||
separated_list1(newline, parse_scanner)(input)
|
separated_list1(newline, parse_scanner)(input)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn find_pivot(group: &Scanner, related: &Scanner) -> Option<Point3> {
|
||||||
|
let mut counter = HashMap::new();
|
||||||
|
|
||||||
|
for (distance, &(a, b)) in &group.distances {
|
||||||
|
if related.distances.contains_key(distance) {
|
||||||
|
*counter.entry(a).or_insert(0) += 1;
|
||||||
|
*counter.entry(b).or_insert(0) += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
counter
|
||||||
|
.into_iter()
|
||||||
|
.max_by_key(|(_, count)| *count)
|
||||||
|
.map(|t| t.0)
|
||||||
|
}
|
||||||
|
|
||||||
fn try_overlap(matched: &Scanner, candidate: &Scanner) -> Option<(Point3, Scanner)> {
|
fn try_overlap(matched: &Scanner, candidate: &Scanner) -> Option<(Point3, Scanner)> {
|
||||||
if !matched.can_overlap(candidate) {
|
if !matched.can_overlap(candidate) {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
|
||||||
let correct: Vec<(Point3, HashSet<Point3>)> = matched
|
let matched_pivot = find_pivot(matched, candidate)?;
|
||||||
.iter()
|
|
||||||
.map(|&base| (base, matched.iter().map(|&other| (other - base)).collect()))
|
let correct: HashSet<_> = matched.iter().map(|&base| base - matched_pivot).collect();
|
||||||
.collect();
|
|
||||||
|
|
||||||
let mut relative = HashSet::new();
|
let mut relative = HashSet::new();
|
||||||
for rot in Rotations::new(&candidate.visible) {
|
for rot in Rotations::new(&candidate.visible) {
|
||||||
@@ -191,13 +206,14 @@ fn try_overlap(matched: &Scanner, candidate: &Scanner) -> Option<(Point3, Scanne
|
|||||||
|
|
||||||
relative.extend(rot.iter().map(|&other| other - start));
|
relative.extend(rot.iter().map(|&other| other - start));
|
||||||
|
|
||||||
if let Some((base, _)) = correct.iter().find(|(_, correct_relative)| {
|
if correct.intersection(&relative).count() >= 12 {
|
||||||
correct_relative.intersection(&relative).count() >= 12
|
|
||||||
}) {
|
|
||||||
// Found a solution, build the correct output
|
// Found a solution, build the correct output
|
||||||
let translated = relative.drain().map(|point| point + *base).collect();
|
let translated = relative
|
||||||
|
.drain()
|
||||||
|
.map(|point| point + matched_pivot)
|
||||||
|
.collect();
|
||||||
|
|
||||||
return Some((start - *base, Scanner::new(translated)));
|
return Some((start - matched_pivot, Scanner::new(translated)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user