Recursive function that returns the remainder - python

I am instructed to define a recursive function in Python that finds the remainder of n divided by b with the condition to not use the "/" ,"%" or "//" operator. I have defined the following function, which works fine for positive numbers. Is there a better way to do this using recursion and simple conditions.
def division(n, b, q = 1):
"""
parameters : a et b (integers)
returns: the remainder of a and b
pre-requisites : q = 1
"""
if n <= 0 or n < b:
if n == 0:
print("Your division has no remainder.")
elif n in range(0,5):
print("Your remainder is", n)
return 0
else:
return division(n - b, b, q) + q
print(division(274,5))

I believe your teacher was probably only trying to go for remainders without quotients.
def division(n, b):
if n < b:
return n
return division(n - b, b)
print(division(274, 5))
However, since you brought it up, you can do it with the quotient, without having to start with a 1 for the default.
def division(n, b, q = 0):
if n < b:
return n, q
return division(n - b, b, q + 1)
print(division(274, 5))
Main takeaways, you do not need to check n for range (0,5).

What about
def remainder(n, q):
if(n < q):
return n
return remainder(n - q, q)
print(remainder(274, 5)) # will return: 4
print(remainder(275, 5)) # will return: 0
print(remainder(123, 3)) # will return: 0
much shorter ...

Related

Python function that is supposed to return the nth Fibonacci number, but it's returning the wrong value for certain inputs

def fibonacci(n):
if n <= 0:
return 0
elif n == 1:
return 1
else:
return fibonacci(n-1) + fibonacci(n-2)
print(fibonacci(5)) # should return 3
have a Python function that is supposed to return the nth Fibonacci number, but it's returning the wrong value for certain inputs.
You could write a generator that is designed to return up n Fibonacci numbers. Out of that, create a list and print the last item in that list.
For example:
def fibonacci(n):
a = 0
b = 1
for _ in range(n):
yield a
a, b = b, a + b
print(list(fibonacci(5))[-1])
Output:
3
Note:
I only suggest this way as I already had the generator coded. Perhaps better would be:
def fibonacci(n):
a = 0
b = 1
for _ in range(n-1):
a, b = b, a + b
return a
print(fibonacci(5))

RSA Cryptography shows wrong result for large prime numbers

I implemented a RSA Cryptography program, using python, and it works perfectly using prime numbers with aproximally 10 digits. But when I use numbers with 25 digits or more, for example, it does not work.
It worked with the following keys:
p = 2324731
q = 186647
e = 433899328297
n = 433904066957
It not worked with:
p = 3673864730662357928718503
q = 2127738717256957618781057
e = 7817024229395103552360986476332293342120062315901
n = 7817024229395103552360993847944520620136941797671
here's the code:
inverse (d key):
#classmethod
def __linearOperation(cls, a, b, mdc, i):
t = -int(a / b)
r = a % b
mdc.append([1, a, t, b])
if r == 1:
return mdc
inverseLine = cls.__linearOperation(b, r, mdc, i + 1)
s = inverseLine[i][0]
t = inverseLine[i][2]
inverseLine[i - 1][0] *= t
inverseLine[i - 1][2] *= t
inverseLine[i - 1][2] += s
inverseLine.remove(inverseLine[i])
return inverseLine
def __inverse(self, e, φ):
inverseLine = self.__linearOperation(e, φ, [], 1)
inverse = inverseLine[0][0]
if inverse < 0:
return inverse + φ
if inverse > φ:
return inverse % φ
else:
return inverse
Modular Exponentiation:
#staticmethod
def __QuickMod(base, exp, n):
result = 1
while exp > 0:
if exp & 1:
result = (result * base) % n
base = (base ** 2) % n
exp = exp >> 1
return result
encrypt/decrypt:
def encryptChar(self, n: int, e: int, M: int) -> int:
C = self.__QuickMod(M, e, n) # C = M^e mod n
return C
def decryptChar(self, p: int, q: int, e: int, C: int) -> int:
d = self.__inverse(e, (p - 1) * (q - 1))
M = self.__QuickMod(C, d, p * q) # M = C^d mod n
return M
By trying to encrypt the number 109 ("m" char in ascII), the encryptChar function returns 6825028446539883496812231478440519650519629664279.
By trying to decrypt the number above the decryptChar function should returns the number 109 back. But that's not what happens.
In my conception, by using python we do not have number size restriction.
Is there something i'm not seeing? Thank you for your help.
The problem is in my inverse algorithm. I'll try to re-implement it. But using pow() function with -1 as expoent works.

Variable not properly updating when searching for consecutive primes

