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
Related
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.
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 ...
So I am trying to create a very simple RSA encryption/decryption program where I only encrypt/decrypt int numbers. All works fine except for one problem. Sometimes my decrypted number (message) does not match my original number (the message I needed to encrypt and decrypt). This seems to happen whenever my inputted number (message) is close to my the number in my 'n' variable (n=p*q where p and q are prime numbers). I have browsed Stackoverflow a bit now and have found out that RSA algoritms cannot properly decrypt messages that are greater than 'n'. But in my case it fails to decrypt messages that are close to 'n'. If n=35 and my input number (the number to encrypt/decrypt) is 32, the program does not properly decrypt it back to 32 despite 32 being lower than 35 (works for 31, 30 ... though). Why?
Code:
import math
def isPrime(n):
if n>=2:
for m in range(2, int(math.sqrt(n)+1)):
if n%m == 0:
return False
return True
else:
return False
def gcd(x, y):
while y != 0:
(x, y) = (y, x % y)
return x
def phi(n):
amount = 0
for k in range(1, n + 1):
if gcd(n, k) == 1:
amount += 1
return amount
def findPubE(n, phiN):
for e in range(3, n, 2):
if gcd(e,phiN)==1:
return e
else:
raise AssertionError("cannot find 'e'")
def multiplicative_inverse(a, b):
"""Returns a tuple (r, i, j) such that r = gcd(a, b) = ia + jb
"""
# r = gcd(a,b) i = multiplicitive inverse of a mod b
# or j = multiplicitive inverse of b mod a
# Neg return values for i or j are made positive mod b or a respectively
# Iterateive Version is faster and uses much less stack space
x = 0
y = 1
lx = 1
ly = 0
oa = a # Remember original a/b to remove
ob = b # negative values from return results
while b != 0:
q = a // b
(a, b) = (b, a % b)
(x, lx) = ((lx - (q * x)), x)
(y, ly) = ((ly - (q * y)), y)
if lx < 0:
lx += ob # If neg wrap modulo orignal b
if ly < 0:
ly += oa # If neg wrap modulo orignal a
# return a , lx, ly # Return only positive values
return lx
def encrypt(m,e,n):
return (m^(e)) % n
def decrypt(M, d):
return M^(d)
def main():
p=int(input("Input first prime number (p): "))
q=int(input("Input second prime number (q): "))
n=p*q
print("n = ",n)
msg= int(input("Input message: "))
assert msg < n
phiN=(p-1)*(q-1)
e = findPubE(n,phiN)
d = multiplicative_inverse(e,phiN)
encryptedMsg = encrypt(msg,e,n)
decryptedMsg = decrypt(encryptedMsg,d)
assert isPrime(p) and isPrime(q)
print("phi(n) = ",phiN)
print("e = ",e)
print("d = ",d)
print("Encrypted message: ",encryptedMsg)
print("Decrypted message: ",decryptedMsg)
main()
Solved it! I made two little mistakes in my code. First one was that I assumed that the "^" symbol meant "to the power of" in Python (the correct symbol is "**") and the second one was that I forgot to add "mod n" to the line in my decrypt() function (so return M**(d) % n instead of return M^(d)).
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)
If I have an simple function (pseudocode) like
fun(a, b):
x = a
i = 0
while i < b do
x = x + a
i ++
return x
Can I replace the while loop in this function by a recursion?
Something like:
fun (a, b, i):
if i >= b:
return 1
else:
return a + fun(a, b, i + 1)
Without using an extra parameter you can try:
def f(a, b):
if b <= 1:
return a
else:
return a + f(a, b - 1)
Note: This will only work for b >= 1.
def fun(x, y):
if y != 0:
for i in fun(x, y-1):
yield x + i
yield 0