finding primes in a list, then printing them - python-3.x

i have to generate primes for a project at school. heres the requirement: The Sieve of Eratosthenes is an elegant algorithm for finding all of the prime numbers up to some limit n. The basic idea is to first create a list of numbers from 2 to n. The first number is removed from the list, and announced as a prime number, and all multiples of the number up to n are removed from the list. This process continues until the list is empty. For example, if we wished to find all the primes up to 10, the list would originally contain [2, 3, 4, 5, 6, 7, 8, 9, 10]. The 2 is removed and announced to be prime. Then 4, 6, 8, and 10 are removed, since they are multiples of 2. That leaves [3, 5, 7, 9]. Repeating the process, 3 is announced as prime, and 9 is removed because it is a multiple of 9. That leaves [5, 7]. And so on. Write a program called generatePrimes.py that prompts the user for a number n and outputs all the primes less than or equal to n. im lost

This question is of terrible quality and doesn't really deserve an answer, but here is a function for the sieve being described:
def pSieve(limit):
flags = [True] * limit
flags[0] = flags[1] = False
primes = []
for index, flag in enumerate(flags):
if flag:
primes.append(index)
for n in range(index * index, limit, index):
flags[n] = False
return primes
and you can see that it produces the correct results:
>>> pSieve(10)
[2, 3, 5, 7]
>>> pSieve(100)
[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]

def pSieve(n):
m = (n-1)
b = [True]*m
i,p,ps = 0,3,[2]
while p*p < n:
if b[i]:
ps.append(p)
j = 2*i*i + 6*i + 3
while j < m:
b[j] = False
j = j + 2*i + 3
i+=1; p+=2
while i < m:
if b[i]:
ps.append(p)
i+=1; p+=2
return ps

Related

Return range of integer list based on input number

I found this question in my test today, I have been trying to find correct answer for this but failing to do so.
Question is:
Imagine we have range of page numbers lets say 0, 100. When we click on page lets say 15, we only what to show 10 pages on UI i.e. from page 10 to 20
more example input: 50 output: returns list
[46,47,48,49,50,51,52,53,54,55]
input: 15
output: returns list
[11,12,13,14,15,16,17,18,19,20]
also list should include first page and last page i.e. 0 and 50
so the actual output would be for first example
[0,46,47,48,49,50,51,52,53,54,55,100]
Below is what I have tried
def get_thread_page_num(num, max_page_num):
# Returns 10 numbers dynamically
new_lst =[1,50]
# default list
# defult_lst = [1,2,3,4,5,6,7,8,9,10]
num -4 > 0
num+5 <max_page_num
i = 10
m = 4
p = 5
while i != 0:
if num-1 >0 and m !=0:
new_lst.append(num-m)
i=i-1
m = m-1
elif num+1<max_page_num and p != 0:
new_lst.append(num+p)
i=i-1
p = p-1
print(sorted(new_lst))
get_thread_page_num(9, 50)
In your code m and p starts with value 4 and 5 respectively. In every iteration, either of them decreases by 1. So, after 9 iteration both of them are 0 and new_lst contains 9 elements. Also i becomes 10-9 = 1.
But i never becomes 0 and the loop becomes infinite.
You can try below code instead. Please refer to the comments.
def get_thread_page_num(num, max_page_num):
# low and high denotes the low and high end of the list
# where middle element is num
low = max(0, num - 4)
high = min(num + 5, max_page_num)
lst = []
if max_page_num < 9:
# 10 element list is not possible
return lst
# In case high is same as max, just make the list as
# high-9, high -8, ..., high
if high == max_page_num:
lst = list(range(max(0, high - 9), high + 1))
else:
# Just create a list starting from low like -
# low, low + 1, ..., low + 9
lst = list(range(low, low+10))
# Add 0 and max if not already present
if 0 not in lst:
lst.append(0)
if max_page_num not in lst:
lst.append(max_page_num)
# return sorted lst
return sorted(lst)
Call to get_thread_page_num():
print(get_thread_page_num(15, 50))
print(get_thread_page_num(0, 50))
print(get_thread_page_num(2, 50))
print(get_thread_page_num(50, 50))
print(get_thread_page_num(43, 50))
Output:
[0, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 50]
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 50]
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 50]
[0, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50]
[0, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 50]

Repetitive sequence (optimization)

