From 50d39561e4748f44840f08dc90eeac9f36ebe2fb Mon Sep 17 00:00:00 2001 From: christianbender Date: Sat, 18 Nov 2017 16:29:34 +0100 Subject: [PATCH 1/8] primelib This python library contains some useful functions to deal with prime numbers and whole numbers. The ideas came by the problems sets from ProjectEuler. --- other/primelib.py | 605 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 605 insertions(+) create mode 100644 other/primelib.py diff --git a/other/primelib.py b/other/primelib.py new file mode 100644 index 000000000..16c44a093 --- /dev/null +++ b/other/primelib.py @@ -0,0 +1,605 @@ +# -*- coding: utf-8 -*- +""" +Created on Thu Oct 5 16:44:23 2017 + +@author: Christian Bender + +This python library contains some useful functions to deal with +prime numbers and whole numbers. + +Overview: + +isPrime(number) +sieveEr(N) +getPrimeNumbers(N) +primeFactorization(number) +greatestPrimeFactor(number) +smallestPrimeFactor(number) +getPrime(n) +getPrimesBetween(pNumber1, pNumber2) + +---- + +isEven(number) +isOdd(number) +gcd(number1, number2) // greatest common divisor +kgV(number1, number2) // least common multiple +getDivisors(number) // all divisors of 'number' inclusive 1, number +isPerfectNumber(number) + +NEW-FUNCTIONS + +simplifyFraction(numerator, denominator) +factorial (n) // n! +fib (n) // calculate the n-th fibonacci term. + +----- + +goldbach(number) // Goldbach's assumption + +""" + +def isPrime(number): + """ + input: positive integer 'number' + returns true if 'number' is prime otherwise false. + """ + import math # for function sqrt + + # precondition + assert isinstance(number,int) and (number >= 0) , \ + "'number' must been an int and positive" + + status = True + + # 0 and 1 are none primes. + if number <= 1: + status = False + + for divisor in range(2,int(round(math.sqrt(number)))+1): + + # if 'number' divisible by 'divisor' then sets 'status' + # of false and break up the loop. + if number % divisor == 0: + status = False + break + + # precondition + assert isinstance(status,bool), "'status' must been from type bool" + + return status + +# ------------------------------------------ + +def sieveEr(N): + """ + input: positive integer 'N' > 2 + returns a list of prime numbers from 2 up to N. + + This function implements the algorithm called + sieve of erathostenes. + + """ + + # precondition + assert isinstance(N,int) and (N > 2), "'N' must been an int and > 2" + + # beginList: conatins all natural numbers from 2 upt to N + beginList = [x for x in range(2,N+1)] + + ans = [] # this list will be returns. + + # actual sieve of erathostenes + for i in range(len(beginList)): + + for j in range(i+1,len(beginList)): + + if (beginList[i] != 0) and \ + (beginList[j] % beginList[i] == 0): + beginList[j] = 0 + + # filters actual prime numbers. + ans = [x for x in beginList if x != 0] + + # precondition + assert isinstance(ans,list), "'ans' must been from type list" + + return ans + + +# -------------------------------- + +def getPrimeNumbers(N): + """ + input: positive integer 'N' > 2 + returns a list of prime numbers from 2 up to N (inclusive) + This function is more efficient as function 'sieveEr(...)' + """ + + # precondition + assert isinstance(N,int) and (N > 2), "'N' must been an int and > 2" + + ans = [] + + # iterates over all numbers between 2 up to N+1 + # if a number is prime then appends to list 'ans' + for number in range(2,N+1): + + if isPrime(number): + + ans.append(number) + + # precondition + assert isinstance(ans,list), "'ans' must been from type list" + + return ans + + +# ----------------------------------------- + +def primeFactorization(number): + """ + input: positive integer 'number' + returns a list of the prime number factors of 'number' + """ + + import math # for function sqrt + + # precondition + assert isinstance(number,int) and number >= 0, \ + "'number' must been an int and >= 0" + + ans = [] # this list will be returns of the function. + + # potential prime number factors. + + factor = 2 + + quotient = number + + + if number == 0 or number == 1: + + ans.append(number) + + # if 'number' not prime then builds the prime factorization of 'number' + elif not isPrime(number): + + while (quotient != 1): + + if isPrime(factor) and (quotient % factor == 0): + ans.append(factor) + quotient /= factor + else: + factor += 1 + + else: + ans.append(number) + + # precondition + assert isinstance(ans,list), "'ans' must been from type list" + + return ans + + +# ----------------------------------------- + +def greatestPrimeFactor(number): + """ + input: positive integer 'number' >= 0 + returns the greatest prime number factor of 'number' + """ + + # precondition + assert isinstance(number,int) and (number >= 0), \ + "'number' bust been an int and >= 0" + + ans = 0 + + # prime factorization of 'number' + primeFactors = primeFactorization(number) + + ans = max(primeFactors) + + # precondition + assert isinstance(ans,int), "'ans' must been from type int" + + return ans + + +# ---------------------------------------------- + + +def smallestPrimeFactor(number): + """ + input: integer 'number' >= 0 + returns the smallest prime number factor of 'number' + """ + + # precondition + assert isinstance(number,int) and (number >= 0), \ + "'number' bust been an int and >= 0" + + ans = 0 + + # prime factorization of 'number' + primeFactors = primeFactorization(number) + + ans = min(primeFactors) + + # precondition + assert isinstance(ans,int), "'ans' must been from type int" + + return ans + + +# ---------------------- + +def isEven(number): + """ + input: integer 'number' + returns true if 'number' is even, otherwise false. + """ + + # precondition + assert isinstance(number, int), "'number' must been an int" + assert isinstance(number % 2 == 0, bool), "compare bust been from type bool" + + return number % 2 == 0 + +# ------------------------ + +def isOdd(number): + """ + input: integer 'number' + returns true if 'number' is odd, otherwise false. + """ + + # precondition + assert isinstance(number, int), "'number' must been an int" + assert isinstance(number % 2 != 0, bool), "compare bust been from type bool" + + return number % 2 != 0 + +# ------------------------ + + +def goldbach(number): + """ + Goldbach's assumption + input: a even positive integer 'number' > 2 + returns a list of two prime numbers whose sum is equal to 'number' + """ + + # precondition + assert isinstance(number,int) and (number > 2) and isEven(number), \ + "'number' must been an int, even and > 2" + + ans = [] # this list will returned + + # creates a list of prime numbers between 2 up to 'number' + primeNumbers = getPrimeNumbers(number) + lenPN = len(primeNumbers) + + # run variable for while-loops. + i = 0 + j = 1 + + # exit variable. for break up the loops + loop = True + + while (i < lenPN and loop): + + j = i+1; + + + while (j < lenPN and loop): + + if primeNumbers[i] + primeNumbers[j] == number: + loop = False + ans.append(primeNumbers[i]) + ans.append(primeNumbers[j]) + + j += 1; + + + i += 1 + + # precondition + assert isinstance(ans,list) and (len(ans) == 2) and \ + (ans[0] + ans[1] == number) and isPrime(ans[0]) and isPrime(ans[1]), \ + "'ans' must contains two primes. And sum of elements must been eq 'number'" + + return ans + +# ---------------------------------------------- + +def gcd(number1,number2): + """ + Greatest common divisor + input: two positive integer 'number1' and 'number2' + returns the greatest common divisor of 'number1' and 'number2' + """ + + # precondition + assert isinstance(number1,int) and isinstance(number2,int) \ + and (number1 >= 0) and (number2 >= 0), \ + "'number1' and 'number2' must been positive integer." + + rest = 0 + + while number2 != 0: + + rest = number1 % number2 + number1 = number2 + number2 = rest + + # precondition + assert isinstance(number1,int) and (number1 >= 0), \ + "'number' must been from type int and positive" + + return number1 + +# ---------------------------------------------------- + +def kgV(number1, number2): + """ + Least common multiple + input: two positive integer 'number1' and 'number2' + returns the least common multiple of 'number1' and 'number2' + """ + + # precondition + assert isinstance(number1,int) and isinstance(number2,int) \ + and (number1 >= 1) and (number2 >= 1), \ + "'number1' and 'number2' must been positive integer." + + ans = 1 # actual answer that will be return. + + # for kgV (x,1) + if number1 > 1 and number2 > 1: + + # builds the prime factorization of 'number1' and 'number2' + primeFac1 = primeFactorization(number1) + primeFac2 = primeFactorization(number2) + + elif number1 == 1 or number2 == 1: + + primeFac1 = [] + primeFac2 = [] + ans = max(number1,number2) + + count1 = 0 + count2 = 0 + + done = [] # captured numbers int both 'primeFac1' and 'primeFac2' + + # iterates through primeFac1 + for n in primeFac1: + + if n not in done: + + if n in primeFac2: + + count1 = primeFac1.count(n) + count2 = primeFac2.count(n) + + for i in range(max(count1,count2)): + ans *= n + + else: + + count1 = primeFac1.count(n) + + for i in range(count1): + ans *= n + + done.append(n) + + # iterates through primeFac2 + for n in primeFac2: + + if n not in done: + + count2 = primeFac2.count(n) + + for i in range(count2): + ans *= n + + done.append(n) + + # precondition + assert isinstance(ans,int) and (ans >= 0), \ + "'ans' must been from type int and positive" + + return ans + +# ---------------------------------- + +def getPrime(n): + """ + Gets the n-th prime number. + input: positive integer 'n' >= 0 + returns the n-th prime number, beginning at index 0 + """ + + # precondition + assert isinstance(n,int) and (n >= 0), "'number' must been a positive int" + + index = 0 + ans = 2 # this variable holds the answer + + while index < n: + + index += 1 + + ans += 1 # counts to the next number + + # if ans not prime then + # runs to the next prime number. + while not isPrime(ans): + ans += 1 + + # precondition + assert isinstance(ans,int) and isPrime(ans), \ + "'ans' must been a prime number and from type int" + + return ans + +# --------------------------------------------------- + +def getPrimesBetween(pNumber1, pNumber2): + """ + input: prime numbers 'pNumber1' and 'pNumber2' + pNumber1 < pNumber2 + returns a list of all prime numbers between 'pNumber1' (exclusiv) + and 'pNumber2' (exclusiv) + """ + + # precondition + assert isPrime(pNumber1) and isPrime(pNumber2) and (pNumber1 < pNumber2), \ + "The arguments must been prime numbers and 'pNumber1' < 'pNumber2'" + + number = pNumber1 + 1 # jump to the next number + + ans = [] # this list will be returns. + + # if number is not prime then + # fetch the next prime number. + while not isPrime(number): + number += 1 + + while number < pNumber2: + + ans.append(number) + + number += 1 + + # fetch the next prime number. + while not isPrime(number): + number += 1 + + # precondition + assert isinstance(ans,list) and ans[0] != pNumber1 \ + and ans[len(ans)-1] != pNumber2, \ + "'ans' must been a list without the arguments" + + # 'ans' contains not 'pNumber1' and 'pNumber2' ! + return ans + +# ---------------------------------------------------- + +def getDivisors(n): + """ + input: positive integer 'n' >= 1 + returns all divisors of n (inclusive 1 and 'n') + """ + + # precondition + assert isinstance(n,int) and (n >= 1), "'n' must been int and >= 1" + + from math import sqrt + + ans = [] # will be returned. + + for divisor in range(1,n+1): + + if n % divisor == 0: + ans.append(divisor) + + + #precondition + assert ans[0] == 1 and ans[len(ans)-1] == n, \ + "Error in function getDivisiors(...)" + + + return ans + + +# ---------------------------------------------------- + + +def isPerfectNumber(number): + """ + input: positive integer 'number' > 1 + returns true if 'number' is a perfect number otherwise false. + """ + + # precondition + assert isinstance(number,int) and (number > 1), \ + "'number' must been an int and >= 1" + + divisors = getDivisors(number) + + # precondition + assert isinstance(divisors,list) and(divisors[0] == 1) and \ + (divisors[len(divisors)-1] == number), \ + "Error in help-function getDivisiors(...)" + + # summed all divisors up to 'number' (exclusive), hence [:-1] + return sum(divisors[:-1]) == number + +# ------------------------------------------------------------ + +def simplifyFraction(numerator, denominator): + """ + input: two integer 'numerator' and 'denominator' + assumes: 'denominator' != 0 + returns: a tuple with simplify numerator and denominator. + """ + + # precondition + assert isinstance(numerator, int) and isinstance(denominator,int) \ + and (denominator != 0), \ + "The arguments must been from type int and 'denominator' != 0" + + # build the greatest common divisor of numerator and denominator. + gcdOfFraction = gcd(abs(numerator), abs(denominator)) + + # precondition + assert isinstance(gcdOfFraction, int) and (numerator % gcdOfFraction == 0) \ + and (denominator % gcdOfFraction == 0), \ + "Error in function gcd(...,...)" + + return (numerator // gcdOfFraction, denominator // gcdOfFraction) + +# ----------------------------------------------------------------- + +def factorial(n): + """ + input: positive integer 'n' + returns the factorial of 'n' (n!) + """ + + # precondition + assert isinstance(n,int) and (n >= 0), "'n' must been a int and >= 0" + + ans = 1 # this will be return. + + for factor in range(1,n+1): + ans *= factor + + return ans + +# ------------------------------------------------------------------- + +def fib(n): + """ + input: positive integer 'n' + returns the n-th fibonacci term , indexing by 0 + """ + + # precondition + assert isinstance(n, int) and (n >= 0), "'n' must been an int and >= 0" + + tmp = 0 + fib1 = 1 + ans = 1 # this will be return + + for i in range(n-1): + + tmp = ans + ans += fib1 + fib1 = tmp + + return ans From 567f2adab87baaec6872e28571a9725e6228f7a9 Mon Sep 17 00:00:00 2001 From: Christian Bender Date: Sun, 19 Nov 2017 14:54:30 +0100 Subject: [PATCH 2/8] Correction: Remove semicolons I have remove the semicolons in line 8 and line 12 --- Project Euler/Problem 01/sol1.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Project Euler/Problem 01/sol1.py b/Project Euler/Problem 01/sol1.py index 512154e29..0c87df75d 100644 --- a/Project Euler/Problem 01/sol1.py +++ b/Project Euler/Problem 01/sol1.py @@ -5,8 +5,8 @@ we get 3,5,6 and 9. The sum of these multiples is 23. Find the sum of all the multiples of 3 or 5 below N. ''' n = int(raw_input().strip()) -sum=0; +sum=0 for a in range(3,n): if(a%3==0 or a%5==0): sum+=a -print sum; \ No newline at end of file +print sum From a5c954ff6e66404a632c0f663f585363ebfdf006 Mon Sep 17 00:00:00 2001 From: Christian Bender Date: Sun, 19 Nov 2017 15:06:42 +0100 Subject: [PATCH 3/8] Correction: File solv3.py I have remove some semicolons. line 11, 12 and 42 --- Project Euler/Problem 01/sol3.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Project Euler/Problem 01/sol3.py b/Project Euler/Problem 01/sol3.py index 0caa30a53..5448cb897 100644 --- a/Project Euler/Problem 01/sol3.py +++ b/Project Euler/Problem 01/sol3.py @@ -8,8 +8,8 @@ Find the sum of all the multiples of 3 or 5 below N. This solution is based on the pattern that the successive numbers in the series follow: 0+3,+2,+1,+3,+1,+2,+3. ''' n = int(raw_input().strip()) -sum=0; -num=0; +sum=0 +num=0 while(1): num+=3 if(num>=n): @@ -39,4 +39,4 @@ while(1): if(num>=n): break sum+=num -print sum; \ No newline at end of file +print sum From 8d9da8f623141657e2fe69773a5f2a0408806261 Mon Sep 17 00:00:00 2001 From: Christian Bender Date: Sun, 19 Nov 2017 15:10:09 +0100 Subject: [PATCH 4/8] Correction: File solv01.py I have remove some semicolons. --- Project Euler/Problem 02/sol1.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/Project Euler/Problem 02/sol1.py b/Project Euler/Problem 02/sol1.py index 6cf520767..065af1ebd 100644 --- a/Project Euler/Problem 02/sol1.py +++ b/Project Euler/Problem 02/sol1.py @@ -8,11 +8,13 @@ e.g. for n=10, we have {2,8}, sum is 10. ''' n = int(raw_input().strip()) -i=1; j=2; sum=0 +i=1 +j=2 +sum=0 while(j<=n): if((j&1)==0): #can also use (j%2==0) sum+=j temp=i i=j j=temp+i -print sum \ No newline at end of file +print sum From 01f48e708d4f1b093b02818510dc2ab58154382a Mon Sep 17 00:00:00 2001 From: Christian Bender Date: Sun, 19 Nov 2017 15:13:50 +0100 Subject: [PATCH 5/8] Correction: File solv01.py Identifier 'max' changed in 'maxNumber' , since 'max' is a function. --- Project Euler/Problem 03/sol1.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Project Euler/Problem 03/sol1.py b/Project Euler/Problem 03/sol1.py index bd3e237e7..23ab8746a 100644 --- a/Project Euler/Problem 03/sol1.py +++ b/Project Euler/Problem 03/sol1.py @@ -17,7 +17,7 @@ def isprime(no): return False return True -max=0 +maxNumber = 0 n=int(input()) if(isprime(n)): print n @@ -31,8 +31,8 @@ else: for i in range(3,n1,2): if(n%i==0): if(isprime(n/i)): - max=n/i + maxNumber = n/i break elif(isprime(i)): - max=i - print max + maxNumber = i + print maxNumber From abe0f29b8be567d99f01cec362dafa301219e5a0 Mon Sep 17 00:00:00 2001 From: Christian Bender Date: Sun, 19 Nov 2017 22:01:31 +0100 Subject: [PATCH 6/8] Problem 29 -- Project Euler On this solution I used a 'set' data structure, since more efficient. --- main.py | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) create mode 100644 main.py diff --git a/main.py b/main.py new file mode 100644 index 000000000..9d6148da3 --- /dev/null +++ b/main.py @@ -0,0 +1,34 @@ +def main(): + """ + Consider all integer combinations of ab for 2 <= a <= 5 and 2 <= b <= 5: + + 22=4, 23=8, 24=16, 25=32 + 32=9, 33=27, 34=81, 35=243 + 42=16, 43=64, 44=256, 45=1024 + 52=25, 53=125, 54=625, 55=3125 + If they are then placed in numerical order, with any repeats removed, we get the following sequence of 15 distinct terms: + + 4, 8, 9, 16, 25, 27, 32, 64, 81, 125, 243, 256, 625, 1024, 3125 + + How many distinct terms are in the sequence generated by ab for 2 <= a <= 100 and 2 <= b <= 100? + """ + + collectPowers = set() + + currentPow = 0 + + N = 101 # maximum limit + + for a in range(2,N): + + for b in range (2,N): + + currentPow = a**b # calculates the current power + collectPowers.add(currentPow) # adds the result to the set + + + print "Number of terms ", len(collectPowers) + + +if __name__ == '__main__': + main() From 01ae338b75a92b37d9463c12640e1cdf11a8034f Mon Sep 17 00:00:00 2001 From: Christian Bender Date: Sun, 19 Nov 2017 22:02:06 +0100 Subject: [PATCH 7/8] Delete main.py --- main.py | 34 ---------------------------------- 1 file changed, 34 deletions(-) delete mode 100644 main.py diff --git a/main.py b/main.py deleted file mode 100644 index 9d6148da3..000000000 --- a/main.py +++ /dev/null @@ -1,34 +0,0 @@ -def main(): - """ - Consider all integer combinations of ab for 2 <= a <= 5 and 2 <= b <= 5: - - 22=4, 23=8, 24=16, 25=32 - 32=9, 33=27, 34=81, 35=243 - 42=16, 43=64, 44=256, 45=1024 - 52=25, 53=125, 54=625, 55=3125 - If they are then placed in numerical order, with any repeats removed, we get the following sequence of 15 distinct terms: - - 4, 8, 9, 16, 25, 27, 32, 64, 81, 125, 243, 256, 625, 1024, 3125 - - How many distinct terms are in the sequence generated by ab for 2 <= a <= 100 and 2 <= b <= 100? - """ - - collectPowers = set() - - currentPow = 0 - - N = 101 # maximum limit - - for a in range(2,N): - - for b in range (2,N): - - currentPow = a**b # calculates the current power - collectPowers.add(currentPow) # adds the result to the set - - - print "Number of terms ", len(collectPowers) - - -if __name__ == '__main__': - main() From 31ebde6e17c2d4b996701779eeb9bc05837834fa Mon Sep 17 00:00:00 2001 From: Christian Bender Date: Sun, 19 Nov 2017 22:03:30 +0100 Subject: [PATCH 8/8] Problem 29 On this solution I used a 'set' data structure, since more efficient. --- Project Euler/Problem 29/solution.py | 34 ++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) create mode 100644 Project Euler/Problem 29/solution.py diff --git a/Project Euler/Problem 29/solution.py b/Project Euler/Problem 29/solution.py new file mode 100644 index 000000000..9d6148da3 --- /dev/null +++ b/Project Euler/Problem 29/solution.py @@ -0,0 +1,34 @@ +def main(): + """ + Consider all integer combinations of ab for 2 <= a <= 5 and 2 <= b <= 5: + + 22=4, 23=8, 24=16, 25=32 + 32=9, 33=27, 34=81, 35=243 + 42=16, 43=64, 44=256, 45=1024 + 52=25, 53=125, 54=625, 55=3125 + If they are then placed in numerical order, with any repeats removed, we get the following sequence of 15 distinct terms: + + 4, 8, 9, 16, 25, 27, 32, 64, 81, 125, 243, 256, 625, 1024, 3125 + + How many distinct terms are in the sequence generated by ab for 2 <= a <= 100 and 2 <= b <= 100? + """ + + collectPowers = set() + + currentPow = 0 + + N = 101 # maximum limit + + for a in range(2,N): + + for b in range (2,N): + + currentPow = a**b # calculates the current power + collectPowers.add(currentPow) # adds the result to the set + + + print "Number of terms ", len(collectPowers) + + +if __name__ == '__main__': + main()