chiark / gitweb /
Fix addition of different-sized vectors
authorSimon Tatham <anakin@pobox.com>
Sat, 12 Apr 2025 08:54:00 +0000 (09:54 +0100)
committerSimon Tatham <anakin@pobox.com>
Sat, 12 Apr 2025 08:54:00 +0000 (09:54 +0100)
Cargo.lock
Cargo.toml
src/finitenimber.rs

index 367e152a5dd099b5df912c5c49605a49e3b40b4b..53afa525048768f2b2b27ff7bb8186e9ffcd667c 100644 (file)
@@ -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",
+]
index e8ddd3863b0a337f9e15da7406e9e5d5b48e1e98..abd9b7404a7094e0704fcb44ec640da22876d648 100644 (file)
@@ -4,3 +4,4 @@ version = "0.1.0"
 edition = "2021"
 
 [dependencies]
+itertools = { version = "0.14.0", default-features = false }
index 92596ee5a7b0caee189f6b79790f09e1146a4f4e..6440d42a14fdcc22fdb8992e329b6f4dc432ebf7 100644 (file)
@@ -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<FiniteNimberRef<'a>> 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]