-5

What i have tried :

for num in range(2,50):
    prime = True
    for i in range(2,num):
        if (num%i==0):
            prime = False
    if prime:
       print (num)

The result were fine but its prohibited to use for or while loops in any way so, is there any other way to do it without using for or while loops?

6 Answers6

3

Is there any other way to do it without using for or while loops?

Yes, you can use a recursive function:

def prime_number(n, d):
    if n//2 < d:
      return True
    if n%d == 0:
      return False
    return prime_number(n, d+1)

def find_primes(n,i, result):
  if i == n + 1:
    return result
  if prime_number(i, 2):
    result.append(i)
  return find_primes(n, i+1, result)

print(find_primes(100,2, []))

Output

[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]

Also, you can simplify for loops using list comprehension.

primes = [n for n in range(2, 50) if all(n % d for d in range(2, n))]
Mihai Alexandru-Ionut
  • 41,021
  • 10
  • 77
  • 103
  • This runs into trouble above `find_primes(672, 2, [])` when using Python's default stack size. I posted an alternative implementation that only pushes that limit by 3x. – cdlane May 14 '18 at 22:30
2

This is dumb, but it works, so maybe it'll at least give you some ideas:

print(list(filter(lambda x: not list(filter(lambda y:x%y == 0, range(2,x))), range(2, 50))))

Outputs:

[2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47]
snowcat
  • 254
  • 1
  • 5
1

Here's a recursive implementation of the Sieve of Eratosthenes. It uses extended slice assignment to perform the main sieving step. It will fail with RecursionError on large numbers, but with default settings it can safely calculate primes up to 990000 or so. It's not as fast as the more usual iterative version of this code, but it's quite a bit faster than doing simple brute-force factor searching.

def rsieve(i, num, stop, seq):
    if i == stop:
        return
    if seq[i]:
        seq[i*i : num : i] = [False] * (1 + (num - 1)//i - i)
    rsieve(i + 1, num, stop, seq)

def primes(num):
    seq = [True] * num
    seq[:2] = [False] * 2
    rsieve(2, num, int(num ** 0.5) + 1, seq)
    return filter(lambda i: seq[i], range(num))

# Test
print(*primes(100))

output

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

FWIW, you can make this code run almost twice as fast by replacing the lambda function argument to filter with a direct call to the seq.__getitem__ "magic" method. That is,

return filter(seq.__getitem__, range(num))

It's generally considered bad practice to call "magic" methods directly, so please do not do that unless you understand what you're doing. ;)

PM 2Ring
  • 50,023
  • 5
  • 64
  • 150
0

This solves printing a list, one number a time, each on new line - without for loop.

print( *[2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47], sep = '\n')

Output:

2
3
5
7
11
13
17
19
23
29
31
37
41
43
47

All primes up to 50 - no for loops involved.


As for the primes-list, I cheated by hardcoding them (you did not ask about creating, just printing - although your code tries to create them).

If you are interested in creating them efficiently, I suggest searching SO - f.e. you find Fastest way to list all primes below N

Patrick Artner
  • 43,256
  • 8
  • 36
  • 57
0

This is my rework of @MihaiAlexandru-Ionut's solution which can compute 3x higher, before running afoul of Python's default stack size, by eliminating prime testing of even numbers and stopping prime tests at the square root instead of 1/2 of the target:

def find_primes(n, i=2):

    primes = []

    if i > n:
        return primes

    def is_odd_prime(n, d=3):
        if n < d * d:
            return True

        if n % d == 0:
            return False

        return is_odd_prime(n, d + 2)

    multi = i != 2

    if not multi or is_odd_prime(i):
        primes.append(i)

    return primes + find_primes(n, i + 1 + multi)

print(find_primes(1960))

Still no where near the (stack) efficiency of @PM2Ring's sieve solution!

cdlane
  • 33,404
  • 4
  • 23
  • 63
0

This gives you all primenumbers up to t using no external libraries or for/while loops.

t=1000

a=set(range(2,t))
l=map(lambda c:range(2*c,t,c),a)
result=a.difference(*l)

print(sorted(result))

Its also not too slow:

>>> Calculating primes up to 1 took 2.599999999997049e-05 seconds
>>> Calculating primes up to 10 took 4.6000000000101515e-05 seconds
>>> Calculating primes up to 100 took 0.00015300000000006975 seconds
>>> Calculating primes up to 1000 took 0.001670999999999978 seconds
>>> Calculating primes up to 10000 took 0.023809999999999998 seconds
>>> Calculating primes up to 100000 took 0.24447599999999992 seconds
>>> Calculating primes up to 1000000 took 3.301934 seconds
>>> Calculating primes up to 10000000 took 42.691604 seconds

Using 100000000 produced an memory Error

A. P
  • 103
  • 4