Skip to content

Commit bb2e61d

Browse files
committed
feat(2018): refactor days 7-12 to use aoc-rust-common
1 parent 0225609 commit bb2e61d

2 files changed

Lines changed: 33 additions & 6 deletions

File tree

2018/src/day07/mod.rs

Lines changed: 33 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,32 @@
11
use aoc_rust_common::Solution;
22
use std::fmt::Display;
33
use std::collections::{HashMap, HashSet};
4-
use serde_scan::scan;
4+
use nom::{
5+
bytes::complete::tag,
6+
character::complete::anychar,
7+
sequence::{preceded, separated_pair},
8+
IResult,
9+
};
510

611
pub struct Day07;
712

813
type Step = char;
914

15+
fn parse_dependency(input: &str) -> IResult<&str, (Step, Step)> {
16+
let (input, _) = tag("Step ")(input)?;
17+
let (input, req) = anychar(input)?;
18+
let (input, _) = tag(" must be finished before step ")(input)?;
19+
let (input, step) = anychar(input)?;
20+
let (input, _) = tag(" can begin.")(input)?;
21+
Ok((input, (req, step)))
22+
}
23+
1024
fn get_deps(input: &str) -> (HashSet<Step>, HashMap<Step, HashSet<Step>>) {
1125
let mut all_steps = HashSet::new();
1226
let mut requirements: HashMap<Step, HashSet<Step>> = HashMap::new();
1327

1428
for line in input.lines() {
15-
let (req, step): (Step, Step) = scan!("Step {} must be finished before step {} can begin." <- line).unwrap();
29+
let (_, (req, step)) = parse_dependency(line).unwrap();
1630
all_steps.insert(req);
1731
all_steps.insert(step);
1832
requirements.entry(step).or_default().insert(req);
@@ -39,6 +53,8 @@ impl Solution for Day07 {
3953
if let Some(next_step) = available.first() {
4054
ordered.push(*next_step);
4155
done.insert(*next_step);
56+
} else {
57+
break; // No available steps
4258
}
4359
}
4460
Box::new(ordered)
@@ -56,7 +72,7 @@ impl Solution for Day07 {
5672
.filter(|s| !done.contains(s) && !workers.iter().any(|&(_, w)| w == **s))
5773
.filter(|s| requirements.get(s).map_or(true, |reqs| reqs.is_subset(&done)))
5874
.copied().collect();
59-
available.sort_unstable();
75+
available.sort_unstable_by(|a, b| b.cmp(a)); // So we can pop from the end
6076

6177
for (time_free, step) in workers.iter_mut().filter(|(tf, _)| *tf <= time) {
6278
if *step != '.' { done.insert(*step); }
@@ -66,8 +82,20 @@ impl Solution for Day07 {
6682
*time_free = time + base_duration + (next_step as u32 - 'A' as u32 + 1);
6783
}
6884
}
69-
time = workers.iter().filter(|&&(_, s)| s != '.').map(|(tf, _)| *tf).min().unwrap_or(time);
85+
86+
let next_event_time = workers.iter().filter(|&&(_, s)| s != '.').map(|(tf, _)| *tf).min();
87+
if let Some(t) = next_event_time {
88+
time = t;
89+
} else if !available.is_empty() {
90+
// All workers are idle, but there are still steps to do. This can happen if we are waiting for a dependency.
91+
// In this case, we need to advance time.
92+
time += 1;
93+
} else if done.len() == all_steps.len() {
94+
break;
95+
}
7096
}
71-
Box::new(time)
97+
98+
let final_time = workers.iter().map(|(tf, _)| *tf).max().unwrap_or(time);
99+
Box::new(final_time)
72100
}
73101
}

2018/src/day12/mod.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,6 @@ fn run_simulation(initial_state: Vec<bool>, rules: [bool; 32], generations: i64)
4949
let mut zero_offset = 0i64;
5050

5151
for _ in 0..generations {
52-
let first_plant = state.iter().position(|&p| p).unwrap_or(0);
5352
let last_plant = state.iter().rposition(|&p| p).unwrap_or(0);
5453

5554
let mut next_state = Vec::new();

0 commit comments

Comments
 (0)