I try to solve this problem:
initial list = [0, 1, 2, 2]
You get this sequence of numbers [0, 1, 2, 2] and you need to add every time the next natural number (so 3, 4, 5, etc.) n times, where n is the element of its index. For example, the next number to add is 3, and list[3] is 2, so you append [3] 2 times. New list will be: [0, 1, 2, 2, 3, 3]. Then the index of 4 is 3, so you have to append 4 three times. The list will be [0, 1, 2, 2, 3, 3, 4, 4, 4] and so on. ([0, 1, 2, 2, 3, 3, 4, 4, 4, 5, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10])
In order to solve this, I tried various approaches. I used recursion, but a recursive approach is very slow in this case. I tried as well the mathematical formula from OEIS (A055086) => a(n) = ceiling(2*sqrt(n+1)) - 2. The problem with the formula is that after 2 ** 20 it is too imprecise.
So, my next idea was to use memoization:
lst = [0, 1, 2, 2]
from itertools import repeat
def find(n):
global lst
print(lst[-1], n, flush = True)
if len(lst) > n:
return lst[n]
for number in range(lst[-1]+1, n+1):
lst += list(repeat(number, lst[number]))
if len(lst) > n:
return lst[n]
Now, this approach works until 2 ** 37, but after this is just timing out. The site where I try to implement my algorithm is (https://www.codewars.com/kata/5f134651bc9687000f8022c4/train/python). I don't ask for a solution, but for any hint on how to optimize my code.
I googled some similar problems and I found that in this case, I could use the total sum of the list, but is not very clear to me yet how could this help me.
Any help is welcomed!
You can answer it iteratively like so:
def find(n):
lst = [0,1,2,2]
if n < 4:
return lst[n]
to_add = 3
while n >= len(lst):
for i in range(lst[to_add]):
lst.append(to_add)
to_add += 1
return lst[n]
You could optimise for large n by breaking early in the for loop, and by keeping track of the list length separately, rather than calls to len

How to print list?

So i'm writing a code, listing square numbers lower than n.
I want the output to be a list. like so: [1, 4, 9, 16] etc.
n=int(input("input number: "))
counter = 1
while counter * counter < n:
for counter in range(1,n):
a = counter*counter
print (a)
if a < n:
break
I would be very grateful if I can get some help.
you can remove the need for the while loop and utilise pythons range function to generate your numbers up to n and use a for loop to iterate over them. you also need to initalise a list to store them in before the loop starts. and then each iteration of the loop append the square number to the list.
n=int(input("input number: "))
squares = []
for num in range(1, n):
squares.append(num * num)
print(squares)
OUTPUT for n=10
[1, 4, 9, 16, 25, 36, 49, 64, 81]
Although this can be simpfied using pythons list comprehension style as
n=int(input("input number: "))
squares = [num * num for num in range(1, n)]
print(squares)
OUTPUT for n=10
[1, 4, 9, 16, 25, 36, 49, 64, 81]
UPDATE based on comment from B. Go
user B. Go pointed out that my answer is printing all the results of squaring number up to the value of N. But the question was actually print all the square numbers less than N. Below code to print squares less than N
n=int(input("input number: "))
squares = []
for num in range(1, n):
result = num * num
if result >= n:
break
squares.append(num * num)
print(squares)
OUTPUT N=50
[1, 4, 9, 16, 25, 36, 49]

How to find larger numbers of any selected number in a series in an ascending order in NumPy?

I have a series of randomly scrabbled numbers. I want to pick a number (say X), and then find and write larger numbers than X in an ascending order. I’m using Python and NumPy.
EXAMPLE:
Series of random numbers:
4, 8, 5, 9, 3, 11, 17, 19, 9, 15, 16
X=4, Then:
4, 8, 9, 11, 17, 19
X=8, Then:
8, 9, 11, 17, 19
X=3, Then:
3, 11, 17, 19
Please note that when we pick X, our desire is to put X at the beginning of the ascending series, meaning that the count should start from X.
Also note that we don’t want to sort the numbers in terms of their position. No position change in the numbers. Only reading and writing the numbers in an ascending order. Next numbers in the sequence that are smaller than X should be ignored. Thank you.
EDIT:
def get_elements(get_from,get_by):
return [ (get_from[i], i ) for i in range(len(get_from)) if get_by[i] == 0 ]
def ordered_position():
ordered_lst = [0] *len(data_arr)
new_val = 1
while True:
print(new_val)
ge = get_elements(data_arr,ordered_lst)
if new_val >= len(data_arr) or not ge: break
first_val, idx_fist_val = ge.pop(0)
ordered_lst[idx_fist_val] = (first_val,new_val)
for item, idx in ge:
if data_arr[idx] >= first_val:
ordered_lst[idx] = (first_val,new_val)
first_val = item
new_val += 1
return ordered_lst
You can use np.maximum.accumulate like so::
a = np.array([4, 8, 5, 9, 3, 11, 17, 19, 9, 15, 16])
X = 4
withreps = np.maximum.accumulate(a[np.argmax(a==X):])
result = withreps[np.where(np.diff(withreps, prepend=withreps[0]-1))]
result
# array([ 4, 8, 9, 11, 17, 19])

How-to Create A List From An Existant List

I'm having some issues with an exercise assignment on python:
I need to take a list of items, lets say lst = [1, 4, 37, 48, 7, 15], and create a function that would allow me to extract from this list all numbers that are divisible by one and/or by themselves, creating a new list of items.
lst = [1, 4, 37, 48, 7, 15], z is non negative.
def func(lst,z):
y = []
z > 0
for i in lst:
if (i % z == 0):
y.append(i)
return y
print(func(lst,z))
Output: [1, 4, 37, 48, 7, 15]
I get the same result list/result.
Well, isn't every number divisible by itself and 1? That is why your list is the same.
Setting z=4 yields [4,48], which is every number that is divisible by 1, itself, and 4.

Resources