Browse Source

Completed day 7 part 1

Tyler Hallada 5 years ago
parent
commit
f4392d62c0
4 changed files with 246 additions and 3 deletions
  1. 101 0
      inputs/7.txt
  2. 7 0
      inputs/7_test.txt
  3. 132 0
      src/day7.rs
  4. 6 3
      src/main.rs

+ 101 - 0
inputs/7.txt

@@ -0,0 +1,101 @@
1
+Step I must be finished before step Q can begin.
2
+Step B must be finished before step O can begin.
3
+Step J must be finished before step M can begin.
4
+Step W must be finished before step Y can begin.
5
+Step U must be finished before step X can begin.
6
+Step T must be finished before step Q can begin.
7
+Step G must be finished before step M can begin.
8
+Step K must be finished before step C can begin.
9
+Step F must be finished before step Z can begin.
10
+Step D must be finished before step A can begin.
11
+Step N must be finished before step Y can begin.
12
+Step Y must be finished before step Q can begin.
13
+Step Q must be finished before step Z can begin.
14
+Step V must be finished before step E can begin.
15
+Step A must be finished before step X can begin.
16
+Step E must be finished before step C can begin.
17
+Step O must be finished before step R can begin.
18
+Step P must be finished before step L can begin.
19
+Step H must be finished before step R can begin.
20
+Step M must be finished before step R can begin.
21
+Step C must be finished before step Z can begin.
22
+Step R must be finished before step L can begin.
23
+Step L must be finished before step S can begin.
24
+Step S must be finished before step X can begin.
25
+Step Z must be finished before step X can begin.
26
+Step T must be finished before step O can begin.
27
+Step D must be finished before step Z can begin.
28
+Step P must be finished before step R can begin.
29
+Step M must be finished before step Z can begin.
30
+Step L must be finished before step Z can begin.
31
+Step W must be finished before step N can begin.
32
+Step Q must be finished before step R can begin.
33
+Step P must be finished before step C can begin.
34
+Step U must be finished before step O can begin.
35
+Step F must be finished before step O can begin.
36
+Step K must be finished before step X can begin.
37
+Step G must be finished before step K can begin.
38
+Step M must be finished before step C can begin.
39
+Step Y must be finished before step Z can begin.
40
+Step A must be finished before step O can begin.
41
+Step D must be finished before step P can begin.
42
+Step K must be finished before step S can begin.
43
+Step I must be finished before step E can begin.
44
+Step G must be finished before step F can begin.
45
+Step S must be finished before step Z can begin.
46
+Step N must be finished before step V can begin.
47
+Step F must be finished before step D can begin.
48
+Step A must be finished before step Z can begin.
49
+Step F must be finished before step X can begin.
50
+Step T must be finished before step Y can begin.
51
+Step W must be finished before step H can begin.
52
+Step D must be finished before step H can begin.
53
+Step W must be finished before step G can begin.
54
+Step J must be finished before step X can begin.
55
+Step T must be finished before step X can begin.
56
+Step U must be finished before step R can begin.
57
+Step O must be finished before step P can begin.
58
+Step L must be finished before step X can begin.
59
+Step I must be finished before step B can begin.
60
+Step M must be finished before step L can begin.
61
+Step C must be finished before step R can begin.
62
+Step R must be finished before step X can begin.
63
+Step F must be finished before step N can begin.
64
+Step V must be finished before step H can begin.
65
+Step K must be finished before step A can begin.
66
+Step W must be finished before step O can begin.
67
+Step U must be finished before step Q can begin.
68
+Step O must be finished before step C can begin.
69
+Step K must be finished before step V can begin.
70
+Step R must be finished before step S can begin.
71
+Step E must be finished before step S can begin.
72
+Step J must be finished before step A can begin.
73
+Step E must be finished before step X can begin.
74
+Step K must be finished before step Y can begin.
75
+Step Y must be finished before step X can begin.
76
+Step P must be finished before step Z can begin.
77
+Step W must be finished before step X can begin.
78
+Step Y must be finished before step A can begin.
79
+Step V must be finished before step X can begin.
80
+Step O must be finished before step M can begin.
81
+Step I must be finished before step J can begin.
82
+Step W must be finished before step L can begin.
83
+Step I must be finished before step G can begin.
84
+Step D must be finished before step O can begin.
85
+Step D must be finished before step N can begin.
86
+Step M must be finished before step X can begin.
87
+Step I must be finished before step R can begin.
88
+Step Y must be finished before step M can begin.
89
+Step F must be finished before step M can begin.
90
+Step U must be finished before step M can begin.
91
+Step Y must be finished before step H can begin.
92
+Step K must be finished before step D can begin.
93
+Step N must be finished before step O can begin.
94
+Step H must be finished before step S can begin.
95
+Step G must be finished before step L can begin.
96
+Step T must be finished before step D can begin.
97
+Step J must be finished before step N can begin.
98
+Step K must be finished before step M can begin.
99
+Step K must be finished before step P can begin.
100
+Step E must be finished before step R can begin.
101
+Step N must be finished before step H can begin.

+ 7 - 0
inputs/7_test.txt

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

+ 132 - 0
src/day7.rs

