Compare commits
2 Commits
ba2cfffc3f
...
e97931acf3
| Author | SHA1 | Date | |
|---|---|---|---|
|
e97931acf3
|
|||
|
95b6c0ed9e
|
173
src/day8.rs
Normal file
173
src/day8.rs
Normal file
@@ -0,0 +1,173 @@
|
||||
use std::{
|
||||
collections::{HashMap, HashSet},
|
||||
f64,
|
||||
fmt::{Display, Write},
|
||||
iter::repeat_n,
|
||||
};
|
||||
|
||||
use aoc_runner_derive::{aoc, aoc_generator};
|
||||
use cached::proc_macro::cached;
|
||||
use itertools::Itertools;
|
||||
|
||||
#[derive(Eq, PartialEq, Clone, Debug, Hash)]
|
||||
struct Junction {
|
||||
pos: (i64, i64, i64),
|
||||
}
|
||||
|
||||
fn distance(a: &Junction, b: &Junction) -> f64 {
|
||||
if a.pos == b.pos {
|
||||
f64::MAX // ugh
|
||||
} else {
|
||||
(((a.pos.0 - b.pos.0).pow(2) + (a.pos.1 - b.pos.1).pow(2) + (a.pos.2 - b.pos.2).pow(2))
|
||||
as f64)
|
||||
.sqrt()
|
||||
}
|
||||
}
|
||||
|
||||
impl Junction {
|
||||
fn distance(&self, other: &Junction) -> f64 {
|
||||
distance(self, other)
|
||||
}
|
||||
}
|
||||
|
||||
impl Display for Junction {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
f.write_fmt(format_args!(
|
||||
"({},{},{})",
|
||||
self.pos.0, self.pos.1, self.pos.2
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
impl From<&str> for Junction {
|
||||
fn from(value: &str) -> Self {
|
||||
Self {
|
||||
pos: value
|
||||
.split(',')
|
||||
.map(|v| v.parse().unwrap())
|
||||
.collect_tuple()
|
||||
.unwrap(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
struct Circuits {
|
||||
junctions: Vec<Junction>,
|
||||
circuits: Vec<Vec<usize>>,
|
||||
checked: HashSet<(usize, usize)>,
|
||||
}
|
||||
|
||||
impl Circuits {
|
||||
fn find_circuit(&self, junction: usize) -> Option<usize> {
|
||||
self.circuits
|
||||
.iter()
|
||||
.enumerate()
|
||||
.find(|(_i, c)| c.contains(&junction))
|
||||
.map(|(i, _c)| i)
|
||||
}
|
||||
fn merge_circuits(&mut self, a: usize, b: usize) {
|
||||
if a == b {
|
||||
return;
|
||||
}
|
||||
let mut items = Vec::new();
|
||||
std::mem::swap(&mut items, &mut self.circuits[b]);
|
||||
self.circuits[a].append(&mut items);
|
||||
self.circuits.remove(b);
|
||||
}
|
||||
|
||||
fn connect(&mut self, a: usize, b: usize) {
|
||||
let a_circuit = self.find_circuit(a);
|
||||
let b_circuit = self.find_circuit(b);
|
||||
self.checked.insert((a, b));
|
||||
|
||||
match (a_circuit, b_circuit) {
|
||||
(None, None) => self.circuits.push(vec![a, b]), // both are unconnected
|
||||
(Some(a_circuit), Some(b_circuit)) => {
|
||||
self.merge_circuits(a_circuit, b_circuit); // both are already in circuits, merge them
|
||||
}
|
||||
(Some(a_circuit), None) => self.circuits[a_circuit].push(b), // one is in a circuit, so add the other to the existing circuit
|
||||
(None, Some(b_circuit)) => self.circuits[b_circuit].push(a),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#[aoc_generator(day8)]
|
||||
fn parse(input: &str) -> Circuits {
|
||||
let junctions = input.lines().map(|l| l.into()).collect_vec();
|
||||
|
||||
Circuits {
|
||||
junctions,
|
||||
circuits: Vec::new(),
|
||||
checked: HashSet::new(),
|
||||
}
|
||||
}
|
||||
|
||||
#[aoc(day8, part1)]
|
||||
fn part1(input: &Circuits) -> u64 {
|
||||
let mut circuits = input.clone();
|
||||
for (a, b, d) in circuits
|
||||
.junctions
|
||||
.iter()
|
||||
.enumerate()
|
||||
.combinations(2)
|
||||
.map(|p| (p[0].0, p[1].0, p[0].1.distance(p[1].1)))
|
||||
.sorted_by(|a, b| a.2.partial_cmp(&b.2).unwrap())
|
||||
.take(1000)
|
||||
{
|
||||
println!(
|
||||
"connecting {} <-> {} = {d}",
|
||||
circuits.junctions[a], circuits.junctions[b]
|
||||
);
|
||||
circuits.connect(a, b)
|
||||
}
|
||||
println!("{:?}", circuits.circuits);
|
||||
circuits
|
||||
.circuits
|
||||
.iter()
|
||||
.take(3)
|
||||
.map(|c| c.len())
|
||||
.reduce(|a, b| a * b)
|
||||
.unwrap() as u64
|
||||
}
|
||||
|
||||
#[aoc(day8, part2)]
|
||||
fn part2(input: &Circuits) -> u64 {
|
||||
0
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
const EXAMPLE: &str = "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";
|
||||
|
||||
#[test]
|
||||
fn part1_example() {
|
||||
assert_eq!(part1(&parse(EXAMPLE)), 40);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn part2_example() {
|
||||
assert_eq!(part2(&parse(EXAMPLE)), 0);
|
||||
}
|
||||
}
|
||||
@@ -5,6 +5,7 @@ mod day4;
|
||||
mod day5;
|
||||
mod day6;
|
||||
mod day7;
|
||||
mod day8;
|
||||
|
||||
use aoc_runner_derive::aoc_lib;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user