Shortest-code for prime-calculation
Question
The newspaper for the Computer Science-line at my school (called readme, it's norwegian, page 19) had a fun competition to write the shortest possible Java-code for the following problem.
Take in an integer (as a string in the first entry of a string array, since the Java main method only takes a string array) as an argument, and write out first all numbers below this number that are primes, and then all numbers that are not primes. The shortest code wins!
As an answer, I will post the shortest Java-code that won the competition. I wonder if the Stack Overflow Community can make a code that is shorter If you know Norwegian, you will see that you could've won a bottle of champagne if you had done it, but unfortunately the last submit date of the competition is over.
How would you have solved this problem?
Solution
I was already doing it in Haskell before you changed the title to "Java". Since this is a community wiki, here it is anyway.
primes n =
let sieve (p:xs) = p : sieve [x | x<-xs, x `mod` p /= 0] in
let primes = takeWhile (<n) $ sieve [2..] in
([0..n] \\ primes, primes)
*Main> primes 20
([0,1,4,6,8,9,10,12,14,15,16,18,20],[2,3,5,7,11,13,17,19])
(edit:) Shortening names and removing whitespace makes it 79 chars:
p n=let s(p:xs)=p:s[x|x<-xs,x`mod`p/=0];r=takeWhile(<n)$s[2..]in(r,[0..n-1]\\r)
here also the resulting pair's order is swapped, and n-1
is used, as per the spec.
Using sub-optimal trial division brings it down to 50 chars:
p n=partition(\k->all((>0).rem k)[2..k-1])[2..n-1]
OTHER TIPS
The Java-code that won the competition (153 bytes without spacing, spacing included here for readability):
class F {
public static void main(String[] a) {
for (int i, j, k = 2; k-- > 0;)
for (i = 1; i++ < new Long(a[0]);) {
for (j = i; i % --j > 0;)
;
if (k > 0 ? j < 2 : j > 1)
System.out.println(i);
}
}
}
Just for fun, here's a Java version of the previous Haskell answer. This program terminates for all arguments, given sufficient heap.
import fj.data.Natural;
import fj.data.Stream;
import static fj.data.Stream.*;
import static fj.pre.Ord.naturalOrd;
import fj.pre.Show;
import static fj.pre.Show.streamShow;
import static fj.pre.Show.naturalShow;
import static fj.data.Natural.ZERO;
import static fj.data.Natural.natural;
import fj.P1;
import fj.F;
import static fj.data.Enumerator.naturalEnumerator;
import java.math.BigInteger;
public class Primes2
{public static Stream<Natural> sieve(final Stream<Natural> xs)
{return cons(xs.head(), new P1<Stream<Natural>>()
{public Stream<Natural> _1()
{return sieve(xs.tail()._1().filter(new F<Natural, Boolean>()
{public Boolean f(final Natural x)
{return !naturalOrd.eq(x.mod(xs.head()), ZERO);}}));}});}
public static Stream<Natural> primes(final Natural n)
{return sieve(forever(naturalEnumerator, natural(2).some()))
.takeWhile(naturalOrd.isLessThan(n));}
public static void main(final String[] a)
{final Natural n = natural(new BigInteger(a[0])).some();
final Show<Stream<Natural>> s = streamShow(naturalShow);
s.println(primes(n));
s.println(range(naturalEnumerator, ZERO, n)
.minus(naturalOrd.equal(), primes(n)));}
}
My attempt in Ruby. 93 characters.
def s n
(a=(2..n).to_a).each{|n|a.reject!{|k|k%n==0&&k/n!=1}}
p[[1]+a,(2..n).to_a-a]
end
Python, 65 characters
print[i for i in range(2,input())if all(i%j for j in range(2,i))]
Usage:
>>> print[i for i in range(2,input())if all(i%j for j in range(2,i))]
70
[2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67]
>>>
if you would like a js code : n is the max (62 chars)
for(i=1; i<n;i++)
{
for(f = j= 2;j<i && f;)
f = i%j++
if(f) console.log(i)
}
An easy to understand and smart code may be like:
public class test3 {
public static void main(String[] args) {
for (int i = 2; i <= 100; i++) {
int count = 0;
for (int j = i / 2; j >= 2; j--) {
if (i % j == 0)
count = count + 1;
}
if (count == 0)
System.out.println(i);
}
}
}
For completeness, two more Haskell definitions. The archetypal
primes = map head . scanl (\\) [2..] . map (\p -> [p, p+p..]) $ primes
where
(\\) = Data.List.Ordered.minus
and the absolute champion in brevity,
nubBy (((>1).).gcd) [2..] -- (((>1).).gcd) meaning (\a b -> gcd a b > 1)
133 characters :-)
class F {
public static void main(String[] z) {
l:
for (int a=1,b; a < z; a += 2) {
for (b = 2; b < a; b++)
if (a % b == 0)
continue l;
System.out.println(a);
}
}
}