@@ -0,0 +1,132 @@
1
+extern crate regex;
2
+
3
+use std::error::Error;
4
+use std::fs::File;
5
+use std::io::{BufRead, BufReader};
6
+use std::fmt;
7
+use std::collections::HashMap;
8
+
9
+use regex::{Regex, Captures};
10
+
11
+const INPUT: &str = "inputs/7.txt";
12
+
13
+#[derive(Debug, Clone, PartialEq)]
14
+struct MalformedInstruction {
15
+    details: String
16
+}
17
+
18
+impl MalformedInstruction {
19
+    fn new(msg: &str) -> MalformedInstruction {
20
+        MalformedInstruction{ details: msg.to_string() }
21
+    }
22
+}
23
+
24
+impl fmt::Display for MalformedInstruction {
25
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
26
+        write!(f, "{}", self.details)
27
+    }
28
+}
29
+
30
+impl Error for MalformedInstruction {
31
+    fn description(&self) -> &str {
32
+        &self.details
33
+    }
34
+}
35
+
36
+pub fn solve_part1() -> Result<String, Box<Error>> {
37
+    let mut instructions = read_instructions(INPUT)?;
38
+    Ok(get_step_sequence(&mut instructions))
39
+}
40
+
41
+fn read_instructions(filename: &str) -> Result<HashMap<String, Vec<String>>, Box<Error>> {
42
+    let mut instructions: HashMap<String, Vec<String>> = HashMap::new();
43
+    lazy_static! {
44
+        static ref INSTRUCTION_REGEX: Regex = Regex::new(
45
+            r"Step (?P<dependency>\w) must be finished before step (?P<step>\w) can begin."
46
+        ).unwrap();
47
+    }
48
+    let file = File::open(filename)?;
49
+    for (index, line) in BufReader::new(file).lines().enumerate() {
50
+        match INSTRUCTION_REGEX.captures(&line?) {
51
+            Some(captures) => {
52
+                let step = get_captured_field(&captures, "step")?.parse()?;
53
+                let dependency: String = get_captured_field(&captures, "dependency")?.parse()?;
54
+                instructions.entry(dependency.clone()).or_insert(Vec::new());
55
+                let dependencies = instructions.entry(step).or_insert(Vec::new());
56
+                dependencies.push(dependency);
57
+            },
58
+            None => return Err(Box::new(MalformedInstruction {
59
+                details: "Malformed instruction line, no fields could be found".to_string()
60
+            })),
61
+        };
62
+    }
63
+    Ok(instructions)
64
+}
65
+
66
+fn get_captured_field(captures: &Captures, field: &str) -> Result<String, Box<Error>> {
67
+    match captures.name(field) {
68
+        Some(capture) => Ok(String::from(capture.as_str())),
69
+        None => return Err(Box::new(MalformedInstruction {
70
+            details: format!("Malformed instruction line, field {} could not be found", field)
71
+        }))
72
+    }
73
+}
74
+
75
+fn get_step_sequence(instructions: &mut HashMap<String, Vec<String>>) -> String {
76
+    let mut sequence: Vec<String> = Vec::new();
77
+    loop {
78
+        let mut available: Vec<String> = instructions
79
+            .iter()
80
+            .filter(|(_, dependencies)| dependencies.len() == 0)
81
+            .map(|(step, _)| step.clone())
82
+            .collect();
83
+        if available.len() == 0 { break; }
84
+        available.sort();
85
+        available.reverse();
86
+        let next = available.pop().unwrap();
87
+        instructions.remove(&next);
88
+        for dependencies in instructions.values_mut() {
89
+            match dependencies.iter().position(|d| *d == next) {
90
+                Some(index) => { dependencies.remove(index); },
91
+                None => ()
92
+            }
93
+        }
94
+        sequence.push(next);
95
+    }
96
+    sequence.join("")
97
+}
98
+
99
+#[cfg(test)]
100
+mod tests {
101
+    use super::*;
102
+
103
+    const TEST_INPUT: &str = "inputs/7_test.txt";
104
+
105
+    #[test]
106
+    fn reads_instructions_file() {
107
+        let expected: HashMap<String, Vec<String>> = [
108
+            ("A".to_string(), vec!["C".to_string()]),
109
+            ("F".to_string(), vec!["C".to_string()]),
110
+            ("C".to_string(), vec![]),
111
+            ("B".to_string(), vec!["A".to_string()]),
112
+            ("D".to_string(), vec!["A".to_string()]),
113
+            ("E".to_string(), vec!["B".to_string(), "D".to_string(), "F".to_string()]),
114
+
115
+        ].iter().cloned().collect();
116
+        assert_eq!(read_instructions(TEST_INPUT).unwrap(), expected);
117
+    }
118
+
119
+    #[test]
120
+    fn gets_step_sequence() {
121
+        let mut instructions: HashMap<String, Vec<String>> = [
122
+            ("A".to_string(), vec!["C".to_string()]),
123
+            ("F".to_string(), vec!["C".to_string()]),
124
+            ("C".to_string(), vec![]),
125
+            ("B".to_string(), vec!["A".to_string()]),
126
+            ("D".to_string(), vec!["A".to_string()]),
127
+            ("E".to_string(), vec!["B".to_string(), "D".to_string(), "F".to_string()]),
128
+
129
+        ].iter().cloned().collect();
130
+        assert_eq!(get_step_sequence(&mut instructions), "CABDFE");
131
+    }
132
+}

+ 6 - 3
src/main.rs

@@ -7,6 +7,7 @@ mod day3;
7 7
 mod day4;
8 8
 mod day5;
9 9
 mod day6;
10
+mod day7;
10 11
 
11 12
 fn main() {
12 13
     // println!("Day 1:");
@@ -24,7 +25,9 @@ fn main() {
24 25
     // println!("Day 5:");
25 26
     // println!("{}", day5::solve_part1().unwrap());
26 27
     // println!("{}", day5::solve_part2().unwrap());
27
-    println!("Day 6:");
28
-    println!("{}", day6::solve_part1().unwrap());
29
-    println!("{}", day6::solve_part2().unwrap());
28
+    // println!("Day 6:");
29
+    // println!("{}", day6::solve_part1().unwrap());
30
+    // println!("{}", day6::solve_part2().unwrap());
31
+    println!("Day 7:");
32
+    println!("{}", day7::solve_part1().unwrap());
30 33
 }