Skip to content

Commit 12d1931

Browse files
committed
2025 10.2 | Comically slow
1 parent 197bee4 commit 12d1931

File tree

1 file changed

+108
-9
lines changed

1 file changed

+108
-9
lines changed

src/aoc/y2025/day10.rs

Lines changed: 108 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,46 @@ impl IndicatorState {
6868
}
6969
}
7070

71+
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
72+
struct JoltState([u16; 10]);
73+
74+
impl FromStr for JoltState {
75+
type Err = AoCError;
76+
77+
fn from_str(s: &str) -> Result<Self, Self::Err> {
78+
let mut tmp: Vec<u16> = s.split(',').map(|s| s.parse()).try_collect()?;
79+
match tmp.len().cmp(&10) {
80+
Ordering::Less => {
81+
tmp.extend((0..(10 - tmp.len())).map(|_| 0));
82+
}
83+
Ordering::Equal => (),
84+
Ordering::Greater => {
85+
return Err(AoCError::new(format!("Input string {s} is too long!")));
86+
}
87+
}
88+
Ok(Self(tmp.into_iter().collect_array().unwrap()))
89+
}
90+
}
91+
92+
impl Display for JoltState {
93+
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
94+
write!(f, "{{{}}}", self.0.iter().join(","))
95+
}
96+
}
97+
98+
impl JoltState {
99+
fn be_pushed(mut self, button: &Button) -> Self {
100+
for btn in button.0.iter().copied() {
101+
self.0[btn] += 1;
102+
}
103+
self
104+
}
105+
106+
fn still_valid(&self, target: &Self) -> bool {
107+
std::iter::zip(self.0.iter(), target.0.iter()).all(|(me, them)| me <= them)
108+
}
109+
}
110+
71111
#[derive(Debug)]
72112
struct Button(Vec<usize>);
73113

@@ -94,6 +134,7 @@ impl Display for Button {
94134
#[derive(Debug)]
95135
struct Machine {
96136
target: IndicatorState,
137+
jolt_target: JoltState,
97138
buttons: Vec<Button>,
98139
}
99140

@@ -103,7 +144,7 @@ impl FromStr for Machine {
103144
fn from_str(s: &str) -> Result<Self, Self::Err> {
104145
lazy_static! {
105146
// I swear he intentionally makes these annoying to parse with regex
106-
static ref RE: Regex = Regex::new(r"^\[([#.]+)\] ((?:\([\d,]+\) ?)+) \{[\d,]+\}$").unwrap();
147+
static ref RE: Regex = Regex::new(r"^\[([#.]+)\] ((?:\([\d,]+\) ?)+) \{([\d,]+)\}$").unwrap();
107148
}
108149

109150
let matches = RE
@@ -112,6 +153,7 @@ impl FromStr for Machine {
112153

113154
Ok(Self {
114155
target: matches[1].parse()?,
156+
jolt_target: matches[3].parse()?,
115157
buttons: matches[2]
116158
.split_whitespace()
117159
.map(|s| s.parse())
@@ -124,20 +166,21 @@ impl Display for Machine {
124166
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
125167
write!(
126168
f,
127-
"{} {} {{???}}",
169+
"{} {} {}",
128170
self.target,
129-
self.buttons.iter().join(" ")
171+
self.buttons.iter().join(" "),
172+
self.jolt_target
130173
)
131174
}
132175
}
133176

134-
struct PushResult {
135-
last_button: usize,
136-
state: IndicatorState,
137-
}
138-
139177
impl Machine {
140178
fn part_1(&self) -> usize {
179+
struct PushResult {
180+
last_button: usize,
181+
state: IndicatorState,
182+
}
183+
141184
let current_state: IndicatorState = Default::default();
142185

143186
let mut pushes: Vec<PushResult> = self
@@ -175,6 +218,53 @@ impl Machine {
175218
}
176219
unreachable!();
177220
}
221+
222+
fn part_2(&self) -> usize {
223+
struct PushResult {
224+
last_button: usize,
225+
state: JoltState,
226+
}
227+
228+
let current_state: JoltState = Default::default();
229+
230+
let mut pushes: Vec<PushResult> = self
231+
.buttons
232+
.iter()
233+
.enumerate()
234+
.map(|(i, btn)| PushResult {
235+
last_button: i,
236+
state: current_state.be_pushed(btn),
237+
})
238+
.collect();
239+
240+
for i in 1.. {
241+
if pushes
242+
.iter()
243+
.any(|PushResult { state, .. }| state == &self.jolt_target)
244+
{
245+
return i;
246+
}
247+
248+
assert!(!pushes.is_empty());
249+
250+
// Let's get fucking stupid with it
251+
pushes = pushes
252+
.into_iter()
253+
.flat_map(|PushResult { last_button, state }| {
254+
self.buttons
255+
.iter()
256+
.enumerate()
257+
.filter(move |(i, _)| *i != last_button)
258+
.map(move |(last_button, button)| PushResult {
259+
last_button,
260+
state: state.be_pushed(button),
261+
})
262+
.filter(|push| push.state.still_valid(&self.jolt_target))
263+
})
264+
.collect();
265+
}
266+
unreachable!();
267+
}
178268
}
179269

180270
pub fn part_1(data: crate::DataIn) -> crate::AoCResult<String> {
@@ -189,12 +279,21 @@ pub fn part_1(data: crate::DataIn) -> crate::AoCResult<String> {
189279
Ok(ret.to_string())
190280
}
191281

282+
pub fn part_2(data: crate::DataIn) -> crate::AoCResult<String> {
283+
let machines: Vec<Machine> = data.parse().try_collect()?;
284+
let ret: usize = machines.into_iter().map(|machine| machine.part_2()).sum();
285+
Ok(ret.to_string())
286+
}
287+
192288
inventory::submit!(crate::AoCDay {
193289
year: "2025",
194290
day: "10",
195291
part_1: crate::AoCPart {
196292
main: part_1,
197293
example: part_1
198294
},
199-
part_2: None
295+
part_2: Some(crate::AoCPart {
296+
main: part_2,
297+
example: part_2
298+
})
200299
});

0 commit comments

Comments
 (0)