summary refs log tree commit diff homepage
diff options
context:
space:
mode:
-rw-r--r--input/day08.txt174
-rw-r--r--src/bin/day08.rs148
2 files changed, 322 insertions, 0 deletions
diff --git a/input/day08.txt b/input/day08.txt
new file mode 100644
index 0000000..2def566
--- /dev/null
+++ b/input/day08.txt
@@ -0,0 +1,174 @@
+rect 1x1
+rotate row y=0 by 10
+rect 1x1
+rotate row y=0 by 10
+rect 1x1
+rotate row y=0 by 5
+rect 1x1
+rotate row y=0 by 3
+rect 2x1
+rotate row y=0 by 4
+rect 1x1
+rotate row y=0 by 3
+rect 1x1
+rotate row y=0 by 2
+rect 1x1
+rotate row y=0 by 3
+rect 2x1
+rotate row y=0 by 2
+rect 1x1
+rotate row y=0 by 3
+rect 2x1
+rotate row y=0 by 5
+rotate column x=0 by 1
+rect 4x1
+rotate row y=1 by 12
+rotate row y=0 by 10
+rotate column x=0 by 1
+rect 9x1
+rotate column x=7 by 1
+rotate row y=1 by 3
+rotate row y=0 by 2
+rect 1x2
+rotate row y=1 by 3
+rotate row y=0 by 1
+rect 1x3
+rotate column x=35 by 1
+rotate column x=5 by 2
+rotate row y=2 by 5
+rotate row y=1 by 5
+rotate row y=0 by 2
+rect 1x3
+rotate row y=2 by 8
+rotate row y=1 by 10
+rotate row y=0 by 5
+rotate column x=5 by 1
+rotate column x=0 by 1
+rect 6x1
+rotate row y=2 by 7
+rotate row y=0 by 5
+rotate column x=0 by 1
+rect 4x1
+rotate column x=40 by 2
+rotate row y=2 by 10
+rotate row y=0 by 12
+rotate column x=5 by 1
+rotate column x=0 by 1
+rect 9x1
+rotate column x=43 by 1
+rotate column x=40 by 2
+rotate column x=38 by 1
+rotate column x=15 by 1
+rotate row y=3 by 35
+rotate row y=2 by 35
+rotate row y=1 by 32
+rotate row y=0 by 40
+rotate column x=32 by 1
+rotate column x=29 by 1
+rotate column x=27 by 1
+rotate column x=25 by 1
+rotate column x=23 by 2
+rotate column x=22 by 1
+rotate column x=21 by 3
+rotate column x=20 by 1
+rotate column x=18 by 3
+rotate column x=17 by 1
+rotate column x=15 by 1
+rotate column x=14 by 1
+rotate column x=12 by 1
+rotate column x=11 by 3
+rotate column x=10 by 1
+rotate column x=9 by 1
+rotate column x=8 by 2
+rotate column x=7 by 1
+rotate column x=4 by 1
+rotate column x=3 by 1
+rotate column x=2 by 1
+rotate column x=0 by 1
+rect 34x1
+rotate column x=44 by 1
+rotate column x=24 by 1
+rotate column x=19 by 1
+rotate row y=1 by 8
+rotate row y=0 by 10
+rotate column x=8 by 1
+rotate column x=7 by 1
+rotate column x=6 by 1
+rotate column x=5 by 2
+rotate column x=3 by 1
+rotate column x=2 by 1
+rotate column x=1 by 1
+rotate column x=0 by 1
+rect 9x1
+rotate row y=0 by 40
+rotate column x=43 by 1
+rotate row y=4 by 10
+rotate row y=3 by 10
+rotate row y=2 by 5
+rotate row y=1 by 10
+rotate row y=0 by 15
+rotate column x=7 by 2
+rotate column x=6 by 3
+rotate column x=5 by 2
+rotate column x=3 by 2
+rotate column x=2 by 4
+rotate column x=0 by 2
+rect 9x2
+rotate row y=3 by 47
+rotate row y=0 by 10
+rotate column x=42 by 3
+rotate column x=39 by 4
+rotate column x=34 by 3
+rotate column x=32 by 3
+rotate column x=29 by 3
+rotate column x=22 by 3
+rotate column x=19 by 3
+rotate column x=14 by 4
+rotate column x=4 by 3
+rotate row y=4 by 3
+rotate row y=3 by 8
+rotate row y=1 by 5
+rotate column x=2 by 3
+rotate column x=1 by 3
+rotate column x=0 by 2
+rect 3x2
+rotate row y=4 by 8
+rotate column x=45 by 1
+rotate column x=40 by 5
+rotate column x=26 by 3
+rotate column x=25 by 5
+rotate column x=15 by 5
+rotate column x=10 by 5
+rotate column x=7 by 5
+rotate row y=5 by 35
+rotate row y=4 by 42
+rotate row y=2 by 5
+rotate row y=1 by 20
+rotate row y=0 by 45
+rotate column x=48 by 5
+rotate column x=47 by 5
+rotate column x=46 by 5
+rotate column x=43 by 5
+rotate column x=41 by 5
+rotate column x=38 by 5
+rotate column x=37 by 5
+rotate column x=36 by 5
+rotate column x=33 by 1
+rotate column x=32 by 5
+rotate column x=31 by 5
+rotate column x=30 by 1
+rotate column x=28 by 5
+rotate column x=27 by 5
+rotate column x=26 by 5
+rotate column x=23 by 1
+rotate column x=22 by 5
+rotate column x=21 by 5
+rotate column x=20 by 1
+rotate column x=17 by 5
+rotate column x=16 by 5
+rotate column x=13 by 1
+rotate column x=12 by 3
+rotate column x=7 by 5
+rotate column x=6 by 5
+rotate column x=3 by 1
+rotate column x=2 by 3
\ No newline at end of file
diff --git a/src/bin/day08.rs b/src/bin/day08.rs
new file mode 100644
index 0000000..1443ec3
--- /dev/null
+++ b/src/bin/day08.rs
@@ -0,0 +1,148 @@
+use std::fmt::{Display as FmtDisplay, Error as FmtError, Formatter};
+use std::io::{self, Read};
+use std::ops::{Index, IndexMut};
+use std::str::FromStr;
+
+enum Operation {
+    Rect(usize, usize),
+    RotateRow(usize, usize),
+    RotateColumn(usize, usize),
+}
+
+impl FromStr for Operation {
+    type Err = ();
+    fn from_str(s: &str) -> Result<Self, ()> {
+        if s.starts_with("rect") {
+            let mut iter = s[5..].split('x');
+            let width = iter.next().ok_or(())?.parse().map_err(|_| ())?;
+            let height = iter.next().ok_or(())?.parse().map_err(|_| ())?;
+            Ok(Operation::Rect(width, height))
+
+        } else if s.starts_with("rotate row") {
+            let mut iter = s[13..].split(" by ");
+            let y = iter.next().ok_or(())?.parse().map_err(|_| ())?;
+            let count = iter.next().ok_or(())?.parse().map_err(|_| ())?;
+            Ok(Operation::RotateRow(y, count))
+
+        } else if s.starts_with("rotate column") {
+            let mut iter = s[16..].split(" by ");
+            let x = iter.next().ok_or(())?.parse().map_err(|_| ())?;
+            let count = iter.next().ok_or(())?.parse().map_err(|_| ())?;
+            Ok(Operation::RotateColumn(x, count))
+
+        } else {
+            Err(())
+        }
+    }
+}
+
+struct Display {
+    width: usize,
+    height: usize,
+    pixels: Box<[bool]>,
+}
+
+impl Index<(usize, usize)> for Display {
+    type Output = bool;
+    fn index(&self, index: (usize, usize)) -> &bool {
+        &self.pixels[index.1 * self.width + index.0]
+    }
+}
+
+impl IndexMut<(usize, usize)> for Display {
+    fn index_mut(&mut self, index: (usize, usize)) -> &mut bool {
+        &mut self.pixels[index.1 * self.width + index.0]
+    }
+}
+
+impl Display {
+    fn new(width: usize, height: usize) -> Self {
+        Display {
+            width: width,
+            height: height,
+            pixels: vec![false; width * height].into_boxed_slice(),
+        }
+    }
+
+    fn apply(&mut self, operation: Operation) {
+        match operation {
+            Operation::Rect(width, height) => {
+                for y in 0..height {
+                    for x in 0..width {
+                        self[(x, y)] = true;
+                    }
+                }
+            },
+
+            Operation::RotateRow(y, count) => {
+                for _ in 0..count {
+                    let last = self[(self.width - 1, y)];
+                    for x in (1..self.width).rev() {
+                        self[(x, y)] = self[(x - 1, y)];
+                    }
+                    self[(0, y)] = last;
+                }
+            },
+
+            Operation::RotateColumn(x, count) => {
+                for _ in 0..count {
+                    let last = self[(x, self.height - 1)];
+                    for y in (1..self.height).rev() {
+                        self[(x, y)] = self[(x, y - 1)];
+                    }
+                    self[(x, 0)] = last;
+                }
+            },
+        }
+    }
+
+    fn pixels_lit(&self) -> usize {
+        self.pixels.iter().filter(|&&p| p).count()
+    }
+}
+
+impl FmtDisplay for Display {
+    fn fmt(&self, f: &mut Formatter) -> Result<(), FmtError> {
+        for y in 0..self.height {
+            for x in 0..self.width {
+                if self[(x, y)] {
+                    write!(f, "#")?;
+                } else {
+                    write!(f, " ")?;
+                }
+            }
+            write!(f, "\n")?;
+        }
+        Ok(())
+    }
+}
+
+fn solve(width: usize, height: usize, input: &str) -> Display {
+    let mut display = Display::new(width, height);
+
+    for line in input.lines() {
+        display.apply(line.parse().unwrap());
+    }
+
+    display
+}
+
+fn main() {
+    let mut input = String::new();
+    io::stdin().read_to_string(&mut input).unwrap();
+
+    let display = solve(50, 6, &input);
+    println!("Part 1: {}", display.pixels_lit());
+    println!("Part 2:\n{}", display);
+}
+
+#[test]
+fn part1() {
+    let input = "
+rect 3x2
+rotate column x=1 by 1
+rotate row y=0 by 4
+rotate row x=1 by 1
+";
+    assert_eq!(6, solve(7, 3, input.trim()).pixels_lit());
+}