Completed day 7 part 1

This commit is contained in:
Tyler Hallada 2019-01-02 01:32:44 -05:00
parent e3ab089ce3
commit f4392d62c0
4 changed files with 246 additions and 3 deletions

101
inputs/7.txt Executable file
View File

@ -0,0 +1,101 @@
Step I must be finished before step Q can begin.
Step B must be finished before step O can begin.
Step J must be finished before step M can begin.
Step W must be finished before step Y can begin.
Step U must be finished before step X can begin.
Step T must be finished before step Q can begin.
Step G must be finished before step M can begin.
Step K must be finished before step C can begin.
Step F must be finished before step Z can begin.
Step D must be finished before step A can begin.
Step N must be finished before step Y can begin.
Step Y must be finished before step Q can begin.
Step Q must be finished before step Z can begin.
Step V must be finished before step E can begin.
Step A must be finished before step X can begin.
Step E must be finished before step C can begin.
Step O must be finished before step R can begin.
Step P must be finished before step L can begin.
Step H must be finished before step R can begin.
Step M must be finished before step R can begin.
Step C must be finished before step Z can begin.
Step R must be finished before step L can begin.
Step L must be finished before step S can begin.
Step S must be finished before step X can begin.
Step Z must be finished before step X can begin.
Step T must be finished before step O can begin.
Step D must be finished before step Z can begin.
Step P must be finished before step R can begin.
Step M must be finished before step Z can begin.
Step L must be finished before step Z can begin.
Step W must be finished before step N can begin.
Step Q must be finished before step R can begin.
Step P must be finished before step C can begin.
Step U must be finished before step O can begin.
Step F must be finished before step O can begin.
Step K must be finished before step X can begin.
Step G must be finished before step K can begin.
Step M must be finished before step C can begin.
Step Y must be finished before step Z can begin.
Step A must be finished before step O can begin.
Step D must be finished before step P can begin.
Step K must be finished before step S can begin.
Step I must be finished before step E can begin.
Step G must be finished before step F can begin.
Step S must be finished before step Z can begin.
Step N must be finished before step V can begin.
Step F must be finished before step D can begin.
Step A must be finished before step Z can begin.
Step F must be finished before step X can begin.
Step T must be finished before step Y can begin.
Step W must be finished before step H can begin.
Step D must be finished before step H can begin.
Step W must be finished before step G can begin.
Step J must be finished before step X can begin.
Step T must be finished before step X can begin.
Step U must be finished before step R can begin.
Step O must be finished before step P can begin.
Step L must be finished before step X can begin.
Step I must be finished before step B can begin.
Step M must be finished before step L can begin.
Step C must be finished before step R can begin.
Step R must be finished before step X can begin.
Step F must be finished before step N can begin.
Step V must be finished before step H can begin.
Step K must be finished before step A can begin.
Step W must be finished before step O can begin.
Step U must be finished before step Q can begin.
Step O must be finished before step C can begin.
Step K must be finished before step V can begin.
Step R must be finished before step S can begin.
Step E must be finished before step S can begin.
Step J must be finished before step A can begin.
Step E must be finished before step X can begin.
Step K must be finished before step Y can begin.
Step Y must be finished before step X can begin.
Step P must be finished before step Z can begin.
Step W must be finished before step X can begin.
Step Y must be finished before step A can begin.
Step V must be finished before step X can begin.
Step O must be finished before step M can begin.
Step I must be finished before step J can begin.
Step W must be finished before step L can begin.
Step I must be finished before step G can begin.
Step D must be finished before step O can begin.
Step D must be finished before step N can begin.
Step M must be finished before step X can begin.
Step I must be finished before step R can begin.
Step Y must be finished before step M can begin.
Step F must be finished before step M can begin.
Step U must be finished before step M can begin.
Step Y must be finished before step H can begin.
Step K must be finished before step D can begin.
Step N must be finished before step O can begin.
Step H must be finished before step S can begin.
Step G must be finished before step L can begin.
Step T must be finished before step D can begin.
Step J must be finished before step N can begin.
Step K must be finished before step M can begin.
Step K must be finished before step P can begin.
Step E must be finished before step R can begin.
Step N must be finished before step H can begin.

7
inputs/7_test.txt Normal file
View File

@ -0,0 +1,7 @@
Step C must be finished before step A can begin.
Step C must be finished before step F can begin.
Step A must be finished before step B can begin.
Step A must be finished before step D can begin.
Step B must be finished before step E can begin.
Step D must be finished before step E can begin.
Step F must be finished before step E can begin.

132
src/day7.rs Normal file
View File

