[2018][rust][07] refactor

sorbet
Alpha Chen 6 years ago
parent 7d0de7aa2b
commit 7e3f8f8b10

@ -1,6 +1,7 @@
use std::collections::{HashMap, HashSet}; use std::collections::{HashMap, HashSet};
use std::error::Error; use std::error::Error;
use std::io::{self, Read}; use std::io::{self, Read};
use std::str::FromStr;
use regex::Regex; use regex::Regex;
@ -15,27 +16,16 @@ fn main() -> Result<(), Box<Error>> {
} }
fn solve(input: &str) -> Result<String, Box<Error>> { fn solve(input: &str) -> Result<String, Box<Error>> {
let re = Regex::new(r"^Step (\w).*step (\w)").unwrap(); let instructions: Instructions = input.parse()?;
let output = part_one(instructions).iter().map(char::to_string).collect();
let mut steps = HashMap::new(); Ok(output)
input }
.trim()
.lines() #[allow(dead_code)]
.flat_map(|x| re.captures(x)) fn part_one(instructions: Instructions) -> Vec<char> {
.map(|x| { let mut steps = instructions.steps;
x.iter()
.flat_map(|x| x)
.map(|x| x.as_str())
.collect::<Vec<_>>()
})
.map(|x| (x[1], x[2]))
.for_each(|(x, y)| {
steps.entry(x).or_insert_with(HashSet::new);
let entry = steps.entry(y).or_insert_with(HashSet::new);
entry.insert(x);
});
let mut output = String::new(); let mut output = Vec::new();
while !steps.is_empty() { while !steps.is_empty() {
let mut ready: Vec<_> = steps let mut ready: Vec<_> = steps
.iter() .iter()
@ -43,21 +33,21 @@ fn solve(input: &str) -> Result<String, Box<Error>> {
.map(|(k, _)| k) .map(|(k, _)| k)
.collect(); .collect();
ready.sort(); ready.sort();
let done = ready[0].clone(); let done = *ready[0];
steps.remove(done); steps.remove(&done);
for dependencies in steps.values_mut() { for dependencies in steps.values_mut() {
dependencies.remove(done); dependencies.remove(&done);
} }
output.push_str(done); output.push(done);
} }
Ok(output) output
} }
#[test] #[test]
fn test_solve() { fn test_part_one() {
let input = r" let input = r"
Step C must be finished before step A can begin. Step C must be finished before step A can begin.
Step C must be finished before step F can begin. Step C must be finished before step F can begin.
@ -68,6 +58,39 @@ 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 output = solve(input).unwrap(); let instructions: Instructions = input.parse().unwrap();
assert_eq!(output, "CABDFE".to_string()); let output = part_one(instructions);
assert_eq!(output, vec!['C', 'A', 'B', 'D', 'F', 'E']);
}
struct Instructions {
steps: HashMap<char, HashSet<char>>,
}
impl FromStr for Instructions {
type Err = Box<Error>;
fn from_str(s: &str) -> Result<Self, Self::Err> {
let re = Regex::new(r"^Step (\w).*step (\w)").unwrap();
let mut steps = HashMap::new();
s
.trim()
.lines()
.flat_map(|x| re.captures(x))
.map(|x| {
x.iter()
.flat_map(|x| x)
.map(|x| x.as_str().chars().next().unwrap())
.collect::<Vec<_>>()
})
.map(|x| (x[1], x[2]))
.for_each(|(x, y)| {
steps.entry(x).or_insert_with(HashSet::new);
let entry = steps.entry(y).or_insert_with(HashSet::new);
entry.insert(x);
});
Ok(Instructions{steps})
}
} }

Loading…
Cancel
Save