Сито Ератосфена, крок за кроком


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=10, 100не проста, тому будуть видалені в якій - то момент. Потрібно, щоб усі цифри були зафіксовані на 3 символи, тому що 100мають 3 цифри?
mbomb007

4
Чому ви залишили - вирівняти номери?
Денніс

2
Чи прийнятні останні рядки?
Денніс

2
Чи дозволені вбудовані сітки? Вихід буде виглядати ідентично прикладу в публікації, але не буде рядком.
JungHwan Min

Відповіді:


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)

Кожен з двох прямолінійних рядків зберігає 1 байт замість \ n.

Вибірка зразка (вхід 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: Збережено 12 байтів, використовуючи явно $ d в одному місці, яке було викликано замість створення окремої змінної, об'єднавши деякі декларації та усунувши одну з моїх умов для nextоператора всередині першого foreachциклу, додавши пробіл десь ще . Додаткових 29 байтів було оброблено, переробивши два для циклу в єдиний цикл, усунувши дві заяви змінної та перетворивши unlessзаяви в оператори, якщо ні. Оголошення, що my$e=$n*$n;потім замінило три екземпляри $ n * $ n на $ e (що дозволило мені скинути батьківське значення для одного з них), виявилося, отримало ± 0 байт, але я все-таки зберігав це.

Редагування 3: Завдяки @Dada, ще 40 байтів було розіграно (декларації змінних, "foreach" стає "for", неявні $ _ у кількох місцях та скорочення розміру заяви printf). Додатковий 1 байт був поголений, перетворившись if!($c%$p||$c==$p||$p==1)на if!($p~~[(1,$_)]||$_%$p). На жаль, [] навколо масиву є необхідним, оскільки оператор smartmatch ~~ все ще експериментальний і, здається, не працює належним чином на фактичних масивах, але замість цього працює над посиланнями на них. Ще 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для збереження одного байти при ініціалізації $e. Погляньте на поради щодо гри в гольф , він містить багато корисних порад. Але приємно бачити нового гольфіста Perl, ласкаво просимо! :) (і пробачте мої орфографічні помилки, можливо, я написав попередній коментар занадто швидко)
Дада,

@Dada Дякую за пораду! Я не дуже знайомий із запуском коду в командному рядку (я схильний запускати його як файл), але я погляну на те, як це зробити. Щодо if!$c%$n, то! Оператор має перевагу перед% -оператором, тому технічно це було б таким, if((!$c)%$n)що виходить помилковим для чогось іншого, ніж $ c = 0 (чого я не хочу). Щодо інших ваших порад, я побачу, що я можу зробити! Велике спасибі!
Габріель Бенамі

Не потрібно запускати його в командному рядку, ці зміни працюватимуть, якщо ви також помістите їх у файл. Вибачте за те !, що я не був на своєму комп’ютері, щоб перевірити це. Ви повинні мати можливість зійти до 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 байт Дякую

Спробуй це

Перший раз, коли я використовую друк у режимі після циклу

Зламатися

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
Криптовалюта

1
-1 байт, використовуючи цей трюк, щоб отримати цілу довжину $l=strlen($m)+1до$l=log10($m)+2
Crypto

1
-3 байти: $i=$d*$x=$d>1замість $i=$d<2?0:$dта $xдля інших двох випадків$d>1
Тит

1
-2 байти: $n*$n>=$i+=$dзамість ($i+=$d)<=$m=$n**2і $n*$nдля іншого виникнення$m
Тіт

1
-1 байт: ведучий замість того, щоб прокласти новий рядок
Тіт

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
На мене це не виглядає ліворуч.
Денніс

Виправлено ... Я просто не отримав шансу редагувати його до цих пір ...
Magic Octopus Urn

@Dennis Я насправді побачив ваші коментарі і подумав, що він змінив його на основі вашого коментаря.
Чарівна восьминога урна

3

Перл, 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випливало -n. Якщо ваш perl занадто старий, додайте -nпараметр.

Виводить новий рядок, який дозволено.


2

Python 2, 199 202 201 байт

+3 байт (я не зупинявся рано)
-1 байт завдяки @Oliver (пропустив пробіл)

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
Олівер Ні

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. Зовнішній цикл від 1до nПотім виконується один раз для одного мережива, виклику підпрограми :i. Спочатку перевіряється значення, щоб побачити, чи є 1 чи простим; якщо ні, то ця сітка пропускається. Внутрішній цикл з , 1щоб n*nпотім обробляє рядки і стовпці сітки, виклик підпрограми:j. Кожне значення перевіряється, щоб це було одне з простих чисел, знайдених до цих пір, чи ні одне з найпростіших чисел, знайдених поки що, не ділить його. Якщо так, то значення приєднується до вихідного буфера, який потім додається до потрібної ширини стовпця. Буфер друкується та очищається кожен nрядок, а в кінці сітки додається додатковий порожній рядок. :flabel позначає підпрограму перевірки факторів; f (x, y) додає 1 до fкожного цілого числа між 2 та, xщо ділиться y, виключаючи yсебе.


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для отримання 1 2 3 4. По-друге, якщо ви визначаєте, a=b=1:n^2ви можете пізніше використовувати for(j in b)замість визначення іншого вектора, щоб перейти на цикл. Потрібно заощадити пару байтів.
Billywob

Справді! Спасибі! Ніколи не можу згадати точний порядок пріоритетності оператора ...
plannapus

Чому між числами в f (2) і f (3) є три пробіли і два простори в f (9)? Це завжди має бути один простір.
Олівер Ні

Ну правильно, я встановив 3 символи як норму, тому що я тестував N = 10, дозвольте це виправити.
планнапус

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

Математика, 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 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)зберегти один байт
Йорг Гюльсерманн
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.