TheAlgorithms-Python
841 строка · 19.8 Кб
1"""
2Created on Thu Oct 5 16:44:23 2017
3
4@author: Christian Bender
5
6This Python library contains some useful functions to deal with
7prime numbers and whole numbers.
8
9Overview:
10
11is_prime(number)
12sieve_er(N)
13get_prime_numbers(N)
14prime_factorization(number)
15greatest_prime_factor(number)
16smallest_prime_factor(number)
17get_prime(n)
18get_primes_between(pNumber1, pNumber2)
19
20----
21
22is_even(number)
23is_odd(number)
24kg_v(number1, number2) // least common multiple
25get_divisors(number) // all divisors of 'number' inclusive 1, number
26is_perfect_number(number)
27
28NEW-FUNCTIONS
29
30simplify_fraction(numerator, denominator)
31factorial (n) // n!
32fib (n) // calculate the n-th fibonacci term.
33
34-----
35
36goldbach(number) // Goldbach's assumption
37
38"""
39
40from math import sqrt41
42from maths.greatest_common_divisor import gcd_by_iterative43
44
45def is_prime(number: int) -> bool:46"""47input: positive integer 'number'
48returns true if 'number' is prime otherwise false.
49
50>>> is_prime(3)
51True
52>>> is_prime(10)
53False
54>>> is_prime(97)
55True
56>>> is_prime(9991)
57False
58>>> is_prime(-1)
59Traceback (most recent call last):
60...
61AssertionError: 'number' must been an int and positive
62>>> is_prime("test")
63Traceback (most recent call last):
64...
65AssertionError: 'number' must been an int and positive
66"""
67
68# precondition69assert isinstance(number, int) and (70number >= 071), "'number' must been an int and positive"72
73status = True74
75# 0 and 1 are none primes.76if number <= 1:77status = False78
79for divisor in range(2, int(round(sqrt(number))) + 1):80# if 'number' divisible by 'divisor' then sets 'status'81# of false and break up the loop.82if number % divisor == 0:83status = False84break85
86# precondition87assert isinstance(status, bool), "'status' must been from type bool"88
89return status90
91
92# ------------------------------------------
93
94
95def sieve_er(n):96"""97input: positive integer 'N' > 2
98returns a list of prime numbers from 2 up to N.
99
100This function implements the algorithm called
101sieve of erathostenes.
102
103>>> sieve_er(8)
104[2, 3, 5, 7]
105>>> sieve_er(-1)
106Traceback (most recent call last):
107...
108AssertionError: 'N' must been an int and > 2
109>>> sieve_er("test")
110Traceback (most recent call last):
111...
112AssertionError: 'N' must been an int and > 2
113"""
114
115# precondition116assert isinstance(n, int) and (n > 2), "'N' must been an int and > 2"117
118# beginList: contains all natural numbers from 2 up to N119begin_list = list(range(2, n + 1))120
121ans = [] # this list will be returns.122
123# actual sieve of erathostenes124for i in range(len(begin_list)):125for j in range(i + 1, len(begin_list)):126if (begin_list[i] != 0) and (begin_list[j] % begin_list[i] == 0):127begin_list[j] = 0128
129# filters actual prime numbers.130ans = [x for x in begin_list if x != 0]131
132# precondition133assert isinstance(ans, list), "'ans' must been from type list"134
135return ans136
137
138# --------------------------------
139
140
141def get_prime_numbers(n):142"""143input: positive integer 'N' > 2
144returns a list of prime numbers from 2 up to N (inclusive)
145This function is more efficient as function 'sieveEr(...)'
146
147>>> get_prime_numbers(8)
148[2, 3, 5, 7]
149>>> get_prime_numbers(-1)
150Traceback (most recent call last):
151...
152AssertionError: 'N' must been an int and > 2
153>>> get_prime_numbers("test")
154Traceback (most recent call last):
155...
156AssertionError: 'N' must been an int and > 2
157"""
158
159# precondition160assert isinstance(n, int) and (n > 2), "'N' must been an int and > 2"161
162ans = []163
164# iterates over all numbers between 2 up to N+1165# if a number is prime then appends to list 'ans'166for number in range(2, n + 1):167if is_prime(number):168ans.append(number)169
170# precondition171assert isinstance(ans, list), "'ans' must been from type list"172
173return ans174
175
176# -----------------------------------------
177
178
179def prime_factorization(number):180"""181input: positive integer 'number'
182returns a list of the prime number factors of 'number'
183
184>>> prime_factorization(0)
185[0]
186>>> prime_factorization(8)
187[2, 2, 2]
188>>> prime_factorization(287)
189[7, 41]
190>>> prime_factorization(-1)
191Traceback (most recent call last):
192...
193AssertionError: 'number' must been an int and >= 0
194>>> prime_factorization("test")
195Traceback (most recent call last):
196...
197AssertionError: 'number' must been an int and >= 0
198"""
199
200# precondition201assert isinstance(number, int) and number >= 0, "'number' must been an int and >= 0"202
203ans = [] # this list will be returns of the function.204
205# potential prime number factors.206
207factor = 2208
209quotient = number210
211if number in {0, 1}:212ans.append(number)213
214# if 'number' not prime then builds the prime factorization of 'number'215elif not is_prime(number):216while quotient != 1:217if is_prime(factor) and (quotient % factor == 0):218ans.append(factor)219quotient /= factor220else:221factor += 1222
223else:224ans.append(number)225
226# precondition227assert isinstance(ans, list), "'ans' must been from type list"228
229return ans230
231
232# -----------------------------------------
233
234
235def greatest_prime_factor(number):236"""237input: positive integer 'number' >= 0
238returns the greatest prime number factor of 'number'
239
240>>> greatest_prime_factor(0)
2410
242>>> greatest_prime_factor(8)
2432
244>>> greatest_prime_factor(287)
24541
246>>> greatest_prime_factor(-1)
247Traceback (most recent call last):
248...
249AssertionError: 'number' must been an int and >= 0
250>>> greatest_prime_factor("test")
251Traceback (most recent call last):
252...
253AssertionError: 'number' must been an int and >= 0
254"""
255
256# precondition257assert isinstance(number, int) and (258number >= 0259), "'number' must been an int and >= 0"260
261ans = 0262
263# prime factorization of 'number'264prime_factors = prime_factorization(number)265
266ans = max(prime_factors)267
268# precondition269assert isinstance(ans, int), "'ans' must been from type int"270
271return ans272
273
274# ----------------------------------------------
275
276
277def smallest_prime_factor(number):278"""279input: integer 'number' >= 0
280returns the smallest prime number factor of 'number'
281
282>>> smallest_prime_factor(0)
2830
284>>> smallest_prime_factor(8)
2852
286>>> smallest_prime_factor(287)
2877
288>>> smallest_prime_factor(-1)
289Traceback (most recent call last):
290...
291AssertionError: 'number' must been an int and >= 0
292>>> smallest_prime_factor("test")
293Traceback (most recent call last):
294...
295AssertionError: 'number' must been an int and >= 0
296"""
297
298# precondition299assert isinstance(number, int) and (300number >= 0301), "'number' must been an int and >= 0"302
303ans = 0304
305# prime factorization of 'number'306prime_factors = prime_factorization(number)307
308ans = min(prime_factors)309
310# precondition311assert isinstance(ans, int), "'ans' must been from type int"312
313return ans314
315
316# ----------------------
317
318
319def is_even(number):320"""321input: integer 'number'
322returns true if 'number' is even, otherwise false.
323
324>>> is_even(0)
325True
326>>> is_even(8)
327True
328>>> is_even(287)
329False
330>>> is_even(-1)
331False
332>>> is_even("test")
333Traceback (most recent call last):
334...
335AssertionError: 'number' must been an int
336"""
337
338# precondition339assert isinstance(number, int), "'number' must been an int"340assert isinstance(number % 2 == 0, bool), "compare must been from type bool"341
342return number % 2 == 0343
344
345# ------------------------
346
347
348def is_odd(number):349"""350input: integer 'number'
351returns true if 'number' is odd, otherwise false.
352
353>>> is_odd(0)
354False
355>>> is_odd(8)
356False
357>>> is_odd(287)
358True
359>>> is_odd(-1)
360True
361>>> is_odd("test")
362Traceback (most recent call last):
363...
364AssertionError: 'number' must been an int
365"""
366
367# precondition368assert isinstance(number, int), "'number' must been an int"369assert isinstance(number % 2 != 0, bool), "compare must been from type bool"370
371return number % 2 != 0372
373
374# ------------------------
375
376
377def goldbach(number):378"""379Goldbach's assumption
380input: a even positive integer 'number' > 2
381returns a list of two prime numbers whose sum is equal to 'number'
382
383>>> goldbach(8)
384[3, 5]
385>>> goldbach(824)
386[3, 821]
387>>> goldbach(0)
388Traceback (most recent call last):
389...
390AssertionError: 'number' must been an int, even and > 2
391>>> goldbach(-1)
392Traceback (most recent call last):
393...
394AssertionError: 'number' must been an int, even and > 2
395>>> goldbach("test")
396Traceback (most recent call last):
397...
398AssertionError: 'number' must been an int, even and > 2
399"""
400
401# precondition402assert (403isinstance(number, int) and (number > 2) and is_even(number)404), "'number' must been an int, even and > 2"405
406ans = [] # this list will returned407
408# creates a list of prime numbers between 2 up to 'number'409prime_numbers = get_prime_numbers(number)410len_pn = len(prime_numbers)411
412# run variable for while-loops.413i = 0414j = None415
416# exit variable. for break up the loops417loop = True418
419while i < len_pn and loop:420j = i + 1421
422while j < len_pn and loop:423if prime_numbers[i] + prime_numbers[j] == number:424loop = False425ans.append(prime_numbers[i])426ans.append(prime_numbers[j])427
428j += 1429
430i += 1431
432# precondition433assert (434isinstance(ans, list)435and (len(ans) == 2)436and (ans[0] + ans[1] == number)437and is_prime(ans[0])438and is_prime(ans[1])439), "'ans' must contains two primes. And sum of elements must been eq 'number'"440
441return ans442
443
444# ----------------------------------------------
445
446
447def kg_v(number1, number2):448"""449Least common multiple
450input: two positive integer 'number1' and 'number2'
451returns the least common multiple of 'number1' and 'number2'
452
453>>> kg_v(8,10)
45440
455>>> kg_v(824,67)
45655208
457>>> kg_v(1, 10)
45810
459>>> kg_v(0)
460Traceback (most recent call last):
461...
462TypeError: kg_v() missing 1 required positional argument: 'number2'
463>>> kg_v(10,-1)
464Traceback (most recent call last):
465...
466AssertionError: 'number1' and 'number2' must been positive integer.
467>>> kg_v("test","test2")
468Traceback (most recent call last):
469...
470AssertionError: 'number1' and 'number2' must been positive integer.
471"""
472
473# precondition474assert (475isinstance(number1, int)476and isinstance(number2, int)477and (number1 >= 1)478and (number2 >= 1)479), "'number1' and 'number2' must been positive integer."480
481ans = 1 # actual answer that will be return.482
483# for kgV (x,1)484if number1 > 1 and number2 > 1:485# builds the prime factorization of 'number1' and 'number2'486prime_fac_1 = prime_factorization(number1)487prime_fac_2 = prime_factorization(number2)488
489elif number1 == 1 or number2 == 1:490prime_fac_1 = []491prime_fac_2 = []492ans = max(number1, number2)493
494count1 = 0495count2 = 0496
497done = [] # captured numbers int both 'primeFac1' and 'primeFac2'498
499# iterates through primeFac1500for n in prime_fac_1:501if n not in done:502if n in prime_fac_2:503count1 = prime_fac_1.count(n)504count2 = prime_fac_2.count(n)505
506for _ in range(max(count1, count2)):507ans *= n508
509else:510count1 = prime_fac_1.count(n)511
512for _ in range(count1):513ans *= n514
515done.append(n)516
517# iterates through primeFac2518for n in prime_fac_2:519if n not in done:520count2 = prime_fac_2.count(n)521
522for _ in range(count2):523ans *= n524
525done.append(n)526
527# precondition528assert isinstance(ans, int) and (529ans >= 0530), "'ans' must been from type int and positive"531
532return ans533
534
535# ----------------------------------
536
537
538def get_prime(n):539"""540Gets the n-th prime number.
541input: positive integer 'n' >= 0
542returns the n-th prime number, beginning at index 0
543
544>>> get_prime(0)
5452
546>>> get_prime(8)
54723
548>>> get_prime(824)
5496337
550>>> get_prime(-1)
551Traceback (most recent call last):
552...
553AssertionError: 'number' must been a positive int
554>>> get_prime("test")
555Traceback (most recent call last):
556...
557AssertionError: 'number' must been a positive int
558"""
559
560# precondition561assert isinstance(n, int) and (n >= 0), "'number' must been a positive int"562
563index = 0564ans = 2 # this variable holds the answer565
566while index < n:567index += 1568
569ans += 1 # counts to the next number570
571# if ans not prime then572# runs to the next prime number.573while not is_prime(ans):574ans += 1575
576# precondition577assert isinstance(ans, int) and is_prime(578ans
579), "'ans' must been a prime number and from type int"580
581return ans582
583
584# ---------------------------------------------------
585
586
587def get_primes_between(p_number_1, p_number_2):588"""589input: prime numbers 'pNumber1' and 'pNumber2'
590pNumber1 < pNumber2
591returns a list of all prime numbers between 'pNumber1' (exclusive)
592and 'pNumber2' (exclusive)
593
594>>> get_primes_between(3, 67)
595[5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61]
596>>> get_primes_between(0)
597Traceback (most recent call last):
598...
599TypeError: get_primes_between() missing 1 required positional argument: 'p_number_2'
600>>> get_primes_between(0, 1)
601Traceback (most recent call last):
602...
603AssertionError: The arguments must been prime numbers and 'pNumber1' < 'pNumber2'
604>>> get_primes_between(-1, 3)
605Traceback (most recent call last):
606...
607AssertionError: 'number' must been an int and positive
608>>> get_primes_between("test","test")
609Traceback (most recent call last):
610...
611AssertionError: 'number' must been an int and positive
612"""
613
614# precondition615assert (616is_prime(p_number_1) and is_prime(p_number_2) and (p_number_1 < p_number_2)617), "The arguments must been prime numbers and 'pNumber1' < 'pNumber2'"618
619number = p_number_1 + 1 # jump to the next number620
621ans = [] # this list will be returns.622
623# if number is not prime then624# fetch the next prime number.625while not is_prime(number):626number += 1627
628while number < p_number_2:629ans.append(number)630
631number += 1632
633# fetch the next prime number.634while not is_prime(number):635number += 1636
637# precondition638assert (639isinstance(ans, list)640and ans[0] != p_number_1641and ans[len(ans) - 1] != p_number_2642), "'ans' must been a list without the arguments"643
644# 'ans' contains not 'pNumber1' and 'pNumber2' !645return ans646
647
648# ----------------------------------------------------
649
650
651def get_divisors(n):652"""653input: positive integer 'n' >= 1
654returns all divisors of n (inclusive 1 and 'n')
655
656>>> get_divisors(8)
657[1, 2, 4, 8]
658>>> get_divisors(824)
659[1, 2, 4, 8, 103, 206, 412, 824]
660>>> get_divisors(-1)
661Traceback (most recent call last):
662...
663AssertionError: 'n' must been int and >= 1
664>>> get_divisors("test")
665Traceback (most recent call last):
666...
667AssertionError: 'n' must been int and >= 1
668"""
669
670# precondition671assert isinstance(n, int) and (n >= 1), "'n' must been int and >= 1"672
673ans = [] # will be returned.674
675for divisor in range(1, n + 1):676if n % divisor == 0:677ans.append(divisor)678
679# precondition680assert ans[0] == 1 and ans[len(ans) - 1] == n, "Error in function getDivisiors(...)"681
682return ans683
684
685# ----------------------------------------------------
686
687
688def is_perfect_number(number):689"""690input: positive integer 'number' > 1
691returns true if 'number' is a perfect number otherwise false.
692
693>>> is_perfect_number(28)
694True
695>>> is_perfect_number(824)
696False
697>>> is_perfect_number(-1)
698Traceback (most recent call last):
699...
700AssertionError: 'number' must been an int and >= 1
701>>> is_perfect_number("test")
702Traceback (most recent call last):
703...
704AssertionError: 'number' must been an int and >= 1
705"""
706
707# precondition708assert isinstance(number, int) and (709number > 1710), "'number' must been an int and >= 1"711
712divisors = get_divisors(number)713
714# precondition715assert (716isinstance(divisors, list)717and (divisors[0] == 1)718and (divisors[len(divisors) - 1] == number)719), "Error in help-function getDivisiors(...)"720
721# summed all divisors up to 'number' (exclusive), hence [:-1]722return sum(divisors[:-1]) == number723
724
725# ------------------------------------------------------------
726
727
728def simplify_fraction(numerator, denominator):729"""730input: two integer 'numerator' and 'denominator'
731assumes: 'denominator' != 0
732returns: a tuple with simplify numerator and denominator.
733
734>>> simplify_fraction(10, 20)
735(1, 2)
736>>> simplify_fraction(10, -1)
737(10, -1)
738>>> simplify_fraction("test","test")
739Traceback (most recent call last):
740...
741AssertionError: The arguments must been from type int and 'denominator' != 0
742"""
743
744# precondition745assert (746isinstance(numerator, int)747and isinstance(denominator, int)748and (denominator != 0)749), "The arguments must been from type int and 'denominator' != 0"750
751# build the greatest common divisor of numerator and denominator.752gcd_of_fraction = gcd_by_iterative(abs(numerator), abs(denominator))753
754# precondition755assert (756isinstance(gcd_of_fraction, int)757and (numerator % gcd_of_fraction == 0)758and (denominator % gcd_of_fraction == 0)759), "Error in function gcd_by_iterative(...,...)"760
761return (numerator // gcd_of_fraction, denominator // gcd_of_fraction)762
763
764# -----------------------------------------------------------------
765
766
767def factorial(n):768"""769input: positive integer 'n'
770returns the factorial of 'n' (n!)
771
772>>> factorial(0)
7731
774>>> factorial(20)
7752432902008176640000
776>>> factorial(-1)
777Traceback (most recent call last):
778...
779AssertionError: 'n' must been a int and >= 0
780>>> factorial("test")
781Traceback (most recent call last):
782...
783AssertionError: 'n' must been a int and >= 0
784"""
785
786# precondition787assert isinstance(n, int) and (n >= 0), "'n' must been a int and >= 0"788
789ans = 1 # this will be return.790
791for factor in range(1, n + 1):792ans *= factor793
794return ans795
796
797# -------------------------------------------------------------------
798
799
800def fib(n: int) -> int:801"""802input: positive integer 'n'
803returns the n-th fibonacci term , indexing by 0
804
805>>> fib(0)
8061
807>>> fib(5)
8088
809>>> fib(20)
81010946
811>>> fib(99)
812354224848179261915075
813>>> fib(-1)
814Traceback (most recent call last):
815...
816AssertionError: 'n' must been an int and >= 0
817>>> fib("test")
818Traceback (most recent call last):
819...
820AssertionError: 'n' must been an int and >= 0
821"""
822
823# precondition824assert isinstance(n, int) and (n >= 0), "'n' must been an int and >= 0"825
826tmp = 0827fib1 = 1828ans = 1 # this will be return829
830for _ in range(n - 1):831tmp = ans832ans += fib1833fib1 = tmp834
835return ans836
837
838if __name__ == "__main__":839import doctest840
841doctest.testmod()842