Day 8
This commit is contained in:
1000
src/day8/act.txt
Normal file
1000
src/day8/act.txt
Normal file
File diff suppressed because it is too large
Load Diff
219
src/day8/main.rs
Normal file
219
src/day8/main.rs
Normal file
@@ -0,0 +1,219 @@
|
||||
use anyhow::Result;
|
||||
use std::{
|
||||
collections::{HashMap, HashSet},
|
||||
fs,
|
||||
};
|
||||
|
||||
#[derive(Debug, PartialEq, Eq, Hash)]
|
||||
struct JunctionBox {
|
||||
x: i64,
|
||||
y: i64,
|
||||
z: i64,
|
||||
}
|
||||
|
||||
impl JunctionBox {
|
||||
fn dist(&self, other: &JunctionBox) -> f64 {
|
||||
(((self.x - other.x).pow(2) + (self.y - other.y).pow(2) + (self.z - other.z).pow(2)) as f64)
|
||||
.sqrt()
|
||||
}
|
||||
}
|
||||
|
||||
impl Into<JunctionBox> for &str {
|
||||
fn into(self) -> JunctionBox {
|
||||
let mut niter = self.split(",");
|
||||
let x: i64 = niter.next().unwrap().parse().unwrap();
|
||||
let y: i64 = niter.next().unwrap().parse().unwrap();
|
||||
let z: i64 = niter.next().unwrap().parse().unwrap();
|
||||
JunctionBox { x, y, z }
|
||||
}
|
||||
}
|
||||
|
||||
struct Pair<'a> {
|
||||
b1: &'a JunctionBox,
|
||||
b2: &'a JunctionBox,
|
||||
dist: f64,
|
||||
}
|
||||
|
||||
impl<'a> Pair<'a> {
|
||||
fn new(b1: &'a JunctionBox, b2: &'a JunctionBox) -> Pair<'a> {
|
||||
Pair {
|
||||
b1,
|
||||
b2,
|
||||
dist: b1.dist(b2),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct Circuit<'a> {
|
||||
set: HashSet<&'a JunctionBox>,
|
||||
}
|
||||
|
||||
fn sol1(text: &str) {
|
||||
let boxes: Vec<JunctionBox> = text
|
||||
.split("\n")
|
||||
.filter(|s| s.len() > 0)
|
||||
.map(|s| s.into())
|
||||
.collect();
|
||||
|
||||
let mut pairs: Vec<Pair> = Vec::with_capacity(boxes.len() * boxes.len());
|
||||
|
||||
for (i, b1) in boxes.iter().enumerate() {
|
||||
for b2 in boxes.iter().skip(i + 1) {
|
||||
pairs.push(Pair::new(b1, b2))
|
||||
}
|
||||
}
|
||||
|
||||
pairs.sort_by(|a, b| a.dist.total_cmp(&b.dist));
|
||||
|
||||
let mut box_to_circuit: HashMap<&JunctionBox, usize> = HashMap::new();
|
||||
let mut circuits: Vec<Option<Circuit>> = Vec::new();
|
||||
|
||||
for pair in pairs.iter().take(1000) {
|
||||
print!("{} {:?} {:?}", pair.dist, pair.b1, pair.b2);
|
||||
let b1c = box_to_circuit.get(pair.b1);
|
||||
let b2c = box_to_circuit.get(pair.b2);
|
||||
if b1c.is_some() && b2c.is_some() {
|
||||
let b1c = *b1c.unwrap();
|
||||
let b1c_set = circuits[b1c].as_ref().unwrap();
|
||||
if b1c_set.set.contains(pair.b2) {
|
||||
println!(" nothing");
|
||||
continue;
|
||||
}
|
||||
let b2c = *b2c.unwrap();
|
||||
let mut b2c_set: Option<Circuit> = None;
|
||||
std::mem::swap(&mut circuits[b2c], &mut b2c_set);
|
||||
let b2c_set = b2c_set.unwrap();
|
||||
for item in b2c_set.set.iter() {
|
||||
box_to_circuit.insert(item, b1c);
|
||||
}
|
||||
circuits[b1c].as_mut().unwrap().set.extend(&b2c_set.set);
|
||||
println!(" merge");
|
||||
} else if b1c.is_some() {
|
||||
let b1c = *b1c.unwrap();
|
||||
circuits[b1c].as_mut().unwrap().set.insert(pair.b2);
|
||||
box_to_circuit.insert(pair.b2, b1c);
|
||||
println!(" b1");
|
||||
} else if b2c.is_some() {
|
||||
let b2c = *b2c.unwrap();
|
||||
circuits[b2c].as_mut().unwrap().set.insert(pair.b1);
|
||||
box_to_circuit.insert(pair.b1, b2c);
|
||||
println!(" b2");
|
||||
} else {
|
||||
let mut set = HashSet::new();
|
||||
set.insert(pair.b1);
|
||||
set.insert(pair.b2);
|
||||
circuits.push(Some(Circuit { set }));
|
||||
box_to_circuit.insert(pair.b1, circuits.len() - 1);
|
||||
box_to_circuit.insert(pair.b2, circuits.len() - 1);
|
||||
println!(" new");
|
||||
}
|
||||
}
|
||||
|
||||
let mut circuits: Vec<Circuit> = circuits
|
||||
.into_iter()
|
||||
.filter(|s| s.is_some())
|
||||
.map(|a| a.unwrap())
|
||||
.collect();
|
||||
|
||||
circuits.sort_by(|a, b| a.set.len().cmp(&b.set.len()));
|
||||
|
||||
println!("cirt tot: {}", circuits.len());
|
||||
for i in circuits.iter().rev() {
|
||||
println!("cirt: {}", i.set.len());
|
||||
}
|
||||
|
||||
println!(
|
||||
"Sol1: {}",
|
||||
circuits
|
||||
.iter()
|
||||
.rev()
|
||||
.take(3)
|
||||
.fold(1, |m, i| m * i.set.len())
|
||||
);
|
||||
}
|
||||
|
||||
fn main() -> Result<()> {
|
||||
let text = fs::read_to_string("src/day8/act.txt")?;
|
||||
|
||||
sol1(&text);
|
||||
|
||||
let boxes: Vec<JunctionBox> = text
|
||||
.split("\n")
|
||||
.filter(|s| s.len() > 0)
|
||||
.map(|s| s.into())
|
||||
.collect();
|
||||
|
||||
let mut pairs: Vec<Pair> = Vec::with_capacity(boxes.len() * boxes.len());
|
||||
|
||||
for (i, b1) in boxes.iter().enumerate() {
|
||||
for b2 in boxes.iter().skip(i + 1) {
|
||||
pairs.push(Pair::new(b1, b2))
|
||||
}
|
||||
}
|
||||
|
||||
pairs.sort_by(|a, b| a.dist.total_cmp(&b.dist));
|
||||
|
||||
let mut box_to_circuit: HashMap<&JunctionBox, usize> = HashMap::new();
|
||||
let mut circuits: Vec<Option<Circuit>> = Vec::new();
|
||||
|
||||
for pair in pairs.iter() {
|
||||
print!("{} {:?} {:?}", pair.dist, pair.b1, pair.b2);
|
||||
let b1c = box_to_circuit.get(pair.b1);
|
||||
let b2c = box_to_circuit.get(pair.b2);
|
||||
if b1c.is_some() && b2c.is_some() {
|
||||
let b1c = *b1c.unwrap();
|
||||
let b1c_set = circuits[b1c].as_ref().unwrap();
|
||||
if b1c_set.set.contains(pair.b2) {
|
||||
println!(" nothing");
|
||||
continue;
|
||||
}
|
||||
let b2c = *b2c.unwrap();
|
||||
let mut b2c_set: Option<Circuit> = None;
|
||||
std::mem::swap(&mut circuits[b2c], &mut b2c_set);
|
||||
let b2c_set = b2c_set.unwrap();
|
||||
for item in b2c_set.set.iter() {
|
||||
box_to_circuit.insert(item, b1c);
|
||||
}
|
||||
circuits[b1c].as_mut().unwrap().set.extend(&b2c_set.set);
|
||||
|
||||
if circuits[b1c].as_ref().unwrap().set.len() == boxes.len() {
|
||||
println!("\n\nsol2: {}", pair.b1.x * pair.b2.x);
|
||||
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
println!(" merge");
|
||||
} else if b1c.is_some() {
|
||||
let b1c = *b1c.unwrap();
|
||||
circuits[b1c].as_mut().unwrap().set.insert(pair.b2);
|
||||
box_to_circuit.insert(pair.b2, b1c);
|
||||
|
||||
if circuits[b1c].as_ref().unwrap().set.len() == boxes.len() {
|
||||
println!("\n\nsol2: {}", pair.b1.x * pair.b2.x);
|
||||
|
||||
return Ok(());
|
||||
}
|
||||
println!(" b1");
|
||||
} else if b2c.is_some() {
|
||||
let b2c = *b2c.unwrap();
|
||||
circuits[b2c].as_mut().unwrap().set.insert(pair.b1);
|
||||
box_to_circuit.insert(pair.b1, b2c);
|
||||
if circuits[b2c].as_ref().unwrap().set.len() == boxes.len() {
|
||||
println!("\n\nsol2: {}", pair.b1.x * pair.b2.x);
|
||||
|
||||
return Ok(());
|
||||
}
|
||||
println!(" b2");
|
||||
} else {
|
||||
let mut set = HashSet::new();
|
||||
set.insert(pair.b1);
|
||||
set.insert(pair.b2);
|
||||
circuits.push(Some(Circuit { set }));
|
||||
box_to_circuit.insert(pair.b1, circuits.len() - 1);
|
||||
box_to_circuit.insert(pair.b2, circuits.len() - 1);
|
||||
println!(" new");
|
||||
}
|
||||
}
|
||||
|
||||
panic!("Sould not reach here");
|
||||
}
|
||||
20
src/day8/test.txt
Normal file
20
src/day8/test.txt
Normal file
@@ -0,0 +1,20 @@
|
||||
162,817,812
|
||||
57,618,57
|
||||
906,360,560
|
||||
592,479,940
|
||||
352,342,300
|
||||
466,668,158
|
||||
542,29,236
|
||||
431,825,988
|
||||
739,650,466
|
||||
52,470,668
|
||||
216,146,977
|
||||
819,987,18
|
||||
117,168,530
|
||||
805,96,715
|
||||
346,949,466
|
||||
970,615,88
|
||||
941,993,340
|
||||
862,61,35
|
||||
984,92,344
|
||||
425,690,689
|
||||
Reference in New Issue
Block a user