day 13
This commit is contained in:
parent
dffb8a8673
commit
50db6dafd0
131
2021/src/day13.rs
Normal file
131
2021/src/day13.rs
Normal 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))
|
||||
}
|
@ -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];
|
||||
|
@ -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();
|
||||
|
Loading…
x
Reference in New Issue
Block a user