Tamis d'Ératosthène, étape par étape

15

Étant donné un nombre N , dessinez un tableau de nombres aligné à gauche N x N , en laissant 1 vide (comme un espace) (je montrerai des diagrammes avec 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

Votre travail consiste à construire le tamis d'Ératosthène, étape par étape. Tout d'abord, commencez par 2. Il est premier, alors laissez-le là, et remplacez tous les autres nombres divisibles par 2 par le nombre approprié d'espaces.

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

Ensuite, passez au prochain numéro non imprimé ( 3dans ce cas) et faites de même.

   2  3     5
   7          
11    13      
   17    19   
      23    25

Et ainsi de suite, jusqu'à ce que vous atteindre N .

Vous devez d'abord imprimer la grille complète, et chaque fois que vous accédez à un nouveau numéro, imprimez le tableau avec les multiples supprimés. Assurez-vous d'imprimer une ligne vierge entre les deux!

Exemples

Le texte entre parenthèses ()est juste pour référence, vous n'avez pas besoin de l'imprimer

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'oubliez pas qu'il s'agit de , donc le code avec le plus petit nombre d'octets l'emporte.

Oliver Ni
la source
Normalement , pour un N × N tamis vous arrêter après tamisage N .
Neil
1
Par exemple, si N=10, 100n'est pas premier, il sera supprimé à un moment donné. Est-ce que tous les nombres doivent être remplis à 3 caractères car 100a 3 chiffres?
mbomb007
4
Pourquoi voudriez-vous laisser des chiffres alignés?
Dennis
2
Les sauts de ligne sont-ils acceptables?
Dennis
2
Les grilles intégrées sont-elles autorisées? La sortie sera identique à l'exemple de la publication, mais ne sera pas une chaîne.
JungHwan Min

Réponses:

7

Gelée , 34 octets

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

Essayez-le en ligne!

Comment ça fonctionne

²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.
Dennis
la source
5

Perl, 250 243 231 202 157 octets

$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}

Testez le golf actuel en ligne! (assurez-vous d'exécuter en tant que perl -M5.010 main.pl)

Les deux sauts de ligne littéraux enregistrent chacun 1 octet à la place de \ n.

Exemple de sortie (entrée de 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       

Je suis certain que je ne l'ai pas très bien joué au golf, donc quand je rentrerai à la maison, j'y jetterai un autre coup d'œil pour voir à quel point je peux me raser.

Modifier 1: -7 octets (en changeant "print sprintf" en évident "printf")

Edit 2: 12 octets enregistrés en utilisant explicitement $ d au seul endroit où il a été appelé au lieu de créer une variable distincte, en combinant certaines déclarations et en éliminant l'une de mes conditions pour l' nextinstruction à l'intérieur de la première foreachboucle en ajoutant un espace ailleurs . 29 octets supplémentaires ont été analysés en retravaillant deux boucles for en une seule boucle, en éliminant deux déclarations de variables et en transformant les unlessinstructions en instructions if-not. Déclarer my$e=$n*$n;puis remplacer les trois instances de $ n * $ n par $ e (me permettant de supprimer un paren pour l'un d'entre eux) s'est avéré donner ± 0 octets, mais je l'ai quand même conservé.

Edit 3: Grâce à @Dada, 40 autres octets ont été joués (déclarations de variables, 'foreach' devenant 'for', $ _ implicite à plusieurs endroits, et réduction de la taille de l'instruction printf). Un 1 octet supplémentaire a été rasé en tournant if!($c%$p||$c==$p||$p==1)dans if!($p~~[(1,$_)]||$_%$p). Malheureusement, le [] autour du tableau est nécessaire, car l'opérateur smartmatch ~~ est encore expérimental et ne semble pas fonctionner correctement sur les tableaux réels, mais fonctionne sur les références à leur place. 4 octets supplémentaires ont été supprimés en supprimant deux points-virgules et un ensemble vide de guillemets après le dernier say.

Gabriel Benamy
la source
1
C'est un bon début, mais vous pouvez jouer au golf beaucoup plus. Ne déclarez pas de variables (donc n'utilisez pas my). Utilisez le -pdrapeau pour avoir à l' Nintérieur $_au lieu d'utiliser $n=<>. Écrirefor place de foreach(cette instruction est équivalente). Laissez tomber la parenthèse autour de la condition de ceux ifqui sont dans la position de modification de l' instruction (par exemple au if!$c%$nlieu de if(!$c%$n)Aucune parenthèse nécessaire pour initialiser. @a: @a=0..$e. Vous pouvez tomber à forvariable et $_wiil être utilisé à la place écriture. printf"%*s",1+length$e,$a[$c](La `` sprintf` doc pour plus de détails à ce sujet *)
Dada
1
Utilisez $"au lieu de " ". say""au lieu de print"\n"(vous avez une nouvelle ligne littérale dans votre code mais je ne peux pas l'écrire en commentaire) (vous ajouterez pour ajouter -M5.010à la ligne de commande, mais cela ne compte pas dans le nombre d'octets). Vous pouvez probablement utiliser 0..$e=$n*$npour enregistrer un octet lors de l'initialisation de $e. Jetez un oeil à la conseils de golf Perl , il contient de nombreux conseils utiles. Mais c'est agréable de voir un nouveau golfeur Perl, bienvenue! :) (et pardonnez mes fautes d'orthographe, j'ai peut-être écrit mon commentaire précédent trop vite)
Dada
@Dada Merci pour vos conseils! Je ne suis pas très familier avec l'exécution de code sur la ligne de commande (j'ai tendance à l'exécuter en tant que fichier) mais je vais essayer de le faire de cette façon. Quant à if!$c%$n, le! L'opérateur a la priorité sur l'opérateur%, donc techniquement ce serait ce if((!$c)%$n)qui se révèle faux pour autre chose que $ c = 0 (ce que je ne veux pas). Quant à vos autres astuces, je vais voir ce que je peux faire! Merci beaucoup!
Gabriel Benamy
Vous n'avez pas besoin de l' exécuter sur la ligne de commande, ces modifications fonctionneront si vous les placez également dans un fichier. Désolé pour !, je n'étais pas sur mon ordinateur pour le vérifier. Vous devriez pouvoir descendre à 160 caractères je pense.
Dada
5

PHP, 155 octets

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 octets Merci @Titus -6 octets Merci

Essayez-le

Première fois que j'utilise l'impression dans une condition de boucle après

Panne

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 

Version précédente 174 octets

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);  
Jörg Hülsermann
la source
1
-3 octets changeant la condition: !($d<2||$a[$d]>0)=>$d>1&&$a[$d]<1
Crypto
1
-1 octets en utilisant cette astuce pour obtenir la longueur entière $l=strlen($m)+1à$l=log10($m)+2
Crypto
1
-3 octets: $i=$d*$x=$d>1au lieu de $i=$d<2?0:$det $xpour les deux autres occurrences de$d>1
Titus
1
-2 octets: $n*$n>=$i+=$dau lieu de ($i+=$d)<=$m=$n**2et $n*$npour l'autre occurrence de$m
Titus
1
-1 octet: début au lieu de retour à la ligne
Titus
3

Groovy, 201 195 191 octets

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

Ceci est un cluster absolu ... L'alignement à gauche a tué mon nombre d'octets. Mais bon, ça marche. Voici la sortie pour 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         

Non golfé:

{
    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.
    }        
}

La

Urne de poulpe magique
la source
2
Cela ne me semble pas aligné à gauche.
Dennis
Corrigé ... Je n'ai tout simplement pas eu la chance de le modifier jusqu'à présent ...
Urne de poulpe magique
@Dennis J'ai vu vos commentaires et j'ai pensé qu'il les avait modifiés en fonction de vos commentaires.
Urne de poulpe magique du
3

Perl, 115 114 113 112 octets

Comprend +1 pour -a

Exécuter avec le numéro d'entrée sur 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

Nécessite un perl assez récent pour que cela -aimplique -n. Si votre perl est trop ancien, ajoutez une -noption.

Imprime une nouvelle ligne de fin autorisée.

Ton Hospel
la source
2

Python 2, 199 202 201 octets

+3 octets (je ne
m'arrêtais pas tôt) -1 octet grâce à @Oliver (a manqué un espace)

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

Jonathan Allan
la source
1
Vous pouvez supprimer un espace entre 1etfor
Oliver Ni
2

JavaScript (ES6), 190 189 octets

Imprime directement sur la console.

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

Démo

Arnauld
la source
2

Lot, 464 octets

@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)

C'était un peu laborieux. Explication: commence par une mise au carré nafin de pouvoir calculer la largeur de colonne souhaitée cet la quantité appropriée de remplissage pà l'aide de la boucle :l. La boucle externe de 1à ns'exécute ensuite une fois pour chaque grille, appelant le sous-programme :i. D'abord, la valeur est vérifiée pour voir s'il s'agit de 1 ou premier; sinon, cette grille est ignorée. La boucle interne de 1à n*ngère ensuite les lignes et les colonnes de la grille, appelant le sous-programme:j. Chaque valeur est vérifiée pour voir si elle est l'un des nombres premiers trouvés jusqu'à présent, ou si aucun des nombres premiers trouvés jusqu'à présent ne la divise. Si tel est le cas, la valeur est concaténée dans le tampon de sortie, qui est ensuite complété à la largeur de colonne souhaitée. Le tampon est imprimé et effacé toutes lesn lignes et une ligne vierge supplémentaire est ajoutée à la fin de la grille. L' :fétiquette indique le sous-programme de vérification des facteurs; f (x, y) ajoute 1 à fpour chaque entier entre 2 et xqui divise y, en s'excluant ylui-même.

Neil
la source
2

R, 195 191 185 185 204 octets

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

Merci à @Billywob pour 6 octets supplémentaires enregistrés!

En retrait, avec de nouvelles lignes:

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

Usage:

> 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                     
plannapus
la source
Bien, je ne peux jamais comprendre comment imprimer correctement des matrices pour se conformer aux exigences de golf de code, ne vous inquiétez pas de les justifier. Vous pouvez cependant économiser quelques octets. L'opérateur d'exponentiation ^est le seul qui n'est pas vectorisé lors de la génération de séquences en utilisant :ce qui signifie que vous pouvez par exemple utiliser 1:2^2pour obtenir 1 2 3 4. Deuxièmement, si vous définissez, a=b=1:n^2vous pouvez utiliser plus tard for(j in b)au lieu de définir un autre vecteur à boucler. Devrait vous faire économiser quelques octets.
Billywob
En effet! Merci! Je ne me souviens jamais de l'ordre exact de priorité des opérateurs ...
plannapus
Pourquoi y a-t-il trois espaces entre les nombres en f (2) et f (3) et deux espaces en f (9)? Ce devrait toujours être un espace.
Oliver Ni
Oh oui j'ai mis 3 caractères comme norme parce que je testais avec N = 10, permettez-moi de corriger cela.
plannapus
1

J, 125 octets

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

C'est explicite, pas tacite J, mais il devrait y avoir un moyen de jouer au golf tacitement.

Usage

   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      
miles
la source
1

Mathematica, 133 octets

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

PHP, 155 150 147 145 142 140 140 octets

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

panne

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";
}
Titus
la source
1
$a[$i]="";au lieu de unset($a[$i]);devrait économiser 4 octets
Jörg Hülsermann
$i%$k<1au lieu d' !($i%$k)enregistrer un octet
Jörg Hülsermann