use std::collections::hash_map::Entry;
use std::collections::HashMap;
use std::fmt::{Display, Formatter};
-use std::ops::Add;
+use std::ops::AddAssign;
use nimber::{FiniteNimber, Word};
}
}
-impl Add<&Polynomial> for Polynomial {
- type Output = Polynomial;
-
- fn add(self, other: &Polynomial) -> Self {
- Self(
- self.0
- .into_iter()
- .zip_longest(other.0.iter().cloned())
- .map(|pair| pair.reduce(|a, b| a ^ b))
- .collect(),
- )
+impl AddAssign<&Polynomial> for Polynomial {
+ fn add_assign(&mut self, other: &Polynomial) {
+ self.0 = self
+ .0
+ .iter()
+ .cloned()
+ .zip_longest(other.0.iter().cloned())
+ .map(|pair| pair.reduce(|a, b| a ^ b))
+ .collect();
}
}
match map.entry(bit) {
Entry::Occupied(e) => {
let e: &(FiniteNimber, Polynomial) = e.get();
- val = val + &e.0;
- comb = comb + &e.1;
+ val += &e.0;
+ comb += &e.1;
}
Entry::Vacant(e) => {
e.insert((val.clone(), comb));
}
}
}
- power = power * n;
+ power *= n;
exp += 1;
}
}
}
macro_rules! impl_binop_wrappers {
- ($trait:tt, $fn:ident) => {
+ ($trait:tt, $fn:ident, $assigntrait:tt, $assignfn:ident) => {
impl $trait<FiniteNimberRef<'_>> for FiniteNimber {
type Output = FiniteNimber;
fn $fn(self, other: FiniteNimberRef<'_>) -> FiniteNimber {
$trait::$fn(aref, bref)
}
}
+
+ impl core::ops::$assigntrait<&FiniteNimber> for FiniteNimber {
+ fn $assignfn(&mut self, other: &FiniteNimber) {
+ let aref: FiniteNimberRef = (&self as &FiniteNimber).into();
+ let bref: FiniteNimberRef = other.into();
+ *self = $trait::$fn(aref, bref);
+ }
+ }
+
+ impl core::ops::$assigntrait<FiniteNimber> for FiniteNimber {
+ fn $assignfn(&mut self, other: FiniteNimber) {
+ let aref: FiniteNimberRef = (&self as &FiniteNimber).into();
+ let bref: FiniteNimberRef = (&other).into();
+ *self = $trait::$fn(aref, bref);
+ }
+ }
};
}
}
}
-impl_binop_wrappers!(Add, add);
-impl_binop_wrappers!(Sub, sub);
-impl_binop_wrappers!(Mul, mul);
+impl_binop_wrappers!(Add, add, AddAssign, add_assign);
+impl_binop_wrappers!(Sub, sub, SubAssign, sub_assign);
+impl_binop_wrappers!(Mul, mul, MulAssign, mul_assign);
#[cfg(test)]
mod tests {
9
);
assert_eq!(
- FiniteNimber::from(vec![1, 1, 1, 1, 1, 1, 1, 1]).to_ref().level(),
+ FiniteNimber::from(vec![1, 1, 1, 1, 1, 1, 1, 1])
+ .to_ref()
+ .level(),
9
);
assert_eq!(
- FiniteNimber::from(vec![1, 1, 1, 1, 1, 1, 1, 1, 1]).to_ref().level(),
+ FiniteNimber::from(vec![1, 1, 1, 1, 1, 1, 1, 1, 1])
+ .to_ref()
+ .level(),
10
);
}