implement day_02
This commit is contained in:
parent
8149ad3379
commit
8da65689bc
123
src/day_02.rs
Normal file
123
src/day_02.rs
Normal file
|
@ -0,0 +1,123 @@
|
|||
use std::str::FromStr;
|
||||
|
||||
use aoc_runner_derive::{aoc, aoc_generator};
|
||||
|
||||
#[aoc_generator(day2)]
|
||||
pub fn parse_movements(input: &str) -> Vec<Movement> {
|
||||
input
|
||||
.split('\n')
|
||||
.map(|input| input.parse().unwrap())
|
||||
.collect()
|
||||
}
|
||||
|
||||
#[aoc(day2, part1)]
|
||||
pub fn part1(input: &[Movement]) -> isize {
|
||||
let mut state = NaiveState::default();
|
||||
input.iter().for_each(|movement| state.movement(movement));
|
||||
state.depth * state.horizontal_pos
|
||||
}
|
||||
|
||||
#[aoc(day2, part2)]
|
||||
pub fn part2(input: &[Movement]) -> isize {
|
||||
let mut state = State::default();
|
||||
input.iter().for_each(|movement| state.movement(movement));
|
||||
state.depth * state.horizontal_pos
|
||||
}
|
||||
|
||||
pub struct State {
|
||||
horizontal_pos: isize,
|
||||
depth: isize,
|
||||
aim: isize,
|
||||
}
|
||||
|
||||
impl Default for State {
|
||||
fn default() -> State {
|
||||
State {
|
||||
horizontal_pos: 0,
|
||||
depth: 0,
|
||||
aim: 0,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl State {
|
||||
fn movement(&mut self, movement: &Movement) {
|
||||
match movement {
|
||||
Movement::Forward(units) => {
|
||||
self.horizontal_pos += units;
|
||||
self.depth += units * self.aim;
|
||||
}
|
||||
Movement::Down(units) => self.aim += units,
|
||||
Movement::Up(units) => self.aim -= units,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct NaiveState {
|
||||
horizontal_pos: isize,
|
||||
depth: isize,
|
||||
}
|
||||
|
||||
impl Default for NaiveState {
|
||||
fn default() -> NaiveState {
|
||||
NaiveState {
|
||||
horizontal_pos: 0,
|
||||
depth: 0,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl NaiveState {
|
||||
fn movement(&mut self, movement: &Movement) {
|
||||
match movement {
|
||||
Movement::Forward(units) => self.horizontal_pos += units,
|
||||
Movement::Down(units) => self.depth += units,
|
||||
Movement::Up(units) => self.depth -= units,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub enum Movement {
|
||||
Forward(isize),
|
||||
Down(isize),
|
||||
Up(isize),
|
||||
}
|
||||
|
||||
impl FromStr for Movement {
|
||||
type Err = ();
|
||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||
if let Some(units) = s.strip_prefix("forward ") {
|
||||
Ok(Self::Forward(units.parse().unwrap()))
|
||||
} else if let Some(units) = s.strip_prefix("down ") {
|
||||
Ok(Self::Down(units.parse().unwrap()))
|
||||
} else if let Some(units) = s.strip_prefix("up ") {
|
||||
Ok(Self::Up(units.parse().unwrap()))
|
||||
} else {
|
||||
Err(())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
const EXAMPLE_INPUT: &str = "forward 5
|
||||
down 5
|
||||
forward 8
|
||||
up 3
|
||||
down 8
|
||||
forward 2";
|
||||
|
||||
#[test]
|
||||
fn part1_example() {
|
||||
let input = super::parse_movements(EXAMPLE_INPUT);
|
||||
let result = super::part1(&input);
|
||||
assert_eq!(result, 150);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn part2_example() {
|
||||
let input = super::parse_movements(EXAMPLE_INPUT);
|
||||
let result = super::part2(&input);
|
||||
assert_eq!(result, 900);
|
||||
}
|
||||
}
|
|
@ -1,5 +1,6 @@
|
|||
use aoc_runner_derive::aoc_lib;
|
||||
|
||||
pub mod day_01;
|
||||
pub mod day_02;
|
||||
|
||||
aoc_lib! { year = 2021 }
|
||||
|
|
Loading…
Reference in a new issue