From a7631b0efe458d1726cc41af384291b6e669b712 Mon Sep 17 00:00:00 2001 From: Oliver Booth Date: Sat, 30 Apr 2022 11:29:09 +0100 Subject: [PATCH] Add MultiplicativePersistence for integer types --- X10D.Tests/src/Math/ByteTests.cs | 10 ++++ X10D.Tests/src/Math/Int16Tests.cs | 12 +++++ X10D.Tests/src/Math/Int32Tests.cs | 15 ++++++ X10D.Tests/src/Math/Int64Tests.cs | 17 +++++++ X10D.Tests/src/Math/SByteTests.cs | 16 +++++-- X10D.Tests/src/Math/UInt16Tests.cs | 12 +++++ X10D.Tests/src/Math/UInt32Tests.cs | 20 +++++++- X10D.Tests/src/Math/UInt64Tests.cs | 17 +++++++ X10D/src/Int64Extensions/Int64Extensions.cs | 51 --------------------- X10D/src/Math/ByteExtensions.cs | 15 ++++++ X10D/src/Math/Int16Extensions.cs | 15 ++++++ X10D/src/Math/Int32Extensions.cs | 15 ++++++ X10D/src/Math/Int64Extensions.cs | 46 +++++++++++++++++++ X10D/src/Math/SByteExtensions.cs | 15 ++++++ X10D/src/Math/UInt16Extensions.cs | 15 ++++++ X10D/src/Math/UInt32Extensions.cs | 15 ++++++ X10D/src/Math/UInt64Extensions.cs | 46 +++++++++++++++++++ 17 files changed, 296 insertions(+), 56 deletions(-) delete mode 100644 X10D/src/Int64Extensions/Int64Extensions.cs diff --git a/X10D.Tests/src/Math/ByteTests.cs b/X10D.Tests/src/Math/ByteTests.cs index 96a5131..cfc4386 100644 --- a/X10D.Tests/src/Math/ByteTests.cs +++ b/X10D.Tests/src/Math/ByteTests.cs @@ -49,4 +49,14 @@ public class ByteTests Assert.IsTrue(one.IsOdd()); Assert.IsFalse(two.IsOdd()); } + + [TestMethod] + public void MultiplicativePersistence_ShouldBeCorrect_ForRecordHolders() + { + Assert.AreEqual(0, ((byte)0).MultiplicativePersistence()); + Assert.AreEqual(1, ((byte)10).MultiplicativePersistence()); + Assert.AreEqual(2, ((byte)25).MultiplicativePersistence()); + Assert.AreEqual(3, ((byte)39).MultiplicativePersistence()); + Assert.AreEqual(4, ((byte)77).MultiplicativePersistence()); + } } diff --git a/X10D.Tests/src/Math/Int16Tests.cs b/X10D.Tests/src/Math/Int16Tests.cs index 00129a0..15edb9a 100644 --- a/X10D.Tests/src/Math/Int16Tests.cs +++ b/X10D.Tests/src/Math/Int16Tests.cs @@ -50,6 +50,18 @@ public class Int16Tests Assert.IsFalse(two.IsOdd()); } + [TestMethod] + public void MultiplicativePersistence_ShouldBeCorrect_ForRecordHolders() + { + Assert.AreEqual(0, ((short)0).MultiplicativePersistence()); + Assert.AreEqual(1, ((short)10).MultiplicativePersistence()); + Assert.AreEqual(2, ((short)25).MultiplicativePersistence()); + Assert.AreEqual(3, ((short)39).MultiplicativePersistence()); + Assert.AreEqual(4, ((short)77).MultiplicativePersistence()); + Assert.AreEqual(5, ((short)679).MultiplicativePersistence()); + Assert.AreEqual(6, ((short)6788).MultiplicativePersistence()); + } + [TestMethod] public void NegativeFactorialShouldThrow() { diff --git a/X10D.Tests/src/Math/Int32Tests.cs b/X10D.Tests/src/Math/Int32Tests.cs index 3e30c67..db0d5fb 100644 --- a/X10D.Tests/src/Math/Int32Tests.cs +++ b/X10D.Tests/src/Math/Int32Tests.cs @@ -50,6 +50,21 @@ public class Int32Tests Assert.IsFalse(two.IsOdd()); } + [TestMethod] + public void MultiplicativePersistence_ShouldBeCorrect_ForRecordHolders() + { + Assert.AreEqual(0, 0.MultiplicativePersistence()); + Assert.AreEqual(1, 10.MultiplicativePersistence()); + Assert.AreEqual(2, 25.MultiplicativePersistence()); + Assert.AreEqual(3, 39.MultiplicativePersistence()); + Assert.AreEqual(4, 77.MultiplicativePersistence()); + Assert.AreEqual(5, 679.MultiplicativePersistence()); + Assert.AreEqual(6, 6788.MultiplicativePersistence()); + Assert.AreEqual(7, 68889.MultiplicativePersistence()); + Assert.AreEqual(8, 2677889.MultiplicativePersistence()); + Assert.AreEqual(9, 26888999.MultiplicativePersistence()); + } + [TestMethod] public void NegativeFactorialShouldThrow() { diff --git a/X10D.Tests/src/Math/Int64Tests.cs b/X10D.Tests/src/Math/Int64Tests.cs index 7db89fc..44acb55 100644 --- a/X10D.Tests/src/Math/Int64Tests.cs +++ b/X10D.Tests/src/Math/Int64Tests.cs @@ -50,6 +50,23 @@ public class Int64Tests Assert.IsFalse(two.IsOdd()); } + [TestMethod] + public void MultiplicativePersistence_ShouldBeCorrect_ForRecordHolders() + { + Assert.AreEqual(0, 0L.MultiplicativePersistence()); + Assert.AreEqual(1, 10L.MultiplicativePersistence()); + Assert.AreEqual(2, 25L.MultiplicativePersistence()); + Assert.AreEqual(3, 39L.MultiplicativePersistence()); + Assert.AreEqual(4, 77L.MultiplicativePersistence()); + Assert.AreEqual(5, 679L.MultiplicativePersistence()); + Assert.AreEqual(6, 6788L.MultiplicativePersistence()); + Assert.AreEqual(7, 68889L.MultiplicativePersistence()); + Assert.AreEqual(8, 2677889L.MultiplicativePersistence()); + Assert.AreEqual(9, 26888999L.MultiplicativePersistence()); + Assert.AreEqual(10, 3778888999L.MultiplicativePersistence()); + Assert.AreEqual(11, 277777788888899L.MultiplicativePersistence()); + } + [TestMethod] public void NegativeFactorialShouldThrow() { diff --git a/X10D.Tests/src/Math/SByteTests.cs b/X10D.Tests/src/Math/SByteTests.cs index abf7f21..73b97a2 100644 --- a/X10D.Tests/src/Math/SByteTests.cs +++ b/X10D.Tests/src/Math/SByteTests.cs @@ -14,7 +14,7 @@ public class SByteTests Assert.AreEqual(1, value.DigitalRoot()); Assert.AreEqual(1, (-value).DigitalRoot()); } - + [TestMethod] public void FactorialShouldBeCorrect() { @@ -36,7 +36,7 @@ public class SByteTests { const sbyte one = 1; const sbyte two = 2; - + Assert.IsFalse(one.IsEven()); Assert.IsTrue(two.IsEven()); } @@ -46,11 +46,21 @@ public class SByteTests { const sbyte one = 1; const sbyte two = 2; - + Assert.IsTrue(one.IsOdd()); Assert.IsFalse(two.IsOdd()); } + [TestMethod] + public void MultiplicativePersistence_ShouldBeCorrect_ForRecordHolders() + { + Assert.AreEqual(0, ((sbyte)0).MultiplicativePersistence()); + Assert.AreEqual(1, ((sbyte)10).MultiplicativePersistence()); + Assert.AreEqual(2, ((sbyte)25).MultiplicativePersistence()); + Assert.AreEqual(3, ((sbyte)39).MultiplicativePersistence()); + Assert.AreEqual(4, ((sbyte)77).MultiplicativePersistence()); + } + [TestMethod] public void NegativeFactorialShouldThrow() { diff --git a/X10D.Tests/src/Math/UInt16Tests.cs b/X10D.Tests/src/Math/UInt16Tests.cs index 991dac5..ac8575a 100644 --- a/X10D.Tests/src/Math/UInt16Tests.cs +++ b/X10D.Tests/src/Math/UInt16Tests.cs @@ -50,4 +50,16 @@ public class UInt16Tests Assert.IsTrue(one.IsOdd()); Assert.IsFalse(two.IsOdd()); } + + [TestMethod] + public void MultiplicativePersistence_ShouldBeCorrect_ForRecordHolders() + { + Assert.AreEqual(0, ((ushort)0).MultiplicativePersistence()); + Assert.AreEqual(1, ((ushort)10).MultiplicativePersistence()); + Assert.AreEqual(2, ((ushort)25).MultiplicativePersistence()); + Assert.AreEqual(3, ((ushort)39).MultiplicativePersistence()); + Assert.AreEqual(4, ((ushort)77).MultiplicativePersistence()); + Assert.AreEqual(5, ((ushort)679).MultiplicativePersistence()); + Assert.AreEqual(6, ((ushort)6788).MultiplicativePersistence()); + } } diff --git a/X10D.Tests/src/Math/UInt32Tests.cs b/X10D.Tests/src/Math/UInt32Tests.cs index 6983cee..6c06407 100644 --- a/X10D.Tests/src/Math/UInt32Tests.cs +++ b/X10D.Tests/src/Math/UInt32Tests.cs @@ -36,7 +36,7 @@ public class UInt32Tests { const uint one = 1; const uint two = 2; - + Assert.IsFalse(one.IsEven()); Assert.IsTrue(two.IsEven()); } @@ -46,8 +46,24 @@ public class UInt32Tests { const uint one = 1; const uint two = 2; - + Assert.IsTrue(one.IsOdd()); Assert.IsFalse(two.IsOdd()); } + + [TestMethod] + public void MultiplicativePersistence_ShouldBeCorrect_ForRecordHolders() + { + Assert.AreEqual(0, 0U.MultiplicativePersistence()); + Assert.AreEqual(1, 10U.MultiplicativePersistence()); + Assert.AreEqual(2, 25U.MultiplicativePersistence()); + Assert.AreEqual(3, 39U.MultiplicativePersistence()); + Assert.AreEqual(4, 77U.MultiplicativePersistence()); + Assert.AreEqual(5, 679U.MultiplicativePersistence()); + Assert.AreEqual(6, 6788U.MultiplicativePersistence()); + Assert.AreEqual(7, 68889U.MultiplicativePersistence()); + Assert.AreEqual(8, 2677889U.MultiplicativePersistence()); + Assert.AreEqual(9, 26888999U.MultiplicativePersistence()); + Assert.AreEqual(10, 3778888999U.MultiplicativePersistence()); + } } diff --git a/X10D.Tests/src/Math/UInt64Tests.cs b/X10D.Tests/src/Math/UInt64Tests.cs index 5deba76..d18a7d6 100644 --- a/X10D.Tests/src/Math/UInt64Tests.cs +++ b/X10D.Tests/src/Math/UInt64Tests.cs @@ -54,4 +54,21 @@ public class UInt64Tests Assert.IsTrue(one.IsOdd()); Assert.IsFalse(two.IsOdd()); } + + [TestMethod] + public void MultiplicativePersistence_ShouldBeCorrect_ForRecordHolders() + { + Assert.AreEqual(0, 0UL.MultiplicativePersistence()); + Assert.AreEqual(1, 10UL.MultiplicativePersistence()); + Assert.AreEqual(2, 25UL.MultiplicativePersistence()); + Assert.AreEqual(3, 39UL.MultiplicativePersistence()); + Assert.AreEqual(4, 77UL.MultiplicativePersistence()); + Assert.AreEqual(5, 679UL.MultiplicativePersistence()); + Assert.AreEqual(6, 6788UL.MultiplicativePersistence()); + Assert.AreEqual(7, 68889UL.MultiplicativePersistence()); + Assert.AreEqual(8, 2677889UL.MultiplicativePersistence()); + Assert.AreEqual(9, 26888999UL.MultiplicativePersistence()); + Assert.AreEqual(10, 3778888999UL.MultiplicativePersistence()); + Assert.AreEqual(11, 277777788888899UL.MultiplicativePersistence()); + } } diff --git a/X10D/src/Int64Extensions/Int64Extensions.cs b/X10D/src/Int64Extensions/Int64Extensions.cs deleted file mode 100644 index 6469bb5..0000000 --- a/X10D/src/Int64Extensions/Int64Extensions.cs +++ /dev/null @@ -1,51 +0,0 @@ -namespace X10D; - -/// -/// Extension methods for . -/// -public static class Int64Extensions -{ - /// - /// Returns the multiplicative persistence of a specified value. - /// - /// The value whose multiplicative persistence to calculate. - /// The multiplicative persistence. - /// - /// Multiplicative persistence is defined as the recursive digital product until that product is a single digit. - /// - public static int MultiplicativePersistence(this long value) - { - var persistence = 0; - long product = value; - - while (product > 9) - { - if (value % 10 == 0) - { - return persistence + 1; - } - - while (value > 9) - { - value /= 10; - if (value % 10 == 0) - { - return persistence + 1; - } - } - - long newProduct = 1; - long currentProduct = product; - while (currentProduct > 0) - { - newProduct *= currentProduct % 10; - currentProduct /= 10; - } - - product = newProduct; - persistence++; - } - - return persistence; - } -} diff --git a/X10D/src/Math/ByteExtensions.cs b/X10D/src/Math/ByteExtensions.cs index 65e7a3f..8e25088 100644 --- a/X10D/src/Math/ByteExtensions.cs +++ b/X10D/src/Math/ByteExtensions.cs @@ -91,4 +91,19 @@ public static class ByteExtensions { return ((long)value).IsPrime(); } + + /// + /// Returns the multiplicative persistence of a specified value. + /// + /// The value whose multiplicative persistence to calculate. + /// The multiplicative persistence. + /// + /// Multiplicative persistence is defined as the recursive digital product until that product is a single digit. + /// + [Pure] + [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] + public static int MultiplicativePersistence(this byte value) + { + return ((long)value).MultiplicativePersistence(); + } } diff --git a/X10D/src/Math/Int16Extensions.cs b/X10D/src/Math/Int16Extensions.cs index 702ba6c..731c285 100644 --- a/X10D/src/Math/Int16Extensions.cs +++ b/X10D/src/Math/Int16Extensions.cs @@ -120,6 +120,21 @@ public static class Int16Extensions return (short)(r < 0 ? r + divisor : r); } + /// + /// Returns the multiplicative persistence of a specified value. + /// + /// The value whose multiplicative persistence to calculate. + /// The multiplicative persistence. + /// + /// Multiplicative persistence is defined as the recursive digital product until that product is a single digit. + /// + [Pure] + [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] + public static int MultiplicativePersistence(this short value) + { + return ((long)value).MultiplicativePersistence(); + } + /// /// Returns an integer that indicates the sign of this 16-bit signed integer. /// diff --git a/X10D/src/Math/Int32Extensions.cs b/X10D/src/Math/Int32Extensions.cs index a3099cd..faaeb5d 100644 --- a/X10D/src/Math/Int32Extensions.cs +++ b/X10D/src/Math/Int32Extensions.cs @@ -120,6 +120,21 @@ public static class Int32Extensions return r < 0 ? r + divisor : r; } + /// + /// Returns the multiplicative persistence of a specified value. + /// + /// The value whose multiplicative persistence to calculate. + /// The multiplicative persistence. + /// + /// Multiplicative persistence is defined as the recursive digital product until that product is a single digit. + /// + [Pure] + [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] + public static int MultiplicativePersistence(this int value) + { + return ((long)value).MultiplicativePersistence(); + } + /// /// Returns an integer that indicates the sign of this 32-bit signed integer. /// diff --git a/X10D/src/Math/Int64Extensions.cs b/X10D/src/Math/Int64Extensions.cs index 56ab1dd..48d5ed3 100644 --- a/X10D/src/Math/Int64Extensions.cs +++ b/X10D/src/Math/Int64Extensions.cs @@ -145,6 +145,52 @@ public static class Int64Extensions return r < 0 ? r + divisor : r; } + /// + /// Returns the multiplicative persistence of a specified value. + /// + /// The value whose multiplicative persistence to calculate. + /// The multiplicative persistence. + /// + /// Multiplicative persistence is defined as the recursive digital product until that product is a single digit. + /// + [Pure] + [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] + public static int MultiplicativePersistence(this long value) + { + var persistence = 0; + long product = System.Math.Abs(value); + + while (product > 9) + { + if (value % 10 == 0) + { + return persistence + 1; + } + + while (value > 9) + { + value /= 10; + if (value % 10 == 0) + { + return persistence + 1; + } + } + + long newProduct = 1; + long currentProduct = product; + while (currentProduct > 0) + { + newProduct *= currentProduct % 10; + currentProduct /= 10; + } + + product = newProduct; + persistence++; + } + + return persistence; + } + /// /// Returns an integer that indicates the sign of this 64-bit signed integer. /// diff --git a/X10D/src/Math/SByteExtensions.cs b/X10D/src/Math/SByteExtensions.cs index 02b7347..8e640a0 100644 --- a/X10D/src/Math/SByteExtensions.cs +++ b/X10D/src/Math/SByteExtensions.cs @@ -121,6 +121,21 @@ public static class SByteExtensions return (sbyte)(r < 0 ? r + divisor : r); } + /// + /// Returns the multiplicative persistence of a specified value. + /// + /// The value whose multiplicative persistence to calculate. + /// The multiplicative persistence. + /// + /// Multiplicative persistence is defined as the recursive digital product until that product is a single digit. + /// + [Pure] + [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] + public static int MultiplicativePersistence(this sbyte value) + { + return ((long)value).MultiplicativePersistence(); + } + /// /// Returns an integer that indicates the sign of this 8-bit signed integer. /// diff --git a/X10D/src/Math/UInt16Extensions.cs b/X10D/src/Math/UInt16Extensions.cs index 889c025..e781942 100644 --- a/X10D/src/Math/UInt16Extensions.cs +++ b/X10D/src/Math/UInt16Extensions.cs @@ -92,4 +92,19 @@ public static class UInt16Extensions { return !value.IsEven(); } + + /// + /// Returns the multiplicative persistence of a specified value. + /// + /// The value whose multiplicative persistence to calculate. + /// The multiplicative persistence. + /// + /// Multiplicative persistence is defined as the recursive digital product until that product is a single digit. + /// + [Pure] + [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] + public static int MultiplicativePersistence(this ushort value) + { + return ((ulong)value).MultiplicativePersistence(); + } } diff --git a/X10D/src/Math/UInt32Extensions.cs b/X10D/src/Math/UInt32Extensions.cs index 38284cf..65217a4 100644 --- a/X10D/src/Math/UInt32Extensions.cs +++ b/X10D/src/Math/UInt32Extensions.cs @@ -92,4 +92,19 @@ public static class UInt32Extensions { return !value.IsEven(); } + + /// + /// Returns the multiplicative persistence of a specified value. + /// + /// The value whose multiplicative persistence to calculate. + /// The multiplicative persistence. + /// + /// Multiplicative persistence is defined as the recursive digital product until that product is a single digit. + /// + [Pure] + [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] + public static int MultiplicativePersistence(this uint value) + { + return ((ulong)value).MultiplicativePersistence(); + } } diff --git a/X10D/src/Math/UInt64Extensions.cs b/X10D/src/Math/UInt64Extensions.cs index 16b98d9..08f88ba 100644 --- a/X10D/src/Math/UInt64Extensions.cs +++ b/X10D/src/Math/UInt64Extensions.cs @@ -117,4 +117,50 @@ public static class UInt64Extensions { return !value.IsEven(); } + + /// + /// Returns the multiplicative persistence of a specified value. + /// + /// The value whose multiplicative persistence to calculate. + /// The multiplicative persistence. + /// + /// Multiplicative persistence is defined as the recursive digital product until that product is a single digit. + /// + [Pure] + [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] + public static int MultiplicativePersistence(this ulong value) + { + var persistence = 0; + ulong product = value; + + while (product > 9) + { + if (value % 10 == 0) + { + return persistence + 1; + } + + while (value > 9) + { + value /= 10; + if (value % 10 == 0) + { + return persistence + 1; + } + } + + ulong newProduct = 1; + ulong currentProduct = product; + while (currentProduct > 0) + { + newProduct *= currentProduct % 10; + currentProduct /= 10; + } + + product = newProduct; + persistence++; + } + + return persistence; + } }