Skip to content

Instantly share code, notes, and snippets.

@whiter4bbit
Created December 24, 2019 19:02
Show Gist options
  • Save whiter4bbit/b9bd5d15ebb778e6b6f4626fe26a8724 to your computer and use it in GitHub Desktop.
Save whiter4bbit/b9bd5d15ebb778e6b6f4626fe26a8724 to your computer and use it in GitHub Desktop.
day 24b
use std::fs::File;
use std::io::{BufRead, BufReader, Result};
use std::collections::HashSet;
type Cell = (isize, isize, isize);
struct Grid {
rows: isize,
cols: isize,
bugs: HashSet<Cell>,
}
const DIRS: [(isize, isize); 4] = [(-1, 0), (1, 0), (0, 1), (0, -1)];
impl Grid {
fn from_file(path: &str) -> Result<Grid> {
let f = File::open(path)?;
let f = BufReader::new(f);
let (mut bugs, mut rows, mut cols) = (HashSet::new(), 0isize, 0isize);
for (r, row) in f.lines().enumerate() {
for (c, cell) in row.unwrap().chars().enumerate() {
cols = cols.max(c as isize + 1);
rows = rows.max(r as isize + 1);
if cell == '#' {
bugs.insert((r as isize, c as isize, 0));
}
}
}
Ok(Grid {
rows: rows,
cols: cols,
bugs: bugs,
})
}
fn adj_cells(&self, cell: &Cell) -> Vec<Cell> {
let (r, c, l) = cell;
let mut adj = Vec::new();
for (dr, dc) in &DIRS {
let (nr, nc, nl) = (r + dr, c + dc, *l);
if nc == self.cols / 2 && nr == self.rows / 2 {
if *dr == 0 {
for nr in 0..self.rows {
adj.push(match dc {
1 => (nr, 0, nl - 1),
_ => (nr, self.cols - 1, nl - 1),
});
}
} else {
for nc in 0..self.cols {
adj.push(match dr {
1 => (0, nc, nl - 1),
_ => (self.rows - 1, nc, nl - 1),
});
}
}
} else if nr < 0 || nc < 0 || nr >= self.rows || nc >= self.cols {
adj.push((self.rows / 2 + dr, self.cols / 2 + dc, l + 1));
} else {
adj.push((nr, nc, nl));
}
}
adj
}
fn adj_bugs_count(&self, cell: &Cell) -> usize {
self.adj_cells(cell).into_iter()
.filter(|cell| self.bugs.contains(cell))
.count()
}
fn tick(&mut self) {
let mut bugs = HashSet::new();
for bug in &self.bugs {
if self.adj_bugs_count(bug) == 1 {
bugs.insert(*bug);
}
for infested in self.adj_cells(bug) {
if !&self.bugs.contains(&infested) {
let count = self.adj_bugs_count(&infested);
if count == 1 || count == 2 {
bugs.insert(infested);
}
}
}
}
self.bugs = bugs;
}
fn count(&self) -> usize {
self.bugs.len()
}
}
fn main() {
let mut grid = Grid::from_file("input-day24.txt").unwrap();
for _ in 0..200 {
grid.tick();
}
println!("{}", grid.count());
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment