エラトステネスのふるい、ステップバイステップ


15

数字Nを指定すると、左揃えのN x Nの数字のボードを描画し、1つの空白(スペースとして)を残します(N = 5の図を表示します)

   2  3  4  5
6  7  8  9  10
11 12 13 14 15
16 17 18 19 20
21 22 23 24 25

あなたの仕事は、エラトステネスのふるいを段階的に構築することです。まず、2から始めます。素数なので、そのままにしておき、2で割り切れる他のすべての数字を適切な数のスペースに置き換えます。

   2  3     5
   7     9    
11    13    15
   17    19   
21    23    25

次に、次の印刷されていない番号(3この場合)に移動して、同じ操作を行います。

   2  3     5
   7          
11    13      
   17    19   
      23    25

など、Nに達するまで。

最初に完全なグリッドを印刷する必要があり、新しい番号に行くたびに、倍数を削除してボードを印刷します。間に空白行を印刷してください!

括弧内のテキストは()参照用であり、印刷する必要はありません

N = 2:

  2 (complete grid)
3 4

  2 (remove multiples of 2)
3  

N = 3:

  2 3 (complete grid)
4 5 6
7 8 9

  2 3 (remove multiples of 2)
  5  
7   9

  2 3 (remove multiples of 3)
  5  
7    

これはであるため、バイト数が最小のコードが優先されます。


通常のためのN×N君は後にふるい分け停止ふるいN
ニール

1
たとえばN=10100が素数でない場合、ある時点で削除されます。1003桁であるため、すべての数字を3文字にパディングする必要がありますか?
mbomb007

4
なぜ数字揃えるのですか?
デニス

2
末尾の改行は受け入れられますか?
デニス

2
組み込みのグリッドは許可されていますか?出力は投稿の例と同じに見えますが、文字列ではありません。
ジョンファンミン

回答:


7

ゼリー、34 バイト

Ṿ€“1“ ”ys³G
>®i©1ḍoṛ®¦
²R;1©ÇÐĿÑ€Y

オンラインでお試しください!

使い方

²R;1©ÇÐĿÑ€Y  Main link. Argument: n (integer)

²            Yield n².
 R           Range; yield [1, ..., n²].
   1©        Yield 1 and copy it to the register.
  ;          Append 1 to the range.
             This is the initial state. Let's call it S.
     ÇÐĿ     Call the second helper link until the results are no longer unique.
             This returns all unique results as an array.
        Ṅ€   Call the first helper link on each result.
          Y  Join, separating by linefeeds.

>®i©1ḍoṛ®¦   Second helper link. Argument: S (state)

