Python check through two lists - python

I am relatively new to python and I came across a problem given below:
Given two lists a and b and an integer n, Check if
a) All elements of a is a factor of n
b) n is a factor of all elements of b
My code doesn't seem to be correct. Can someone please point out the mistake here.
return n if n%x==0 for x in a and y%n==0 for y in b
Any help is appreciated

Obvious one (you were missing all(...)):
all(n % x == 0 for x in a) and all(y % n == 0 for y in b)
Fun one:
0 == n % reduce(lcm, a) == reduce(gcd, b) % n
Requires Python 3.9, though.
Test code:
from itertools import product
from math import gcd, lcm
from functools import reduce
R = range(1, 11)
true = false = 0
for n in R:
for a in product(R, repeat=3):
for b in product(R, repeat=3):
expect = all(n % x == 0 for x in a) and all(y % n == 0 for y in b)
result = 0 == n % reduce(lcm, a) == reduce(gcd, b) % n
assert result == expect
true += expect
false += not expect
print(true, false)
=> No failures, same 2,723 true results and 9,997,277 false results.

Related

I am trying to write a function in Python encapsulating the Miller-Rabin primality test, but it is very slow

Here is my code:
import random
def miller(n, k):
"""
takes an integer n and evaluates whether it is a prime or a composite
n > 3, odd integer to be tested for primality
k, rounds of testing (the more tests, the more accurate the result)
"""
temp = n - 1 # used to find r and d in n = 2**d * r + 1, hence temporary
r = 0
while True:
if temp / 2 == type(int):
r += 1
else:
d = temp
break
temp = temp / 2
for _ in range(k):
a = random.SystemRandom().randrange(2, n - 2)
x = a**d % n
if x == 1 or x == n - 1:
continue
for _ in range(r - 1):
x = x**2 % n
if x == n - 1:
continue
return "Composite"
return "Probably prime"
Certainly there must be more effective ways to implement the algorithm in Python, so that it may handle large integers with ease?
Cheers

Why classical division ("/") for large integers is much slower than integer division ("//")?

