Skip to content

Commit bf0a82f

Browse files
committed
perf: use stack-based approach
1 parent 388ba88 commit bf0a82f

File tree

1 file changed

+27
-35
lines changed

1 file changed

+27
-35
lines changed

day3/src/main.rs

Lines changed: 27 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -2,48 +2,39 @@ use aoc_derive::aoc_main;
22
use itertools::Itertools;
33
use utils::*;
44

5-
fn find_best(numbers: &[usize], cur: usize, depth: u32, max: usize) -> Option<usize> {
6-
if depth == 12 {
7-
return Some(cur);
8-
}
9-
10-
if numbers.is_empty() || cur + 10_usize.pow(12 - depth) < max {
11-
return None;
12-
}
13-
14-
let skip_result = find_best(&numbers[1..], cur, depth, max);
15-
16-
let no_skip_result = find_best(
17-
&numbers[1..],
18-
cur + 10_usize.pow(12 - depth - 1) * numbers[0],
19-
depth + 1,
20-
skip_result.unwrap_or(max),
21-
);
22-
23-
skip_result.max(no_skip_result)
5+
fn find_joltage(bank: &[usize], num_digits: usize) -> usize {
6+
bank.iter()
7+
.enumerate()
8+
.fold(Vec::with_capacity(num_digits), |mut stack, (pos, &battery)| {
9+
let remaining = bank.len() - pos - 1;
10+
11+
while let Some(&back) = stack.last()
12+
&& battery > back
13+
&& stack.len() + remaining >= num_digits
14+
{
15+
stack.pop();
16+
}
17+
if stack.len() < num_digits {
18+
stack.push(battery);
19+
}
20+
stack
21+
})
22+
.into_iter()
23+
.rev()
24+
.enumerate()
25+
.fold(0, |acc, (i, n)| acc + n * 10_usize.pow(i as u32))
2426
}
2527

2628
#[aoc_main]
2729
fn solve(input: Input) -> impl Into<Solution> {
2830
let banks = input
2931
.lines()
30-
.map(|line| line.chars().map(|c| c.to_digit(10).unwrap() as usize).collect_vec())
31-
.collect_vec();
32-
33-
let part1 = banks
34-
.iter()
35-
.map(|bank| {
36-
bank.iter()
37-
.enumerate()
38-
.flat_map(|(i, n1)| bank.iter().skip(i + 1).map(move |n2| 10 * n1 + n2))
39-
.max()
40-
.unwrap()
41-
})
42-
.sum_usize();
32+
.map(|line| line.chars().map(|c| c.to_digit(10).unwrap() as usize).collect_vec());
4333

44-
let part2 = banks.iter().map(|bank| find_best(bank, 0, 0, 0).unwrap()).sum_usize();
45-
46-
(part1, part2)
34+
(
35+
banks.clone().map(|bank| find_joltage(&bank, 2)).sum_usize(),
36+
banks.map(|bank| find_joltage(&bank, 12)).sum_usize(),
37+
)
4738
}
4839

4940
#[cfg(test)]
@@ -52,6 +43,7 @@ mod tests {
5243
#[test]
5344
fn test_examples() {
5445
use utils::assert_example;
46+
5547
assert_example!(
5648
r#"987654321111111
5749
811111111111119

0 commit comments

Comments
 (0)