why use True is slower than use 1 in Python3 - python

I've read this question: Why is if True slower than if 1?, but i'm using Python3 now. I am writing leetcode 204 and someone said that using one is faster than using two.
My code:
import timeit
count = 1000
def countPrimes(n=100000):
if n < 3:
return 0
primes = [True] * n
primes[0], primes[1] = False, False
for i in range(2, int(n ** 0.5) + 1):
if primes[i]:
for j in range(i * i, n, i):
primes[j] = False
return sum(primes)
def countPrimes2(n=100000):
if n < 3:
return 0
primes = [1] * n
primes[0], primes[1] = 0, 0
for i in range(2, int(n ** 0.5) + 1):
if primes[i]:
for j in range(i * i, n, i):
primes[j] = 0
return sum(primes)
print('use False,True ', timeit.timeit(countPrimes, number=count))
print('use 0,1 ', timeit.timeit(countPrimes2, number=count))
The result is:
-> % python3 test.py
use False,True 10.634566191001795
use 0,1 9.187052419991232
Can anyone tell me why?

ok, as furas said, it's the sum cost much time:
import timeit
count = 1000
def countPrimes(n=100000):
primes = [True] * n
return sum(primes)
def countPrimes2(n=100000):
primes = [1] * n
return sum(primes)
print('use False,True ', timeit.timeit(countPrimes, number=count))
print('use 0,1 ', timeit.timeit(countPrimes2, number=count))
result is:
-> % python3 test.py
use False,True 2.4546820300165564
use 0,1 1.0242620470235124
without sum:
import timeit
count = 1000
def countPrimes(n=100000):
if n < 3:
return 0
primes = [True] * n
primes[0], primes[1] = False, False
for i in range(2, int(n ** 0.5) + 1):
if primes[i]:
for j in range(i * i, n, i):
primes[j] = False
def countPrimes2(n=100000):
if n < 3:
return 0
primes = [1] * n
primes[0], primes[1] = 0, 0
for i in range(2, int(n ** 0.5) + 1):
if primes[i]:
for j in range(i * i, n, i):
primes[j] = 0
print('use False,True ', timeit.timeit(countPrimes, number=count))
print('use 0,1 ', timeit.timeit(countPrimes2, number=count))
result is:
-> % python3 test.py
use False,True 8.47771276300773
use 0,1 8.44074950099457
time is almost the same

Related

Creating triangle pattern in python looping two characters using nested loop

Please help. I need to create this pattern:
*
* $
* $ *
* $ * $
* $ * $ *
* $ * $
* $ *
* $
*
The best I can do is:
rows = 5
for i in range(0, 1):
for j in range(0, i + 1):
print("*", end=' ')
print("\r")
for i in range(0, rows):
for j in range(0, i + 1):
d = "$"
print("*",d, end=' ')
print("\r")
for i in range(rows, 0, -1):
for j in range(0, i - 1):
print("*", d, end=' ')
print("\r")
But it is not what I need. I desperately need help.
You cna simplify a bit : a loop for the increase from 1 to 4, another for the decrease from 5 to 1, then depend on odd/even values choose the correct symbol
rows = 5
for i in range(1, rows):
for j in range(i):
print('*' if j % 2 == 0 else "$", end=" ")
print()
for i in range(rows, 0, -1):
for j in range(i):
print('*' if j % 2 == 0 else "$", end=" ")
print()
Can be done in one outer loop
rows = 3
for i in range(-rows + 1, rows):
for j in range(rows - abs(i)):
print('*' if j % 2 == 0 else "$", end=" ")
print()
Slightly different approach:
N = 5
result = []
for i in range(N):
s = [('*', '$')[j % 2] for j in range(i+1)]
result.append(s)
print(*s)
for i in range(N-2, -1, -1):
print(*result[i])
You can use the abs function to handle the inflection point with one loop:
print(
*(
' '.join(
'*$'[m % 2]
for m in range(rows - abs(rows - n - 1))
)
for n in range(2 * rows - 1)
),
sep='\n'
)
Or the above in one line, if you prefer:
print(*(' '.join('*$'[m % 2] for m in range(rows - abs(rows - n - 1))) for n in range(2 * rows - 1)), sep='\n')
Demo: https://replit.com/#blhsing/KnowledgeableWellwornProblem

