Last active
March 17, 2020 12:34
-
-
Save pizzacat83/498dee7d940d5ad22d68288e515d45b4 to your computer and use it in GitHub Desktop.
[WIP] Z/nZライブラリ
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
use num::Num; | |
use std::ops; | |
#[derive(std::cmp::PartialEq, Clone, Copy)] | |
struct ResidueRing<T> | |
where T: std::fmt::Display + Copy + num::Num + num::Unsigned + PartialEq | |
{ | |
n: T, | |
modulo: T, | |
} | |
impl<T> ResidueRing<T> | |
where T: std::fmt::Display + Copy + num::Num + num::Unsigned + PartialEq | |
{ | |
fn from(n: T, modulo: T) -> Self { | |
Self { | |
n: n % modulo, modulo | |
} | |
} | |
} | |
impl<T> std::ops::Add for ResidueRing<T> | |
where T: std::fmt::Display + Copy + num::Num + num::Unsigned + PartialEq | |
{ | |
type Output = Self; | |
fn add(self, other: Self) -> Self { | |
#[cfg(debug_assertions)] | |
{ | |
if self.modulo != other.modulo { | |
panic!("different modulo: {} (mod {}) + {} (mod {})", self.n, self.modulo, other.n, other.modulo); | |
} | |
} | |
Self { | |
n: (self.n + other.n) % self.modulo, | |
modulo: self.modulo, | |
} | |
} | |
} | |
impl<T> std::ops::Add<T> for ResidueRing<T> | |
where T: std::fmt::Display + Copy + num::Num + num::Unsigned + PartialEq | |
{ | |
type Output = Self; | |
fn add(self, other: T) -> Self { | |
#[cfg(debug_assertions)] | |
let other = Self::from(other, self.modulo); | |
self + other | |
} | |
} | |
impl<T> std::ops::Sub for ResidueRing<T> | |
where T: std::fmt::Display + Copy + num::Num + num::Unsigned + PartialEq | |
{ | |
type Output = Self; | |
fn sub(self, other: Self) -> Self { | |
#[cfg(debug_assertions)] | |
{ | |
if self.modulo != other.modulo { | |
panic!("different modulo: {} (mod {}) - {} (mod {})", self.n, self.modulo, other.n, other.modulo); | |
} | |
} | |
Self { | |
n: (self.modulo + self.n - other.n) % self.modulo, | |
modulo: self.modulo, | |
} | |
} | |
} | |
impl<T> std::ops::Sub<T> for ResidueRing<T> | |
where T: std::fmt::Display + Copy + num::Num + num::Unsigned + PartialEq | |
{ | |
type Output = Self; | |
fn sub(self, other: T) -> Self { | |
#[cfg(debug_assertions)] | |
let other = Self::from(other, self.modulo); | |
self - other | |
} | |
} | |
impl<T> std::ops::Index<ResidueRing<usize>> for Vec<T> { | |
type Output = T; | |
fn index(&self, index: ResidueRing<usize>) -> &T { | |
&self[index.n] | |
} | |
} | |
impl<T> std::ops::IndexMut<ResidueRing<usize>> for Vec<T> { | |
fn index_mut(&mut self, index: ResidueRing<usize>) -> &mut T { | |
&mut self[index.n] | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment