From: Simon Tatham Date: Sat, 12 Apr 2025 09:44:20 +0000 (+0100) Subject: Implement compound assignment operators. X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ian/git?a=commitdiff_plain;h=6552b888210d8fa13faa1d8b396ebac8866f4ade;p=nimber.git Implement compound assignment operators. --- diff --git a/examples/a382121.rs b/examples/a382121.rs index 967f665..1159fc1 100644 --- a/examples/a382121.rs +++ b/examples/a382121.rs @@ -3,7 +3,7 @@ use std::borrow::Borrow; 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}; @@ -36,17 +36,15 @@ impl Polynomial { } } -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(); } } @@ -87,8 +85,8 @@ fn minimal_polynomial(n: &FiniteNimber) -> Polynomial { 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)); @@ -96,7 +94,7 @@ fn minimal_polynomial(n: &FiniteNimber) -> Polynomial { } } } - power = power * n; + power *= n; exp += 1; } } diff --git a/src/finitenimber.rs b/src/finitenimber.rs index 84bbb4c..42c67a9 100644 --- a/src/finitenimber.rs +++ b/src/finitenimber.rs @@ -242,7 +242,7 @@ impl From<&[Word]> for FiniteNimber { } macro_rules! impl_binop_wrappers { - ($trait:tt, $fn:ident) => { + ($trait:tt, $fn:ident, $assigntrait:tt, $assignfn:ident) => { impl $trait> for FiniteNimber { type Output = FiniteNimber; fn $fn(self, other: FiniteNimberRef<'_>) -> FiniteNimber { @@ -296,6 +296,22 @@ macro_rules! impl_binop_wrappers { $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 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); + } + } }; } @@ -372,9 +388,9 @@ impl<'a, 'b> Mul> for FiniteNimberRef<'b> { } } -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 { @@ -548,11 +564,15 @@ 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 ); }