Shortest prime number program

S

swisscheese

I figured someone out there must have written a minimal code size prime
number generator. I did not find one after a bit of searching around.
For primes up to 100 the best I could do was 70 characters (including
spaces):

r=range(2,99)
m=[x*y for x in r for y in r]
[x for x in r if not x in m]
 
M

Mitja Trampus

swisscheese said:
I figured someone out there must have written a minimal code size prime
number generator. I did not find one after a bit of searching around.
For primes up to 100 the best I could do was 70 characters (including
spaces):

r=range(2,99)
m=[x*y for x in r for y in r]
[x for x in r if not x in m]

A more straightforward and somewhat shorter solution:

r=range(2,99)
[x for x in r if [x%d for d in r].count(0)<2]

I'm sure it can be made shorter still.
 
S

swisscheese

At 58, very nice :) Building on yours we get 57:
r=range(2,99)
[x for x in r if sum([x%d==0 for d in r])<2]
 
I

Ian Bygrave

I figured someone out there must have written a minimal code size prime
number generator. I did not find one after a bit of searching around.
For primes up to 100 the best I could do was 70 characters (including
spaces):

r=range(2,99)
m=[x*y for x in r for y in r]
[x for x in r if not x in m]

I swore I'd never play Python golf.

p,r=[],range(2,99)
while r:p,r=p+r[:1],[x for x in r if x%r[0]]

And the result's in p.

--Ian Bygrave
 
?

=?ISO-8859-1?Q?=22Martin_v=2E_L=F6wis=22?=

You can save two bytes with
r=range(2,99)
[x for x in r if sum(x%d==0 for d in r)<2]
 
S

swisscheese

You can save two bytes with

56 - nice catch.
55:
r=range(2,99)
[x for x in r if sum(x%d<1 for d in r)<2]
 
M

mensanator

swisscheese said:
I figured someone out there must have written a minimal code size prime
number generator. I did not find one after a bit of searching around.
For primes up to 100 the best I could do was 70 characters (including
spaces):

r=range(2,99)
m=[x*y for x in r for y in r]
[x for x in r if not x in m]

import gmpy
p=2
while p<99:p=gmpy.next_prime(p)
 
I

Ian Bygrave

p,r=[],range(2,99)
while r:p,r=p+r[:1],[x for x in r if x%r[0]]

And the result's in p.

Well, given a hypothetical new function 'sieve'

def sieve(f,l):
if not l:
return l
head,tail=l[0],l[1:]
def filter_func(x):
return f(x,head)
tail=filter(filter_func,tail)
return [head]+tail

The prime generation can be reduced to:

from operator import *
sieve(mod,range(2,99))

Is there any precedent for such a function, or any other uses?

--Ian Bygrave
 
I

Ian Bygrave

Well, given a hypothetical new function 'sieve'

which should have been:

def sieve(f,l):
if not l:
return l
head,tail=l[0],l[1:]
def filter_func(x):
return f(x,head)
tail=filter(filter_func,tail)
return [head]+sieve(f,tail)
The prime generation can be reduced to:

from operator import *
sieve(mod,range(2,99))

--Ian Bygrave
 
S

swisscheese

[2]+[x for x in range(1,99) if 2**x%x==2]

42 - brilliant!
41:
[2]+[x for x in range(1,99)if 2**x%x==2]
.... although it appears Christoph is right that it's not scalable.
 
B

bearophileHUGS

This is a little shorter :)

[2]+[x for x in range(2,99)if 2**x%x==2]

Bye,
bearophile
 
R

Ralf Muschall

Christoph said:
How about:
[2]+[x for x in range(1,99) if 2**x%x==2]
If the range goes beyond 340, it also gives non-primes...

[2,3]+[x for x in range(1,99) if 2**x%x==2 and 3**x%x==3]
[2,3,5]+[x for x in range(1,99) if 2**x%x==2 and 3**x%x==3 and 5**x%x==5]

SCNR, Ralf

PS: They both break at 561, and further strengthening of the
condition will not help. Manual loop unrolling as follows works:

[2,3,... <insert all primes here>]+[x for x in range(1,99) if False]

For sufficiently small values of 99, this will also be a rather
short program.
 
T

Tim Hochberg

While not nearly the shortest proposed thus far, I'm fond of:

from itertools import count, ifilter
def sieve(s=count(2)):
while 1:p=s.next();s=ifilter(p.__rmod__,s);yield p

It will generate quite a large number of primes before blowing up (at
least 50,000 primes, p=611,957) and it's much faster than the other
submissions thus far that can generate a more or less arbitrary number
of primes. It's still much slower than Alex Martelli's version in the
cookbook though.

[And yes I know that you can shave off one character by importing
ifilter as i, but that's too much ick for too little gain. There may
well be other, more fruitful ways to compact it though]

-tim
 
T

Tim Hochberg

In the spirit of pointless pessimization and obfuscation I have crushed
something very similar to Alex Martelli's eratosthenes function onto a
single line. It's truly monstrous, but somewhat entertaining [Some
preemptive linebreaks added]:

def short():import itertools as it;D={};g=D.get;return (
q for q in it.count(2) if
D.__setitem__(it.dropwhile(D.__contains__,
xrange(g(q,q)+q,2**30,g(q,q))).next(),g(q,q))
or q not in D and D.pop(q,1))


I'm sure there's a lesson to this somewhere. Something like I need to
find something better to do with my spare time.

-tim
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,581
Members
45,056
Latest member
GlycogenSupporthealth

Latest Threads

Top