creates a submarine trait

This commit is contained in:
JasterV 2021-12-02 13:05:23 +01:00
parent 6d0452b8e2
commit 2cf6b3eb50
4 changed files with 158 additions and 62 deletions

View file

@ -1,6 +1,6 @@
mod models;
use models::{Command, Submarine};
use models::{Command, Submarine, SubmarineV1, SubmarineV2};
use std::fs::File;
use std::io::{self, BufRead, BufReader, Lines, Result};
use std::iter::Iterator;
@ -9,15 +9,23 @@ use std::path::Path;
static INPUT_PATH: &str = "input.txt";
fn main() -> Result<()> {
let submarine = Submarine { xcord: 0, depth: 0 };
// First puzzle
let submarine_v1 = SubmarineV1::new();
let commands = read_commands(INPUT_PATH)?;
let submarine = apply_commands(submarine, &commands);
println!("First puzzle: {}", submarine.depth * submarine.xcord);
let submarine_v1 = apply_commands(submarine_v1, &commands);
println!("First puzzle: {}", submarine_v1.position_x_depth());
// Second puzzle
let submarine_v2 = SubmarineV2::new();
let submarine_v2 = apply_commands(submarine_v2, &commands);
println!("Second puzzle: {}", submarine_v2.position_x_depth());
Ok(())
}
fn apply_commands(submarine: Submarine, commands: &[Command]) -> Submarine {
commands.iter().copied().fold(submarine, Submarine::exec)
fn apply_commands(submarine: impl Submarine, commands: &[Command]) -> impl Submarine {
commands
.iter()
.copied()
.fold(submarine, |submarine, command| submarine.exec(command))
}
fn read_commands(file_path: &str) -> Result<Vec<Command>> {

View file

@ -0,0 +1,20 @@
#[derive(Debug, Clone, Copy)]
pub enum Command {
Forward(i32),
Down(i32),
Up(i32),
}
impl From<String> for Command {
fn from(str: String) -> Self {
let words: Vec<&str> = str.split_ascii_whitespace().collect();
let action = words[0];
let unit: i32 = words[1].parse().unwrap();
match action {
"forward" => Command::Forward(unit),
"down" => Command::Down(unit),
"up" => Command::Up(unit),
_ => panic!("Invalid command {}", action),
}
}
}

View file

@ -1,57 +1,5 @@
#[derive(Debug, Clone, Copy)]
pub struct Submarine {
pub xcord: i32,
pub depth: i32,
}
mod command;
mod submarines;
impl Submarine {
pub fn exec(submarine: Self, command: Command) -> Self {
match command {
Command::Forward(unit) => Self::forward(submarine, unit),
Command::Down(unit) => Self::down(submarine, unit),
Command::Up(unit) => Self::up(submarine, unit),
}
}
fn forward(submarine: Self, unit: i32) -> Self {
Submarine {
xcord: submarine.xcord + unit,
depth: submarine.depth,
}
}
fn down(submarine: Self, unit: i32) -> Self {
Submarine {
xcord: submarine.xcord,
depth: submarine.depth + unit,
}
}
fn up(submarine: Self, unit: i32) -> Self {
Submarine {
xcord: submarine.xcord,
depth: submarine.depth - unit,
}
}
}
#[derive(Debug, Clone, Copy)]
pub enum Command {
Forward(i32),
Down(i32),
Up(i32),
}
impl From<String> for Command {
fn from(str: String) -> Self {
let words: Vec<&str> = str.split_ascii_whitespace().collect();
let action = words[0];
let unit: i32 = words[1].parse().unwrap();
match action {
"forward" => Command::Forward(unit),
"down" => Command::Down(unit),
"up" => Command::Up(unit),
_ => panic!("Invalid command {}", action),
}
}
}
pub use command::Command;
pub use submarines::{Submarine, SubmarineV1, SubmarineV2};

View file

@ -0,0 +1,120 @@
use super::Command;
pub trait Submarine {
fn exec(&self, command: Command) -> Self;
fn position(&self) -> i32;
fn depth(&self) -> i32;
fn position_x_depth(&self) -> i32 {
self.position() * self.depth()
}
}
#[derive(Debug, Clone, Copy)]
pub struct SubmarineV1 {
pub xcord: i32,
pub depth: i32,
}
impl SubmarineV1 {
pub fn new() -> Self {
Self { xcord: 0, depth: 0 }
}
fn forward(self, unit: i32) -> Self {
SubmarineV1 {
xcord: self.xcord + unit,
depth: self.depth,
}
}
fn down(self, unit: i32) -> Self {
SubmarineV1 {
xcord: self.xcord,
depth: self.depth + unit,
}
}
fn up(self, unit: i32) -> Self {
SubmarineV1 {
xcord: self.xcord,
depth: self.depth - unit,
}
}
}
impl Submarine for SubmarineV1 {
fn exec(&self, command: Command) -> Self {
match command {
Command::Forward(unit) => self.forward(unit),
Command::Down(unit) => self.down(unit),
Command::Up(unit) => self.up(unit),
}
}
fn position(&self) -> i32 {
self.xcord
}
fn depth(&self) -> i32 {
self.depth
}
}
#[derive(Debug, Clone, Copy)]
pub struct SubmarineV2 {
pub xcord: i32,
pub depth: i32,
pub aim: i32,
}
impl SubmarineV2 {
pub fn new() -> Self {
Self {
xcord: 0,
depth: 0,
aim: 0,
}
}
fn forward(self, unit: i32) -> Self {
SubmarineV2 {
xcord: self.xcord + unit,
depth: self.depth + self.aim * unit,
aim: self.aim,
}
}
fn down(self, unit: i32) -> Self {
SubmarineV2 {
xcord: self.xcord,
depth: self.depth,
aim: self.aim + unit,
}
}
fn up(self, unit: i32) -> Self {
SubmarineV2 {
xcord: self.xcord,
depth: self.depth,
aim: self.aim - unit,
}
}
}
impl Submarine for SubmarineV2 {
fn exec(&self, command: Command) -> Self {
match command {
Command::Forward(unit) => self.forward(unit),
Command::Down(unit) => self.down(unit),
Command::Up(unit) => self.up(unit),
}
}
fn position(&self) -> i32 {
self.xcord
}
fn depth(&self) -> i32 {
self.depth
}
}