From: Simon Tatham Date: Sat, 12 Apr 2025 08:54:00 +0000 (+0100) Subject: Fix addition of different-sized vectors X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ian/git?a=commitdiff_plain;h=4c07b70c414995fe13fb07bc48d41f94960770c7;p=nimber.git Fix addition of different-sized vectors --- diff --git a/Cargo.lock b/Cargo.lock index 367e152..53afa52 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,6 +2,24 @@ # It is not intended for manual editing. version = 3 +[[package]] +name = "either" +version = "1.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719" + +[[package]] +name = "itertools" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b192c782037fadd9cfa75548310488aabdbf3d2da73885b31bd0abd03351285" +dependencies = [ + "either", +] + [[package]] name = "nimber" version = "0.1.0" +dependencies = [ + "itertools", +] diff --git a/Cargo.toml b/Cargo.toml index e8ddd38..abd9b74 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -4,3 +4,4 @@ version = "0.1.0" edition = "2021" [dependencies] +itertools = { version = "0.14.0", default-features = false } diff --git a/src/finitenimber.rs b/src/finitenimber.rs index 92596ee..6440d42 100644 --- a/src/finitenimber.rs +++ b/src/finitenimber.rs @@ -1,8 +1,10 @@ +use core::borrow::Borrow; use core::cmp::max; use core::fmt::{Debug, Display, Formatter}; use core::ops::{Add, Mul, Sub}; +use itertools::Itertools; -type Word = u64; // element type of the vectors we use +pub type Word = u64; // element type of the vectors we use const WORDLEVELS: usize = 6; // 2^{2^6} = 64 = size of Word #[derive(Clone, PartialEq, Eq, Hash)] @@ -67,6 +69,12 @@ impl Display for FiniteNimber { } } +impl Borrow<[Word]> for FiniteNimber { + fn borrow(&self) -> &[Word] { + &self.0 + } +} + impl<'a> FiniteNimberRef<'a> { fn zero() -> Self { OneWord(0) @@ -297,8 +305,9 @@ impl<'a, 'b> Add> for FiniteNimberRef<'b> { FiniteNimber( self.as_slice() .iter() - .zip(other.as_slice().iter()) - .map(|(a, b)| a ^ b) + .cloned() + .zip_longest(other.as_slice().iter().cloned()) + .map(|pair| pair.reduce(|a, b| a ^ b)) .collect(), ) } @@ -505,13 +514,35 @@ mod tests { assert_eq!(FiniteNimber::from(vec![0xffff]).to_ref().level(), 4); assert_eq!(FiniteNimber::from(vec![0x00010000]).to_ref().level(), 5); assert_eq!(FiniteNimber::from(vec![0xffffffff]).to_ref().level(), 5); - assert_eq!(FiniteNimber::from(vec![0x0000000100000000]).to_ref().level(), 6); - assert_eq!(FiniteNimber::from(vec![0xffffffffffffffff]).to_ref().level(), 6); + assert_eq!( + FiniteNimber::from(vec![0x0000000100000000]) + .to_ref() + .level(), + 6 + ); + assert_eq!( + FiniteNimber::from(vec![0xffffffffffffffff]) + .to_ref() + .level(), + 6 + ); - assert_eq!(FiniteNimber::from(vec![0x55, 0, 0, 0]).to_ref().level(), 3); - assert_eq!(FiniteNimber::from(vec![0x55, 1, 0, 0]).to_ref().level(), 7); - assert_eq!(FiniteNimber::from(vec![0x55, 1, 1, 0]).to_ref().level(), 8); - assert_eq!(FiniteNimber::from(vec![0x55, 1, 1, 1]).to_ref().level(), 8); + assert_eq!( + FiniteNimber::from(vec![0x55, 0, 0, 0]).to_ref().level(), + 3 + ); + assert_eq!( + FiniteNimber::from(vec![0x55, 1, 0, 0]).to_ref().level(), + 7 + ); + assert_eq!( + FiniteNimber::from(vec![0x55, 1, 1, 0]).to_ref().level(), + 8 + ); + assert_eq!( + FiniteNimber::from(vec![0x55, 1, 1, 1]).to_ref().level(), + 8 + ); } #[test] @@ -523,6 +554,10 @@ mod tests { let a = FiniteNimber::from(vec![1, 1, 0, 0]); let b = FiniteNimber::from(vec![1, 0, 1, 0]); assert_eq!(a + b, FiniteNimber::from(vec![0, 1, 1, 0])); + + let a = FiniteNimber::from(vec![1, 1, 1, 1]); + let b = FiniteNimber::from(2); + assert_eq!(a + b, FiniteNimber::from(vec![3, 1, 1, 1])); } #[test]