>®           Compare all integers in S with the value in the register.
  i 1        Find the first index of 1 (i.e., the first number that is greater
             than the register.
   ©         Copy the index to the register. Let's call the index p.
     ḍ       Test all numbers in S for divisibility by p. This yield 1 for
             multiples of p, 0 otherwise.
      o      Logical OR; replace 0's with the corresponding values of S.
       ṛ®¦   Replace the 0 at index p with the corresponding element of S (p).
             For the purposes of the explanation, S is now the updated state.

Ṿ€“1“ ”ys³G  First helper link. Argument: A (array)

Ṿ€           Uneval each; convert all integers in A into strings.
  “1“ ”y     Replace each string "1" with the string " ".
        s³   Split into chunks of length n (command-line argument).
          G  Grid; separate row items by spaces (left-padding since the row items
             are strings), the rows themselves by linefeeds.

5

Perl、250 243 231 202 157バイト

$n=<>;@a=0..($e=$n*$n);$a[1]=$";for$p(1..$n){next if!$a[$p];for(1..$e){$a[$_]=""if!($p~~[(1,$_)]||$_%$p);printf"%-*s",1+length$e,$a[$_];say""if!($_%$n)}say}

現在のゴルフをオンラインでテストしてください!(必ずとして実行してくださいperl -M5.010 main.pl

2つのリテラル改行は、それぞれ\ nの代わりに1バイトを節約します。

サンプル出力(7の入力):

   2  3  4  5  6  7  
8  9  10 11 12 13 14 
15 16 17 18 19 20 21 
22 23 24 25 26 27 28 
29 30 31 32 33 34 35 
36 37 38 39 40 41 42 
43 44 45 46 47 48 49 

   2  3     5     7  
   9     11    13    
15    17    19    21 
   23    25    27    
29    31    33    35 
   37    39    41    
43    45    47    49 

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

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

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

ゴルフはあまり上手くいかなかったので、家に帰ったら、それをもう一度見て、どれだけ削れるかを確かめます。

編集1:-7バイト(「print sprintf」を明白な「printf」に変更)

編集2:1つの場所で明示的に$ Dを使用して保存12バイトは、それは、とのための私の条件の一つ排除することにより、代わりにいくつかの宣言を組み合わせることで、別の変数を作成すると呼ばれたnext最初の内側の文foreachどこかにスペースを追加することによって、ループを。追加の29バイトは、2つのforループを1つのループに作り直し、2つの変数宣言を削除し、unlessステートメントをif-notステートメントに変換することによりゴルフアウトされました。宣言してmy$e=$n*$n;から、$ n * $ nの3つのインスタンスを$ eに置き換えて(そのうちの1つに対してかっこをドロップできるようにします)、結果は±0バイトになりましたが、とにかくそのままにしました。

編集3:@Dadaのおかげで、さらに40バイトが出力されました(変数宣言、「foreach」が「for」になり、いくつかの場所で暗黙の$ _、printfステートメントのサイズを削減)。に変更することで、さらに1バイト削り取られif!($c%$p||$c==$p||$p==1)ましたif!($p~~[(1,$_)]||$_%$p)。残念ながら、smartmatch演算子~~はまだ実験的であり、実際の配列では適切に動作しないように見えますが、代わりにそれらの参照では動作するため、配列の周りの[]が必要です。2つのセミコロンと最後の後の空の引用符のセットを削除することによって、さらに4バイトが削除されましたsay


1
それは良いスタートですが、もっとたくさんゴルフできます。変数を宣言しないでください(したがって、使用しないでくださいmy)。を使用する代わりに、-pフラグを使用してN$_に入れ$n=<>ます。for代わりに書き込みますforeach(この命令は同等です)。条件の周りに括弧をドロップしifます(例えば文の修飾位置にあるif!$c%$nの代わりif(!$c%$n)はありませんが、初期化するために必要なかっこ。@a@a=0..$e。あなたがにドロップすることができfor、変数と$_代わりに使用することwiil書き込み。printf"%*s",1+length$e,$a[$c]( `` sprintf`ドキュメントをその詳細については*
ダダ

1
$"代わりに使用します" "say""代わりにprint"\n"(コードに改行がありますが、コメントに書き込めません)(-M5.010コマンドラインに追加して追加しますが、バイトカウントにはカウントされません)。0..$e=$n*$nの初期化時に1バイトを保存するためにおそらく使用できます$e。見ていPerlのゴルフのヒントを、それが便利なヒントがたくさん含まれています。しかし、新しいperlゴルファーに会えてうれしいです!:)(そしてスペルミスを許して、以前のコメントを書くのが速すぎたかもしれません)
ダダ

@Dadaアドバイスありがとうございます!私はコマンドラインでコードを実行することにはあまり詳しくありません(ファイルとして実行する傾向があります)が、そのようにする方法を見ていきます。についてif!$c%$nは、!演算子は%演算子よりも優先されるため、技術的にif((!$c)%$n)は$ c = 0(これは望ましくありません)以外の場合はfalseになります。あなたの他のヒントについては、私ができることを見ていきます!どうもありがとうございました!
ガブリエルベナミー

コマンドラインで実行する必要はありません。これらの変更は、ファイル内に配置しても機能します。ごめんなさい!、私はそれをチェックするために私のコンピューターにいませんでした。あなたは私が思うに160文字まで得ることができるはずです。
ダダ

5

PHP、155バイト

for(;$d++<$n=$argv[1];$x&$a[$d]<1?:print"\n".chunk_split(join($a),$n*$l))for($i=$d*$x=$d>1;$n**2>=$i+=$d;)$a[$i]=str_pad($x|$i<2?"":$i,$l=strlen($n**2)+1);

@Crypto -3バイトありがとうございます@Titus -6バイトありがとうございます

それを試してみてください

ループ後条件で初めてprintを使用する

壊す

for(;$d++<$n=$argv[1];
$x&$a[$d]<1?:print"\n".chunk_split(join($a),$n*$l))
#after loop print the grid if $d = 1 or is prime
for($i=$d*$x=$d>1;$n**2>=$i+=$d;)
$a[$i]=str_pad($x|$i<2?"":$i,$l=strlen($n**2)+1);
#fills the array at first run and replace positions with space in the next runs 

以前のバージョン174バイト

for(;$d++<=$n=$argv[1];!($d<2||$a[$d]>0)?:print chunk_split(join($a),$n*$l)."\n")for($i=$d<2?1:2*$d;$i<=$m=$n**2;$i+=$d)$a[$i]=str_pad($d<2?($i<2?"":$i):" ",$l=strlen($m)+1);  

1
条件を変更する-3バイト:!($d<2||$a[$d]>0)=>$d>1&&$a[$d]<1
Crypto

1
このトリックを使用して-1バイトで整数の長さ$l=strlen($m)+1を取得するには$l=log10($m)+2
暗号化

1
-3バイト:$i=$d*$x=$d>1代わりの$i=$d<2?0:$d及び$x他の2つの出現箇所ため$d>1
タイタス

1
-2バイト:$n*$n>=$i+=$d代わりの($i+=$d)<=$m=$n**2及び$n*$n他の出現のために$m
タイタス

1
-1バイト:末尾の改行ではなく先頭
Titus

3

Groovy、201 195 191バイト

{n->a=(1..n*n).toArray();y={a.collect{(it?"$it":"").padRight((""+n*n).size())}.collate(n).each{println it.join(" ")}};a[0]=0;y(a);(2..n).each{b->(b+1..n*n).each{if(it%b==0){a[it-1]=0}};y(a)}}

これは絶対的なクラスターです...左揃えでバイトカウントが殺されました。しかし、ちょっと、それは動作します。4の出力は次のとおりです。

   2  3  4 
5  6  7  8 
9  10 11 12
13 14 15 16

   2  3    
5     7    
9     11   
13    15   

   2  3    
5     7    
      11   
13         

   2  3    
5     7    
      11   
13         

ゴルフをしていない:

{
    n->
    a = (1..n*n).toArray();                           // Create initial array.
    y = {                                             // Createa  printing utility closure.
        a.collect {                                   // Create an array collection of...
            (it ? "$it":"").padRight((""+n*n).size()) // If 0, store "", else store number & right pad it.
        }.collate(n).each{                            // Collate by n (break into nxn grid).
            println it.join(" ")                      // print each separated by spaces.
        }
    };
    a[0]=0;                                           // Remove first element.
    y(a);                                             // Print initial status.
    (2..n).each{                                      // From 2 to n...
        b->
        (b+1..n*n).each{                              // From current number + 1 to end of grid...
            if(it%b==0){                              // If current grid position is divisible...
                a[it-1]=0                             // Replace with 0.
            }
        }
        y(a)                                          // Print it.
    }        
}


2
これは私には左揃えに見えません。
デニス

固定...私は...今まで編集にそれを機会がなかった
マジックタコ壺

@デニス実際にあなたのコメントを見て、彼はあなたのコメントに基づいて変更したと思った。
魔法のタコUr

3

Perl、115 114 113 112バイト

+1を含む -a

STDINの入力番号で実行:

perl -M5.010 sieving.pl <<< 7

sieving.pl

#!/usr/bin/perl -a
$_*=$_;$a.="$_"x$|++|$"x"@+".($_%"@F"?$":$/)for/\d+/..$_;*_=a;s^^$$_++||say;$.++;s//$&%$.|$&==$.?$&:$&&$_/eg^eg

それが-a意味するように、最近の十分なperlが必要です-n。perlが古すぎる場合は、-nオプションを追加します。

許可されている末尾の改行を出力します。


2

Python 2、 2、199 202 201バイト

+3バイト(早めに停止していません
でした)@Oliverのおかげで-1バイト(スペースがありません)

def f(n,p={()}):
 m=n*n;g=['']+[[i,''][any(i>n and i%n<1for n in p)]for i in range(2,m+1)];x=min(set(g)-p);i=0
 while i<m+n:print' '.join('%%%ds'%-len(`m`)%v for v in g[i:i+n]);i+=n
 if x<=n:f(n,p|{x})

repl.it


1
1との間のスペースを削除することができますfor
オリバーNi

2

JavaScript(ES6)、190 189バイト

コンソールに直接印刷します。

f=(w,k=1,a=[...Array(w*w)].map((_,n)=>n&&n+1))=>k++<=w&&(k==2|a[k-2]&&console.log(a.map((n,x)=>`${n||''}    `.slice(0,`_${w*w}`.length)+(++x%w?'':`
`)).join``),f(w,k,a.map(n=>n==k|n%k&&n)))

デモ


2

バッチ、464バイト

@echo off
set/an=%1,s=n*n,t=s,c=1
set p=
:l
set/ac+=1,t/=10
set p= %p%
if %t% gtr 0 goto l
for /l %%i in (1,1,%1)do call:i %%i
exit/b
:i
set l=
set/af=0
call:f %1 %1
if %f%==0 for /l %%j in (1,1,%s%)do call:j %1 %%j
exit/b
:j
set/am=%2,f=!(m-1),g=%2%%n
call:f %1 %2
if %f% gtr 0 set m=
set m=%m% %p%
call set l=%%l%%%%m:~0,%c%%%
if %g%==0 echo(%l%&set l=
if %2==%s% echo(
exit/b
:f
for /l %%l in (2,1,%1)do if %%l neq %2 set/af+=!(%2%%%%l)

これはやや面倒でした。説明:ループを使用してn、目的の列幅cと適切な量のパディングを計算できるように、平方で開始しpます:l。外側のループfrom 1から行、およびグリッドの最後に余分な空白行が追加されます。ラベルは、要因チェックサブルーチンを示し、f(x、y)は、2から除算までの整数ごとに1を加算し、それ自体を除外します。nグリッドごとに1回実行され、サブルーチンを呼び出し:iます。最初に、値がチェックされて1か素数かが確認されます。そうでない場合、そのグリッドはスキップされます。内側ループ1n*n、その後は、サブルーチンを呼び出し、グリッドの行および列を処理します:j。各値は、それがこれまでに見つかった素数の1つであるかどうか、またはこれまでに見つかった素数のどれもそれを分割しないかどうかを確認するためにチェックされます。そうである場合、値は出力バッファーに連結され、出力バッファーは目的の列幅に埋め込まれます。バッファーはごとに印刷および消去n:ffxyy


2

R、195 191 185 204バイト

f=function(N){a=b=1:N^2;i=1;a[1]="";S=sprintf;while(i<=N){for(j in b)cat(a[j]<-S(S("%%-%is",nchar(N^2)),if(j==i|j%%i|i<2)a[j]else ""),if(j%%N)"" else"\n");cat("\n");i=(grep("\\d",a[-(1:i)],v=T)[1]:1)[1]}}

@Billywobに6バイト追加してくれてありがとう!

インデント、改行あり:

f=function(N){
   a=b=1:N^2 #Initial array
   i=1 #Turn counter
   a[1]="" #1 never shown
   S=sprintf
   while(i<=N){
      for(j in b)
         cat(a[j]<-S(S("%%-%is",nchar(N^2)),if(j==i|j%%i|i<2)a[j]else ""),
             if(j%%N)"" else"\n") #Newline at end of row
      cat("\n") #Newline between turns
      i=(grep("\\d",a[-(1:i)],v=T)[1]:1)[1] #Select next prime as next i
   }
}

使用法:

> f(2)
  2 
3 4 

  2 
3   

> f(3)
  2 3 
4 5 6 
7 8 9 

  2 3 
  5   
7   9 

  2 3 
  5   
7     

> f(9)
   2  3  4  5  6  7  8  9  
10 11 12 13 14 15 16 17 18 
19 20 21 22 23 24 25 26 27 
28 29 30 31 32 33 34 35 36 
37 38 39 40 41 42 43 44 45 
46 47 48 49 50 51 52 53 54 
55 56 57 58 59 60 61 62 63 
64 65 66 67 68 69 70 71 72 
73 74 75 76 77 78 79 80 81 

   2  3     5     7     9  
   11    13    15    17    
19    21    23    25    27 
   29    31    33    35    
37    39    41    43    45 
   47    49    51    53    
55    57    59    61    63 
   65    67    69    71    
73    75    77    79    81 

   2  3     5     7        
   11    13          17    
19          23    25       
   29    31          35    
37          41    43       
   47    49          53    
55          59    61       
   65    67          71    
73          77    79       

   2  3     5     7        
   11    13          17    
19          23             
   29    31                
37          41    43       
   47    49          53    
            59    61       
         67          71    
73          77    79       

   2  3     5     7        
   11    13          17    
19          23             
   29    31                
37          41    43       
   47                53    
            59    61       
         67          71    
73                79       

> f(12)
    2   3   4   5   6   7   8   9   10  11  12  
13  14  15  16  17  18  19  20  21  22  23  24  
25  26  27  28  29  30  31  32  33  34  35  36  
37  38  39  40  41  42  43  44  45  46  47  48  
49  50  51  52  53  54  55  56  57  58  59  60  
61  62  63  64  65  66  67  68  69  70  71  72  
73  74  75  76  77  78  79  80  81  82  83  84  
85  86  87  88  89  90  91  92  93  94  95  96  
97  98  99  100 101 102 103 104 105 106 107 108 
109 110 111 112 113 114 115 116 117 118 119 120 
121 122 123 124 125 126 127 128 129 130 131 132 
133 134 135 136 137 138 139 140 141 142 143 144 

    2   3       5       7       9       11      
13      15      17      19      21      23      
25      27      29      31      33      35      
37      39      41      43      45      47      
49      51      53      55      57      59      
61      63      65      67      69      71      
73      75      77      79      81      83      
85      87      89      91      93      95      
97      99      101     103     105     107     
109     111     113     115     117     119     
121     123     125     127     129     131     
133     135     137     139     141     143     

    2   3       5       7               11      
13              17      19              23      
25              29      31              35      
37              41      43              47      
49              53      55              59      
61              65      67              71      
73              77      79              83      
85              89      91              95      
97              101     103             107     
109             113     115             119     
121             125     127             131     
133             137     139             143     

    2   3       5       7               11      
13              17      19              23      
                29      31                      
37              41      43              47      
49              53                      59      
61                      67              71      
73              77      79              83      
                89      91                      
97              101     103             107     
109             113                     119     
121                     127             131     
133             137     139             143     

    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              101     103             107     
109             113                             
121                     127             131     
                137     139             143     

    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              101     103             107     
109             113                             
                        127             131     
                137     139                     

ニース、私はマトリックスを適切に印刷して、コードゴルフの要件に準拠する方法を理解することはできません。ただし、数バイトは節約できます。累乗演算子^は、を使用し:てシーケンスを生成するときにベクトル化されない唯一の演算子です。つまり1:2^2、getなどに使用できます1 2 3 4。次に、定義するa=b=1:n^2場合for(j in b)、別のベクトルを定義してループオーバーする代わりに後で使用できます。数バイト節約できます。
ビリーウォブ

確かに!ありがとう!...演算子の優先順位の正確な順序を覚えていることはできません
plannapus

f(2)とf(3)の数字の間に3つのスペースがあり、f(9)の2つのスペースがあるのはなぜですか?常に1つのスペースである必要があります。
オリバーNi

ああ、私はN = 10でテストしていたので、標準として3文字を設定しました、それを修正させてください。
プランナパス

1

J、125バイト

p=:3 :'}."1,./('' '',.>)"1|:(-%:#y)]\((a:"_)`(<@":)@.*)"+y'
3 :'p@>~.|.(]*](*@|~+.=)({[:I.*){])&.>/\.(<"+i.-y),<]`>:@.*i.*:y'

これは明示的であり、暗黙のJではありませんが、暗黙のうちにゴルフする方法があるはずです。

使用法

   p =: 3 :'}."1,./('' '',.>)"1|:(-%:#y)]\((a:"_)`(<@":)@.*)"+y'
   f =: 3 :'p@>~.|.(]*](*@|~+.=)({[:I.*){])&.>/\.(<"+i.-y),<]`>:@.*i.*:y'
   f 2
  2
3 4

  2
3  
   f 3
  2 3
4 5 6
7 8 9

  2 3
  5  
7   9

  2 3
  5  
7    
   f 4
   2  3  4 
5  6  7  8 
9  10 11 12
13 14 15 16

   2  3    
5     7    
9     11   
13    15   

   2  3    
5     7    
      11   
13         
   f 5
   2  3  4  5 
6  7  8  9  10
11 12 13 14 15
16 17 18 19 20
21 22 23 24 25

   2  3     5 
   7     9    
11    13    15
   17    19   
21    23    25

   2  3     5 
   7          
11    13      
   17    19   
      23    25

   2  3     5 
   7          
11    13      
   17    19   
      23      

1

Mathematica、133バイト

Grid[#,Alignment->Left]~Print~"
"&/@FoldList[#/.(##|1&@@(2~r~i#2)->Null)&,(r=Range)[i=#^2]~Partition~#/.Rule[1,],Prime@r@PrimePi@#];&

1

PHP、155の 150 147 145 142 140バイト

for(;$k++<$n=$argv[1];)if($k<2||$a[$k]){for($i=0;$i++<$n*$n;)echo$a[$i]=$k>1?$i>$k&$i%$k<1?"":$a[$i]:($i<2?"":$i),"\t\n"[$i%$n<1];echo"\n";}

壊す

for(;$k++<$n=$argv[1];)
    if($k<2||$a[$k])    // if first iteration or number unprinted ...
{
    for($i=0;$i++<$n*$n;)
        echo
            $a[$i]=$k>1
                ?$i>$k&$i%$k<1
                    ?""         // sieve
                    :$a[$i]     // or copy value
                :($i<2?"":$i)   // first iteration: init grid
            ,
            // append tab, linebreak every $n columns
            "\t\n"[$i%$n<1]
        ;
    // blank line after each iteration
    echo"\n";
}

1
$a[$i]="";代わりにunset($a[$i]);4バイトを保存する必要があります
ヨルグヒュルサーマン

$i%$k<1!($i%$k)1バイトを保存する代わりに
ヨルグヒュルサーマン
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.