I ran into a problem: The code was very slow for 512 bit odd integers if you use classical division for (p-1)/2. But with floor division it works instantly. Is it caused by float conversion?
def solovayStrassen(p, iterations):
for i in range(iterations):
a = random.randint(2, p - 1)
if gcd(a, p) > 1:
return False
first = pow(a, int((p - 1) / 2), p)
j = (Jacobian(a, p) + p) % p
if first != j:
return False
return True
The full code
import random
from math import gcd
#Jacobian symbol
def Jacobian(a, n):
if (a == 0):
return 0
ans = 1
if (a < 0):
a = -a
if (n % 4 == 3):
ans = -ans
if (a == 1):
return ans
while (a):
if (a < 0):
a = -a
if (n % 4 == 3):
ans = -ans
while (a % 2 == 0):
a = a // 2
if (n % 8 == 3 or n % 8 == 5):
ans = -ans
a, n = n, a
if (a % 4 == 3 and n % 4 == 3):
ans = -ans
a = a % n
if (a > n // 2):
a = a - n
if (n == 1):
return ans
return 0
def solovayStrassen(p, iterations):
for i in range(iterations):
a = random.randint(2, p - 1)
if gcd(a, p) > 1:
return False
first = pow(a, int((p - 1) / 2), p)
j = (Jacobian(a, p) + p) % p
if first != j:
return False
return True
def findFirstPrime(n, k):
while True:
if solovayStrassen(n,k):
return n
n+=2
a = random.getrandbits(512)
if a%2==0:
a+=1
print(findFirstPrime(a,100))
As noted in comments, int((p - 1) / 2) can produce garbage if p is an integer with more than 53 bits. Only the first 53 bits of p-1 are retained when converting to float for the division.
>>> p = 123456789123456789123456789
>>> (p-1) // 2
61728394561728394561728394
>>> hex(_)
'0x330f7ef971d8cfbe022f8a'
>>> int((p-1) / 2)
61728394561728395668881408
>>> hex(_) # lots of trailing zeroes
'0x330f7ef971d8d000000000'
Of course the theory underlying the primality test relies on using exactly the infinitely precise value of (p-1)/2, not some approximation more-or-less good to only the first 53 most-significant bits.
As also noted in a comment, using garbage is likely to make this part return earlier, not later:
if first != j:
return False
So why is it much slower over all? Because findFirstPrime() has to call solovayStrassen() many more times to find garbage that passes by sheer blind luck.
To see this, change the code to show how often the loop is trying:
def findFirstPrime(n, k):
count = 0
while True:
count += 1
if count % 1000 == 0:
print(f"at count {count:,}")
if solovayStrassen(n,k):
return n, count
n+=2
Then add, e.g.,
random.seed(12)
at the start of the main program so you can get reproducible results.
Using floor (//) division, it runs fairly quickly, displaying
(6170518232878265099306454685234429219657996228748920426206889067017854517343512513954857500421232718472897893847571955479036221948870073830638539006377457, 906)
So it found a probable prime on the 906th try.
But with float (/) division, I never saw it succeed by blind luck:
at count 1,000
at count 2,000
at count 3,000
...
at count 1,000,000
Gave up then - "garbage in, garbage out".
One other thing to note, in passing: the + p in:
j = (Jacobian(a, p) + p) % p
has no effect on the value of j. Right? p % p is 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)

How to divide with a loop? (Python)

I am trying to write a function to determine if a number is prime. I have come up with
the following solution, however inelegant, but cannot figure out how to write it.
I want to do the following: take the number x and divide it by every number that is less than itself. If any solution equals zero, print 'Not prime.' If no solution equals zero, print 'Prime.'
In other words, I want the function to do the following:
x % (x - 1) =
x % (x - 2) =
x % (x - 3) =
x % (x - 4) =
etc...
Here is as far as I have been able to get:
def prime_num(x):
p = x - 1
p = p - 1
L = (x % (p))
while p > 0:
return L
Wikipedia provides one possible primality check in Python
def is_prime(n):
if n <= 3:
return n >= 2
if n % 2 == 0 or n % 3 == 0:
return False
for i in range(5, int(n ** 0.5) + 1, 6):
if n % i == 0 or n % (i + 2) == 0:
return False
return True

Prime factorization - list

I am trying to implement a function primeFac() that takes as input a positive integer n and returns a list containing all the numbers in the prime factorization of n.
I have gotten this far but I think it would be better to use recursion here, not sure how to create a recursive code here, what would be the base case? to start with.
My code:
def primes(n):
primfac = []
d = 2
while (n > 1):
if n%d==0:
primfac.append(d)
# how do I continue from here... ?
A simple trial division:
def primes(n):
primfac = []
d = 2
while d*d <= n:
while (n % d) == 0:
primfac.append(d) # supposing you want multiple factors repeated
n //= d
d += 1
if n > 1:
primfac.append(n)
return primfac
with O(sqrt(n)) complexity (worst case). You can easily improve it by special-casing 2 and looping only over odd d (or special-casing more small primes and looping over fewer possible divisors).
The primefac module does factorizations with all the fancy techniques mathematicians have developed over the centuries:
#!python
import primefac
import sys
n = int( sys.argv[1] )
factors = list( primefac.primefac(n) )
print '\n'.join(map(str, factors))
This is a comprehension based solution, it might be the closest you can get to a recursive solution in Python while being possible to use for large numbers.
You can get proper divisors with one line:
divisors = [ d for d in xrange(2,int(math.sqrt(n))) if n % d == 0 ]
then we can test for a number in divisors to be prime:
def isprime(d): return all( d % od != 0 for od in divisors if od != d )
which tests that no other divisors divides d.
Then we can filter prime divisors:
prime_divisors = [ d for d in divisors if isprime(d) ]
Of course, it can be combined in a single function:
def primes(n):
divisors = [ d for d in range(2,n//2+1) if n % d == 0 ]
return [ d for d in divisors if \
all( d % od != 0 for od in divisors if od != d ) ]
Here, the \ is there to break the line without messing with Python indentation.
I've tweaked #user448810's answer to use iterators from itertools (and python3.4, but it should be back-portable). The solution is about 15% faster.
import itertools
def factors(n):
f = 2
increments = itertools.chain([1,2,2], itertools.cycle([4,2,4,2,4,6,2,6]))
for incr in increments:
if f*f > n:
break
while n % f == 0:
yield f
n //= f
f += incr
if n > 1:
yield n
Note that this returns an iterable, not a list. Wrap it in list() if that's what you want.
Most of the above solutions appear somewhat incomplete. A prime factorization would repeat each prime factor of the number (e.g. 9 = [3 3]).
Also, the above solutions could be written as lazy functions for implementation convenience.
The use sieve Of Eratosthenes to find primes to test is optimal, but; the above implementation used more memory than necessary.
I'm not certain if/how "wheel factorization" would be superior to applying only prime factors, for division tests of n.
While these solution are indeed helpful, I'd suggest the following two functions -
Function-1 :
def primes(n):
if n < 2: return
yield 2
plist = [2]
for i in range(3,n):
test = True
for j in plist:
if j>n**0.5:
break
if i%j==0:
test = False
break
if test:
plist.append(i)
yield i
Function-2 :
def pfactors(n):
for p in primes(n):
while n%p==0:
yield p
n=n//p
if n==1: return
list(pfactors(99999))
[3, 3, 41, 271]
3*3*41*271
99999
list(pfactors(13290059))
[3119, 4261]
3119*4261
13290059
Here is my version of factorization by trial division, which incorporates the optimization of dividing only by two and the odd integers proposed by Daniel Fischer:
def factors(n):
f, fs = 3, []
while n % 2 == 0:
fs.append(2)
n /= 2
while f * f <= n:
while n % f == 0:
fs.append(f)
n /= f
f += 2
if n > 1: fs.append(n)
return fs
An improvement on trial division by two and the odd numbers is wheel factorization, which uses a cyclic set of gaps between potential primes to greatly reduce the number of trial divisions. Here we use a 2,3,5-wheel:
def factors(n):
gaps = [1,2,2,4,2,4,2,4,6,2,6]
length, cycle = 11, 3
f, fs, nxt = 2, [], 0
while f * f <= n:
while n % f == 0:
fs.append(f)
n /= f
f += gaps[nxt]
nxt += 1
if nxt == length:
nxt = cycle
if n > 1: fs.append(n)
return fs
Thus, print factors(13290059) will output [3119, 4261]. Factoring wheels have the same O(sqrt(n)) time complexity as normal trial division, but will be two or three times faster in practice.
I've done a lot of work with prime numbers at my blog. Please feel free to visit and study.
def get_prime_factors(number):
"""
Return prime factor list for a given number
number - an integer number
Example: get_prime_factors(8) --> [2, 2, 2].
"""
if number == 1:
return []
# We have to begin with 2 instead of 1 or 0
# to avoid the calls infinite or the division by 0
for i in xrange(2, number):
# Get remainder and quotient
rd, qt = divmod(number, i)
if not qt: # if equal to zero
return [i] + get_prime_factors(rd)
return [number]
Most of the answer are making things too complex. We can do this
def prime_factors(n):
num = []
#add 2 to list or prime factors and remove all even numbers(like sieve of ertosthenes)
while(n%2 == 0):
num.append(2)
n /= 2
#divide by odd numbers and remove all of their multiples increment by 2 if no perfectlly devides add it
for i in xrange(3, int(sqrt(n))+1, 2):
while (n%i == 0):
num.append(i)
n /= i
#if no is > 2 i.e no is a prime number that is only divisible by itself add it
if n>2:
num.append(n)
print (num)
Algorithm from GeeksforGeeks
prime factors of a number:
def primefactors(x):
factorlist=[]
loop=2
while loop<=x:
if x%loop==0:
x//=loop
factorlist.append(loop)
else:
loop+=1
return factorlist
x = int(input())
alist=primefactors(x)
print(alist)
You'll get the list.
If you want to get the pairs of prime factors of a number try this:
http://pythonplanet.blogspot.in/2015/09/list-of-all-unique-pairs-of-prime.html
def factorize(n):
for f in range(2,n//2+1):
while n%f == 0:
n //= f
yield f
It's slow but dead simple. If you want to create a command-line utility, you could do:
import sys
[print(i) for i in factorize(int(sys.argv[1]))]
Here is an efficient way to accomplish what you need:
def prime_factors(n):
l = []
if n < 2: return l
if n&1==0:
l.append(2)
while n&1==0: n>>=1
i = 3
m = int(math.sqrt(n))+1
while i < m:
if n%i==0:
l.append(i)
while n%i==0: n//=i
i+= 2
m = int(math.sqrt(n))+1
if n>2: l.append(n)
return l
prime_factors(198765430488765430290) = [2, 3, 5, 7, 11, 13, 19, 23, 3607, 3803, 52579]
You can use sieve Of Eratosthenes to generate all the primes up to (n/2) + 1 and then use a list comprehension to get all the prime factors:
def rwh_primes2(n):
# http://stackoverflow.com/questions/2068372/fastest-way-to-list-all-primes-below-n-in-python/3035188#3035188
""" Input n>=6, Returns a list of primes, 2 <= p < n """
correction = (n%6>1)
n = {0:n,1:n-1,2:n+4,3:n+3,4:n+2,5:n+1}[n%6]
sieve = [True] * (n/3)
sieve[0] = False
for i in xrange(int(n**0.5)/3+1):
if sieve[i]:
k=3*i+1|1
sieve[ ((k*k)/3) ::2*k]=[False]*((n/6-(k*k)/6-1)/k+1)
sieve[(k*k+4*k-2*k*(i&1))/3::2*k]=[False]*((n/6-(k*k+4*k-2*k*(i&1))/6-1)/k+1)
return [2,3] + [3*i+1|1 for i in xrange(1,n/3-correction) if sieve[i]]
def primeFacs(n):
primes = rwh_primes2((n/2)+1)
return [x for x in primes if n%x == 0]
print primeFacs(99999)
#[3, 41, 271]
from sets import Set
# this function generates all the possible factors of a required number x
def factors_mult(X):
L = []
[L.append(i) for i in range(2,X) if X % i == 0]
return L
# this function generates list containing prime numbers upto the required number x
def prime_range(X):
l = [2]
for i in range(3,X+1):
for j in range(2,i):
if i % j == 0:
break
else:
l.append(i)
return l
# This function computes the intersection of the two lists by invoking Set from the sets module
def prime_factors(X):
y = Set(prime_range(X))
z = Set(factors_mult(X))
k = list(y & z)
k = sorted(k)
print "The prime factors of " + str(X) + " is ", k
# for eg
prime_factors(356)
Simple way to get the desired solution
def Factor(n):
d = 2
factors = []
while n >= d*d:
if n % d == 0:
n//=d
# print(d,end = " ")
factors.append(d)
else:
d = d+1
if n>1:
# print(int(n))
factors.append(n)
return factors
This is the code I made. It works fine for numbers with small primes, but it takes a while for numbers with primes in the millions.
def pfactor(num):
div = 2
pflist = []
while div <= num:
if num % div == 0:
pflist.append(div)
num /= div
else:
div += 1
# The stuff afterwards is just to convert the list of primes into an expression
pfex = ''
for item in list(set(pflist)):
pfex += str(item) + '^' + str(pflist.count(item)) + ' * '
pfex = pfex[0:-3]
return pfex
I would like to share my code for finding the prime factors of number given input by the user:
a = int(input("Enter a number: "))
def prime(a):
b = list()
i = 1
while i<=a:
if a%i ==0 and i!=1 and i!=a:
b.append(i)
i+=1
return b
c = list()
for x in prime(a):
if len(prime(x)) == 0:
c.append(x)
print(c)
def prime_factors(num, dd=2):
while dd <= num and num>1:
if num % dd == 0:
num //= dd
yield dd
dd +=1
Lot of answers above fail on small primes, e.g. 3, 5 and 7. The above is succinct and fast enough for ordinary use.
print list(prime_factors(3))
[3]

Categories

Resources