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