@ -0,0 +1,132 @@
extern crate regex;
use std::error::Error;
use std::fs::File;
use std::io::{BufRead, BufReader};
use std::fmt;
use std::collections::HashMap;
use regex::{Regex, Captures};
const INPUT: &str = "inputs/7.txt";
#[derive(Debug, Clone, PartialEq)]
struct MalformedInstruction {
details: String
}
impl MalformedInstruction {
fn new(msg: &str) -> MalformedInstruction {
MalformedInstruction{ details: msg.to_string() }
}
}
impl fmt::Display for MalformedInstruction {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}", self.details)
}
}
impl Error for MalformedInstruction {
fn description(&self) -> &str {
&self.details
}
}
pub fn solve_part1() -> Result<String, Box<Error>> {
let mut instructions = read_instructions(INPUT)?;
Ok(get_step_sequence(&mut instructions))
}
fn read_instructions(filename: &str) -> Result<HashMap<String, Vec<String>>, Box<Error>> {
let mut instructions: HashMap<String, Vec<String>> = HashMap::new();
lazy_static! {
static ref INSTRUCTION_REGEX: Regex = Regex::new(
r"Step (?P<dependency>\w) must be finished before step (?P<step>\w) can begin."
).unwrap();
}
let file = File::open(filename)?;
for (index, line) in BufReader::new(file).lines().enumerate() {
match INSTRUCTION_REGEX.captures(&line?) {
Some(captures) => {
let step = get_captured_field(&captures, "step")?.parse()?;
let dependency: String = get_captured_field(&captures, "dependency")?.parse()?;
instructions.entry(dependency.clone()).or_insert(Vec::new());
let dependencies = instructions.entry(step).or_insert(Vec::new());
dependencies.push(dependency);
},
None => return Err(Box::new(MalformedInstruction {
details: "Malformed instruction line, no fields could be found".to_string()
})),
};
}
Ok(instructions)
}
fn get_captured_field(captures: &Captures, field: &str) -> Result<String, Box<Error>> {
match captures.name(field) {
Some(capture) => Ok(String::from(capture.as_str())),
None => return Err(Box::new(MalformedInstruction {
details: format!("Malformed instruction line, field {} could not be found", field)
}))
}
}
fn get_step_sequence(instructions: &mut HashMap<String, Vec<String>>) -> String {
let mut sequence: Vec<String> = Vec::new();
loop {
let mut available: Vec<String> = instructions
.iter()
.filter(|(_, dependencies)| dependencies.len() == 0)
.map(|(step, _)| step.clone())
.collect();
if available.len() == 0 { break; }
available.sort();
available.reverse();
let next = available.pop().unwrap();
instructions.remove(&next);
for dependencies in instructions.values_mut() {
match dependencies.iter().position(|d| *d == next) {
Some(index) => { dependencies.remove(index); },
None => ()
}
}
sequence.push(next);
}
sequence.join("")
}
#[cfg(test)]
mod tests {
use super::*;
const TEST_INPUT: &str = "inputs/7_test.txt";
#[test]
fn reads_instructions_file() {
let expected: HashMap<String, Vec<String>> = [
("A".to_string(), vec!["C".to_string()]),
("F".to_string(), vec!["C".to_string()]),
("C".to_string(), vec![]),
("B".to_string(), vec!["A".to_string()]),
("D".to_string(), vec!["A".to_string()]),
("E".to_string(), vec!["B".to_string(), "D".to_string(), "F".to_string()]),
].iter().cloned().collect();
assert_eq!(read_instructions(TEST_INPUT).unwrap(), expected);
}
#[test]
fn gets_step_sequence() {
let mut instructions: HashMap<String, Vec<String>> = [
("A".to_string(), vec!["C".to_string()]),
("F".to_string(), vec!["C".to_string()]),
("C".to_string(), vec![]),
("B".to_string(), vec!["A".to_string()]),
("D".to_string(), vec!["A".to_string()]),
("E".to_string(), vec!["B".to_string(), "D".to_string(), "F".to_string()]),
].iter().cloned().collect();
assert_eq!(get_step_sequence(&mut instructions), "CABDFE");
}
}

View File

@ -7,6 +7,7 @@ mod day3;
mod day4; mod day4;
mod day5; mod day5;
mod day6; mod day6;
mod day7;
fn main() { fn main() {
// println!("Day 1:"); // println!("Day 1:");
@ -24,7 +25,9 @@ fn main() {
// println!("Day 5:"); // println!("Day 5:");
// println!("{}", day5::solve_part1().unwrap()); // println!("{}", day5::solve_part1().unwrap());
// println!("{}", day5::solve_part2().unwrap()); // println!("{}", day5::solve_part2().unwrap());
println!("Day 6:"); // println!("Day 6:");
println!("{}", day6::solve_part1().unwrap()); // println!("{}", day6::solve_part1().unwrap());
println!("{}", day6::solve_part2().unwrap()); // println!("{}", day6::solve_part2().unwrap());
println!("Day 7:");
println!("{}", day7::solve_part1().unwrap());
} }