Showing the 10 first prime Fibonacci numbers in python

There is a problem we need to solve in my university where we need to print the 10 smallest prime fibonacci numbers in an ascending order.So far i have found this code but it takes about 2 min to print them and was wondering if there was a faster way to print them.
import math
def isSquare(n):
sr = (int)(math.sqrt(n))
return (sr * sr == n)
def printPrimeAndFib(n):
prime = [True] * (n + 1)
p = 2
while (p * p <= n):
if (prime[p] == True):
for i in range(p * 2, n + 1, p):
prime[i] = False
p = p + 1
list=[]
for i in range(2, n + 1):
if (prime[i] and (isSquare(5 * i * i + 4) > 0 or
isSquare(5 * i * i - 4) > 0)):
list.append(i)
print(list)
n = 500000000
printPrimeAndFib(n)
With a Fibonacci generator and a prime filter. Takes about 0.002 seconds.
from itertools import islice
from math import isqrt
def fibonacci():
a, b = 0, 1
while True:
yield a
a, b = b, a + b
def is_prime(n):
return n > 1 and all(map(n.__mod__, range(2, isqrt(n) + 1)))
fibonacci_primes = filter(is_prime, fibonacci())
print(list(islice(fibonacci_primes, 10)))
Output:
[2, 3, 5, 13, 89, 233, 1597, 28657, 514229, 433494437]
This approach generates Fibonacci numbers until it finds 10 that are prime; takes approx 0.001-0.002 seconds
from math import sqrt
def isprime(x):
#deal with prime special cases 1 and 2
if x==2:
return True
if x == 1 or x%2==0:
return False
#Fast-ish prime checking - only scan odds numbers up to sqrt(x)
for n in range(3,int(sqrt(x))+1,2):
if x%n==0:
return False
return True
fib_primes = []
current=1
previous=1
while (len(fib_primes)<10):
if isprime(current):
fib_primes.append(current)
next = current+previous
previous = current
current = next
print(fib_primes)

How i **2 different from i * i in python while calculating?

I was trying to solve Leetcode#279.Perfect-Squares
When I tried i ** 2 in loops, I got Time Limit Exceed. But once I change it to i * i, the code was accepted, that means i * i is faster than i ** 2 in python
What principles in python3 caused this difference?
Code and result for reference:
Use j * j, AC, beats 23%
class Solution:
def numSquares(self, n: int):
if n < 2:
return n
dp = [n] * (n + 1)
dp[0] = 0
dp[1] = 1
for i in range(2, n + 1):
j = 1
while j * j <= i:
dp[i] = min(dp[i], dp[i - j * j] + 1)
j += 1
return dp[-1]
If change all j * j to j ** 2, TLE.

Pythagorean triple with python

