adventofcode/src/coordinate_systems/kartesian/external_traits.rs

142 Zeilen
4 KiB
Rust

use super::{Kartesian, KartesianDirection, KartesianIterator};
use super::{Map, Velocity};
use num::*;
use std::{fmt::Display, ops::*};
impl<T: Integer> Add for Kartesian<T> {
fn add(self, rhs: Self) -> Self::Output {
Kartesian { x: self.x + rhs.x, y: self.y + rhs.y }
}
type Output = Kartesian<T>;
}
impl<T: Integer + AddAssign> AddAssign for Kartesian<T> {
fn add_assign(&mut self, rhs: Self) {
self.x += rhs.x;
self.y += rhs.y;
}
}
impl<T: Integer> Sub for Kartesian<T> {
fn sub(self, rhs: Self) -> Self::Output {
Kartesian { x: self.x - rhs.x, y: self.y - rhs.y }
}
type Output = Kartesian<T>;
}
impl<T: Integer + SubAssign> SubAssign for Kartesian<T> {
fn sub_assign(&mut self, rhs: Self) {
self.x -= rhs.x;
self.y -= rhs.y;
}
}
impl<T: Integer + Display + Copy> Display for Kartesian<T> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.write_fmt(format_args!("{}:{}", self.x, self.y))
}
}
impl<T: Integer + Copy> Div<T> for Kartesian<T> {
type Output = Kartesian<T>;
fn div(self, rhs: T) -> Self::Output {
Kartesian {
x: self.x.div_ceil(&rhs),
y: self.y.div_ceil(&rhs),
}
}
}
impl<T: Integer + Rem> Rem for Kartesian<T> {
type Output = Self;
fn rem(self, rhs: Self) -> Self {
Kartesian { x: self.x % rhs.x, y: self.y % rhs.y }
}
}
impl<T: Integer + RemAssign> RemAssign for Kartesian<T> {
fn rem_assign(&mut self, rhs: Self) {
self.x %= rhs.x;
self.y %= rhs.y;
}
}
impl Iterator for KartesianIterator {
type Item = KartesianDirection;
fn next(&mut self) -> Option<Self::Item> {
let mut i = self.i;
if self.straight {
if i < 4 {
self.i += 1;
}
match i {
0 => return Some(KartesianDirection::Right),
1 => return Some(KartesianDirection::Bottom),
2 => return Some(KartesianDirection::Left),
3 => return Some(KartesianDirection::Top),
_ => i -= 4,
}
}
if self.none {
if i == 0 {
self.i += 1;
return Some(KartesianDirection::None);
}
i -= 1;
}
if self.diagonal {
if i < 4 {
self.i += 1;
}
match i {
0 => return Some(KartesianDirection::TopLeft),
1 => return Some(KartesianDirection::TopRight),
2 => return Some(KartesianDirection::BottomLeft),
3 => return Some(KartesianDirection::BottomRight),
_ => {},
}
}
None
}
}
impl<T: Display + Copy + Default> Display for Map<T> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
for row in self.data.iter() {
for v in row.iter() {
v.fmt(f)?
}
for _ in row.len()..=self.maximum.y {
T::default().fmt(f)?
}
println!()
}
for _ in self.data.len()..=self.maximum.x {
for _ in 0..self.maximum.y {
T::default().fmt(f)?
}
println!()
}
Ok(())
}
}
impl<T: Integer + Display + Unsigned + Copy> Display for Velocity<T> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.write_str(match self.direction {
KartesianDirection::None => "",
KartesianDirection::TopLeft => "",
KartesianDirection::Top => "",
KartesianDirection::TopRight => "",
KartesianDirection::Left => "",
KartesianDirection::Right => "",
KartesianDirection::BottomLeft => "",
KartesianDirection::Bottom => "",
KartesianDirection::BottomRight => "",
})?;
self.speed.fmt(f)?;
Ok(())
}
}