Browse Source

Completed day 14

Tyler Hallada 4 years ago
parent
commit
e85f9131be
4 changed files with 259 additions and 7 deletions
  1. 1 0
      inputs/14.txt
  2. 0 2
      src/day13.rs
  3. 249 0
      src/day14.rs
  4. 9 5
      src/main.rs

+ 1 - 0
inputs/14.txt

@@ -0,0 +1 @@
1
+236021

+ 0 - 2
src/day13.rs

@@ -1,5 +1,3 @@
1
-extern crate regex;
2
-
3 1
 use std::collections::{HashMap, HashSet};
4 2
 use std::error::Error;
5 3
 use std::fs;

+ 249 - 0
src/day14.rs

@@ -0,0 +1,249 @@
1
+use std::error::Error;
2
+use std::fmt;
3
+use std::fs;
4
+use std::result;
5
+
6
+type Result<T> = result::Result<T, Box<Error>>;
7
+
8
+const INPUT: &str = "inputs/14.txt";
9
+
10
+#[derive(Debug, PartialEq)]
11
+struct Recipes {
12
+    scores: Vec<u8>,
13
+    elf1_index: usize,
14
+    elf2_index: usize,
15
+}
16
+
17
+impl fmt::Display for Recipes {
18
+    #[allow(clippy::write_with_newline)]
19
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
20
+        for (index, score) in self.scores.iter().enumerate() {
21
+            if index == self.elf1_index {
22
+                write!(f, "({})", score)?;
23
+            } else if index == self.elf2_index {
24
+                write!(f, "[{}]", score)?;
25
+            } else {
26
+                write!(f, " {} ", score)?;
27
+            }
28
+        }
29
+        write!(f, "\n")?;
30
+        Ok(())
31
+    }
32
+}
33
+
34
+impl Recipes {
35
+    fn new() -> Recipes {
36
+        Recipes {
37
+            scores: vec![3, 7],
38
+            elf1_index: 0,
39
+            elf2_index: 1,
40
+        }
41
+    }
42
+
43
+    fn new_recipes(&mut self) {
44
+        let elf1_score = self.scores[self.elf1_index];
45
+        let elf2_score = self.scores[self.elf2_index];
46
+        let sum = elf1_score + elf2_score;
47
+        fn push_digits(n: u8, digits: &mut Vec<u8>) {
48
+            if n >= 10 {
49
+                push_digits(n / 10, digits);
50
+            }
51
+            digits.push(n % 10);
52
+        }
53
+        push_digits(sum, &mut self.scores);
54
+    }
55
+
56
+    fn pick_recipes(&mut self) {
57
+        let elf1_score = self.scores[self.elf1_index];
58
+        let elf2_score = self.scores[self.elf2_index];
59
+        self.elf1_index = (self.elf1_index + (1 + elf1_score as usize)) % self.scores.len();
60
+        self.elf2_index = (self.elf2_index + (1 + elf2_score as usize)) % self.scores.len();
61
+    }
62
+
63
+    fn scores_after_n_recipes(&mut self, n: usize, num_scores: usize) -> String {
64
+        while self.scores.len() < n + num_scores {
65
+            self.new_recipes();
66
+            self.pick_recipes();
67
+        }
68
+        self.scores[n..n + num_scores].iter().map(|score| format!("{}", score)).collect()
69
+    }
70
+
71
+    fn find_index_of_sequence(&mut self, seq: &[u8]) -> usize {
72
+        let seq_len = seq.len();
73
+        loop {
74
+            let scores_len = self.scores.len();
75
+            self.new_recipes();
76
+            self.pick_recipes();
77
+            let new_scores_len = self.scores.len();
78
+            let diff = new_scores_len - scores_len;
79
+            if scores_len >= seq_len {
80
+                for i in 0..diff {
81
+                    let seq_index = scores_len + i - seq_len;
82
+                    if &self.scores[seq_index..(seq_index + seq_len)] == seq {
83
+                        return seq_index;
84
+                    }
85
+                }
86
+            }
87
+        }
88
+    }
89
+}
90
+
91
+fn digit_seq(n: &str) -> Vec<u8> {
92
+    let mut digits: Vec<u8> = vec![];
93
+    for digit in n.chars() {
94
+        digits.push(digit.to_digit(10).unwrap() as u8);
95
+    }
96
+    digits
97
+}
98
+
99
+fn read_input_file(filename: &str) -> Result<usize> {
100
+    let input = fs::read_to_string(filename)?;
101
+    Ok(input.trim().parse()?)
102
+}
103
+
104
+pub fn solve_part1() -> Result<String> {
105
+    let input = read_input_file(INPUT)?;
106
+    let mut recipes = Recipes::new();
107
+    Ok(recipes.scores_after_n_recipes(input, 10))
108
+}
109
+
110
+pub fn solve_part2() -> Result<usize> {
111
+    let input = fs::read_to_string(INPUT)?;
112
+    let mut recipes = Recipes::new();
113
+    let seq = digit_seq(&input.trim());
114
+    Ok(recipes.find_index_of_sequence(&seq[..]))
115
+}
116
+
117
+#[cfg(test)]
118
+mod tests {
119
+    use super::*;
120
+
121
+    #[test]
122
+    fn creates_new_recipes_struct() {
123
+        let recipes = Recipes::new();
124
+        assert_eq!(recipes.scores, vec![3, 7]);
125
+        assert_eq!(recipes.elf1_index, 0);
126
+        assert_eq!(recipes.elf2_index, 1);
127
+    }
128
+
129
+    #[test]
130
+    fn adds_new_recipes() {
131
+        let mut recipes = Recipes::new();
132
+        recipes.new_recipes();
133
+        assert_eq!(recipes.scores, vec![3, 7, 1, 0]);
134
+    }
135
+
136
+    #[test]
137
+    fn picks_new_recipes() {
138
+        let mut recipes = Recipes::new();
139
+        recipes.new_recipes();
140
+        recipes.pick_recipes();
141
+        assert_eq!(recipes.elf1_index, 0);
142
+        assert_eq!(recipes.elf2_index, 1);
143
+    }
144
+
145
+    #[test]
146
+    fn iterates_15_times() {
147
+        let mut recipes = Recipes::new();
148
+        for _ in 0..15 {
149
+            recipes.new_recipes();
150
+            recipes.pick_recipes();
151
+        }
152
+        assert_eq!(
153
+            format!("{}", recipes),
154
+            " 3  7  1  0 [1] 0  1  2 (4) 5  1  5  8  9  1  6  7  7  9  2 \n",
155
+        );
156
+    }
157
+
158
+    #[test]
159
+    fn scores_after_5_recipes() {
160
+        let mut recipes = Recipes::new();
161
+        assert_eq!(
162
+            recipes.scores_after_n_recipes(5, 10),
163
+            "0124515891",
164
+        );
165
+    }
166
+
167
+    #[test]
168
+    fn scores_after_9_recipes() {
169
+        let mut recipes = Recipes::new();
170
+        assert_eq!(
171
+            recipes.scores_after_n_recipes(9, 10),
172
+            "5158916779",
173
+        );
174
+    }
175
+
176
+    #[test]
177
+    fn scores_after_18_recipes() {
178
+        let mut recipes = Recipes::new();
179
+        assert_eq!(
180
+            recipes.scores_after_n_recipes(18, 10),
181
+            "9251071085",
182
+        );
183
+    }
184
+
185
+    #[test]
186
+    fn scores_after_2018_recipes() {
187
+        let mut recipes = Recipes::new();
188
+        assert_eq!(
189
+            recipes.scores_after_n_recipes(2018, 10),
190
+            "5941429882",
191
+        );
192
+    }
193
+
194
+    #[test]
195
+    fn finds_index_of_sequence_1() {
196
+        let mut recipes = Recipes::new();
197
+        let seq = vec![5, 1, 5, 8, 9];
198
+        assert_eq!(
199
+            recipes.find_index_of_sequence(&seq[..]),
200
+            9,
201
+        );
202
+    }
203
+
204
+    #[test]
205
+    fn finds_index_of_sequence_2() {
206
+        let mut recipes = Recipes::new();
207
+        let seq = vec![0, 1, 2, 4, 5];
208
+        assert_eq!(
209
+            recipes.find_index_of_sequence(&seq[..]),
210
+            5,
211
+        );
212
+    }
213
+
214
+    #[test]
215
+    fn finds_index_of_sequence_3() {
216
+        let mut recipes = Recipes::new();
217
+        let seq = vec![9, 2, 5, 1, 0];
218
+        assert_eq!(
219
+            recipes.find_index_of_sequence(&seq[..]),
220
+            18,
221
+        );
222
+    }
223
+
224
+    #[test]
225
+    fn finds_index_of_sequence_4() {
226
+        let mut recipes = Recipes::new();
227
+        let seq = vec![5, 9, 4, 1, 4];
228
+        assert_eq!(
229
+            recipes.find_index_of_sequence(&seq[..]),
230
+            2018,
231
+        );
232
+    }
233
+
234
+    #[test]
235
+    fn gets_digit_seq_1() {
236
+        assert_eq!(
237
+            digit_seq("51589"),
238
+            vec![5, 1, 5, 8, 9],
239
+        );
240
+    }
241
+
242
+    #[test]
243
+    fn gets_digit_seq_2() {
244
+        assert_eq!(
245
+            digit_seq("01245"),
246
+            vec![0, 1, 2, 4, 5],
247
+        );
248
+    }
249
+}

+ 9 - 5
src/main.rs

@@ -16,6 +16,7 @@ mod day10;
16 16
 mod day11;
17 17
 mod day12;
18 18
 mod day13;
19
+mod day14;
19 20
 
20 21
 fn main() {
21 22
     // println!("Day 1:");
@@ -57,9 +58,12 @@ fn main() {
57 58
     // println!("Day 12:");
58 59
     // println!("{}", day12::solve_part1().unwrap());
59 60
     // println!("{}", day12::solve_part2().unwrap());
60
-    println!("Day 13");
61
-    let part1 = day13::solve_part1().unwrap();
62
-    println!("{},{}", part1.x, part1.y);
63
-    let part2 = day13::solve_part2().unwrap();
64
-    println!("{},{}", part2.x, part2.y);
61
+    // println!("Day 13");
62
+    // let part1 = day13::solve_part1().unwrap();
63
+    // println!("{},{}", part1.x, part1.y);
64
+    // println!("{},{}", part2.x, part2.y);
65
+    // let part2 = day13::solve_part2().unwrap();
66
+    println!("Day 14");
67
+    println!("{}", day14::solve_part1().unwrap());
68
+    println!("{}", day14::solve_part2().unwrap());
65 69
 }