mirror of
https://github.com/bertptrs/adventofcode.git
synced 2025-12-25 21:00:31 +01:00
Compare commits
2 Commits
04e8a41d98
...
dba146b299
| Author | SHA1 | Date | |
|---|---|---|---|
| dba146b299 | |||
| 33111615be |
@@ -174,30 +174,45 @@ fn parse_input(input: &[u8]) -> IResult<&[u8], Vec<Scanner>> {
|
||||
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)> {
|
||||
if !matched.can_overlap(candidate) {
|
||||
return None;
|
||||
}
|
||||
|
||||
let correct: Vec<(Point3, HashSet<Point3>)> = matched
|
||||
.iter()
|
||||
.map(|&base| (base, matched.iter().map(|&other| (other - base)).collect()))
|
||||
.collect();
|
||||
let matched_pivot = find_pivot(matched, candidate)?;
|
||||
|
||||
let mut relative = HashSet::new();
|
||||
for rot in Rotations::new(&candidate.visible) {
|
||||
let correct: HashSet<_> = matched.iter().map(|&base| base - matched_pivot).collect();
|
||||
|
||||
for rot in Rotations::new(candidate) {
|
||||
for &start in &rot {
|
||||
relative.clear();
|
||||
let translated_iter = rot.iter().map(|&other| other - start);
|
||||
|
||||
relative.extend(rot.iter().map(|&other| other - start));
|
||||
|
||||
if let Some((base, _)) = correct.iter().find(|(_, correct_relative)| {
|
||||
correct_relative.intersection(&relative).count() >= 12
|
||||
}) {
|
||||
if translated_iter
|
||||
.clone()
|
||||
.filter(|p| correct.contains(p))
|
||||
.count()
|
||||
>= 12
|
||||
{
|
||||
// Found a solution, build the correct output
|
||||
let translated = relative.drain().map(|point| point + *base).collect();
|
||||
let translated = translated_iter.map(|point| point + matched_pivot).collect();
|
||||
|
||||
return Some((start - *base, Scanner::new(translated)));
|
||||
return Some((start - matched_pivot, Scanner::new(translated)));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -232,6 +247,8 @@ fn parts_common(input: &mut dyn Read) -> (HashSet<Point3>, Vec<Point3>) {
|
||||
}
|
||||
}
|
||||
|
||||
assert!(scanners.is_empty());
|
||||
|
||||
(points, scanners_found)
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user