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}
|
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) {
|
pub fn push<S: IntoIterator<Item=T>>(&mut self, row: S) {
|
||||||
self.data.extend(row.into_iter());
|
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> {
|
impl<T> Index<usize> for Vec2<T> {
|
||||||
type Output = [T];
|
type Output = [T];
|
||||||
|
@ -4,14 +4,14 @@ use color_eyre::eyre;
|
|||||||
|
|
||||||
mod lib;
|
mod lib;
|
||||||
use lib::load;
|
use lib::load;
|
||||||
mod day12;
|
mod day13;
|
||||||
|
|
||||||
|
|
||||||
fn main() -> eyre::Result<()> {
|
fn main() -> eyre::Result<()> {
|
||||||
let data = load("data/12.txt")?;
|
let data = load("data/13.txt")?;
|
||||||
|
|
||||||
let start = Instant::now();
|
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 (dur, unit) = format_ns(start.elapsed().as_nanos());
|
||||||
|
|
||||||
let precision = 2.0 - dur.log10().floor();
|
let precision = 2.0 - dur.log10().floor();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user