【问题标题】:Shortest-code for prime-calculation素数计算的最短代码
【发布时间】:2009-05-08 02:37:57
【问题描述】:

我学校计算机科学系的报纸(称为readme,挪威语,第 19 页)举办了一场有趣的比赛,为以下问题编写尽可能短的 Java 代码。

接受一个整数(作为字符串数组的第一个条目中的字符串,因为Java main 方法只接受一个字符串数组)作为参数,并首先写出该数字以下的所有素数,然后所有不是素数的数字。最短的代码获胜!

作为答案,我将发布赢得比赛的最短 Java 代码。我想知道 Stack Overflow 社区是否可以制作更短的代码如果你懂挪威语,你会发现如果你这样做了,你可能会赢得一瓶香槟,但不幸的是,比赛的最后提交日期已经结束。

你会如何解决这个问题?

【问题讨论】:

  • 用什么语言? Java 并不以其简洁而著称。
  • 我同意.. 对其进行了编辑并使其成为社区 Wiki。 :)
  • 它必须有一个主要的吗?你的问题说它需要一个整数,但 main 只需要字符串参数?
  • 添加了一些说明.. :)
  • 最短的源代码还是字节码?

标签: java primes code-golf


【解决方案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]

【讨论】:

  • 不错。这可以通过使用简单的试除法而不是某种筛子来缩短(上述算法的性能比试除法差;请参阅 Melissa O'Neill 的论文)。
  • @Gracenotes 你有论文的链接吗?
  • 接受了这个答案,如果有人想出更短的东西我会改变接受=)
  • 我认为 Gracenotes 指的是这篇论文:[The Genuine Sieve of Eratosthenes][1] [1]: cs.hmc.edu/~oneill/papers/Sieve-JFP.pdf
【解决方案2】:

赢得比赛的 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);
         }
      }
   }

【讨论】:

  • 对于大于 Integer.MAX_VALUE 的输入,此程序不会终止。
  • new Long(String) 比较昂贵,参见。 Long.parseLong(String) 用于循环,但它更短。 ;)
【解决方案3】:

只是为了好玩,这里是the previous Haskell answer. 的 Java 版本。如果堆足够大,这个程序会终止所有参数。

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)));}
}

The fj package is from here.

【讨论】:

    【解决方案4】:

    我在 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
    

    【讨论】:

      【解决方案5】:

      如果你想要一个 js 代码:n 是最大值(62 个字符)

        for(i=1; i<n;i++)
          {
              for(f = j= 2;j<i && f;)
                  f = i%j++
              if(f) console.log(i)
          }
      

      【讨论】:

        【解决方案6】:

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

        【讨论】:

          【解决方案7】:

          一个易于理解和智能的代码可能是这样的:

          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);
                  }
              }
          }
          

          【讨论】:

            【解决方案8】:

            为了完整起见,还有两个 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)
            

            【讨论】:

              【解决方案9】:

              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);
                      }
                  }
              }
              

              【讨论】:

              • 将 1 列为素数,不将 2 列为素数,不列出非素数,并且在使用 jre-1.7 进行测试时不会在未经修改的情况下运行
              猜你喜欢
              • 2023-04-07
              • 1970-01-01
              • 1970-01-01
              • 2020-03-25
              • 1970-01-01
              • 2012-05-25
              • 2020-03-09
              • 1970-01-01
              • 2016-06-02
              相关资源
              最近更新 更多