From ca1b1ccbf28cb447229923a62abe58c7a8154898 Mon Sep 17 00:00:00 2001 From: Oliver Booth Date: Sun, 26 Feb 2023 12:24:51 +0000 Subject: [PATCH] Add GreatestCommonFactor for built-in integer types --- CHANGELOG.md | 1 + X10D.Tests/src/Math/ByteTests.cs | 22 ++++++++++++++++++++++ X10D.Tests/src/Math/Int16Tests.cs | 22 ++++++++++++++++++++++ X10D.Tests/src/Math/Int32Tests.cs | 22 ++++++++++++++++++++++ X10D.Tests/src/Math/Int64Tests.cs | 22 ++++++++++++++++++++++ X10D.Tests/src/Math/SByteTests.cs | 22 ++++++++++++++++++++++ X10D.Tests/src/Math/UInt16Tests.cs | 22 ++++++++++++++++++++++ X10D.Tests/src/Math/UInt32Tests.cs | 22 ++++++++++++++++++++++ X10D.Tests/src/Math/UInt64Tests.cs | 22 ++++++++++++++++++++++ X10D/src/Math/ByteExtensions.cs | 19 ++++++++++++++++++- X10D/src/Math/Int16Extensions.cs | 19 ++++++++++++++++++- X10D/src/Math/Int32Extensions.cs | 19 ++++++++++++++++++- X10D/src/Math/Int64Extensions.cs | 22 ++++++++++++++++++++++ X10D/src/Math/SByteExtensions.cs | 17 +++++++++++++++++ X10D/src/Math/UInt16Extensions.cs | 18 ++++++++++++++++++ X10D/src/Math/UInt32Extensions.cs | 18 ++++++++++++++++++ X10D/src/Math/UInt64Extensions.cs | 23 +++++++++++++++++++++++ 17 files changed, 329 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 93cf30f..695b70f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,7 @@ - X10D: Added `Color.GetClosestConsoleColor()` - X10D: Added `DateTime.GetIso8601WeekOfYear()` and `DateTimeOffset.GetIso8601WeekOfYear()` - X10D: Added `DirectoryInfo.Clear()` +- X10D: Added `GreatestCommonFactor` for built-in integer types - X10D: Added `IEnumerable.CountWhereNot(Func)` - X10D: Added `IEnumerable.FirstWhereNot(Func)` - X10D: Added `IEnumerable.FirstWhereNotOrDefault(Func)` diff --git a/X10D.Tests/src/Math/ByteTests.cs b/X10D.Tests/src/Math/ByteTests.cs index cfc4386..f955682 100644 --- a/X10D.Tests/src/Math/ByteTests.cs +++ b/X10D.Tests/src/Math/ByteTests.cs @@ -30,6 +30,28 @@ public class ByteTests Assert.AreEqual(3628800L, ((byte)10).Factorial()); } + [TestMethod] + public void GreatestCommonFactor_ShouldBe1_ForPrimeNumbers() + { + const byte first = 5; + const byte second = 7; + + byte multiple = first.GreatestCommonFactor(second); + + Assert.AreEqual(1, multiple); + } + + [TestMethod] + public void GreatestCommonFactor_ShouldBe6_Given12And18() + { + const byte first = 12; + const byte second = 18; + + byte multiple = first.GreatestCommonFactor(second); + + Assert.AreEqual(6, multiple); + } + [TestMethod] public void IsEvenShouldBeCorrect() { diff --git a/X10D.Tests/src/Math/Int16Tests.cs b/X10D.Tests/src/Math/Int16Tests.cs index 8500f68..3c78183 100644 --- a/X10D.Tests/src/Math/Int16Tests.cs +++ b/X10D.Tests/src/Math/Int16Tests.cs @@ -30,6 +30,28 @@ public class Int16Tests Assert.AreEqual(3628800L, ((short)10).Factorial()); } + [TestMethod] + public void GreatestCommonFactor_ShouldBe1_ForPrimeNumbers() + { + const short first = 5; + const short second = 7; + + short multiple = first.GreatestCommonFactor(second); + + Assert.AreEqual(1, multiple); + } + + [TestMethod] + public void GreatestCommonFactor_ShouldBe6_Given12And18() + { + const short first = 12; + const short second = 18; + + short multiple = first.GreatestCommonFactor(second); + + Assert.AreEqual(6, multiple); + } + [TestMethod] public void IsEvenShouldBeCorrect() { diff --git a/X10D.Tests/src/Math/Int32Tests.cs b/X10D.Tests/src/Math/Int32Tests.cs index bb35f8c..c58f71a 100644 --- a/X10D.Tests/src/Math/Int32Tests.cs +++ b/X10D.Tests/src/Math/Int32Tests.cs @@ -30,6 +30,28 @@ public class Int32Tests Assert.AreEqual(3628800L, 10.Factorial()); } + [TestMethod] + public void GreatestCommonFactor_ShouldBe1_ForPrimeNumbers() + { + const int first = 5; + const int second = 7; + + int multiple = first.GreatestCommonFactor(second); + + Assert.AreEqual(1, multiple); + } + + [TestMethod] + public void GreatestCommonFactor_ShouldBe6_Given12And18() + { + const int first = 12; + const int second = 18; + + int multiple = first.GreatestCommonFactor(second); + + Assert.AreEqual(6, multiple); + } + [TestMethod] public void IsEvenShouldBeCorrect() { diff --git a/X10D.Tests/src/Math/Int64Tests.cs b/X10D.Tests/src/Math/Int64Tests.cs index 0a857f4..ee19d8f 100644 --- a/X10D.Tests/src/Math/Int64Tests.cs +++ b/X10D.Tests/src/Math/Int64Tests.cs @@ -30,6 +30,28 @@ public class Int64Tests Assert.AreEqual(3628800L, 10L.Factorial()); } + [TestMethod] + public void GreatestCommonFactor_ShouldBe1_ForPrimeNumbers() + { + const long first = 5L; + const long second = 7L; + + long multiple = first.GreatestCommonFactor(second); + + Assert.AreEqual(1L, multiple); + } + + [TestMethod] + public void GreatestCommonFactor_ShouldBe6_Given12And18() + { + const long first = 12L; + const long second = 18L; + + long multiple = first.GreatestCommonFactor(second); + + Assert.AreEqual(6L, multiple); + } + [TestMethod] public void IsEvenShouldBeCorrect() { diff --git a/X10D.Tests/src/Math/SByteTests.cs b/X10D.Tests/src/Math/SByteTests.cs index 73b97a2..116c1d8 100644 --- a/X10D.Tests/src/Math/SByteTests.cs +++ b/X10D.Tests/src/Math/SByteTests.cs @@ -31,6 +31,28 @@ public class SByteTests Assert.AreEqual(3628800L, ((sbyte)10).Factorial()); } + [TestMethod] + public void GreatestCommonFactor_ShouldBe1_ForPrimeNumbers() + { + const sbyte first = 5; + const sbyte second = 7; + + sbyte multiple = first.GreatestCommonFactor(second); + + Assert.AreEqual(1, multiple); + } + + [TestMethod] + public void GreatestCommonFactor_ShouldBe6_Given12And18() + { + const sbyte first = 12; + const sbyte second = 18; + + sbyte multiple = first.GreatestCommonFactor(second); + + Assert.AreEqual(6, multiple); + } + [TestMethod] public void IsEvenShouldBeCorrect() { diff --git a/X10D.Tests/src/Math/UInt16Tests.cs b/X10D.Tests/src/Math/UInt16Tests.cs index 471537d..dd98c88 100644 --- a/X10D.Tests/src/Math/UInt16Tests.cs +++ b/X10D.Tests/src/Math/UInt16Tests.cs @@ -31,6 +31,28 @@ public class UInt16Tests Assert.AreEqual(3628800UL, ((ushort)10).Factorial()); } + [TestMethod] + public void GreatestCommonFactor_ShouldBe1_ForPrimeNumbers() + { + const ushort first = 5; + const ushort second = 7; + + ushort multiple = first.GreatestCommonFactor(second); + + Assert.AreEqual(1, multiple); + } + + [TestMethod] + public void GreatestCommonFactor_ShouldBe6_Given12And18() + { + const ushort first = 12; + const ushort second = 18; + + ushort multiple = first.GreatestCommonFactor(second); + + Assert.AreEqual(6, multiple); + } + [TestMethod] public void IsEvenShouldBeCorrect() { diff --git a/X10D.Tests/src/Math/UInt32Tests.cs b/X10D.Tests/src/Math/UInt32Tests.cs index 6c06407..2a7cc54 100644 --- a/X10D.Tests/src/Math/UInt32Tests.cs +++ b/X10D.Tests/src/Math/UInt32Tests.cs @@ -31,6 +31,28 @@ public class UInt32Tests Assert.AreEqual(3628800UL, 10U.Factorial()); } + [TestMethod] + public void GreatestCommonFactor_ShouldBe1_ForPrimeNumbers() + { + const uint first = 5U; + const uint second = 7U; + + uint multiple = first.GreatestCommonFactor(second); + + Assert.AreEqual(1U, multiple); + } + + [TestMethod] + public void GreatestCommonFactor_ShouldBe6_Given12And18() + { + const uint first = 12U; + const uint second = 18U; + + uint multiple = first.GreatestCommonFactor(second); + + Assert.AreEqual(6U, multiple); + } + [TestMethod] public void IsEvenShouldBeCorrect() { diff --git a/X10D.Tests/src/Math/UInt64Tests.cs b/X10D.Tests/src/Math/UInt64Tests.cs index ff7cdbd..b0e5e54 100644 --- a/X10D.Tests/src/Math/UInt64Tests.cs +++ b/X10D.Tests/src/Math/UInt64Tests.cs @@ -35,6 +35,28 @@ public class UInt64Tests Assert.AreEqual(3628800UL, 10UL.Factorial()); } + [TestMethod] + public void GreatestCommonFactor_ShouldBe1_ForPrimeNumbers() + { + const ulong first = 5UL; + const ulong second = 7UL; + + ulong multiple = first.GreatestCommonFactor(second); + + Assert.AreEqual(1UL, multiple); + } + + [TestMethod] + public void GreatestCommonFactor_ShouldBe6_Given12And18() + { + const ulong first = 12UL; + const ulong second = 18UL; + + ulong multiple = first.GreatestCommonFactor(second); + + Assert.AreEqual(6UL, multiple); + } + [TestMethod] public void IsEvenShouldBeCorrect() { diff --git a/X10D/src/Math/ByteExtensions.cs b/X10D/src/Math/ByteExtensions.cs index ca68dd6..45a3010 100644 --- a/X10D/src/Math/ByteExtensions.cs +++ b/X10D/src/Math/ByteExtensions.cs @@ -1,4 +1,4 @@ -using System.Diagnostics.Contracts; +using System.Diagnostics.Contracts; using System.Runtime.CompilerServices; namespace X10D.Math; @@ -57,6 +57,23 @@ public static class ByteExtensions return result; } + /// + /// Calculates the greatest common factor between the current 8-bit unsigned integer, and another 8-bit unsigned integer. + /// + /// The first value. + /// The second value. + /// The greatest common factor between and . + [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else + [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif + public static byte GreatestCommonFactor(this byte value, byte other) + { + return (byte)((long)value).GreatestCommonFactor(other); + } + /// /// Returns a value indicating whether the current value is evenly divisible by 2. /// diff --git a/X10D/src/Math/Int16Extensions.cs b/X10D/src/Math/Int16Extensions.cs index 50dd890..a0f7a1d 100644 --- a/X10D/src/Math/Int16Extensions.cs +++ b/X10D/src/Math/Int16Extensions.cs @@ -1,4 +1,4 @@ -using System.Diagnostics.Contracts; +using System.Diagnostics.Contracts; using System.Runtime.CompilerServices; namespace X10D.Math; @@ -62,6 +62,23 @@ public static class Int16Extensions return result; } + /// + /// Calculates the greatest common factor between the current 16-bit signed integer, and another 16-bit signed integer. + /// + /// The first value. + /// The second value. + /// The greatest common factor between and . + [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else + [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif + public static short GreatestCommonFactor(this short value, short other) + { + return (short)((long)value).GreatestCommonFactor(other); + } + /// /// Returns a value indicating whether the current value is evenly divisible by 2. /// diff --git a/X10D/src/Math/Int32Extensions.cs b/X10D/src/Math/Int32Extensions.cs index 86d3c2f..dd03aee 100644 --- a/X10D/src/Math/Int32Extensions.cs +++ b/X10D/src/Math/Int32Extensions.cs @@ -1,4 +1,4 @@ -using System.Diagnostics.Contracts; +using System.Diagnostics.Contracts; using System.Runtime.CompilerServices; namespace X10D.Math; @@ -62,6 +62,23 @@ public static class Int32Extensions return result; } + /// + /// Calculates the greatest common factor between the current 32-bit signed integer, and another 32-bit signed integer. + /// + /// The first value. + /// The second value. + /// The greatest common factor between and . + [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else + [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif + public static int GreatestCommonFactor(this int value, int other) + { + return (int)((long)value).GreatestCommonFactor(other); + } + /// /// Returns a value indicating whether the current value is evenly divisible by 2. /// diff --git a/X10D/src/Math/Int64Extensions.cs b/X10D/src/Math/Int64Extensions.cs index fdb920b..a4c26d1 100644 --- a/X10D/src/Math/Int64Extensions.cs +++ b/X10D/src/Math/Int64Extensions.cs @@ -62,6 +62,28 @@ public static class Int64Extensions return result; } + /// + /// Calculates the greatest common factor between the current 64-bit signed integer, and another 64-bit unsigned integer. + /// + /// The first value. + /// The second value. + /// The greatest common factor between and . + [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else + [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif + public static long GreatestCommonFactor(this long value, long other) + { + while (other != 0) + { + (value, other) = (other, value % other); + } + + return value; + } + /// /// Returns a value indicating whether the current value is evenly divisible by 2. /// diff --git a/X10D/src/Math/SByteExtensions.cs b/X10D/src/Math/SByteExtensions.cs index f77d56d..f7c0e0f 100644 --- a/X10D/src/Math/SByteExtensions.cs +++ b/X10D/src/Math/SByteExtensions.cs @@ -63,6 +63,23 @@ public static class SByteExtensions return result; } + /// + /// Calculates the greatest common factor between the current 8-bit signed integer, and another 8-bit signed integer. + /// + /// The first value. + /// The second value. + /// The greatest common factor between and . + [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else + [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif + public static sbyte GreatestCommonFactor(this sbyte value, sbyte other) + { + return (sbyte)((long)value).GreatestCommonFactor(other); + } + /// /// Returns a value indicating whether the current value is evenly divisible by 2. /// diff --git a/X10D/src/Math/UInt16Extensions.cs b/X10D/src/Math/UInt16Extensions.cs index dca43d9..2e8855a 100644 --- a/X10D/src/Math/UInt16Extensions.cs +++ b/X10D/src/Math/UInt16Extensions.cs @@ -57,6 +57,24 @@ public static class UInt16Extensions return result; } + /// + /// Calculates the greatest common factor between the current 16-bit unsigned integer, and another 16-bit unsigned + /// integer. + /// + /// The first value. + /// The second value. + /// The greatest common factor between and . + [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else + [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif + public static ushort GreatestCommonFactor(this ushort value, ushort other) + { + return (ushort)((long)value).GreatestCommonFactor(other); + } + /// /// Returns a value indicating whether the current value is evenly divisible by 2. /// diff --git a/X10D/src/Math/UInt32Extensions.cs b/X10D/src/Math/UInt32Extensions.cs index 8b1ffa5..c0d7b21 100644 --- a/X10D/src/Math/UInt32Extensions.cs +++ b/X10D/src/Math/UInt32Extensions.cs @@ -57,6 +57,24 @@ public static class UInt32Extensions return result; } + /// + /// Calculates the greatest common factor between the current 32-bit unsigned integer, and another 32-bit unsigned + /// integer. + /// + /// The first value. + /// The second value. + /// The greatest common factor between and . + [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else + [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif + public static uint GreatestCommonFactor(this uint value, uint other) + { + return (uint)((long)value).GreatestCommonFactor(other); + } + /// /// Returns a value indicating whether the current value is evenly divisible by 2. /// diff --git a/X10D/src/Math/UInt64Extensions.cs b/X10D/src/Math/UInt64Extensions.cs index 9d2efbc..a8721f4 100644 --- a/X10D/src/Math/UInt64Extensions.cs +++ b/X10D/src/Math/UInt64Extensions.cs @@ -57,6 +57,29 @@ public static class UInt64Extensions return result; } + /// + /// Calculates the greatest common factor between the current 64-bit unsigned integer, and another 64-bit unsigned + /// integer. + /// + /// The first value. + /// The second value. + /// The greatest common factor between and . + [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else + [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif + public static ulong GreatestCommonFactor(this ulong value, ulong other) + { + while (other != 0) + { + (value, other) = (other, value % other); + } + + return value; + } + /// /// Returns a value indicating whether the current value is evenly divisible by 2. ///