Skip to content

Commit 422b1d1

Browse files
Nanak360Nanak Bandyopadhyay
andauthored
Add Magic Number to maths algorithms (keon#730)
* add magic number to maths * add Magic Number to maths * Update test_maths.py * Updated variable names and condition statements Co-authored-by: Nanak Bandyopadhyay <nanakbandyopadhay@hotmail.com>
1 parent 30512d9 commit 422b1d1

File tree

4 files changed

+76
-14
lines changed

4 files changed

+76
-14
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,7 @@ If you want to uninstall algorithms, it is as simple as:
209209
- [gcd/lcm](algorithms/maths/gcd.py)
210210
- [generate_strobogrammtic](algorithms/maths/generate_strobogrammtic.py)
211211
- [is_strobogrammatic](algorithms/maths/is_strobogrammatic.py)
212+
- [magic_number](algorithms/maths/magic_number.py)
212213
- [krishnamurthy_number](algorithms/maths/krishnamurthy_number.py)
213214
- [modular_exponential](algorithms/maths/modular_exponential.py)
214215
- [modular_inverse](algorithms/maths/modular_inverse.py)

algorithms/maths/__init__.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,4 +19,5 @@
1919
from .find_primitive_root_simple import *
2020
from .diffie_hellman_key_exchange import *
2121
from .power import *
22-
from .krishnamurthy_number import *
22+
from .magic_number import *
23+
from .krishnamurthy_number import *

algorithms/maths/magic_number.py

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
"""Magic Number
2+
A number is said to be a magic number,
3+
if the sum of its digits are calculated till a single digit recursively
4+
by adding the sum of the digits after every addition.
5+
If the single digit comes out to be 1,then the number is a magic number.
6+
7+
Example:
8+
Number = 50113 => 5+0+1+1+3=10 => 1+0=1 [This is a Magic Number]
9+
Number = 1234 => 1+2+3+4=10 => 1+0=1 [This is a Magic Number]
10+
Number = 199 => 1+9+9=19 => 1+9=10 => 1+0=1 [This is a Magic Number]
11+
Number = 111 => 1+1+1=3 [This is NOT a Magic Number]
12+
13+
The following function checks for Magic numbers and returns a Boolean accordingly.
14+
"""
15+
16+
17+
def magic_number(n):
18+
total_sum = 0
19+
20+
# will end when n becomes 0
21+
# AND
22+
# sum becomes single digit.
23+
while n > 0 or total_sum > 9:
24+
25+
# when n becomes 0 but we have a total_sum,
26+
# we update the value of n with the value of the sum digits
27+
if n == 0:
28+
n = total_sum # only when sum of digits isn't single digit
29+
total_sum = 0
30+
total_sum += n % 10
31+
n //= 10
32+
33+
# Return true if sum becomes 1
34+
return total_sum == 1
35+
36+

tests/test_maths.py

Lines changed: 37 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
from algorithms.maths import (
2-
power,power_recur,
2+
power, power_recur,
33
int_to_base, base_to_int,
44
decimal_to_binary_ip,
55
euler_totient,
@@ -19,10 +19,11 @@
1919
combination, combination_memo,
2020
hailstone,
2121
cosine_similarity,
22+
magic_number,
2223
find_order,
2324
find_primitive_root,
24-
alice_private_key, alice_public_key, bob_private_key, bob_public_key, alice_shared_key, bob_shared_key, diffie_hellman_key_exchange,
25-
krishnamurthy_number,
25+
alice_private_key, alice_public_key, bob_private_key, bob_public_key, alice_shared_key, bob_shared_key,
26+
diffie_hellman_key_exchange, krishnamurthy_number
2627
)
2728

2829
import unittest
@@ -40,13 +41,13 @@ def test_power(self):
4041
self.assertEqual(8, power(2, 3))
4142
self.assertEqual(1, power(5, 0))
4243
self.assertEqual(0, power(10, 3, 5))
43-
self.assertEqual(280380, power(2265, 1664,465465))
44+
self.assertEqual(280380, power(2265, 1664, 465465))
4445

4546
def test_power_recur(self):
4647
self.assertEqual(8, power_recur(2, 3))
4748
self.assertEqual(1, power_recur(5, 0))
4849
self.assertEqual(0, power_recur(10, 3, 5))
49-
self.assertEqual(280380, power_recur(2265, 1664,465465))
50+
self.assertEqual(280380, power_recur(2265, 1664, 465465))
5051

5152

5253
class TestBaseConversion(unittest.TestCase):
@@ -136,6 +137,7 @@ def test_gcd_bit(self):
136137
self.assertEqual(4, gcd_bit(8, 12))
137138
self.assertEqual(1, gcd(13, 17))
138139

140+
139141
class TestGenerateStroboGrammatic(unittest.TestCase):
140142
"""[summary]
141143
Test for the file generate_strobogrammatic.py
@@ -174,7 +176,7 @@ class TestModularInverse(unittest.TestCase):
174176
175177
Arguments:
176178
unittest {[type]} -- [description]
177-
"""
179+
"""
178180

179181
def test_modular_inverse(self):
180182
# checks if x * x_inv == 1 (mod m)
@@ -183,6 +185,7 @@ def test_modular_inverse(self):
183185
self.assertEqual(1, 2 * modular_inverse.modular_inverse(2, 1000000007) % 1000000007)
184186
self.assertRaises(ValueError, modular_inverse.modular_inverse, 2, 20)
185187

188+
186189
class TestModularExponential(unittest.TestCase):
187190
"""[summary]
188191
Test for the file modular_Exponential.py
@@ -193,8 +196,8 @@ class TestModularExponential(unittest.TestCase):
193196

194197
def test_modular_exponential(self):
195198
self.assertEqual(1, modular_exponential(5, 117, 19))
196-
self.assertEqual(pow(1243, 65321, 10**9 + 7),
197-
modular_exponential(1243, 65321, 10**9 + 7))
199+
self.assertEqual(pow(1243, 65321, 10 ** 9 + 7),
200+
modular_exponential(1243, 65321, 10 ** 9 + 7))
198201
self.assertEqual(1, modular_exponential(12, 0, 78))
199202
self.assertRaises(ValueError, modular_exponential, 12, -2, 455)
200203

@@ -284,7 +287,6 @@ class TestRSA(unittest.TestCase):
284287
"""
285288

286289
def test_encrypt_decrypt(self):
287-
288290
self.assertEqual(7, decrypt(encrypt(7, 23, 143), 47, 143))
289291

290292
# def test_key_generator(self): # this test takes a while!
@@ -326,15 +328,15 @@ def test_factorial(self):
326328
self.assertEqual(1, factorial(0))
327329
self.assertEqual(120, factorial(5))
328330
self.assertEqual(3628800, factorial(10))
329-
self.assertEqual(637816310, factorial(34521, 10**9 + 7))
331+
self.assertEqual(637816310, factorial(34521, 10 ** 9 + 7))
330332
self.assertRaises(ValueError, factorial, -42)
331333
self.assertRaises(ValueError, factorial, 42, -1)
332334

333335
def test_factorial_recur(self):
334336
self.assertEqual(1, factorial_recur(0))
335337
self.assertEqual(120, factorial_recur(5))
336338
self.assertEqual(3628800, factorial_recur(10))
337-
self.assertEqual(637816310, factorial_recur(34521, 10**9 + 7))
339+
self.assertEqual(637816310, factorial_recur(34521, 10 ** 9 + 7))
338340
self.assertRaises(ValueError, factorial_recur, -42)
339341
self.assertRaises(ValueError, factorial_recur, 42, -1)
340342

@@ -346,6 +348,7 @@ class TestHailstone(unittest.TestCase):
346348
Arguments:
347349
unittest {[type]} -- [description]
348350
"""
351+
349352
def test_hailstone(self):
350353
self.assertEqual([8, 4, 2, 1], hailstone.hailstone(8))
351354
self.assertEqual([10, 5, 16, 8, 4, 2, 1], hailstone.hailstone(10))
@@ -358,6 +361,7 @@ class TestCosineSimilarity(unittest.TestCase):
358361
Arguments:
359362
unittest {[type]} -- [description]
360363
"""
364+
361365
def test_cosine_similarity(self):
362366
vec_a = [1, 1, 1]
363367
vec_b = [-1, -1, -1]
@@ -374,12 +378,13 @@ class TestFindPrimitiveRoot(unittest.TestCase):
374378
Arguments:
375379
unittest {[type]} -- [description]
376380
"""
381+
377382
def test_find_primitive_root_simple(self):
378383
self.assertListEqual([0], find_primitive_root(1))
379384
self.assertListEqual([2, 3], find_primitive_root(5))
380385
self.assertListEqual([], find_primitive_root(24))
381386
self.assertListEqual([2, 5, 13, 15, 17, 18, 19, 20, 22, 24, 32, 35], find_primitive_root(37))
382-
387+
383388

384389
class TestFindOrder(unittest.TestCase):
385390
"""[summary]
@@ -388,6 +393,7 @@ class TestFindOrder(unittest.TestCase):
388393
Arguments:
389394
unittest {[type]} -- [description]
390395
"""
396+
391397
def test_find_order_simple(self):
392398
self.assertEqual(1, find_order(1, 1))
393399
self.assertEqual(6, find_order(3, 7))
@@ -410,19 +416,37 @@ def test_krishnamurthy_number(self):
410416
self.assertTrue(krishnamurthy_number(40585))
411417

412418

419+
class TestMagicNumber(unittest.TestCase):
420+
"""[summary]
421+
Test for the file find_order_simple.py
422+
423+
Arguments:
424+
unittest {[type]} -- [description]
425+
"""
426+
427+
def test_magic_number(self):
428+
self.assertTrue(magic_number(50113))
429+
self.assertTrue(magic_number(1234))
430+
self.assertTrue(magic_number(100))
431+
self.assertTrue(magic_number(199))
432+
self.assertFalse(magic_number(2000))
433+
self.assertFalse(magic_number(500000))
434+
435+
413436
class TestDiffieHellmanKeyExchange(unittest.TestCase):
414437
"""[summary]
415438
Test for the file diffie_hellman_key_exchange.py
416439
417440
Arguments:
418441
unittest {[type]} -- [description]
419442
"""
443+
420444
def test_find_order_simple(self):
421445
self.assertFalse(diffie_hellman_key_exchange(3, 6))
422446
self.assertTrue(diffie_hellman_key_exchange(3, 353))
423447
self.assertFalse(diffie_hellman_key_exchange(5, 211))
424448
self.assertTrue(diffie_hellman_key_exchange(11, 971))
425449

450+
426451
if __name__ == "__main__":
427452
unittest.main()
428-

0 commit comments

Comments
 (0)