I want to get a number 'n' and produce Pythagorean triple that total of them is equal with 'n'.
for example for n=12 my output is 3, 4, 5 (12 = 3 + 4 + 5).
I write below code but it take a lot of time for big numbers. please help me to improve it.
a = int(input())
done = False
for i in range(int(a/4)+1,2,-1):
if done:
break
for j in range(i+1,int(a/2)+1):
k = a-(i+j)
if k <= j:
break
if i**2 + j**2 == k**2:
print(i,j,k)
done = True
break
if done == False:
print('Impossible')
This code may help you
limits = int(input())
c, m = 0, 2
# Limiting c would limit
# all a, b and c
while c < limits :
# Now loop on n from 1 to m-1
for n in range(1, m) :
a = m * m - n * n
b = 2 * m * n
c = m * m + n * n
# if c is greater than
# limit then break it
if c > limits :
break
if a+b+c == limits:
print(a, b, c)
m = m + 1
>> 12
>> 3 4 5
I've used the joblib module to parallelize your code, though I haven't tested if there is a speedup for very large n; let me know:
from joblib import Parallel, delayed
done = False
def triple(a):
global done
for i in range(int(a/4)+1,2,-1):
if done:
break
for j in range(i+1,int(a/2)+1):
k = a-(i+j)
if k <= j:
break
if i**2 + j**2 == k**2:
print(i,j,k)
done = True
break
if done == False:
print('Impossible')
if __name__ == '__main__':
a = int(input("n:"))
Parallel(n_jobs=-1, backend="threading")(map(delayed(triple), [a]))
To generate a Pythagorean triplet of a given sum, you can run two loops, where the first loop runs from i = 1 to n/3, the second loop runs from j = i+1 to n/2. In second loop, we check if (n – i – j) is equal to i * i + j * j.
n = int(input()
for i in range(1, int(n / 3) + 1):
for j in range(i + 1, int(n / 2) + 1):
k = n - i - j
if (i * i + j * j == k * k):
print(i, j, k)

Redundant lines in 0/1 Matrix output

I am trying to create a script that can allows me to output all the different combinations possible for different project optimization choices. In short, there are 6 projets (A B C D E F) that each have 2, 3 or 6 possible choices of optimization, that are mutually exclusive (you can't choose F4 and F5 at the same time for example).
import numpy as np
A = range(1, 3)
B = range(1, 3)
C = range(1, 7)
D= range(1,3)
E=range(1,3)
F=range(1,4)
length = len(A) + len(B) + len(C) + len(D) + len(E) + len(F)
nb_projet = len(A) * len(B) * len(C) * len(D) * len(E) * len(F)
result = np.zeros((length, nb_projet))
for k in range(len(A)):
for i in range(len(A)):
for j in range(nb_projet):
result[i, j] = (i+j % len(A)) == k
for k in range(len(B)):
for i in range(len(B)):
for j in range(nb_projet):
result[i + len(A), j] = (i+j % len(B)) == k
for k in range(len(C)):
for i in range(len(C)):
for j in range(nb_projet):
result[i + len(A)+len(B), j] = (i+j % len(C)) == k
for k in range(len(D)):
for i in range(len(D)):
for j in range(nb_projet):
result[i + len(A)+len(B)+len (C), j] = (i+j % len(D)) == k
for k in range(len(E)):
for i in range(len(E)):
for j in range(nb_projet):
result[i + len(A)+len(B)+len (C)+len(D), j] = (i+j % len(E)) == k
for k in range(len(F)):
for i in range(len(F)):
for j in range(nb_projet):
result[i + len(A)+len(B)+len (C)+len(D)+len(E), j] = (i+j % len(F)) == 0
print (result.T)
np.savetxt("ResultsS2.txt", result, delimiter=" ")
Basically the code is supposed to add a 1 if the optimization is chosen. At the moment it only generates 6 differents scenarios and not the 250+ that are possible.
Does anyone have an idea on how to fix this ?
Thank yu a lot !
This is just a bunch of concatenated one-hot arrays, so utilizing the second answer here and meshgrid to create the full factorial, you can just do something like this:
projects = [2,2,6,2,2,3] #[A.size, B.size, C.size . . .]
m = np.meshgrid(*[np.arange(i) for i in projects])
oneHots = [np.eye(projects[i])[m[i].flat] for i in range(len(projects))]
out = np.hstack(oneHots).T
out.shape
>(17, 288)
You can use something like this. Not the smartest, but if the arrays are not too long, it would work perfectly.
import numpy as np
A = range(0, 2)
B = range(0, 2)
C = range(0, 6)
length = len(A) + len(B) + len(C)
nb_projet = len(A) * len(B) * len(C)
result = np.zeros((length, nb_projet))
selectedList = []
count = 0
for i in A:
for j in B:
for k in C:
result[(i,count)]= 1
result[(len(A)+j,count)]=1
result[(len(A)+len(B)+k, count)] = 1
count+=1
Note, that I had changed the ranges to fit better.

Categories