summary refs log tree commit diff homepage
diff options
context:
space:
mode:
authorJune McEnroe <programble@gmail.com>2016-12-17 00:56:37 -0500
committerJune McEnroe <programble@gmail.com>2016-12-17 00:56:37 -0500
commitb7f61ff132f8bdb7e77ca5fd3f8757e15a34101c (patch)
tree628687634efe6ad75bccd853543d68fe5ad30868
parentDay 14 part 2 (diff)
downloadaoc-b7f61ff132f8bdb7e77ca5fd3f8757e15a34101c.tar.gz
aoc-b7f61ff132f8bdb7e77ca5fd3f8757e15a34101c.zip
Day 15
-rw-r--r--input/day15.txt6
-rw-r--r--src/bin/day15.rs91
2 files changed, 97 insertions, 0 deletions
diff --git a/input/day15.txt b/input/day15.txt
new file mode 100644
index 0000000..396cee2
--- /dev/null
+++ b/input/day15.txt
@@ -0,0 +1,6 @@
+Disc #1 has 13 positions; at time=0, it is at position 10.
+Disc #2 has 17 positions; at time=0, it is at position 15.
+Disc #3 has 19 positions; at time=0, it is at position 17.
+Disc #4 has 7 positions; at time=0, it is at position 1.
+Disc #5 has 5 positions; at time=0, it is at position 0.
+Disc #6 has 3 positions; at time=0, it is at position 1.
diff --git a/src/bin/day15.rs b/src/bin/day15.rs
new file mode 100644
index 0000000..c7006eb
--- /dev/null
+++ b/src/bin/day15.rs
@@ -0,0 +1,91 @@
+use std::io::{self, Read};
+
+#[derive(Clone, Copy)]
+struct Disc {
+    positions: u32,
+    position: u32,
+}
+
+impl Disc {
+    fn rotate(&mut self) {
+        self.position = (self.position + 1) % self.positions;
+    }
+
+    fn is_open(&self) -> bool {
+        self.position == 0
+    }
+}
+
+impl<'a> From<&'a str> for Disc {
+    fn from(s: &'a str) -> Disc {
+        let mut iter = s.trim_right_matches('.').split_whitespace();
+        Disc {
+            positions: iter.nth(3).unwrap().parse().unwrap(),
+            position: iter.last().unwrap().parse().unwrap(),
+        }
+    }
+}
+
+#[derive(Clone)]
+struct Sculpture {
+    discs: Vec<Disc>,
+    time: u32,
+    capsule: usize,
+}
+
+impl Sculpture {
+    fn tick(&mut self) {
+        self.time += 1;
+        for disc in &mut self.discs {
+            disc.rotate()
+        }
+    }
+
+    fn drop_capsule(&mut self) -> bool {
+        while self.capsule < self.discs.len() {
+            self.tick();
+            if self.discs[self.capsule].is_open() {
+                self.capsule += 1;
+            } else {
+                return false;
+            }
+        }
+        true
+    }
+}
+
+impl<'a> From<&'a str> for Sculpture {
+    fn from(s: &'a str) -> Sculpture {
+        Sculpture {
+            discs: s.lines().map(Disc::from).collect(),
+            time: 0,
+            capsule: 0,
+        }
+    }
+}
+
+fn solve(input: &str) -> u32 {
+    let mut sculpture = Sculpture::from(input);
+    loop {
+        if sculpture.clone().drop_capsule() {
+            return sculpture.time;
+        }
+        sculpture.tick();
+    }
+}
+
+fn main() {
+    let mut input = String::new();
+    io::stdin().read_to_string(&mut input).unwrap();
+
+    println!("Part 1: {}", solve(&input));
+}
+
+#[test]
+fn part1() {
+    let input = "
+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.
+";
+    assert_eq!(5, solve(input.trim()));
+}