day22 finished

This commit is contained in:
Rüdiger Ludwig 2023-08-12 10:34:53 +02:00
parent 88be9a39a0
commit 80d724a6f6
11 changed files with 927 additions and 305 deletions

182
src/common/pos3.rs Normal file
View file

@ -0,0 +1,182 @@
#![allow(dead_code)]
use num_traits::{Num, PrimInt, Signed, Zero};
use std::fmt;
use std::ops::{Add, Div, Mul, Neg, Sub};
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
pub struct Pos3<T>([T; 3]);
impl<T> Pos3<T> {
#[inline]
pub const fn new(x: T, y: T, z: T) -> Pos3<T> {
Pos3([x, y, z])
}
#[inline]
pub fn get_x(&self) -> &T {
&self.0[0]
}
#[inline]
pub fn get_y(&self) -> &T {
&self.0[1]
}
#[inline]
pub fn get_z(&self) -> &T {
&self.0[2]
}
}
impl<T: Signed + PrimInt> Pos3<T> {
pub fn is_unit(&self) -> bool {
self.abs() == T::one()
}
}
impl<T: Copy + Default> From<&[T]> for Pos3<T> {
fn from(value: &[T]) -> Self {
match value.len() {
0 => Pos3::new(T::default(), T::default(), T::default()),
1 => Pos3::new(value[0], T::default(), T::default()),
2 => Pos3::new(value[0], value[1], T::default()),
_ => Pos3::new(value[0], value[1], value[2]),
}
}
}
impl<T> From<[T; 3]> for Pos3<T> {
fn from(value: [T; 3]) -> Self {
Pos3(value)
}
}
impl<T> From<(T, T, T)> for Pos3<T> {
fn from(value: (T, T, T)) -> Self {
Pos3([value.0, value.1, value.2])
}
}
impl<T> Pos3<T>
where
T: Copy,
{
#[inline]
pub fn splat(v: T) -> Pos3<T> {
Pos3::new(v, v, v)
}
#[inline]
pub fn x(&self) -> T {
self.0[0]
}
#[inline]
pub fn y(&self) -> T {
self.0[1]
}
#[inline]
pub fn z(&self) -> T {
self.0[2]
}
}
impl<T> Zero for Pos3<T>
where
T: Num + Zero + Copy,
{
fn zero() -> Self {
Pos3::splat(T::zero())
}
fn is_zero(&self) -> bool {
self.x().is_zero() && self.y().is_zero() && self.z().is_zero()
}
}
impl<T> Pos3<T>
where
T: Signed,
{
pub fn abs(self) -> T {
self.get_x().abs() + self.get_y().abs() + self.get_z().abs()
}
}
impl<T> fmt::Display for Pos3<T>
where
T: Num + fmt::Display,
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "({}, {}, {})", self.get_x(), self.get_y(), self.get_z())
}
}
impl<T, P: Into<Pos3<T>>> Add<P> for Pos3<T>
where
T: Num + Copy,
{
type Output = Self;
fn add(self, rhs: P) -> Self::Output {
let rhs = rhs.into();
Pos3::new(self.x() + rhs.x(), self.y() + rhs.y(), self.z() + rhs.z())
}
}
impl<T, P: Into<Pos3<T>>> Sub<P> for Pos3<T>
where
T: Num + Copy,
{
type Output = Pos3<T>;
fn sub(self, rhs: P) -> Self::Output {
let rhs = rhs.into();
Pos3::new(self.x() - rhs.x(), self.y() - rhs.y(), self.z() - rhs.z())
}
}
impl<T> Mul<T> for Pos3<T>
where
T: Num + Copy,
{
type Output = Self;
fn mul(self, rhs: T) -> Self::Output {
Pos3::new(self.x() * rhs, self.y() * rhs, self.z() * rhs)
}
}
impl<T> Div<T> for Pos3<T>
where
T: Num + Copy,
{
type Output = Self;
fn div(self, rhs: T) -> Self::Output {
Pos3::new(self.x() / rhs, self.y() / rhs, self.z() / rhs)
}
}
impl<T> Neg for Pos3<T>
where
T: Signed + Copy,
{
type Output = Pos3<T>;
fn neg(self) -> Self::Output {
Pos3::new(-self.x(), -self.y(), -self.z())
}
}
impl<T> Mul<Pos3<T>> for Pos3<T>
where
T: Num + Copy,
{
type Output = Pos3<T>;
fn mul(self, rhs: Pos3<T>) -> Self::Output {
Pos3([
self.y() * rhs.z() - self.z() * rhs.y(),
self.z() * rhs.x() - self.x() * rhs.z(),
self.x() * rhs.y() - self.y() * rhs.x(),
])
}
}