質問
私の学校のコンピューターサイエンスラインの新聞( readme 、ノルウェー語、19ページ)は、次の問題に対して可能な限り短いJavaコードを書くための楽しい競争を行いました。
整数として(Java mainメソッドは文字列配列のみを取得するため、文字列配列の最初のエントリの文字列として)引数として取得し、この数より下の素数であるすべての番号を最初に書き込み、次に素数ではないすべての数字。最短のコードが勝ちます!
答えとして、競争に勝った最短のJavaコードを投稿します。 Stack Overflow Communityがより短いコードを作成できるかどうか疑問に思います。ノルウェー語を知っていれば、シャンパンを1杯獲得できたのに、残念ながら競争の最終提出日が過ぎていることがわかります。
この問題をどのように解決しましたか?
解決
タイトルを" Java"に変更する前に、すでにHaskellでやっていた。これはコミュニティwikiなので、とにかくここにあります。
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])
(編集:)名前を短くして空白を削除すると、79文字になります:
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)
ここでも結果のペアの順序が交換され、仕様に従って n-1
が使用されます。
次善の試用部門を使用すると、 50文字になります:
p n=partition(\k->all((>0).rem k)[2..k-1])[2..n-1]
他のヒント
競合に勝ったJavaコード(スペースなしの153バイト、読みやすくするためにスペースが含まれています):
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);
}
}
}
楽しみのために、Javaバージョンの以前のHaskellの回答をご覧ください。このプログラムは、十分なヒープが与えられると、すべての引数について終了します。
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)));}
}
Rubyでの私の試み。 93文字。
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文字
print[i for i in range(2,input())if all(i%j for j in range(2,i))]
使用法:
>>> 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]
>>>
jsコードが必要な場合:nは最大(62文字)
for(i=1; i<n;i++)
{
for(f = j= 2;j<i && f;)
f = i%j++
if(f) console.log(i)
}
わかりやすくスマートなコードは次のようになります:
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);
}
}
}
完全を期すために、さらに2つのHaskellの定義。典型的な
primes = map head . scanl (\\) [2..] . map (\p -> [p, p+p..]) $ primes
where
(\\) = Data.List.Ordered.minus
そして簡潔な絶対的なチャンピオン、
nubBy (((>1).).gcd) [2..] -- (((>1).).gcd) meaning (\a b -> gcd a b > 1)
133文字:-)
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);
}
}
}