mirror of
https://github.com/RussellChamp/advent-of-code-2025-rust.git
synced 2026-10-28 00:22:29 +00:00
solution for day 8
This commit is contained in:
1 parent
4f0f978c07
commit
9f26142331
3 files changed
+165
-1
No files matched your search
@@ -18,8 +18,9 @@ Solutions for [Advent of Code](https://adventofcode.com/) in [Rust](https://www.
|
|||||||
| [Day 5](./src/bin/05.rs) | `159.6µs` | `21.4µs` |
|
| [Day 5](./src/bin/05.rs) | `159.6µs` | `21.4µs` |
|
||||||
| [Day 6](./src/bin/06.rs) | `50.5µs` | `2.5ms` |
|
| [Day 6](./src/bin/06.rs) | `50.5µs` | `2.5ms` |
|
||||||
| [Day 7](./src/bin/07.rs) | `65.4µs` | `55.4µs` |
|
| [Day 7](./src/bin/07.rs) | `65.4µs` | `55.4µs` |
|
||||||
|
| [Day 8](./src/bin/08.rs) | `26.4ms` | `27.6ms` |
|
||||||
|
|
||||||
**Total: 172.62ms**
|
**Total: 226.62ms**
|
||||||
<!--- benchmarking table --->
|
<!--- benchmarking table --->
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|||||||
@@ -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
|
||||||
+143
@@ -0,0 +1,143 @@
|
|||||||
|
advent_of_code::solution!(8);
|
||||||
|
use std::fmt;
|
||||||
|
use itertools::{Itertools};
|
||||||
|
|
||||||
|
#[derive(PartialEq)]
|
||||||
|
#[derive(Clone)]
|
||||||
|
struct Position {
|
||||||
|
pub x: u64,
|
||||||
|
pub y: u64,
|
||||||
|
pub z: u64,
|
||||||
|
}
|
||||||
|
impl fmt::Debug for Position {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
|
write!(f, "({},{},{})", self.x, self.y, self.z)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl fmt::Display for Position {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
|
write!(f, "({},{},{})", self.x, self.y, self.z)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn distance_squared(pos_a: &Position, pos_b: &Position) -> u64 {
|
||||||
|
pos_a.x.abs_diff(pos_b.x).pow(2) + pos_a.y.abs_diff(pos_b.y).pow(2) + pos_a.z.abs_diff(pos_b.z).pow(2)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn part_one(input: &str) -> Option<u64> {
|
||||||
|
part_one_solve(input, 1000)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn part_one_solve(input: &str, max_connections: u32 ) -> Option<u64> {
|
||||||
|
let junctions = input.lines().filter(|l| !l.is_empty()).map(|line| {
|
||||||
|
let (x, y, z) = line.split(',').map(|v| v.parse::<u64>().unwrap()).collect_tuple().unwrap();
|
||||||
|
Position { x, y, z }
|
||||||
|
}).collect_vec();
|
||||||
|
let size = junctions.len();
|
||||||
|
// println!("Junctions: {junctions:?}");
|
||||||
|
let mut distances = vec![];
|
||||||
|
|
||||||
|
for a_idx in 0..size {
|
||||||
|
for b_idx in a_idx+1..size {
|
||||||
|
distances.push((a_idx, b_idx, distance_squared(&junctions[a_idx], &junctions[b_idx])));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
distances.sort_by(|(_, _, a_distance), (_, _, b_distance)| { a_distance.cmp(b_distance) });
|
||||||
|
// println!("Distances: {distances:?}");
|
||||||
|
|
||||||
|
let mut groups = (0..size).map(|idx| vec![idx; 1]).collect_vec();
|
||||||
|
// println!("Groups: {groups:?}");
|
||||||
|
// println!();
|
||||||
|
|
||||||
|
|
||||||
|
let mut connections_made = 0;
|
||||||
|
for (start, end, _distance) in distances {
|
||||||
|
// println!("Considering {} => {}, {} => {} - distance {}", start, end, junctions[start], junctions[end], distance);
|
||||||
|
// if start and end are not already connected
|
||||||
|
let (group_a_idx, group_a) = groups.iter().find_position(|g| g.contains(&start)).unwrap();
|
||||||
|
connections_made += 1;
|
||||||
|
if group_a.contains(&end) {
|
||||||
|
// println!(" Already exists in the same group! skipping");
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
let (group_b_idx, group_b) = groups.iter().find_position(|g| g.contains(&end)).unwrap();
|
||||||
|
groups[group_a_idx] = [group_a.as_slice(), group_b.as_slice()].concat();
|
||||||
|
// group_a.append(&mut group_b);
|
||||||
|
// groups[group_a_idx] = group_a.append(group_b);
|
||||||
|
groups.remove(group_b_idx);
|
||||||
|
// connections_made += 1;
|
||||||
|
|
||||||
|
// println!("Groups after {connections_made} connections: {groups:?}");
|
||||||
|
// println!();
|
||||||
|
|
||||||
|
// connect them by merging their groups
|
||||||
|
// increment connections_made by 1
|
||||||
|
if connections_made >= max_connections { break }
|
||||||
|
}
|
||||||
|
|
||||||
|
// println!("{groups:?}");
|
||||||
|
|
||||||
|
let top3: usize = groups.iter().map(|g| g.len()).sorted().rev().take(3).product();
|
||||||
|
|
||||||
|
// println!("top3 product {top3}");
|
||||||
|
|
||||||
|
Some(top3 as u64)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn part_two(input: &str) -> Option<u64> {
|
||||||
|
let junctions = input.lines().filter(|l| !l.is_empty()).map(|line| {
|
||||||
|
let (x, y, z) = line.split(',').map(|v| v.parse::<u64>().unwrap()).collect_tuple().unwrap();
|
||||||
|
Position { x, y, z }
|
||||||
|
}).collect_vec();
|
||||||
|
let size = junctions.len();
|
||||||
|
let mut distances = vec![];
|
||||||
|
|
||||||
|
for a_idx in 0..size {
|
||||||
|
for b_idx in a_idx+1..size {
|
||||||
|
distances.push((a_idx, b_idx, distance_squared(&junctions[a_idx], &junctions[b_idx])));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
distances.sort_by(|(_, _, a_distance), (_, _, b_distance)| { a_distance.cmp(b_distance) });
|
||||||
|
|
||||||
|
let mut groups = (0..size).map(|idx| vec![idx; 1]).collect_vec();
|
||||||
|
|
||||||
|
|
||||||
|
let mut last_link = (0, 0);
|
||||||
|
for (start, end, _distance) in distances {
|
||||||
|
let (group_a_idx, group_a) = groups.iter().find_position(|g| g.contains(&start)).unwrap();
|
||||||
|
if group_a.contains(&end) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
let (group_b_idx, group_b) = groups.iter().find_position(|g| g.contains(&end)).unwrap();
|
||||||
|
groups[group_a_idx] = [group_a.as_slice(), group_b.as_slice()].concat();
|
||||||
|
groups.remove(group_b_idx);
|
||||||
|
|
||||||
|
if groups.len() == 1 {
|
||||||
|
last_link = (start, end);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let (last_junction_from, last_junction_to) = (&junctions[last_link.0], &junctions[last_link.1]);
|
||||||
|
// println!("Last junction was between {last_junction_from:?} and {last_junction_to:?}");
|
||||||
|
|
||||||
|
Some(last_junction_from.x * last_junction_to.x)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_part_one() {
|
||||||
|
let result = part_one_solve(&advent_of_code::template::read_file("examples", DAY), 10);
|
||||||
|
assert_eq!(result, Some(40));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_part_two() {
|
||||||
|
let result = part_two(&advent_of_code::template::read_file("examples", DAY));
|
||||||
|
assert_eq!(result, Some(25272));
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in new issue
Block a user