Skip to content

Commit b8a1cfd

Browse files
authored
Add Automorphic Number Calculator (#344)
1 parent bcf01ce commit b8a1cfd

File tree

3 files changed

+189
-0
lines changed

3 files changed

+189
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
using Algorithms.Numeric;
2+
using NUnit.Framework;
3+
using System;
4+
using System.Collections.Generic;
5+
6+
namespace Algorithms.Tests.Numeric
7+
{
8+
public class AutomorphicNumberTests
9+
{
10+
[TestCase(1)]
11+
[TestCase(5)]
12+
[TestCase(6)]
13+
[TestCase(25)]
14+
[TestCase(76)]
15+
[TestCase(376)]
16+
[TestCase(625)]
17+
[TestCase(9376)]
18+
[TestCase(90625)]
19+
[TestCase(109376)]
20+
21+
public void TestAutomorphicNumbers(int number)
22+
{
23+
Assert.That(AutomorphicNumber.IsAutomorphic(number), Is.True);
24+
}
25+
26+
[TestCase(2)]
27+
[TestCase(3)]
28+
[TestCase(7)]
29+
[TestCase(18)]
30+
[TestCase(79)]
31+
[TestCase(356)]
32+
[TestCase(623)]
33+
[TestCase(9876)]
34+
[TestCase(90635)]
35+
[TestCase(119376)]
36+
[TestCase(891625)]
37+
[TestCase(2990625)]
38+
[TestCase(7209376)]
39+
[TestCase(12891625)]
40+
[TestCase(87129396)]
41+
public void TestNonAutomorphicNumbers(int number)
42+
{
43+
Assert.That(AutomorphicNumber.IsAutomorphic(number), Is.False);
44+
}
45+
46+
[TestCase(0)]
47+
[TestCase(-1)]
48+
public void TestInvalidAutomorphicNumbers(int number)
49+
{
50+
Assert.Throws(Is.TypeOf<ArgumentException>()
51+
.And.Message.EqualTo($"An automorphic number must always be positive."),
52+
delegate
53+
{
54+
AutomorphicNumber.IsAutomorphic(number);
55+
});
56+
}
57+
58+
[TestCase(1, 100)]
59+
public void TestAutomorphicNumberSequence(int lower, int upper)
60+
{
61+
List<long> automorphicList = new() { 1, 5, 6, 25, 76 };
62+
Assert.That(AutomorphicNumber.GetAutomorphicNumbers(lower, upper), Is.EqualTo(automorphicList));
63+
}
64+
65+
[TestCase(8, 12)]
66+
public void TestNoAutomorphicNumberInTheSequence(int lower, int upper)
67+
{
68+
List<long> automorphicList = new();
69+
Assert.That(AutomorphicNumber.GetAutomorphicNumbers(lower, upper), Is.EqualTo(automorphicList));
70+
}
71+
72+
[TestCase(25,25)]
73+
public void TestAutomorphicNumberSequenceSameBounds(int lower, int upper)
74+
{
75+
List<long> automorphicList = new() { 25 };
76+
Assert.That(AutomorphicNumber.GetAutomorphicNumbers(lower, upper), Is.EqualTo(automorphicList));
77+
}
78+
79+
[TestCase(-1,1)]
80+
[TestCase(0, 1)]
81+
public void TestAutomorphicNumberSequenceInvalidLowerBound(int lower, int upper)
82+
{
83+
Assert.Throws(Is.TypeOf<ArgumentException>()
84+
.And.Message.EqualTo($"Lower bound must be greater than 0."),
85+
delegate
86+
{
87+
AutomorphicNumber.GetAutomorphicNumbers(lower, upper);
88+
});
89+
}
90+
91+
[TestCase(1, -1)]
92+
[TestCase(10, -1)]
93+
public void TestAutomorphicNumberSequenceInvalidUpperBound(int lower, int upper)
94+
{
95+
Assert.Throws(Is.TypeOf<ArgumentException>()
96+
.And.Message.EqualTo($"Upper bound must be greater than 0."),
97+
delegate
98+
{
99+
AutomorphicNumber.GetAutomorphicNumbers(lower, upper);
100+
});
101+
}
102+
103+
[TestCase(25, 2)]
104+
public void TestAutomorphicNumberSequenceReversedBounds(int lower, int upper)
105+
{
106+
Assert.Throws(Is.TypeOf<ArgumentException>()
107+
.And.Message.EqualTo($"The lower bound must be less than or equal to the upper bound."),
108+
delegate
109+
{
110+
AutomorphicNumber.GetAutomorphicNumbers(lower, upper);
111+
});
112+
}
113+
}
114+
}
+74
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
using System.Numerics;
5+
6+
namespace Algorithms.Numeric
7+
{
8+
/// <summary>
9+
/// Calculates Automorphic numbers. A number is said to be an Automorphic number
10+
/// if the square of the number will contain the number itself at the end.
11+
/// </summary>
12+
public static class AutomorphicNumber
13+
{
14+
/// <summary>
15+
/// Generates a list of automorphic numbers that are between <paramref name="lowerBound"/> and <paramref name="upperBound"/>
16+
/// inclusive.
17+
/// </summary>
18+
/// <param name="lowerBound">The lower bound of the list.</param>
19+
/// <param name="upperBound">The upper bound of the list.</param>
20+
/// <returns>A list that contains all of the automorphic numbers between <paramref name="lowerBound"/> and <paramref name="upperBound"/> inclusive.</returns>
21+
/// <exception cref="ArgumentException">If the <paramref name="lowerBound"/>
22+
/// or <paramref name="upperBound"/> is not greater than zero
23+
/// or <paramref name="upperBound"/>is lower than the <paramref name="lowerBound"/>.</exception>
24+
public static IEnumerable<int> GetAutomorphicNumbers(int lowerBound, int upperBound)
25+
{
26+
if (lowerBound < 1)
27+
{
28+
throw new ArgumentException($"Lower bound must be greater than 0.");
29+
}
30+
31+
if (upperBound < 1)
32+
{
33+
throw new ArgumentException($"Upper bound must be greater than 0.");
34+
}
35+
36+
if (lowerBound > upperBound)
37+
{
38+
throw new ArgumentException($"The lower bound must be less than or equal to the upper bound.");
39+
}
40+
41+
return Enumerable.Range(lowerBound, upperBound).Where(IsAutomorphic);
42+
}
43+
44+
/// <summary>
45+
/// Checks if a given natural number is automorphic or not.
46+
/// </summary>
47+
/// <param name="number">The number to check.</param>
48+
/// <returns>True if the number is automorphic, false otherwise.</returns>
49+
/// <exception cref="ArgumentException">If the number is non-positive.</exception>
50+
public static bool IsAutomorphic(int number)
51+
{
52+
if (number < 1)
53+
{
54+
throw new ArgumentException($"An automorphic number must always be positive.");
55+
}
56+
57+
BigInteger square = BigInteger.Pow(number, 2);
58+
59+
// Extract the last digits of both numbers
60+
while (number > 0)
61+
{
62+
if (number % 10 != square % 10)
63+
{
64+
return false;
65+
}
66+
67+
number /= 10;
68+
square /= 10;
69+
}
70+
71+
return true;
72+
}
73+
}
74+
}

README.md

+1
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@ find more than one implementation for the same objective but using different alg
8181
* [Euler Method](./Algorithms/Numeric/EulerMethod.cs)
8282
* [Miller-Rabin primality check](./Algorithms/Numeric/MillerRabinPrimalityChecker.cs)
8383
* [KrishnamurthyNumberChecker](./Algorithms/Numeric/KrishnamurthyNumberChecker.cs)
84+
* [Automorphic Number](./Algorithms/Numeric/AutomorphicNumber.cs)
8485
* [Searches](./Algorithms/Search)
8586
* [A-Star](./Algorithms/Search/AStar/)
8687
* [Binary Search](./Algorithms/Search/BinarySearcher.cs)

0 commit comments

Comments
 (0)