Tamiz de Eratóstenes, paso a paso

15

Dado un número N , dibuje una tabla de números N x N alineada a la izquierda , dejando 1 en blanco (como un espacio) (mostraré diagramas con 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

Tu trabajo es construir el Tamiz de Eratóstenes, paso a paso. Primero, comience con 2. Es primo, así que déjelo allí y reemplace todos los demás números divisibles por 2 con el número adecuado de espacios.

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

A continuación, vaya al siguiente número sin imprimir ( 3en este caso) y haga lo mismo.

   2  3     5
   7          
11    13      
   17    19   
      23    25

Y así sucesivamente, hasta llegar a N .

Primero debe imprimir la cuadrícula completa, y cada vez que vaya a un nuevo número, imprima el tablero con los múltiplos eliminados. ¡Asegúrese de imprimir una línea en blanco en el medio!

Ejemplos

El texto entre paréntesis ()es solo para referencia, no necesita imprimirlo

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    

Recuerde, este es el , por lo que gana el código con el menor número de bytes.

Oliver Ni
fuente
Normalmente, para un N × N tamiz después de dejar de tamizado N .
Neil
1
Por ejemplo, si N=10, 100no es primo, por lo que será eliminado en algún momento. ¿Deben completarse todos los números con 3 caracteres porque 100tiene 3 dígitos?
mbomb007
44
¿Por qué le dejó números -align?
Dennis
2
¿Son aceptables las nuevas líneas finales?
Dennis
2
¿Están permitidas las rejillas integradas? El resultado se verá idéntico al ejemplo en la publicación, pero no será una cadena.
JungHwan Min

Respuestas:

7

Jalea , 34 bytes

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

Pruébalo en línea!

Cómo funciona

²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
fuente
5

Perl, 250 243 231 202 157 bytes

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

Prueba el golf actual en línea! (asegúrese de correr como perl -M5.010 main.pl)

Las dos nuevas líneas literales guardan cada una 1 byte en lugar de \ n.

Salida de muestra (entrada 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       

Estoy seguro de que no lo jugué muy bien, así que cuando llegue a casa volveré a mirarlo para ver cuánto puedo afeitarme.

Edición 1: -7 bytes (cambiando "print sprintf" por el obvio "printf")

Edición 2: guarde 12 bytes usando $ d explícitamente en el lugar donde se llamó en lugar de crear una variable separada, combinando algunas declaraciones y eliminando una de mis condiciones para la nextdeclaración dentro del primer foreachciclo agregando un espacio en otro lugar . Se desarrollaron 29 bytes adicionales al reelaborar dos bucles for en un solo bucle, eliminando dos declaraciones de variables y convirtiendo las unlessdeclaraciones en declaraciones if-not. Declarar my$e=$n*$n;luego reemplazar las tres instancias de $ n * $ n con $ e (lo que me permite colocar un par para uno de ellos) resultó en un rendimiento de ± 0 bytes, pero lo mantuve de todos modos.

Edición 3: Gracias a @Dada, se desarrollaron otros 40 bytes (declaraciones variables, 'foreach' convirtiéndose en 'for', $ _ implícito en varias ubicaciones y reduciendo el tamaño de la declaración printf). Se eliminó 1 byte adicional convirtiéndolo if!($c%$p||$c==$p||$p==1)en if!($p~~[(1,$_)]||$_%$p). Desafortunadamente, el [] alrededor de la matriz es necesario, porque el operador smartmatch ~~ todavía es experimental y no parece funcionar correctamente en las matrices reales, pero sí funciona en referencias a ellas. Se eliminaron 4 bytes más al eliminar dos puntos y comas y un conjunto vacío de comillas después del último say.

Gabriel Benamy
fuente
1
Es un buen comienzo, pero puedes jugar mucho más. No declare variables (así que no use my). Use la -pbandera para tener Nadentro en $_lugar de usar $n=<>. Escriba en forlugar de foreach(esta instrucción son equivalentes). Coloque el paréntesis alrededor de la condición de ifque está en la posición del modificador de la declaración (por ejemplo, en if!$c%$nlugar de if(!$c%$n). No se necesita paréntesis para inicializar @a:. @a=0..$ePuede colocar la forvariable y $_se utilizará en su lugar. Escriba printf"%*s",1+length$e,$a[$c](el documento `` sprintf '' para obtener detalles sobre eso) *)
Dada
1
Usar en $"lugar de " ". say""en lugar de print"\n"(tiene una nueva línea literal en su código pero no puedo escribirla en el comentario) (agregará para agregar -M5.010a la línea de comando, pero eso no cuenta en el recuento de bytes). Probablemente pueda usar 0..$e=$n*$npara guardar un byte en la inicialización de $e. Eche un vistazo a los consejos de golf de Perl , contiene muchos consejos útiles. Pero es bueno ver a un nuevo golfista perl, ¡bienvenido! :) (y perdone mis errores ortográficos, es posible que haya escrito mi comentario anterior demasiado rápido)
Dada
@Dada ¡Gracias por tu consejo! No estoy muy familiarizado con la ejecución de código en la línea de comandos (tiendo a ejecutarlo como un archivo), pero lo haré de esa manera. En cuanto a if!$c%$n, el! El operador tiene precedencia sobre el operador%, por lo que técnicamente esto sería if((!$c)%$n)falso para cualquier cosa que no sea $ c = 0 (que no quiero). En cuanto a tus otros consejos, ¡veré qué puedo hacer! ¡Muchas gracias!
Gabriel Benamy
No tiene que ejecutarlo en la línea de comando, esas modificaciones funcionarán si las coloca dentro de un archivo también. Lo siento !, no estaba en mi computadora para verificarlo. Debería poder llegar a 160 caracteres, creo.
Dada
5

PHP, 155 bytes

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 Bytes Gracias @Titus -6 Bytes Gracias

Intentalo

Primera vez que uso print en una condición de bucle posterior

Descompostura

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 

Versión anterior 174 Bytes

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
fuente
1
-3 bytes cambiando la condición: !($d<2||$a[$d]>0)=>$d>1&&$a[$d]<1
Crypto
1
-1 byte usando este truco para obtener una longitud entera $l=strlen($m)+1para$l=log10($m)+2
Crypto
1
-3 bytes: en $i=$d*$x=$d>1lugar de $i=$d<2?0:$dy $xpara las otras dos ocurrencias de$d>1
Titus el
1
-2 bytes: en $n*$n>=$i+=$dlugar de ($i+=$d)<=$m=$n**2y $n*$npara la otra ocurrencia de$m
Titus
1
-1 byte: línea principal en lugar de cola
Titus
3

Maravilloso, 201 195 191 Bytes

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

Este es un grupo absoluto ... La alineación izquierda asesinó mi cuenta de bytes. Pero bueno, funciona. Aquí está la salida para 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         

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

Urna de pulpo mágico
fuente
2
Esto no me parece alineado a la izquierda.
Dennis
Solucionado ... Simplemente no tuve la oportunidad de editarlo hasta ahora ...
Magic Octopus Urn
@ Dennis En realidad vi tus comentarios y pensé que lo había cambiado en base a tu comentario.
Urna mágica de pulpo
3

Perl, 115 114 113 112 bytes

Incluye +1 para -a

Ejecutar con el número de entrada en 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

Necesita un perl lo suficientemente reciente para que eso -aimplique -n. Si su perl es demasiado viejo, agregue una -nopción.

Imprime una nueva línea final que está permitida.

Ton Hospel
fuente
2

Python 2, 199202201 bytes

+3 bytes (no me detenía antes)
-1 byte gracias a @Oliver (perdí un espacio)

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
fuente
1
Puede quitar un espacio entre 1yfor
Oliver Ni
2

JavaScript (ES6), 190 189 bytes

Imprime directamente a la consola.

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

Manifestación

Arnauld
fuente
2

Lote, 464 bytes.

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

Esto fue algo laborioso. Explicación: Comienza por cuadrar las líneas y se agrega una línea en blanco adicional al final de la cuadrícula. La etiqueta denota la subrutina de verificación de factores; f (x, y) agrega 1 an para que pueda calcular el ancho de columna deseado cy la cantidad adecuada de relleno p, utilizando el bucle :l. El bucle externo de 1a nse ejecuta una vez para cada cuadrícula, llamando a la subrutina :i. Primero se verifica el valor para ver si es 1 o primo; de lo contrario, se omite esa cuadrícula. El bucle interno de 1a n*nmaneja las filas y columnas de la cuadrícula, llamando a la subrutina:j. Cada valor se verifica para ver si es uno de los números primos encontrados hasta ahora, o si ninguno de los números primos encontrados hasta ahora lo divide. Si es así, el valor se concatena al búfer de salida, que luego se rellena al ancho de columna deseado. El búfer se imprime y borra todas las para cada número entero entre 2 y que divide , excluyéndose a sí mismo.n:ffxyy

Neil
fuente
2

R, 195 191 185 204 bytes

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

¡Gracias a @Billywob por 6 bytes adicionales guardados!

Sangrado, con nuevas líneas:

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

Uso:

> 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
fuente
Agradable, nunca puedo entender cómo imprimir correctamente las matrices para cumplir con los requisitos de codegolfing, no importa dejar de justificarlas. Sin embargo, puede guardar algunos bytes. El operador de exponenciación ^es el único que no está vectorizado al generar secuencias usando lo :que significa que puede usar, por ejemplo, 1:2^2para obtener 1 2 3 4. En segundo lugar, si define a=b=1:n^2, puede usarlo en for(j in b)lugar de definir otro vector para recorrer. Debería ahorrarte un par de bytes.
Billywob
¡En efecto! ¡Gracias! Nunca puedo recordar el orden exacto de precedencia del operador ...
plannapus
¿Por qué hay tres espacios entre los números en f (2) yf (3) y dos espacios en f (9)? Siempre debe ser un espacio.
Oliver Ni
Ah, claro, configuré 3 caracteres como norma porque estaba probando con N = 10, permítanme corregir eso.
plannapus
1

J, 125 bytes

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

Esto es explícito, no tácito J, pero debería haber una forma de jugarlo tácitamente.

Uso

   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      
millas
fuente
1

Mathematica, 133 bytes

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

PHP, 155 150 147 145 142 140 bytes

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

Descompostura

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
fuente
1
$a[$i]="";en lugar de unset($a[$i]);ahorrar 4 bytes
Jörg Hülsermann
$i%$k<1en lugar de !($i%$k)guardar un byte
Jörg Hülsermann