summaryrefslogtreecommitdiff
path: root/d15/src/main.rs
diff options
context:
space:
mode:
Diffstat (limited to 'd15/src/main.rs')
-rw-r--r--d15/src/main.rs71
1 files changed, 71 insertions, 0 deletions
diff --git a/d15/src/main.rs b/d15/src/main.rs
new file mode 100644
index 0000000..be1ce8f
--- /dev/null
+++ b/d15/src/main.rs
@@ -0,0 +1,71 @@
+use std::fs;
+
+#[derive(Clone, Debug)]
+struct Disc {
+ pos: usize,
+ period: usize,
+}
+
+fn parse(lines: Vec<&str>) -> Vec<Disc> {
+ let mut result = Vec::new();
+ // Add a dummy 0th disc for slightly cleaner code later
+ result.push(Disc { pos: 0, period: 1 });
+
+ for line in lines {
+ let words: Vec<&str> = line.split_ascii_whitespace().collect();
+ result.push(Disc {
+ pos: words[11].trim_end_matches('.').parse().unwrap(),
+ period: words[3].parse().unwrap(),
+ });
+ }
+
+ result
+}
+
+fn solve_puzzle(discs: &Vec<Disc>) -> usize {
+ let mut t_start = 0;
+
+ 'outer: loop {
+ let mut dt = 1;
+ while dt < discs.len() {
+ // Calculate the disc's current position. If 0, the capsule
+ // can continue, otherwise this `t_start' must be rejected.
+ if (discs[dt].pos + t_start + dt) % discs[dt].period != 0 {
+ t_start += 1;
+ continue 'outer;
+ }
+ dt += 1;
+ }
+
+ return t_start;
+ }
+}
+
+fn main() {
+ // Read disc stats from input text file
+ let input = fs::read_to_string("input.txt").unwrap();
+ let lines = input.lines().collect();
+ let mut discs = parse(lines);
+
+ // Part 1 gives 203660 for me
+ println!("Part 1 solution: {}", solve_puzzle(&discs));
+
+ discs.push(Disc { pos: 0, period: 11 });
+ // Part 2 gives 2408135 for me
+ println!("Part 2 solution: {}", solve_puzzle(&discs));
+}
+
+#[cfg(test)]
+mod tests {
+ use super::*;
+
+ #[test]
+ fn part1_example1() {
+ let lines = vec![
+ "Disc #1 has 5 positions; at time=0, it is at position 4.",
+ "Disc #2 has 2 positions; at time=0, it is at position 1.",
+ ];
+ let discs = parse(lines);
+ assert_eq!(solve_puzzle(&discs), 5);
+ }
+}