parse day 2 using yap as well and make more generic using traits
This commit is contained in:
parent
dcb22a8a0c
commit
0d3b3db401
|
@ -1,6 +1,9 @@
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
|
|
||||||
use aoc_runner_derive::{aoc, aoc_generator};
|
use aoc_runner_derive::{aoc, aoc_generator};
|
||||||
|
use yap::{IntoTokens, Tokens};
|
||||||
|
|
||||||
|
use crate::parsing::parse_number;
|
||||||
|
|
||||||
#[aoc_generator(day2)]
|
#[aoc_generator(day2)]
|
||||||
pub fn parse_movements(input: &str) -> Vec<Movement> {
|
pub fn parse_movements(input: &str) -> Vec<Movement> {
|
||||||
|
@ -12,35 +15,37 @@ pub fn parse_movements(input: &str) -> Vec<Movement> {
|
||||||
|
|
||||||
#[aoc(day2, part1)]
|
#[aoc(day2, part1)]
|
||||||
pub fn part1(input: &[Movement]) -> isize {
|
pub fn part1(input: &[Movement]) -> isize {
|
||||||
let mut state = NaiveState::default();
|
NaiveState::default().movements(input)
|
||||||
input.iter().for_each(|movement| state.movement(movement));
|
|
||||||
state.depth * state.horizontal_pos
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[aoc(day2, part2)]
|
#[aoc(day2, part2)]
|
||||||
pub fn part2(input: &[Movement]) -> isize {
|
pub fn part2(input: &[Movement]) -> isize {
|
||||||
let mut state = State::default();
|
CorrectState::default().movements(input)
|
||||||
input.iter().for_each(|movement| state.movement(movement));
|
|
||||||
state.depth * state.horizontal_pos
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct State {
|
pub trait State {
|
||||||
|
fn movement(&mut self, movement: &Movement);
|
||||||
|
fn depth(&self) -> isize;
|
||||||
|
fn horizontal_pos(&self) -> isize;
|
||||||
|
fn result(&self) -> isize {
|
||||||
|
self.depth() * self.horizontal_pos()
|
||||||
|
}
|
||||||
|
fn movements(&mut self, moves: &[Movement]) -> isize {
|
||||||
|
for movement in moves {
|
||||||
|
self.movement(&movement);
|
||||||
|
}
|
||||||
|
self.result()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Default)]
|
||||||
|
pub struct CorrectState {
|
||||||
horizontal_pos: isize,
|
horizontal_pos: isize,
|
||||||
depth: isize,
|
depth: isize,
|
||||||
aim: isize,
|
aim: isize,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for State {
|
impl State for CorrectState {
|
||||||
fn default() -> State {
|
|
||||||
State {
|
|
||||||
horizontal_pos: 0,
|
|
||||||
depth: 0,
|
|
||||||
aim: 0,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl State {
|
|
||||||
fn movement(&mut self, movement: &Movement) {
|
fn movement(&mut self, movement: &Movement) {
|
||||||
match movement {
|
match movement {
|
||||||
Movement::Forward(units) => {
|
Movement::Forward(units) => {
|
||||||
|
@ -51,23 +56,23 @@ impl State {
|
||||||
Movement::Up(units) => self.aim -= units,
|
Movement::Up(units) => self.aim -= units,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn depth(&self) -> isize {
|
||||||
|
self.depth
|
||||||
|
}
|
||||||
|
|
||||||
|
fn horizontal_pos(&self) -> isize {
|
||||||
|
self.horizontal_pos
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Default)]
|
||||||
pub struct NaiveState {
|
pub struct NaiveState {
|
||||||
horizontal_pos: isize,
|
horizontal_pos: isize,
|
||||||
depth: isize,
|
depth: isize,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for NaiveState {
|
impl State for NaiveState {
|
||||||
fn default() -> NaiveState {
|
|
||||||
NaiveState {
|
|
||||||
horizontal_pos: 0,
|
|
||||||
depth: 0,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl NaiveState {
|
|
||||||
fn movement(&mut self, movement: &Movement) {
|
fn movement(&mut self, movement: &Movement) {
|
||||||
match movement {
|
match movement {
|
||||||
Movement::Forward(units) => self.horizontal_pos += units,
|
Movement::Forward(units) => self.horizontal_pos += units,
|
||||||
|
@ -75,6 +80,14 @@ impl NaiveState {
|
||||||
Movement::Up(units) => self.depth -= units,
|
Movement::Up(units) => self.depth -= units,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn depth(&self) -> isize {
|
||||||
|
self.depth
|
||||||
|
}
|
||||||
|
|
||||||
|
fn horizontal_pos(&self) -> isize {
|
||||||
|
self.horizontal_pos
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub enum Movement {
|
pub enum Movement {
|
||||||
|
@ -86,15 +99,12 @@ pub enum Movement {
|
||||||
impl FromStr for Movement {
|
impl FromStr for Movement {
|
||||||
type Err = ();
|
type Err = ();
|
||||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||||
if let Some(units) = s.strip_prefix("forward ") {
|
let mut tokens = s.into_tokens();
|
||||||
Ok(Self::Forward(units.parse().unwrap()))
|
yap::one_of!(ts from &mut tokens;
|
||||||
} else if let Some(units) = s.strip_prefix("down ") {
|
ts.tokens("forward ".chars()).then(|| parse_number(ts).map(|num| Movement::Forward(num))).flatten(),
|
||||||
Ok(Self::Down(units.parse().unwrap()))
|
ts.tokens("down ".chars()).then(|| parse_number(ts).map(|num| Movement::Down(num))).flatten(),
|
||||||
} else if let Some(units) = s.strip_prefix("up ") {
|
ts.tokens("up ".chars()).then(|| parse_number(ts).map(|num| Movement::Up(num))).flatten(),
|
||||||
Ok(Self::Up(units.parse().unwrap()))
|
).ok_or(())
|
||||||
} else {
|
|
||||||
Err(())
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue