Self { boxes }
}
- fn part1(&self, n_shortest: usize) -> usize {
- let mut connections: Vec<(i64, (usize, usize))> = Vec::new();
+ fn connections(&self) -> Vec<(i64, (usize, usize))> {
+ let mut connections = Vec::new();
for i in 0..self.boxes.len() {
for j in (i+1)..self.boxes.len() {
connections.push((self.boxes[i].dst(self.boxes[j]), (i, j)));
}
}
connections.sort_by(|a, b| a.0.cmp(&b.0));
+ connections
+ }
+
+ fn add_to_set((b1, b2): (usize, usize), circuits: &mut Vec<HashSet<usize>>) {
+ // if b1 is one of the circuits sets
+ // - if b2 is in one of the circuit sets
+ // -> push the union of the sets
+ // - else add b2 to the set
+ // if b2 is one :of the circuits sets
+ // - if b1 is in one of the circuit sets
+ // -> push the union of the sets
+ // - else add b1 to the set
+ // else add a new set (b1, b2)
+ if let Some(i) = circuits.iter().position(|s| s.contains(&b1)) {
+ if let Some(j) = circuits.iter().position(|s| s.contains(&b2)) {
+ circuits.push( circuits[i].union(&circuits[j]).copied().collect() );
+ circuits.remove(i.max(j));
+ if i != j {
+ circuits.remove(i.min(j));
+ }
+ } else {
+ circuits[i].insert(b2);
+ }
+ } else if let Some(i) = circuits.iter().position(|s| s.contains(&b2)) {
+ if let Some(j) = circuits.iter().position(|s| s.contains(&b1)) {
+ circuits.push( circuits[i].union(&circuits[j]).copied().collect() );
+ circuits.remove(i.max(j));
+ if i != j {
+ circuits.remove(i.min(j));
+ }
+ } else {
+ circuits[i].insert(b1);
+ }
+ } else {
+ let mut s: HashSet<usize> = HashSet::new();
+ s.insert(b1);
+ s.insert(b2);
+ circuits.push(s);
+ }
+ // sort by set length
+ circuits.sort_by_key(|s| std::cmp::Reverse(s.len()));
+ }
- let mut connections: Vec<(usize, usize)> = connections.into_iter()
+ fn part1(&self, n_shortest: usize) -> usize {
+ let mut connections: Vec<(usize, usize)> = self.connections()
+ .into_iter()
.take(n_shortest)
.map(|(_, coord)| coord)
.collect();
let mut circuits: Vec<HashSet<usize>> = Vec::new();
connections.iter()
.for_each(|(b1, b2)| {
- if let Some(i) = circuits.iter().position(|s| s.contains(b1)) {
- if let Some(j) = circuits.iter().position(|s| s.contains(b2)) {
- circuits.push( circuits[i].union(&circuits[j]).map(|v| *v).collect() );
- circuits.remove(i.max(j));
- if i != j {
- circuits.remove(i.min(j));
- }
- } else {
- circuits[i].insert(*b2);
- }
- } else if let Some(i) = circuits.iter().position(|s| s.contains(b2)) {
- if let Some(j) = circuits.iter().position(|s| s.contains(b1)) {
- circuits.push( circuits[i].union(&circuits[j]).map(|v| *v).collect() );
- circuits.remove(i.max(j));
- if i != j {
- circuits.remove(i.min(j));
- }
- } else {
- circuits[i].insert(*b1);
- }
- } else {
- let mut s: HashSet<usize> = HashSet::new();
- s.insert(*b1);
- s.insert(*b2);
- circuits.push(s);
- }
- circuits.sort_by(|a, b| b.len().cmp(&a.len()));
- // si b1 est dans un set de circuits
- // - si b2 est dans un set de circuits
- // -> relier les sets
- // - sinon ajouter b2 au set
- // si b2 est déjà dans un set de circuits
- // - si b1 est dans un set de circuits
- // -> relier les sets
- // - sinon ajouter b1 au set
- // sinon ajouter set (b1, b2)
+ Puzzle::add_to_set((*b1, *b2), &mut circuits);
});
let mut circuits: Vec<usize> = circuits.iter().map(|set| set.len()).collect();
circuits.sort_by(|a, b| b.cmp(a));
}
fn part2(&self) -> i64 {
- let mut connections: Vec<(i64, (usize, usize))> = Vec::new();
- for i in 0..self.boxes.len() {
- for j in (i+1)..self.boxes.len() {
- connections.push((self.boxes[i].dst(self.boxes[j]), (i, j)));
- }
- }
- connections.sort_by(|a, b| a.0.cmp(&b.0));
- let mut connections: Vec<(usize, usize)> = connections.into_iter()
+ let connections: Vec<(usize, usize)> = self.connections()
+ .into_iter()
.map(|(_, coord)| coord)
.collect();
- //connections.sort();
let mut circuits: Vec<HashSet<usize>> = Vec::new();
- let mut it_connections = connections.iter();
- while let Some((b1, b2)) = it_connections.next() {
- if let Some(i) = circuits.iter().position(|s| s.contains(b1)) {
- if let Some(j) = circuits.iter().position(|s| s.contains(b2)) {
- circuits.push( circuits[i].union(&circuits[j]).map(|v| *v).collect() );
- circuits.remove(i.max(j));
- if i != j {
- circuits.remove(i.min(j));
- }
- } else {
- circuits[i].insert(*b2);
- }
- } else if let Some(i) = circuits.iter().position(|s| s.contains(b2)) {
- if let Some(j) = circuits.iter().position(|s| s.contains(b1)) {
- circuits.push( circuits[i].union(&circuits[j]).map(|v| *v).collect() );
- circuits.remove(i.max(j));
- if i != j {
- circuits.remove(i.min(j));
- }
- } else {
- circuits[i].insert(*b1);
- }
- } else {
- let mut s: HashSet<usize> = HashSet::new();
- s.insert(*b1);
- s.insert(*b2);
- circuits.push(s);
- }
- circuits.sort_by(|a, b| b.len().cmp(&a.len()));
+ for (b1, b2) in connections.iter() {
+ Puzzle::add_to_set((*b1, *b2), &mut circuits);
if circuits[0].len() == self.boxes.len() {
return self.boxes[*b1].x * self.boxes[*b2].x;
}