Implement 2025 - Day 10 - Part 1
This commit is contained in:
133
2025/10.rs
Normal file
133
2025/10.rs
Normal file
@@ -0,0 +1,133 @@
|
||||
---cargo
|
||||
[profile.dev]
|
||||
opt-level = 3
|
||||
---
|
||||
|
||||
use std::collections::{HashMap, hash_map::Entry};
|
||||
|
||||
static CONTENT: &'static str = include_str!("./inputs/10_1.txt");
|
||||
|
||||
#[derive(Debug)]
|
||||
struct Machine {
|
||||
desired_lights: u64,
|
||||
buttons: Vec<u64>,
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let machines: Vec<Machine> = CONTENT.lines()
|
||||
.map(|l| l.trim())
|
||||
.map(|l| {
|
||||
let (lights, rest) = l.split_once(' ').unwrap();
|
||||
let buttons: Vec<_> = rest.split(' ').take_while(|p| p.contains('(')).collect();
|
||||
let joltage = rest.split(' ').skip_while(|p| p.contains('(')).next().unwrap();
|
||||
|
||||
(lights, buttons, joltage)
|
||||
})
|
||||
.map(|(raw_lights, raw_buttons, raw_joltage)| {
|
||||
let raw_lights = raw_lights.strip_prefix('[').unwrap().strip_suffix(']').unwrap();
|
||||
|
||||
let lights = raw_lights.chars().enumerate().map(|(idx, c)| {
|
||||
let v = match c {
|
||||
'.' => 0,
|
||||
'#' => 1,
|
||||
c => unreachable!("{:?}", c),
|
||||
};
|
||||
(idx, v)
|
||||
}).fold(0u64, |acc, (idx, v)| {
|
||||
acc + (v << idx)
|
||||
});
|
||||
|
||||
(lights, raw_buttons, raw_joltage)
|
||||
})
|
||||
.map(|(lights, raw_buttons, raw_joltage)| {
|
||||
let buttons: Vec<_> = raw_buttons.iter().map(|button| {
|
||||
let button = button.strip_prefix('(').unwrap().strip_suffix(')').unwrap();
|
||||
|
||||
let switch: u64 = button.split(',').map(|c| {
|
||||
let v: u64 = c.parse().unwrap();
|
||||
1 << v
|
||||
}).fold(0u64, |acc, v| {
|
||||
acc + v
|
||||
});
|
||||
|
||||
switch
|
||||
}).collect();
|
||||
|
||||
(lights, buttons, raw_joltage)
|
||||
})
|
||||
.map(|(lights, buttons, _)| {
|
||||
Machine {
|
||||
desired_lights: lights,
|
||||
buttons,
|
||||
}
|
||||
})
|
||||
.collect();
|
||||
|
||||
println!("{:#?}", machines);
|
||||
|
||||
let machine_states: Vec<_> = machines.iter().map(|machine| {
|
||||
let mut states: HashMap<u64, Vec<u64>> = HashMap::new();
|
||||
let mut queue = vec![0u64];
|
||||
while let Some(state) = queue.pop() {
|
||||
let new_states: Vec<_> = machine.buttons.iter()
|
||||
.map(|button| {
|
||||
state ^ button
|
||||
}).collect();
|
||||
|
||||
match states.entry(state) {
|
||||
Entry::Occupied(_) => {}
|
||||
Entry::Vacant(ventry) => {
|
||||
let new_states = ventry.insert(new_states);
|
||||
queue.extend(new_states.iter().map(|v| *v));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
states
|
||||
}).collect();
|
||||
|
||||
let distances: Vec<_> = machine_states.iter().map(|states| {
|
||||
let mut distances: HashMap<u64, (Option<u64>, usize)> = states.keys().map(|node| {
|
||||
(*node, (None, usize::MAX))
|
||||
}).collect();
|
||||
let mut q: Vec<u64> = states.keys().copied().collect();
|
||||
distances.insert(0, (None, 0));
|
||||
|
||||
while !q.is_empty() {
|
||||
q.sort_by_key(|n| core::cmp::Reverse(distances.get(n).map(|(_, d)| d).unwrap()));
|
||||
let u = q.pop().unwrap();
|
||||
|
||||
let (_, u_distance) = distances.get(&u).copied().unwrap();
|
||||
|
||||
for neighbour in states.get(&u).unwrap() {
|
||||
if !q.contains(neighbour) {
|
||||
continue;
|
||||
}
|
||||
|
||||
let new_distance = u_distance.saturating_add(1);
|
||||
let (neighbour_prev, neighbour_distance) = distances.get_mut(&neighbour).unwrap();
|
||||
|
||||
if new_distance < *neighbour_distance {
|
||||
*neighbour_prev = Some(u);
|
||||
*neighbour_distance = new_distance;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
distances
|
||||
}).collect();
|
||||
|
||||
let mut total_steps = 0;
|
||||
for ((machine, states), distances) in machines.iter().zip(machine_states.iter()).zip(distances.iter()) {
|
||||
println!("{:#?}", machine);
|
||||
//println!("States:\n{:#?}", states);
|
||||
//println!("Distances: {:#?}", distances);
|
||||
|
||||
let (_, steps) = distances.get(&machine.desired_lights).unwrap();
|
||||
println!("Required Steps: {}", steps);
|
||||
|
||||
total_steps += steps;
|
||||
}
|
||||
|
||||
println!("Required Total Steps: {}", total_steps);
|
||||
}
|
||||
Reference in New Issue
Block a user