Related
I want to take the last number and multiply with the multiplier and add the increment. And put that number back into the list. I do not know how to put s into the list. As you can see it is "...8, 4, 2, 1], 4)" I want to put the 4 into the list.
def sfcollatz(n,divs=[2],mult=3,inc=1,maxSize=-1):
result = []
while n not in result and len(result)!=maxSize:
result.append(n)
d = next((d for d in divs if n%d==0),None)
n = (n*mult+inc) if not d else n//d
s = mult*result[-1]+inc
return result + ['...']*(n not in result),s
print(sfcollatz(27,[2],3,1,maxSize=200))
([27, 82, 41, 124, 62, 31, 94, 47, 142, 71, 214, 107, 322, 161, 484, 242, 121, 364, 182, 91, 274, 137, 412, 206, 103, 310, 155, 466, 233, 700, 350, 175, 526, 263, 790, 395, 1186, 593, 1780, 890, 445, 1336, 668, 334, 167, 502, 251, 754, 377, 1132, 566, 283, 850, 425, 1276, 638, 319, 958, 479, 1438, 719, 2158, 1079, 3238, 1619, 4858, 2429, 7288, 3644, 1822, 911, 2734, 1367, 4102, 2051, 6154, 3077, 9232, 4616, 2308, 1154, 577, 1732, 866, 433, 1300, 650, 325, 976, 488, 244, 122, 61, 184, 92, 46, 23, 70, 35, 106, 53, 160, 80, 40, 20, 10, 5, 16, 8, 4, 2, 1], 4)
I'm not exactly sure what you mean by "adding 4 into your array". Do you just mean you want it to go "...8, 4, 2, 1, 4]"? If so, you can just use the .append() function again. You also do not need to keep defining s in your while loop since it will always just take the final value:
def sfcollatz(n,divs,mult,inc,maxSize):
result = []
while n not in result and len(result)!=maxSize:
result.append(n)
d = next((d for d in divs if n%d==0),None)
n = (n*mult+inc) if not d else n//d
s = mult*result[-1]+inc
result.append(s)
return result
Your question was a little vague, but I hope this answers it. Let me know if you need any further help or clarification :)
I have this list:
[29, 64, 65, 66, 128, 129, 130, 166, 167, 168, 184, 185, 186, 215, 216, 217, 237, 238, 239, 349, 350, 351, 443, 483, 484, 485, 495, 496, 497, 526, 527, 528, 542, 543, 544, 564, 565, 566]
and i want to separate them that if the difference between the element and the next one different from 1, the code saves the next elements in another lit like
list1=[29]
liste2=[64, 65, 66]
liste3=[128, 129, 130]
liste3=[166, 167, 168]
until the end
Using numpy you could do this in a single line:
import numpy as np
lst = [29, 64, 65, 66, 128, 129, 130, 166, 167, 168, 184, 185, 186, 215, 216, 217, 237, 238, 239, 349, 350, 351, 443, 483, 484, 485, 495, 496, 497, 526, 527, 528, 542, 543, 544, 564, 565, 566]
[x.tolist() for x in np.split(lst, np.where(np.diff(lst) > 1)[0]+1)]
Output:
[[29],
[64, 65, 66],
[128, 129, 130],
[166, 167, 168],
[184, 185, 186],
[215, 216, 217],
[237, 238, 239],
[349, 350, 351],
[443],
[483, 484, 485],
[495, 496, 497],
[526, 527, 528],
[542, 543, 544],
[564, 565, 566]]
Edit 1: To store each list to separate variables (Not Recommended)
sub_lists = [x.tolist() for x in np.split(lst, np.where(np.diff(lst) > 1)[0]+1)]
for i in range(1, len(sub_lists)+1):
globals()['list_%s' % i] = sub_lists[i-1]
Output:
print(list_1)
>> [29]
print(list_2)
>> [64, 65, 66]
Note:
It is not recommended to have individual variables for multiple reasons, especially in the scenarios where the number of variables can explode based on the condition.
I believe this should be what you are looking for:
sort_me = [29, 64, 65, 66, 128, 129, 130, 166, 167, 168, 184, 185, 186, 215, 216, 217, 237, 238, 239, 349, 350, 351, 443, 483, 484, 485, 495, 496, 497, 526, 527, 528, 542, 543, 544, 564, 565, 566]
sorted_lists = list()
last_num = sort_me[0] # get the first index of the list to be the last number that has been evaluated
current_list = [sort_me[0]] # get first index fo list prepared for for loop
# iterate over all numbers in the list
for i in range(1, len(sort_me)):
num = sort_me[i] # get the next number
if num == last_num + 1: # check if it meets the criteria to be put into list
current_list.append(num) # add number to the list
else:
sorted_lists.append(current_list) # add list to list of lists (say that 10 times fast)
current_list = [num] # start new list
last_num = num # save last num checked as this iteration's number
if len(current_list) > 0:
sorted_lists.append(current_list)
# print them to show that the lists are correct (chnage this bit to do what you want with them)
for ls in sorted_lists:
print(ls)
EDIT added line that missed the last list, should be working fine now.
Can Anyone help me with this.I'm getting runtime error for this in online editor as well as in uploading the file but works with correct output in VS Code.
Problem Description
Given two numbers n1 and n2
Find prime numbers between n1 and n2, then
Make all possible unique combinations of numbers from the prime numbers list you found in step 1.
From this new list, again find all prime numbers.
Find smallest (a) and largest (b) number from the 2nd generated list, also count of this list.
Consider smallest and largest number as the 1st and 2nd number to generate Fibonacci series respectively till the count (number of primes in the 2nd list).
Print the last number of a Fibonacci series as an output
Constraints
2 <= n1, n2 <= 100
n2 - n1 >= 35
Input Format
One line containing two space separated integers n1 and n2.
Output
Last number of a generated Fibonacci series.
Timeout
1
Test Case
Example 1
Input
2 40
Output
13158006689
Explanation
1st prime list = [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37]
Combination of all the primes = [23, 25, 27, 211, 213, 217, 219, 223, 229, 231, 32, 35, 37, 311, 313, 319, 323, 329, 331, 337, 52, 53, 57, 511, 513, 517, 519, 523, 529, 531, 537, 72, 73, 75, 711, 713, 717, 719, 723, 729, 731, 737, 112, 113, 115, 117, 1113, 1117, 1119, 1123, 1129, 1131, 1137, 132, 133, 135, 137, 1311, 1317, 1319, 1323, 1329, 1331, 1337, 172, 173, 175, 177, 1711, 1713, 1719, 1723, 1729, 1731, 1737, 192, 193, 195, 197, 1911, 1913, 1917, 1923, 1929, 1931, 1937, 232, 233, 235, 237, 2311, 2313, 2317, 2319, 2329, 2331, 2337, 292, 293, 295, 297, 2911, 2913, 2917, 2919, 2923, 2931, 2937, 312, 315, 317, 3111, 3113, 3117, 3119, 3123, 3129, 3137, 372, 373, 375, 377, 3711, 3713, 3717, 3719, 3723, 3729, 3731]
2nd prime list=[193, 3137, 197, 2311, 3719, 73, 137, 331, 523, 1931, 719, 337, 211, 23, 1117, 223, 1123, 229, 37, 293, 2917, 1319, 1129, 233, 173, 3119, 113, 53, 373, 311, 313, 1913, 1723, 317]
smallest (a) = 23
largest (b) = 3719
Therefore, the last number of a Fibonacci series i.e. 34th Fibonacci number in the series that has 23 and 3719 as the first 2 numbers is 13158006689
Example 2
Input
30 70
Output
2027041
Explanation
1st prime list=[31, 37, 41, 43, 47, 53, 59, 61, 67]
2nd prime list generated form combination of 1st prime list = [3137, 5953, 5347, 6761, 3761, 4337, 6737, 6131, 3767, 4759, 4153, 3167, 4159, 6143]
smallest prime in 2nd list=3137
largest prime in 2nd list=6761
Therefore, the last number of a Fibonacci series i.e. 14th Fibonacci number in the series that has 3137 and 6761 as the first 2 numbers is 2027041
The code i did is:
def isPrime(num): #function to check for prime Number
if(num>1):
flag=0
for i in range(2,num):
if(num%i==0):
flag=1
break
if(flag==0):
return True #it is a prime number
else:
return False
else:
return False
n,m=map(int,input().split())
first=[int(x) for x in range(n,m) if (isPrime(x))] #first list that contains prime numbers between n and m
second=[]
for i in first:
for j in first:
if(i!=j):
second.append(str(i)+str(j))
prime=list(set([int(x) for x in second if isPrime(int(x))]))
a=min(prime)
b=max(prime)
fib=[a,b]
for i in range(len(prime)-2):
c=a+b
a=b
b=c
fib.append(c)
print(int(fib[len(prime)-1]))
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 6 years ago.
Improve this question
I have a numpy array like,
nums = np.array([17, 18, 19, 20, 21, 22, 23])
How do I filter out the prime numbers from this array in a pythonic manner?
I know to do a simple filtering like,
nums[nums > 20] #array([21, 22, 23])
Is there a way to pass a lambda function for filtering?
Expected output: array([17, 19, 23])
The way that I would do it is with gmpy or a 3rd party library who has developed a good primality test algorithm. The Miller-Rabin primality test is generally a very safe (and fast!) bet. If you just want the slow way, you can do:
import numpy as np
import math
def is_prime(n):
if n % 2 == 0 and n > 2:
return False
return all(n % i for i in range(3, int(math.sqrt(n)) + 1, 2))
a = np.arange(1, 10**3)
foo = np.vectorize(is_prime)
pbools = foo(a)
primes = np.extract(pbools, a)
primes # => Output below
array([ 1, 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37,
41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97,
101, 103, 107, 109, 113, 127, 131, 137, 139, 149, 151, 157, 163,
167, 173, 179, 181, 191, 193, 197, 199, 211, 223, 227, 229, 233,
239, 241, 251, 257, 263, 269, 271, 277, 281, 283, 293, 307, 311,
313, 317, 331, 337, 347, 349, 353, 359, 367, 373, 379, 383, 389,
397, 401, 409, 419, 421, 431, 433, 439, 443, 449, 457, 461, 463,
467, 479, 487, 491, 499, 503, 509, 521, 523, 541, 547, 557, 563,
569, 571, 577, 587, 593, 599, 601, 607, 613, 617, 619, 631, 641,
643, 647, 653, 659, 661, 673, 677, 683, 691, 701, 709, 719, 727,
733, 739, 743, 751, 757, 761, 769, 773, 787, 797, 809, 811, 821,
823, 827, 829, 839, 853, 857, 859, 863, 877, 881, 883, 887, 907,
911, 919, 929, 937, 941, 947, 953, 967, 971, 977, 983, 991, 997])
If you want to filter OUT the primes, just call np.invert on the pbools variables. The same would go for any predicate. You can also pass a lambda into vectorize. For example, say we wanted only prime numbers that are also 1 away from being divisible by 5 (for whatever reason).
import numpy as np
import math
def is_prime(n):
if n % 2 == 0 and n > 2:
return False
return all(n % i for i in range(3, int(math.sqrt(n)) + 1, 2))
a = np.arange(1, 10**3)
foo = np.vectorize(lambda x: (not (x + 1) % 5 or not (x - 1) % 5) and is_prime(x))
primes = a[foo(a)] # => Shorthand.... Output below
array([ 1, 11, 19, 29, 31, 41, 59, 61, 71, 79, 89, 101, 109,
131, 139, 149, 151, 179, 181, 191, 199, 211, 229, 239, 241, 251,
269, 271, 281, 311, 331, 349, 359, 379, 389, 401, 409, 419, 421,
431, 439, 449, 461, 479, 491, 499, 509, 521, 541, 569, 571, 599,
601, 619, 631, 641, 659, 661, 691, 701, 709, 719, 739, 751, 761,
769, 809, 811, 821, 829, 839, 859, 881, 911, 919, 929, 941, 971, 991])
If you care of speed and efficiency I would recommend you to use one of the fastest prime sieves and numpy.intersect1d() function:
import numpy as np
def primesfrom2to(n):
# http://stackoverflow.com/questions/2068372/fastest-way-to-list-all-primes-below-n-in-python/3035188#3035188
""" Input n>=6, Returns a array of primes, 2 <= p < n """
sieve = np.ones(n//3 + (n%6==2), dtype=np.bool)
sieve[0] = False
for i in range(int(n**0.5)//3+1):
if sieve[i]:
k=3*i+1|1
sieve[ ((k*k)//3) ::2*k] = False
sieve[(k*k+4*k-2*k*(i&1))//3::2*k] = False
return np.r_[2,3,((3*np.nonzero(sieve)[0]+1)|1)]
# generate 100.000 random integers from 1 to 1.000.000.000
a1 = np.random.randint(1, 10**9, 100000)
# generate all primes that are equal or less than a1.max()
primes = primesfrom2to(a1.max())
# print result
print(np.intersect1d(primes, a1))
It appears that you question is not about primes at all, but about how to apply a function to numpy array. I used simple is_odd example. Maybe np.vectorize is what you are looking for:
In [34]: nums = np.array([17, 18, 19, 20, 21, 22, 23])
In [35]: def is_odd(n):
if n % 2 == 1:
return True
return False
....:
In [36]: is_odd_v = np.vectorize(is_odd)
In [37]: nums[is_odd_v(nums)]
Out[37]: array([17, 19, 21, 23]
If I recall correctly np.vectorize is used primarily for convenience, and does not have great performance.
Having a setup like this:
import numpy as np
import math
nums = np.array([17, 18, 19, 20, 21, 22, 23])
So now we create an array that contains all possible integer candidates:
divisors = np.arange(2,int(math.sqrt(np.max(nums)))+1) # Numbers from 2 to sqrt(max(nums))
print(divisors)
# [2 3 4]
Now apply the modulo operation on the array but with a different dimension so we check each number with each divisor:
print(nums[:,None] % divisors[None,:]) # Modulo operation on each element (0 means divisible)
[[1 2 1]
[0 0 2]
[1 1 3]
[0 2 0]
[1 0 1]
[0 1 2]
[1 2 3]]
Now how do we get the primes ... we check if there is no result in the line that is zero:
print(np.min(nums[:,None] % divisors[None,:], axis=1)) # Minimum of the modulo for that element
# [1 0 1 0 0 0 1]
and then create a mask to index them:
print(nums[np.min(nums[:,None] % divisors[None,:], axis=1) > 0]) # So index them
# [17 19 23]
So all you need in the end is:
nums = np.array([17, 18, 19, 20, 21, 22, 23])
divisors = np.arange(2,int(math.sqrt(np.max(nums)))+1)
nums[np.min(nums[:,None] % divisors[None,:], axis=1) > 0]
all the other stuff is just for illustrating what each step is doing.
This is not trivial since it uses broadcasting of 1D arrays into a 2D array but the method should be clear. Let me know if you have any questions.
If you want to optimize this, there is another possibility: The divisors are currently every number between 2 and the sqrt(max(array)) but you don't need to test for all these numbers. If you had a function that returned all primes in that range that would be enough. For example using primesfrom2to of #MaxU's answer a faster possibility is:
nums = np.array([17, 18, 19, 20, 21, 22, 23])
# All prime numbers in the range from 2 to sqrt(max(nums))
divisors = primesfrom2to(int(math.sqrt(np.max(nums)))+1)
nums[np.min(nums[:,None] % divisors[None,:], axis=1) > 0]
but it uses the same mechanism as before but is a bit faster. :-)
If you really want to use a Filter, you can use this:
nums[[i for i in range(len(nums)) if sum([nums[i]%val==0 for val in range(2,nums[i]-1)])==0]]
What does this do?
We search all indexes with prime number by using
[i for i in range(len(nums)) if sum([nums[i]%val==0 for val in range(2,nums[i]-1)])==0]
This basically goes through every value and checks if it is not divisible by any value smaller than itself (ignoring 1)
[i for i in range(len(nums)) #for every index
if sum(#calculate sum of booleans
[nums[i]%val==0 for val in range(2,nums[i]-1)] # check if it is divisble by any value smaller than itself
)==0 #check if the number of divisors is zero
# Primality Testing with the Rabin-Miller Algorithm
import random
def rabinMiller(num):
# Returns True if num is a prime number.
s = num - 1
t = 0
while s % 2 == 0:
# keep halving s while it is even (and use t
# to count how many times we halve s)
s = s // 2
t += 1
for trials in range(5): # try to falsify num's primality 5 times
a = random.randrange(2, num - 1)
v = pow(a, s, num)
if v != 1: # this test does not apply if v is 1.
i = 0
while v != (num - 1):
if i == t - 1:
return False
else:
i = i + 1
v = (v ** 2) % num
return True
def isPrime(num):
# Return True if num is a prime number. This function does a quicker
# prime number check before calling rabinMiller().
if (num < 2):
return False # 0, 1, and negative numbers are not prime
# About 1/3 of the time we can quickly determine if num is not prime
# by dividing by the first few dozen prime numbers. This is quicker
# than rabinMiller(), but unlike rabinMiller() is not guaranteed to
# prove that a number is prime.
lowPrimes = [[2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53,
59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127, 131, 137, 139,
149, 151, 157, 163, 167, 173, 179, 181, 191, 193, 197, 199, 211, 223, 227, 229,
233, 239, 241, 251, 257, 263, 269, 271, 277, 281, 283, 293, 307, 311, 313, 317,
331, 337, 347, 349, 353, 359, 367, 373, 379, 383, 389, 397, 401, 409, 419, 421,
431, 433, 439, 443, 449, 457, 461, 463, 467, 479, 487, 491, 499, 503, 509, 521,
523, 541, 547, 557, 563, 569, 571, 577, 587, 593, 599, 601, 607, 613, 617, 619,
631, 641, 643, 647, 653, 659, 661, 673, 677, 683, 691, 701, 709, 719, 727, 733,
739, 743, 751, 757, 761, 769, 773, 787, 797, 809, 811, 821, 823, 827, 829, 839,
853, 857, 859, 863, 877, 881, 883, 887, 907, 911, 919, 929, 937, 941, 947, 953,
967, 971, 977, 983, 991, 997]]
if num in lowPrimes:
return True
# See if any of the low prime numbers can divide num
for prime in lowPrimes:
if (num % prime == 0):
return False
# If all else fails, call rabinMiller() to determine if num is a prime.
return rabinMiller(num)
def generateLargePrime(keysize=1024):
# Returns a random prime number of keysize bits in size.
while True:
num = random.randrange(2**(keysize-1), 2**(keysize))
if isPrime(num):
return num
I am creating a Python program that will tell you if a number is prime or not. It is basically the Rabin Miller Algorithm, but on line 60, my program stops and I get the error:
TypeError: unsupported operand type(s) for %: 'int' and 'list'.
This is line 60:
lowPrimes = [[2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, ...]]
What am I doing wrong?
Your lowPrimes variable is a list of lists, so when you say for prime in lowPrimes, prime is a list, so you can't modulus an int by a list. Try changing lowPrimes = [[...]] to lowPrimes = [...] (remove one layer of brackets).
The error message is pretty instructive here. It's saying that you are trying to apply the % operator to an int and a list. Since you also have the line number you can see the expression it's referring to and that prime must have been a list.
Your lowPrimes array is defined in a wrong way. You want it to be a list of numbers, but instead it is a list of lists of numbers (outer list containing only a single element). This causes the error you see when you iterate over all the elements of lowPrimes and check if your number is divisable by that element of lowPrimes. To fix it, remove outer square brackets:
lowPrimes = [[2, 3, 5, 7, 11, 13, 17, 19, ... 997]]
=>
lowPrimes = [2, 3, 5, 7, 11, 13, 17, 19, ... 997]