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)]
|
||||
struct UintInclusiveRange {
|
||||
@@ -18,29 +18,29 @@ impl UintInclusiveRange {
|
||||
value >= self.start && value <= self.end
|
||||
}
|
||||
|
||||
fn overlaps(&self, other: &UintInclusiveRange) -> bool {
|
||||
(self.start >= other.start && self.start <= 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)
|
||||
}
|
||||
// fn overlaps(&self, other: &UintInclusiveRange) -> bool {
|
||||
// (self.start >= other.start && self.start <= 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)
|
||||
// }
|
||||
|
||||
fn join(&self, other: &UintInclusiveRange) -> UintInclusiveRange {
|
||||
println!(
|
||||
"Joining {:?} and {:?} into {:?}",
|
||||
self,
|
||||
other,
|
||||
UintInclusiveRange::new(
|
||||
cmp::min(self.start, other.start),
|
||||
cmp::max(self.end, other.end),
|
||||
)
|
||||
);
|
||||
assert!(self.overlaps(&other));
|
||||
UintInclusiveRange::new(
|
||||
cmp::min(self.start, other.start),
|
||||
cmp::max(self.end, other.end),
|
||||
)
|
||||
}
|
||||
// fn join(&self, other: &UintInclusiveRange) -> UintInclusiveRange {
|
||||
// println!(
|
||||
// "Joining {:?} and {:?} into {:?}",
|
||||
// self,
|
||||
// other,
|
||||
// UintInclusiveRange::new(
|
||||
// cmp::min(self.start, other.start),
|
||||
// cmp::max(self.end, other.end),
|
||||
// )
|
||||
// );
|
||||
// assert!(self.overlaps(&other));
|
||||
// UintInclusiveRange::new(
|
||||
// cmp::min(self.start, other.start),
|
||||
// cmp::max(self.end, other.end),
|
||||
// )
|
||||
// }
|
||||
|
||||
fn size(self) -> u64 {
|
||||
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]
|
||||
extern crate aoc_runner_derive;
|
||||
|
||||
// pub mod day1;
|
||||
pub mod day1;
|
||||
// pub mod day2;
|
||||
// pub mod day3;
|
||||
// pub mod day4;
|
||||
// pub mod day5;
|
||||
// pub mod day6;
|
||||
pub mod day3;
|
||||
pub mod day4;
|
||||
pub mod day5;
|
||||
pub mod day6;
|
||||
pub mod day7;
|
||||
pub mod day8;
|
||||
|
||||
aoc_lib! { year = 2025 }
|
||||
|
||||
Reference in New Issue
Block a user