This commit is contained in:
Joseph Montanaro 2021-12-29 07:05:02 -08:00
parent dffb8a8673
commit 50db6dafd0
3 changed files with 154 additions and 3 deletions

131
2021/src/day13.rs Normal file
View File

@ -0,0 +1,131 @@
use color_eyre::eyre;
use eyre::eyre;
use crate::lib::{Vec2, IterExt};
enum Direction {
Horizontal,
Vertical,
}
struct Line {
value: usize,
direction: Direction,
}
fn load(data: &str) -> eyre::Result<(Vec2<bool>, Vec<Line>)> {
// populate a 1500x1500 grid
let mut grid: Vec2<bool> = Vec2::with_capacity(1500, 1500);
grid.fill_to_cap(false);
let mut lines = data.lines();
for line in &mut lines {
if line == "" {break}
let (col, row) = line.split(',').map(|s| s.parse::<usize>()).take_pair()?;
grid.set(row?, col?, true);
}
// having consumed the coordinates, we can move on to the fold lines
let mut folds = Vec::new();
for line in lines {
let (axis, intercept) = line
.split(' ')
.nth(2)
.ok_or_else(|| eyre!("Invalid fold line statement: {}", line))?
.split('=')
.take_pair()?;
let direction = match axis {
"x" => Direction::Vertical,
"y" => Direction::Horizontal,
_ => return Err(eyre!("Invalid axis: {}", axis)),
};
let value = intercept.parse::<usize>()?;
folds.push(Line {value, direction});
}
Ok((grid, folds))
}
fn fold(grid: &Vec2<bool>, line: &Line) -> Vec2<bool> {
let mut new_rows = grid.row_count();
let mut new_cols = grid.col_count();
match line.direction {
Direction::Horizontal => new_rows = line.value,
Direction::Vertical => new_cols = line.value,
}
let mut new_grid = Vec2::with_capacity(new_rows, new_cols);
new_grid.fill_to_cap(false);
for row in 0..new_rows {
for col in 0..new_cols {
if *grid.get(row, col) {
new_grid.set(row, col, true);
}
let mut mirror_row = row;
let mut mirror_col = col;
match line.direction {
Direction::Horizontal => mirror_row = 2 * new_rows - row,
Direction::Vertical => mirror_col = 2 * new_cols - col,
}
if mirror_row < grid.row_count() && mirror_col < grid.col_count()
&& *grid.get(mirror_row, mirror_col)
{
new_grid.set(row, col, true);
}
}
}
new_grid
}
fn show(grid: &Vec2<bool>) {
for row in grid.rows() {
let line = row.iter().map(|&v| if v {'#'} else {' '}).collect::<String>();
println!("[{}]", line);
}
}
const SAMPLE: &str = "6,10
0,14
9,10
0,3
10,4
4,11
6,0
6,12
4,1
0,13
10,12
3,4
3,0
8,4
1,10
2,14
8,10
9,0
fold along y=7
fold along x=5";
pub fn run(data: &str) -> eyre::Result<(usize, usize)> {
let (grid, folds) = load(data)?;
let mut folded = fold(&grid, &folds[0]);
let one = folded.values().filter(|v| **v).count();
for line in &folds[1..] {
folded = fold(&folded, line);
}
show(&folded);
Ok((one, 0))
}

View File

@ -151,6 +151,10 @@ impl<T> Vec2<T> {
Vec2 {data: Vec::<T>::new(), columns}
}
pub fn with_capacity(rows: usize, columns: usize) -> Vec2<T> {
Vec2 {data: Vec::<T>::with_capacity(rows * columns), columns}
}
pub fn push<S: IntoIterator<Item=T>>(&mut self, row: S) {
self.data.extend(row.into_iter());
}
@ -213,6 +217,22 @@ impl<T> Vec2<T> {
}
}
#[allow(dead_code)]
impl<T: Copy> Vec2<T> {
pub fn fill(&mut self, value: T) {
for i in 0..self.data.len() {
self.data[i] = value;
}
}
pub fn fill_to_cap(&mut self, value: T) {
self.fill(value);
for _i in self.data.len()..self.data.capacity() {
self.data.push(value);
}
}
}
impl<T> Index<usize> for Vec2<T> {
type Output = [T];

View File

@ -4,14 +4,14 @@ use color_eyre::eyre;
mod lib;
use lib::load;
mod day12;
mod day13;
fn main() -> eyre::Result<()> {
let data = load("data/12.txt")?;
let data = load("data/13.txt")?;
let start = Instant::now();
let (one, two) = day12::run(&data)?;
let (one, two) = day13::run(&data)?;
let (dur, unit) = format_ns(start.elapsed().as_nanos());
let precision = 2.0 - dur.log10().floor();