day8
This commit is contained in:
46
src/day5.rs
46
src/day5.rs
@@ -1,4 +1,4 @@
|
|||||||
use std::cmp;
|
// use std::cmp;
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug)]
|
#[derive(Copy, Clone, Debug)]
|
||||||
struct UintInclusiveRange {
|
struct UintInclusiveRange {
|
||||||
@@ -18,29 +18,29 @@ impl UintInclusiveRange {
|
|||||||
value >= self.start && value <= self.end
|
value >= self.start && value <= self.end
|
||||||
}
|
}
|
||||||
|
|
||||||
fn overlaps(&self, other: &UintInclusiveRange) -> bool {
|
// fn overlaps(&self, other: &UintInclusiveRange) -> bool {
|
||||||
(self.start >= other.start && self.start <= other.end)
|
// (self.start >= other.start && self.start <= other.end)
|
||||||
|| (self.end >= other.start && self.end <= other.end)
|
// || (self.end >= other.start && self.end <= other.end)
|
||||||
|| (self.start <= other.start && self.end >= other.end)
|
// || (self.start <= other.start && self.end >= other.end)
|
||||||
|| (self.start >= other.start && self.end <= other.end)
|
// || (self.start >= other.start && self.end <= other.end)
|
||||||
}
|
// }
|
||||||
|
|
||||||
fn join(&self, other: &UintInclusiveRange) -> UintInclusiveRange {
|
// fn join(&self, other: &UintInclusiveRange) -> UintInclusiveRange {
|
||||||
println!(
|
// println!(
|
||||||
"Joining {:?} and {:?} into {:?}",
|
// "Joining {:?} and {:?} into {:?}",
|
||||||
self,
|
// self,
|
||||||
other,
|
// other,
|
||||||
UintInclusiveRange::new(
|
// UintInclusiveRange::new(
|
||||||
cmp::min(self.start, other.start),
|
// cmp::min(self.start, other.start),
|
||||||
cmp::max(self.end, other.end),
|
// cmp::max(self.end, other.end),
|
||||||
)
|
// )
|
||||||
);
|
// );
|
||||||
assert!(self.overlaps(&other));
|
// assert!(self.overlaps(&other));
|
||||||
UintInclusiveRange::new(
|
// UintInclusiveRange::new(
|
||||||
cmp::min(self.start, other.start),
|
// cmp::min(self.start, other.start),
|
||||||
cmp::max(self.end, other.end),
|
// cmp::max(self.end, other.end),
|
||||||
)
|
// )
|
||||||
}
|
// }
|
||||||
|
|
||||||
fn size(self) -> u64 {
|
fn size(self) -> u64 {
|
||||||
self.end - self.start + 1
|
self.end - self.start + 1
|
||||||
|
|||||||
155
src/day8.rs
Normal file
155
src/day8.rs
Normal file
@@ -0,0 +1,155 @@
|
|||||||
|
use std::collections::HashSet;
|
||||||
|
|
||||||
|
#[aoc(day8, part1)]
|
||||||
|
pub fn part1(input: &str) -> i64 {
|
||||||
|
let nodes = parse(input);
|
||||||
|
let distance_matrix = distances(nodes);
|
||||||
|
let mut circuits = make_circuits(distance_matrix, 1000);
|
||||||
|
circuits.sort_unstable_by(|x, y| y.len().cmp(&x.len()));
|
||||||
|
circuits.iter().take(3).fold(1, |x, y| x * y.len() as i64)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[aoc(day8, part2)]
|
||||||
|
pub fn part2(input: &str) -> i64 {
|
||||||
|
let nodes = parse(input);
|
||||||
|
let distance_matrix = distances(nodes.clone());
|
||||||
|
let last_nodes = fully_connect(distance_matrix).unwrap();
|
||||||
|
println!("{:?}", last_nodes);
|
||||||
|
nodes[last_nodes.0][0] * nodes[last_nodes.1][0]
|
||||||
|
}
|
||||||
|
|
||||||
|
fn parse(input: &str) -> Vec<Vec<i64>> {
|
||||||
|
input
|
||||||
|
.lines()
|
||||||
|
.map(|line| {
|
||||||
|
line.split(',')
|
||||||
|
.map(|num| num.parse::<i64>().unwrap())
|
||||||
|
.collect::<Vec<i64>>()
|
||||||
|
})
|
||||||
|
.collect()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn distances(nodes: Vec<Vec<i64>>) -> Vec<Vec<f64>> {
|
||||||
|
(0..nodes.len())
|
||||||
|
.map(|j| {
|
||||||
|
{
|
||||||
|
((j + 1)..nodes.len()).map(|i| {
|
||||||
|
(0..3)
|
||||||
|
.map(|k| (nodes[i][k] - nodes[j][k]).pow(2) as f64)
|
||||||
|
.sum::<f64>()
|
||||||
|
.sqrt()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
.collect::<Vec<f64>>()
|
||||||
|
})
|
||||||
|
.collect()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn make_circuits(distance_matrix: Vec<Vec<f64>>, n_connections: u32) -> Vec<HashSet<usize>> {
|
||||||
|
let mut distances_sorted = distance_matrix
|
||||||
|
.into_iter()
|
||||||
|
.enumerate()
|
||||||
|
.flat_map(|(i, row)| {
|
||||||
|
row.into_iter()
|
||||||
|
.enumerate()
|
||||||
|
.map(move |(j, elem)| (i, j, elem))
|
||||||
|
})
|
||||||
|
.collect::<Vec<(usize, usize, f64)>>();
|
||||||
|
distances_sorted.sort_unstable_by(|x, y| x.2.partial_cmp(&y.2).unwrap());
|
||||||
|
|
||||||
|
let mut circuits: Vec<HashSet<usize>> = Vec::new();
|
||||||
|
|
||||||
|
for (i, j, _) in distances_sorted.iter().take(n_connections as usize) {
|
||||||
|
let init = HashSet::from([*i, *j + 1 + *i]);
|
||||||
|
let (to_merge, mut existing): (Vec<HashSet<usize>>, Vec<HashSet<usize>>) = circuits
|
||||||
|
.into_iter()
|
||||||
|
.partition(|c| c.contains(i) || c.contains(&(*j + 1 + *i)));
|
||||||
|
// println!("{:?} {} {}", i, j + 1 + i, d);
|
||||||
|
assert!(to_merge.len() < 3);
|
||||||
|
let new_circuit: HashSet<usize> = to_merge
|
||||||
|
.iter()
|
||||||
|
.flatten()
|
||||||
|
.chain(init.iter())
|
||||||
|
.copied()
|
||||||
|
.collect();
|
||||||
|
existing.push(new_circuit);
|
||||||
|
circuits = existing;
|
||||||
|
}
|
||||||
|
circuits
|
||||||
|
}
|
||||||
|
fn fully_connect(distance_matrix: Vec<Vec<f64>>) -> Option<(usize, usize)> {
|
||||||
|
let n_nodes = distance_matrix.len();
|
||||||
|
let mut distances_sorted = distance_matrix
|
||||||
|
.into_iter()
|
||||||
|
.enumerate()
|
||||||
|
.flat_map(|(i, row)| {
|
||||||
|
row.into_iter()
|
||||||
|
.enumerate()
|
||||||
|
.map(move |(j, elem)| (i, j, elem))
|
||||||
|
})
|
||||||
|
.collect::<Vec<(usize, usize, f64)>>();
|
||||||
|
distances_sorted.sort_unstable_by(|x, y| x.2.partial_cmp(&y.2).unwrap());
|
||||||
|
|
||||||
|
let mut circuits: Vec<HashSet<usize>> = Vec::new();
|
||||||
|
|
||||||
|
let mut result: Option<(usize, usize)> = None;
|
||||||
|
|
||||||
|
for (i, j, _) in distances_sorted.iter() {
|
||||||
|
let init = HashSet::from([*i, *j + 1 + *i]);
|
||||||
|
let (to_merge, mut existing): (Vec<HashSet<usize>>, Vec<HashSet<usize>>) = circuits
|
||||||
|
.into_iter()
|
||||||
|
.partition(|c| c.contains(i) || c.contains(&(*j + 1 + *i)));
|
||||||
|
assert!(to_merge.len() < 3);
|
||||||
|
let new_circuit: HashSet<usize> = to_merge
|
||||||
|
.iter()
|
||||||
|
.flatten()
|
||||||
|
.chain(init.iter())
|
||||||
|
.copied()
|
||||||
|
.collect();
|
||||||
|
existing.push(new_circuit);
|
||||||
|
circuits = existing;
|
||||||
|
if circuits.len() == 1 && circuits[0].len() == n_nodes {
|
||||||
|
result = Some((*i, *j + 1 + *i));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
result
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
const EXAMPLE_INPUT: &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 test_part1() {
|
||||||
|
assert_eq!(part1(EXAMPLE_INPUT), 20);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_part2() {
|
||||||
|
assert_eq!(part2(EXAMPLE_INPUT), 25272);
|
||||||
|
}
|
||||||
|
}
|
||||||
11
src/lib.rs
11
src/lib.rs
@@ -3,12 +3,13 @@ extern crate aoc_runner;
|
|||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate aoc_runner_derive;
|
extern crate aoc_runner_derive;
|
||||||
|
|
||||||
// pub mod day1;
|
pub mod day1;
|
||||||
// pub mod day2;
|
// pub mod day2;
|
||||||
// pub mod day3;
|
pub mod day3;
|
||||||
// pub mod day4;
|
pub mod day4;
|
||||||
// pub mod day5;
|
pub mod day5;
|
||||||
// pub mod day6;
|
pub mod day6;
|
||||||
pub mod day7;
|
pub mod day7;
|
||||||
|
pub mod day8;
|
||||||
|
|
||||||
aoc_lib! { year = 2025 }
|
aoc_lib! { year = 2025 }
|
||||||
|
|||||||
Reference in New Issue
Block a user