[2018][rust][07] refactoring

sorbet
Alpha Chen 6 years ago
parent 7e3f8f8b10
commit c807f716da

@ -16,29 +16,22 @@ fn main() -> Result<(), Box<Error>> {
} }
fn solve(input: &str) -> Result<String, Box<Error>> { fn solve(input: &str) -> Result<String, Box<Error>> {
let instructions: Instructions = input.parse()?; let mut assembly: Assembly = input.parse()?;
let output = part_one(instructions).iter().map(char::to_string).collect(); let output = part_one(&mut assembly).iter().map(char::to_string).collect();
Ok(output) Ok(output)
} }
#[allow(dead_code)] fn part_two<F: Fn(char) -> usize>(assembly: Assembly, worker_count: usize, step_time: F) {}
fn part_one(instructions: Instructions) -> Vec<char> {
let mut steps = instructions.steps;
#[allow(dead_code)]
fn part_one(assembly: &mut Assembly) -> Vec<char> {
let mut output = Vec::new(); let mut output = Vec::new();
while !steps.is_empty() { while !assembly.is_done() {
let mut ready: Vec<_> = steps let mut available = assembly.available_steps();
.iter() available.sort();
.filter(|(_, v)| v.is_empty()) let done = *available[0];
.map(|(k, _)| k)
.collect();
ready.sort();
let done = *ready[0];
steps.remove(&done); assembly.finish(&done);
for dependencies in steps.values_mut() {
dependencies.remove(&done);
}
output.push(done); output.push(done);
} }
@ -58,24 +51,44 @@ Step D must be finished before step E can begin.
Step F must be finished before step E can begin. Step F must be finished before step E can begin.
"; ";
let instructions: Instructions = input.parse().unwrap(); let mut assembly: Assembly = input.parse().unwrap();
let output = part_one(instructions); let output = part_one(&mut assembly);
assert_eq!(output, vec!['C', 'A', 'B', 'D', 'F', 'E']); assert_eq!(output, vec!['C', 'A', 'B', 'D', 'F', 'E']);
} }
struct Instructions { struct Assembly {
steps: HashMap<char, HashSet<char>>, steps: HashMap<char, HashSet<char>>,
} }
impl FromStr for Instructions { impl Assembly {
fn is_done(&self) -> bool {
self.steps.is_empty()
}
fn available_steps(&self) -> Vec<&char> {
self.steps
.iter()
.filter(|(_, v)| v.is_empty())
.map(|(k, _)| k)
.collect()
}
fn finish(&mut self, step: &char) {
self.steps.remove(step);
for dependencies in self.steps.values_mut() {
dependencies.remove(step);
}
}
}
impl FromStr for Assembly {
type Err = Box<Error>; type Err = Box<Error>;
fn from_str(s: &str) -> Result<Self, Self::Err> { fn from_str(s: &str) -> Result<Self, Self::Err> {
let re = Regex::new(r"^Step (\w).*step (\w)").unwrap(); let re = Regex::new(r"^Step (\w).*step (\w)").unwrap();
let mut steps = HashMap::new(); let mut steps = HashMap::new();
s s.trim()
.trim()
.lines() .lines()
.flat_map(|x| re.captures(x)) .flat_map(|x| re.captures(x))
.map(|x| { .map(|x| {
@ -84,13 +97,13 @@ impl FromStr for Instructions {
.map(|x| x.as_str().chars().next().unwrap()) .map(|x| x.as_str().chars().next().unwrap())
.collect::<Vec<_>>() .collect::<Vec<_>>()
}) })
.map(|x| (x[1], x[2])) .map(|x| (x[1], x[2]))
.for_each(|(x, y)| { .for_each(|(x, y)| {
steps.entry(x).or_insert_with(HashSet::new); steps.entry(x).or_insert_with(HashSet::new);
let entry = steps.entry(y).or_insert_with(HashSet::new); let entry = steps.entry(y).or_insert_with(HashSet::new);
entry.insert(x); entry.insert(x);
}); });
Ok(Instructions{steps}) Ok(Assembly { steps })
} }
} }

Loading…
Cancel
Save