Implemented parsers as traits
This commit is contained in:
parent
f03ddf12cf
commit
9a155dbda7
|
@ -1,6 +1,6 @@
|
||||||
#![feature(test)]
|
#![feature(test)]
|
||||||
use core::fmt;
|
use core::fmt;
|
||||||
use std::collections::HashMap;
|
use std::{collections::HashMap, str::FromStr};
|
||||||
use lazy_static::lazy_static;
|
use lazy_static::lazy_static;
|
||||||
|
|
||||||
use regex::Regex;
|
use regex::Regex;
|
||||||
|
@ -91,13 +91,13 @@ impl fmt::Display for Boat {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Boat {
|
impl From<Vec<&str>> for Boat {
|
||||||
fn new(lines: &Vec<&str>) -> Boat {
|
fn from(lines: Vec<&str>) -> Self {
|
||||||
lazy_static! {
|
lazy_static! {
|
||||||
static ref RE: Regex = Regex::new(r"\[[A-Z]\]").unwrap();
|
static ref RE: Regex = Regex::new(r"\[[A-Z]\]").unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut boat = Boat{stacks: HashMap::new()};
|
let mut boat = Self{stacks: HashMap::new()};
|
||||||
for line in lines {
|
for line in lines {
|
||||||
for mat in RE.find_iter(line) {
|
for mat in RE.find_iter(line) {
|
||||||
let index = mat.start() / 4 + 1;
|
let index = mat.start() / 4 + 1;
|
||||||
|
@ -115,10 +115,12 @@ impl Boat {
|
||||||
|
|
||||||
return boat;
|
return boat;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Boat {
|
||||||
fn take(&mut self, index: usize, amount: usize) -> Vec<Crate> {
|
fn take(&mut self, index: usize, amount: usize) -> Vec<Crate> {
|
||||||
let stack = self.stacks.entry(index).or_default();
|
let stack = self.stacks.entry(index).or_default();
|
||||||
stack.split_off(stack.len()-amount)
|
stack.split_off(stack.len()-amount as usize)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn put(&mut self, index: usize, mut vec: Vec<Crate>) {
|
fn put(&mut self, index: usize, mut vec: Vec<Crate>) {
|
||||||
|
@ -141,42 +143,54 @@ impl Boat {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// -- Helpers --
|
struct Instruction {
|
||||||
fn parse_instruction(s: &str) -> (usize, usize, usize) {
|
amount: usize,
|
||||||
lazy_static! {
|
from: usize,
|
||||||
static ref RE: Regex = Regex::new(r"move (?P<amount>[0-9]+) from (?P<from>[0-9]) to (?P<to>[0-9])").unwrap();
|
to: usize,
|
||||||
}
|
|
||||||
|
|
||||||
let capture = RE.captures(s).unwrap();
|
|
||||||
|
|
||||||
let parse_number = |name| capture.name(name).unwrap().as_str().parse::<usize>().unwrap();
|
|
||||||
let amount: usize = parse_number("amount");
|
|
||||||
let from: usize = parse_number("from");
|
|
||||||
let to: usize = parse_number("to");
|
|
||||||
|
|
||||||
(amount, from, to)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl FromStr for Instruction {
|
||||||
|
type Err = anyhow::Error;
|
||||||
|
|
||||||
|
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||||
|
lazy_static! {
|
||||||
|
static ref RE: Regex = Regex::new(r"move (?P<amount>[0-9]+) from (?P<from>[0-9]) to (?P<to>[0-9])").unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
let capture = RE.captures(s).unwrap();
|
||||||
|
|
||||||
|
let parse = |name| capture.name(name).unwrap().as_str().parse();
|
||||||
|
|
||||||
|
let amount = parse("amount")?;
|
||||||
|
let from = parse("from")?;
|
||||||
|
let to = parse("to")?;
|
||||||
|
|
||||||
|
Ok(Instruction{amount, from, to})
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// -- Helpers --
|
||||||
fn solution(input: &str, part1: bool) -> String {
|
fn solution(input: &str, part1: bool) -> String {
|
||||||
// The current layout description ends with an empty line
|
// The current layout description ends with an empty line
|
||||||
let mut boat = Boat::new(&input
|
let mut boat: Boat = input.lines()
|
||||||
.lines()
|
|
||||||
.take_while(|line| !line.is_empty())
|
.take_while(|line| !line.is_empty())
|
||||||
.collect());
|
.collect::<Vec<_>>()
|
||||||
|
.into();
|
||||||
|
|
||||||
// Each instruction starts with an 'm'
|
// Each instruction starts with an 'm'
|
||||||
input
|
input
|
||||||
.lines()
|
.lines()
|
||||||
.skip_while(|line| !line.starts_with('m'))
|
.skip_while(|line| !line.starts_with('m'))
|
||||||
.map(parse_instruction)
|
.map(|line| line.parse().unwrap())
|
||||||
.for_each(|(amount, from, to)| {
|
.for_each(|i: Instruction| {
|
||||||
let mut taken = boat.take(from, amount);
|
let mut taken = boat.take(i.from, i.amount);
|
||||||
if part1 {
|
if part1 {
|
||||||
// In part one we move the crates on by one, so the vector needs to be reverse to
|
// In part one we move the crates on by one, so the vector needs to be reverse to
|
||||||
// get the correct order
|
// get the correct order
|
||||||
taken.reverse();
|
taken.reverse();
|
||||||
}
|
}
|
||||||
boat.put(to, taken);
|
boat.put(i.to, taken);
|
||||||
});
|
});
|
||||||
|
|
||||||
boat.to_string()
|
boat.to_string()
|
||||||
|
|
Loading…
Reference in New Issue
Block a user