Consider the following script:
Python
def f(a, b, n):
return (n ** 2) + (a * n) + b
def prime_check(num):
for i in range(2, (num // 2) + 1):
if num % i == 0:
return False
return True
num_primes = []
coefficients = []
for a in range(-999, 1000, 1):
for b in range(-1000, 1001, 1):
n = 0
coefficients.append((a, b))
while True:
result = prime_check(f(a, b, n))
if result:
n += 1
continue
else:
num_primes.append(n - 1)
break
print(f"num_primes: {num_primes[-1]} coefficients: {coefficients[-1]}")
The algorithm above is meant to search values of |a| < 1000 , |b| <= 1000, for function f(a, b, n), where n = 0 to start, and increments if f(a, b, n) returns a prime number. It keeps incrementing n and checking for primes until f returns a non-prime.
At this point, n - 1 is appended to num_primes to reflect the number of primes this set of coefficients (a, b) produced for consecutive values of n.
When I run this code, the print statement at the end of the inner for loop shows num_primes values are stuck alternating between whatever value b is for the current iteration and 0, rather than the proper number of primes for the coefficients.
I'm not sure where I went wrong here.
As noted by #JohanC, when prime_check(num) was given a negative number, it would return True no matter what the number was.
The fix for this was to make a simple change to prime_check(num) as shown below.
Python
def prime_check(num):
for i in range(2, (abs(num) // 2) + 1):
if num % i == 0:
return False
return True
By calculating abs(num) before division, we eliminate the bad behavior when num < 0.

GCD implementation in python

I am solving this problem in SPOJ and it states that :
Problem statement is simple. Given A and B you need to calculate
S(A,B) .
Here, f(n)=n, if n is square free otherwise 0. Also f(1)=1.
Input
The first line contains one integer T - denoting the number of test
cases.
T lines follow each containing two integers A,B.
Output
For each testcase output the value of S(A,B) mod 1000000007 in a
single line.
Constraints
`T <= 1000
1 <= A,B <= 1000000`
Example
Input:
3
42 18
35 1
20 25
Output:
306395
630
128819
I wrote this code for this problem (if I got the the problem right) :
def gcd(a,b): #gcd(a,b)
if b==0:
return a
else:
return gcd(b,a%b)
# print gcd(42,18)
import math
def issquarefree(n): #sqare free number check
i=2
s=i*i
if (n==1 or n==2) or n==3:
return True
while s<=n:
if n%s==0:
i=-1
break
else:
i+=1
s=i*i
if i==-1:return False
else:
return True
for i in range(int(raw_input())): #main program
a,b=map(int,raw_input().split())
g=gcd(a,b)
sa=(a*(a+1))/2 #see below
sb=(b*(b+1))/2 #see below
gc=issquarefree(g)
s=0
if gc== False:
print 0
elif gc==True:
s+=sa*sb*g
print s%1000000007
here I found that so applying this to the problem # S(A,B) I wrote this as (multiplication of sum of first A and B numbers ) multiplied by f(n) which is gcd(a,b) or 0.
But I am not getting the expected output to this problem so is my code wrong or I got the problem wrong
my output vs expected
3
35 1
42 18
20 25
630 630
926478 306395
341250 128819
Writing out the G(a, b) = f(gcd(a, b)) (so that you can use the cited formula) is incorrect since the function is not constant. The proper solution is this:
for i in range(int(raw_input())):
A, B = map(int, raw_input().split())
# proper algorithm
s = 0
for a in xrange(1, A):
for b in xrange(1, B):
s += a * b * G(a, b)
print s % 1000000007
You obviously have to implement G function properly (as returning 0 or gcd(a, b)).
Careful analysis of G might give some optimization insight but it is definitely not a trivial one if any.
Here is a simple optimization:
import fractions
DIVISOR = 1000000007
def is_not_square_free(a):
counter = 1
factor = 1
while factor < a:
counter += 1
factor = counter * counter
if a % factor == 0:
return True
return factor == a
def F(n):
if n == 1:
return 1
if is_not_square_free(n):
return 0
return n
_CACHE = {}
def G(a, b):
a = a % DIVISOR
b = b % DIVISOR
key = (a, b) if a > b else (b, a)
if key not in _CACHE:
_CACHE[key] = (a * b * F(fractions.gcd(a, b))) % DIVISOR
return _CACHE[key]
def S(A, B):
s = 0
for a in range(1, A+1):
for b in range(1, B+1):
s += G(a, b)
return s
for _ in range(int(raw_input())):
A, B = map(int, raw_input().split())
print(S(A, B) % DIVISOR)
def gcd(a, b):
returns greatest common divisor of a and b'''
return gcd(b % a, a) if a and b else max(a, b)
print test gcd should print 6,5, 7, and 9'''
print gcd(48,18)
print gcd(10,5)
print gcd(14,21)
print gcd (9,0)

Harmonic series in python

Does anyone know how to code the Harmonic Series in python?
H(n) = 1 + 1/2 + 1/3 + ... + 1/n
Note: We're not allowed to import from predefined modules. The output must be the numerator and the denominator of the answer in fraction form (lowest terms).
so here's my code for this harmonic series.
n = input("Enter n:")
def harmonic(n):
a=1
b=1
for d in range(2, n+1):
a = a*d+b
b = b*d
return (a,b)
x == max(a,b)%min(a, b)
if x == 0:
y=min(a,b)
return y
else:
y=min(a,b)/x
return y
a=a/y
b=b/y
return (a,b)
print harmonic(n)
what's wrong? Whatever I input, the output is always (3,2)
I have to check your attempt twice - and inserted a simple gcd (in the middle of the your original code)
n = input("Enter n:")
def harmonic(n): #original harmonic series
a=1
b=1
for d in range(2, n+1):
a = a*d+b
b = b*d
return(a,b)
def harmonic_lt(n): #_lt: harmonic series with lowest terms
#not pythonic, but simple
a=1
b=1
for d in range(2, n+1):
a = a*d+b
b = b*d
y=a
x=b
while x > 0:
re = y % x
y = x
x = re
a=a/y
b=b/y
return(a,b)
print harmonic(n)
print harmonic_lt(n)
As others pointed out, you are returning when d = 2 i.e. (1 + 1/2), it should be outside of the for loop.
Here's a code I wrote for doing the same:
#!Python2.7
def gcd(a, b):
if b: return gcd(b, a%b)
return a
def lcm(a, b):
return a*b/gcd(a, b)
def start():
n = int(raw_input())
ans = reduce(lambda x, y: (x[0]*lcm(x[1],y[1])/x[1]+y[0]*lcm(x[1],y[1])/y[1], lcm(x[1],y[1])),[(1,x) for x in xrange(1,n+1)])
_gcd = gcd(ans[0], ans[1])
print (ans[0]/_gcd, ans[1]/_gcd)
start()
If you want to avoid using reduce, lamda and list comprehensions:
#!Python2.7
def gcd(a, b):
if b: return gcd(b, a%b)
return a
def lcm(a, b):
assert a != 0
assert b != 0
return a*b/gcd(a, b)
def next(x, y):
lcmxy = lcm(x[1], y[1])
return (x[0]*lcmxy/x[1]+y[0]*lcmxy/y[1], lcmxy)
def start():
n = int(raw_input())
curr = (1,1)
for x in xrange(2,n+1):
curr = next(curr, (1,x))
_gcd = gcd(curr[0], curr[1])
print (curr[0]/_gcd, curr[1]/_gcd)
start()
You can find the denominator by finding the lowest common multiple of the numbers 1..n.
The nominator will then be the sum of all values denominator/x with x being all values from 1..n.
Here's some code:
def gcd(a, b):
"""Return greatest common divisor using Euclid's Algorithm."""
while b:
a, b = b, a % b
return a
def lcm(a, b):
"""Return lowest common multiple."""
return a * b // gcd(a, b)
def lcmm(args):
"""Return lcm of args."""
return reduce(lcm, args)
def harmonic(n):
lowest_common_multiple = lcmm(range(1,n))
nominator = sum([lowest_common_multiple/i for i in range(1,n)])
greatest_common_denominator = gcd(lowest_common_multiple, nominator)
return nominator/greatest_common_denominator, lowest_common_multiple/greatest_common_denominator
print harmonic(7)
print harmonic(10)
print harmonic(20)
Harmonic series:
1/1 + 1/2 + ... + 1/n == (n!/1 + n!/2 + ... + n!/n)/n!
therefore you can do:
nom = reduce(lambda s, x: s*x, xrange(1, n+1),1) # n!
denom = sum([nom / x for x in xrange(1, n+1)])
Then you need to do gcd-reduction on nom and denom.
Use the version from Thorsten Kranz.
Note that this way only one call to gcd is needed!
Example:
def gcd(a, b):
while b:
a, b = b, a % b
return a
def harmonic(n):
nom = reduce(lambda s, x: s*x, xrange(1,n+1), 1) # n!
denom = sum([nom / x for x in xrange(1, n+1)])
f = gcd(denom, nom)
return (denom / f), (nom / f)
print harmonic(10)
print harmonic(20)
(7381, 2520)
(55835135, 15519504)
You always return (a,b) at the first iteration. – Scharron"
Return always ends a function. If you return (a,b), the rest of the code is unreachable

Categories

Resources