This commit is contained in:
2025-12-08 19:55:48 +00:00
parent 57690eb2b8
commit 0445bde6c1
4 changed files with 1243 additions and 0 deletions

View File

@@ -31,5 +31,9 @@ path = "src/day6/main.rs"
name = "day7"
path = "src/day7/main.rs"
[[bin]]
name = "day8"
path = "src/day8/main.rs"
[dependencies]
anyhow = "1.0.100"

1000
src/day8/act.txt Normal file

File diff suppressed because it is too large Load Diff

219
src/day8/main.rs Normal file
View 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
View 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