mirror of
https://github.com/bertptrs/adventofcode.git
synced 2025-12-25 21:00:31 +01:00
Clean up day 13 a little.
This commit is contained in:
@@ -53,7 +53,7 @@ impl<'a, I: FromStr> LineParser<'a, I> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, I: FromStr> Iterator for LineParser<'a, I> {
|
impl<I: FromStr> Iterator for LineParser<'_, I> {
|
||||||
type Item = I;
|
type Item = I;
|
||||||
|
|
||||||
fn next(&mut self) -> Option<Self::Item> {
|
fn next(&mut self) -> Option<Self::Item> {
|
||||||
@@ -61,6 +61,15 @@ impl<'a, I: FromStr> Iterator for LineParser<'a, I> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<'a, I: FromStr> From<LineIter<'a>> for LineParser<'a, I> {
|
||||||
|
fn from(iter: LineIter<'a>) -> Self {
|
||||||
|
Self {
|
||||||
|
iter,
|
||||||
|
_data: PhantomData,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Return two arguments in their natural PartialOrd order
|
/// Return two arguments in their natural PartialOrd order
|
||||||
pub fn ordered<O: PartialOrd>(a: O, b: O) -> (O, O) {
|
pub fn ordered<O: PartialOrd>(a: O, b: O) -> (O, O) {
|
||||||
if a < b {
|
if a < b {
|
||||||
|
|||||||
@@ -1,12 +1,16 @@
|
|||||||
use std::collections::HashSet;
|
use std::collections::HashSet;
|
||||||
use std::io::Read;
|
use std::io::Read;
|
||||||
|
use std::str::FromStr;
|
||||||
|
|
||||||
use nom::branch::alt;
|
use nom::branch::alt;
|
||||||
use nom::bytes::complete::tag;
|
use nom::bytes::complete::tag;
|
||||||
|
use nom::error::Error;
|
||||||
use nom::sequence::tuple;
|
use nom::sequence::tuple;
|
||||||
|
use nom::Finish;
|
||||||
use nom::IResult;
|
use nom::IResult;
|
||||||
|
|
||||||
use crate::common::LineIter;
|
use crate::common::LineIter;
|
||||||
|
use crate::common::LineParser;
|
||||||
|
|
||||||
type Coords = (u16, u16);
|
type Coords = (u16, u16);
|
||||||
|
|
||||||
@@ -15,6 +19,21 @@ enum Fold {
|
|||||||
Y(u16),
|
Y(u16),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl FromStr for Fold {
|
||||||
|
type Err = Error<String>;
|
||||||
|
|
||||||
|
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||||
|
let (_, fold) = parse_fold(s)
|
||||||
|
.finish()
|
||||||
|
.map_err(|Error { input, code }| Error {
|
||||||
|
input: input.to_string(),
|
||||||
|
code,
|
||||||
|
})?;
|
||||||
|
|
||||||
|
Ok(fold)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn parse_coordinates(input: &str) -> IResult<&str, Coords> {
|
fn parse_coordinates(input: &str) -> IResult<&str, Coords> {
|
||||||
use nom::character::complete::char;
|
use nom::character::complete::char;
|
||||||
use nom::character::complete::u16;
|
use nom::character::complete::u16;
|
||||||
@@ -44,9 +63,23 @@ fn parse_fold(input: &str) -> IResult<&str, Fold> {
|
|||||||
Ok((input, fold))
|
Ok((input, fold))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn apply_fold(dots: &mut HashSet<Coords>, fold: Fold) {
|
fn read_dots(reader: &mut LineIter<'_>) -> HashSet<Coords> {
|
||||||
let mut to_fold = Vec::new();
|
let mut dots = HashSet::new();
|
||||||
|
|
||||||
|
while let Some(line) = reader.next() {
|
||||||
|
if line.is_empty() {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
let (_, coords) = parse_coordinates(line).unwrap();
|
||||||
|
|
||||||
|
dots.insert(coords);
|
||||||
|
}
|
||||||
|
|
||||||
|
dots
|
||||||
|
}
|
||||||
|
|
||||||
|
fn apply_fold(dots: &mut HashSet<Coords>, fold: Fold, to_fold: &mut Vec<Coords>) {
|
||||||
match fold {
|
match fold {
|
||||||
Fold::X(coord) => dots.retain(|&(x, y)| {
|
Fold::X(coord) => dots.retain(|&(x, y)| {
|
||||||
if x < coord {
|
if x < coord {
|
||||||
@@ -95,20 +128,10 @@ fn print_dots(dots: &HashSet<Coords>) -> String {
|
|||||||
pub fn part1(input: &mut dyn Read) -> String {
|
pub fn part1(input: &mut dyn Read) -> String {
|
||||||
let mut reader = LineIter::new(input);
|
let mut reader = LineIter::new(input);
|
||||||
|
|
||||||
let mut dots = HashSet::new();
|
let mut dots = read_dots(&mut reader);
|
||||||
|
|
||||||
while let Some(line) = reader.next() {
|
let fold = reader.next().unwrap().parse().unwrap();
|
||||||
if line == "" {
|
apply_fold(&mut dots, fold, &mut Vec::new());
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
let (_, coords) = parse_coordinates(line).unwrap();
|
|
||||||
|
|
||||||
dots.insert(coords);
|
|
||||||
}
|
|
||||||
|
|
||||||
let fold = parse_fold(reader.next().unwrap()).unwrap().1;
|
|
||||||
apply_fold(&mut dots, fold);
|
|
||||||
|
|
||||||
dots.len().to_string()
|
dots.len().to_string()
|
||||||
}
|
}
|
||||||
@@ -116,22 +139,10 @@ pub fn part1(input: &mut dyn Read) -> String {
|
|||||||
pub fn part2(input: &mut dyn Read) -> String {
|
pub fn part2(input: &mut dyn Read) -> String {
|
||||||
let mut reader = LineIter::new(input);
|
let mut reader = LineIter::new(input);
|
||||||
|
|
||||||
let mut dots = HashSet::new();
|
let mut dots = read_dots(&mut reader);
|
||||||
|
let mut to_fold = Vec::new();
|
||||||
|
|
||||||
while let Some(line) = reader.next() {
|
LineParser::from(reader).for_each(|fold| apply_fold(&mut dots, fold, &mut to_fold));
|
||||||
if line == "" {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
let (_, coords) = parse_coordinates(line).unwrap();
|
|
||||||
|
|
||||||
dots.insert(coords);
|
|
||||||
}
|
|
||||||
|
|
||||||
while let Some(line) = reader.next() {
|
|
||||||
let fold = parse_fold(line).unwrap().1;
|
|
||||||
apply_fold(&mut dots, fold);
|
|
||||||
}
|
|
||||||
|
|
||||||
print_dots(&dots)
|
print_dots(&dots)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user