diff options
author | June McEnroe <programble@gmail.com> | 2016-12-18 00:48:40 -0500 |
---|---|---|
committer | June McEnroe <programble@gmail.com> | 2016-12-18 00:48:40 -0500 |
commit | e27c2929b8eb8cdf3a105bd92975625b18f7f638 (patch) | |
tree | 8e144dadb3cb1bce6d9c273d980a8a7eaee59f8f /src/bin | |
parent | Day 16 part 2 (diff) | |
download | aoc-e27c2929b8eb8cdf3a105bd92975625b18f7f638.tar.gz aoc-e27c2929b8eb8cdf3a105bd92975625b18f7f638.zip |
Day 18
Diffstat (limited to 'src/bin')
-rw-r--r-- | src/bin/day18.rs | 87 |
1 files changed, 87 insertions, 0 deletions
diff --git a/src/bin/day18.rs b/src/bin/day18.rs new file mode 100644 index 0000000..658949e --- /dev/null +++ b/src/bin/day18.rs @@ -0,0 +1,87 @@ +use std::io::{self, Read}; + +#[derive(Clone, Copy, PartialEq, Eq)] +enum Tile { + Safe, + Trap, +} + +impl From<char> for Tile { + fn from(ch: char) -> Tile { + match ch { + '.' => Tile::Safe, + '^' => Tile::Trap, + _ => panic!("invalid tile char {}", ch), + } + } +} + +struct Map { + rows: Vec<Box<[Tile]>>, +} + +impl Map { + fn generate_row(&mut self) { + let mut next = Vec::new(); + + { + let previous = self.rows.last().unwrap(); + + for (i, ¢er) in self.rows.last().unwrap().iter().enumerate() { + let left = previous.get(i.wrapping_sub(1)).cloned().unwrap_or(Tile::Safe); + let right = previous.get(i + 1).cloned().unwrap_or(Tile::Safe); + + let tile = match (left, center, right) { + (Tile::Trap, Tile::Trap, Tile::Safe) => Tile::Trap, + (Tile::Safe, Tile::Trap, Tile::Trap) => Tile::Trap, + (Tile::Trap, Tile::Safe, Tile::Safe) => Tile::Trap, + (Tile::Safe, Tile::Safe, Tile::Trap) => Tile::Trap, + _ => Tile::Safe, + }; + next.push(tile); + } + } + + self.rows.push(next.into_boxed_slice()); + } + + fn count_safe(&self) -> usize { + self.rows.iter() + .map(|row| { + row.iter() + .filter(|&&t| t == Tile::Safe) + .count() + }) + .sum() + } +} + +impl<'a> From<&'a str> for Map { + fn from(s: &'a str) -> Map { + let rows = s.lines() + .map(|l| l.chars().map(Tile::from).collect::<Vec<_>>().into_boxed_slice()) + .collect(); + Map { rows: rows } + } +} + +fn solve(rows: u32, input: &str) -> usize { + let mut map = Map::from(input); + for _ in 1..rows { + map.generate_row(); + } + map.count_safe() +} + +fn main() { + let mut input = String::new(); + io::stdin().read_to_string(&mut input).unwrap(); + + println!("Part 1: {}", solve(40, &input)); +} + +#[test] +fn part1() { + assert_eq!(6, solve(3, "..^^.")); + assert_eq!(38, solve(10, ".^^.^.^^^^")); +} |