2021 day13/rust: add solution
This commit is contained in:
parent
3d52da6074
commit
b0821bc945
2 changed files with 92 additions and 0 deletions
9
2021/day13/day13_rs/Cargo.toml
Normal file
9
2021/day13/day13_rs/Cargo.toml
Normal file
|
@ -0,0 +1,9 @@
|
|||
[package]
|
||||
name = "day13_rs"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
nom = "7.1.0"
|
83
2021/day13/day13_rs/src/main.rs
Normal file
83
2021/day13/day13_rs/src/main.rs
Normal file
|
@ -0,0 +1,83 @@
|
|||
#![warn(clippy::pedantic)]
|
||||
use std::collections::HashSet;
|
||||
use std::io::{stdin, Read};
|
||||
|
||||
use nom::bytes::complete::tag;
|
||||
use nom::character::complete::{anychar, newline, u32};
|
||||
use nom::combinator::{map, map_opt};
|
||||
use nom::multi::many1;
|
||||
use nom::sequence::{preceded, separated_pair, terminated};
|
||||
|
||||
type Input<'a> = &'a str;
|
||||
type IResult<'a, T> = nom::IResult<Input<'a>, T>;
|
||||
|
||||
type Point = (usize, usize);
|
||||
|
||||
fn point(i: Input) -> IResult<Point> {
|
||||
separated_pair(map(u32, |i| i as usize), tag(","), map(u32, |i| i as usize))(i)
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
|
||||
enum Fold {
|
||||
X(usize),
|
||||
Y(usize),
|
||||
}
|
||||
|
||||
fn fold(i: Input) -> IResult<Fold> {
|
||||
map_opt(
|
||||
preceded(
|
||||
tag("fold along "),
|
||||
separated_pair(anychar, tag("="), map(u32, |i| i as usize)),
|
||||
),
|
||||
|(dimension, position)| match dimension {
|
||||
'x' => Some(Fold::X(position)),
|
||||
'y' => Some(Fold::Y(position)),
|
||||
_ => None,
|
||||
},
|
||||
)(i)
|
||||
}
|
||||
|
||||
fn input(i: Input) -> IResult<(Vec<Point>, Vec<Fold>)> {
|
||||
separated_pair(
|
||||
many1(terminated(point, newline)),
|
||||
newline,
|
||||
many1(terminated(fold, newline)),
|
||||
)(i)
|
||||
}
|
||||
|
||||
fn do_fold(points: impl Iterator<Item = Point>, fold: Fold) -> HashSet<Point> {
|
||||
let transform = |x, n| if x < n { x } else { n - (x - n) };
|
||||
points
|
||||
.map(|(x, y)| match fold {
|
||||
Fold::X(n) => (transform(x, n), y),
|
||||
Fold::Y(n) => (x, transform(y, n)),
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let mut data = String::new();
|
||||
stdin().lock().read_to_string(&mut data).unwrap();
|
||||
let (points, folds) = input(&data).unwrap().1;
|
||||
|
||||
let mut points: HashSet<_> = points.into_iter().collect();
|
||||
let mut folds = folds.into_iter();
|
||||
|
||||
points = do_fold(points.into_iter(), folds.next().unwrap());
|
||||
println!("{}", points.len());
|
||||
|
||||
for fold in folds {
|
||||
points = do_fold(points.into_iter(), fold);
|
||||
}
|
||||
|
||||
for row in 0..=points.iter().map(|&(_, y)| y).max().unwrap() {
|
||||
for col in 0..=points.iter().map(|&(x, _)| x).max().unwrap() {
|
||||
if points.contains(&(col, row)) {
|
||||
print!("#");
|
||||
} else {
|
||||
print!(".");
|
||||
}
|
||||
}
|
||||
println!();
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue