Gli anelli degli alberi quadrati possono essere generati dai numeri primi?


33

Apparentemente si! In tre semplici passaggi.

Passo 1

Sia f ( n ) la funzione di conteggio dei primi (numero di numeri primi minore o uguale a n ).

Definire la sequenza intera s ( n ) come segue. Per ogni numero intero positivo n ,

  • Inizializza da t a n .
  • Finché t non è né primo né 1, sostituire t con f ( t ) e iterare.
  • Il numero di iterazioni è s ( n ).

Il processo iterativo termina perché f ( n ) < n per tutto n .

Si consideri ad esempio n = 25. Inizializziamo t = 25. Dato che questo non è un numero primo né 1, calcoliamo f (25), che è 9. Questo diventa il nuovo valore per t . Questo non è un numero primo né 1, quindi continuiamo: f (9) è 4. Continuiamo di nuovo: f (4) è 2. Dato che questo è un numero primo, ci fermiamo qui. Abbiamo eseguito 3 iterazioni (da 25 a 9, quindi a 4, quindi a 2). Quindi s (25) è 3.

I primi 40 termini della sequenza sono i seguenti. La sequenza non è in OEIS.

0 0 0 1 0 1 0 2 2 2 0 1 0 2 2 2 0 1 0 3 3 3 0 3 3 3 3 3 0 3 0 1 1 1 1 1 0 2 2 2

Passo 2

Dato un numero intero dispari positivo N , costruisci un array N × N (matrice) avvolgendo la sequenza finita s (1), s (2), ..., s ( N 2 ) per formare una spirale quadrata verso l'esterno . Ad esempio, dato N = 5 la spirale è

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

o, sostituendo i valori,

 3       3       0       3       3
 3       0       2       2       2
 0       1       0       0       0
 1       0       1       0       1
 0       2       2       2       0

Passaggio 3

Rappresenta l'array N × N come un'immagine con una mappa dei colori grigia o con qualche altra mappa dei colori di tuo gusto. La mappa dovrebbe essere graduale, in modo che l'ordine dei numeri corrisponda a un ordine visivamente evidente dei colori. I casi di test seguenti mostrano alcune mappe dei colori di esempio.

La sfida

Dato un numero intero positivo dispari N , produce l'immagine sopra descritta.

Regole

  • La spirale deve essere esterna, ma può essere in senso orario o antiorario e può iniziare a muoversi a destra (come nell'esempio sopra), a sinistra, in basso o in alto.

  • Le scale degli assi orizzontale e verticale non devono necessariamente essere le stesse. Anche le etichette degli assi, la barra dei colori e elementi simili sono opzionali. Finché la spirale può essere vista chiaramente, l'immagine è valida.

  • Le immagini possono essere emesse con qualsiasi mezzo standard . In particolare, l'immagine può essere visualizzata sullo schermo, oppure può essere prodotto un file grafico o può essere emessa una matrice di valori RGB. Se si genera un file o un array, si prega di pubblicare un esempio di come appare quando viene visualizzato.

  • I mezzi di input e il formato sono flessibili come al solito . È possibile fornire un programma o una funzione . Sono vietate le scappatoie standard .

  • Vince il codice più breve in byte.

Casi test

Le seguenti immagini (clicca per la risoluzione completa) corrispondono a diversi valori di N . Viene utilizzata una prima spirale verso destra, in senso orario, come nell'esempio sopra. Le immagini illustrano anche diverse mappe dei colori valide.

  • N = 301: inserisci qui la descrizione dell'immagine

  • N = 501: inserisci qui la descrizione dell'immagine

  • N = 701: inserisci qui la descrizione dell'immagine


Se un array di valori di s(n)può essere inserito in qualche funzione / pacchetto di stampa senza essere modificato (penso che imshowin matplotlib potrebbe gestirlo ad esempio) è questo un modulo di output accettabile?
Dylnan,

@dylnan Certo, fintanto che stampa l'immagine sullo schermo o produce un file è valido. In effetti ho generato degli esempi con qualcosa di simile a quello che dici. Fai solo attenzione al ridimensionamento dei valori. Ad esempio non è accettabile se tutti i valori superiori a 1 sono riportati stesso colore, come Matlab di (e possibilmente Matplotlib di) imshowfa
Luis Mendo

buon punto. Non sono sicuro se lo imshowfa.
Dylnan,

1
@ kamoroso94 Vedi qui
Luis Mendo

1
Sì, molto chiaro
Christopher

Risposte:


3

Dyalog APL, 94 byte

'P2'
2⍴n←⎕
9
(⍪0){×≢⍵:(≢⍺)((⍉∘⌽⍺,↑)∇↓)⍵⋄⍺}2↓{⍵⌊1+⍵[+\p]}⍣≡9×~p←1=⊃+/(≠⍨,≠⍨,~⍴⍨(×⍨n)-2×≢)¨,\×⍳n

assume ⎕IO=0

output per n = 701 (convertito da .pgm a .png):

inserisci qui la descrizione dell'immagine


10

MATLAB - 197 185 178 175 184 163 162 148 142 140 byte

Rasato 12 byte, grazie ad Ander e Andras, e grazie mille a Luis per aver messo insieme i due. Rasato 16 grazie a Remco, 6 grazie a Flawr

function F(n)
p=@primes
s=@isprime
for a=2:n^2
c=0
if~s(a)
b=nnz(p(a))
while~s(b)
b=nnz(p(b))
c=c+1
end
end
d(a)=c
end
imagesc(d(spiral(n)))

Risultato per N=301( F(301)):

inserisci qui la descrizione dell'immagine

Spiegazione:

function F(n)
p=@primes % Handle
s=@isprime % Handle
for a=2:n^2 % Loop over all numbers
    c=0 % Set initial count
    if~s(a) % If not a prime
        b=nnz(p(a)) % Count primes
        while~s(b) % Stop if b is a prime. Since the code starts at 2, it never reaches 1 anyway
            b=nnz(p(b)) % count again
            c=c+1 % increase count
        end
    end
    d(a)=c % store count
end
imagesc(d(spiral(n))) % plot

8

Wolfram Language (Mathematica) , 124 byte

Grazie a Martin Ender per aver salvato 12 byte!

Image[#/Max@#]&[Array[(n=0;Max[4#2#2-Max[+##,3#2-#],4#
#-{+##,3#-#2}]+1//.x_?CompositeQ:>PrimePi[++n;x];n)&,{#,#},(1-#)/2]]&

Provalo online!


L'immagine generata è:

Spirale

Formula a forma chiusa del valore a spirale presa direttamente da questa mia risposta .


5
#/2-.5salva un byte.
user202729

8
Haha, lo stai suggerendo a te stesso?
Luis Mendo,

6
@ user202729 Non sembra funzionare.
user202729

18
Non intendevo interrompere il tuo dialogo interiore :-P
Luis Mendo il

Rinvia la definizione pfino a quando non ti serve:...,{y,p=(1-#)/2,-p},{x,p,-p}
Martin Ender,

7

MATLAB: 115 114 110 byte

Un liner (eseguito in R2016b + come funzione nello script ) 115 byte

I=@(N)imagesc(arrayfun(@(x)s(x,0),spiral(N)));function k=s(n,k);if n>1&~isprime(n);k=s(nnz(primes(n)),k+1);end;end

Inserendo la funzione in un file separato, come suggerito da flawr, e usando 1 byte aggiuntivo per la regola del file aggiuntivo

Nel file s.m, 64 + 1 byte per codice + file

function k=s(n,k);if n>1&~isprime(n);k=s(nnz(primes(n)),k+1);end

Finestra di comando da definire I, 45 byte

I=@(N)imagesc(arrayfun(@(x)s(x,0),spiral(N)))

Totale: 110 byte


Questo utilizza la ricorsione invece del whilelooping come fanno le altre implementazioni MATLAB ( gnovice , Adriaan ). Eseguirlo come uno script (in R2016b o più recente), questo definisce la funzione Iche può essere eseguita come I(n).

Versione strutturata:

% Anonymous function for use, i.e. I(301)
% Uses arrayfun to avoid for loop, spiral to create spiral!
I=@(N)imagesc(arrayfun(@(x)s(x,0),spiral(N)));

% Function for recursively calculating the s(n) value
function k=s(n,k)
    % Condition for re-iterating. Otherwise return k unchanged
    if n>1 && ~isprime(n)
        % Increment k and re-iterate
        k = s( nnz(primes(n)), k+1 );
    end
end

Esempio:

I(301)

tracciare

Gli appunti:

  • Ho anche cercato di rendere sanonima la funzione, ovviamente per ridurre significativamente il conteggio. Tuttavia, ci sono 2 problemi:

    1. La ricorsione infinita è difficile da evitare quando si utilizzano funzioni anonime, poiché MATLAB non ha un operatore ternario per offrire una condizione di rottura. Gestire una specie di operatore ternario (vedi sotto) costa anche byte poiché abbiamo bisogno della condizione due volte.

    2. Devi passare una funzione anonima a se stessa se è ricorsiva (vedi qui ) che aggiunge byte.

    Il più vicino a questo ho usato le seguenti righe, forse può essere cambiato per funzionare:

    % Condition, since we need to use it twice 
    c=@(n)n>1&&~isprime(n);
    % This uses a bodged ternary operator, multiplying the two possible outputs by
    % c(n) and ~c(n) and adding to return effectively only one of them
    % An attempt was made to use &&'s short-circuiting to avoid infinite recursion
    % but this doesn't seem to work!
    S=@(S,n,k)~c(n)*k+c(n)&&S(S,nnz(primes(n)),k+1);

6

MATLAB - 126 121 * byte

Ho tentato un approccio più vettoriale di Adriaan e sono riuscito a radere più byte. Ecco la soluzione a linea singola:

function t(n),M=1:n^2;c=0;i=1;s=@isprime;v=cumsum(s(M));while any(i),i=M>1&~s(M);c=c+i;M(i)=v(M(i));end;imagesc(c(spiral(n)))

Ed ecco la soluzione ben formattata:

function t(n),
  M = 1:n^2;
  c = 0;
  i = 1;
  s = @isprime;
  v = cumsum(s(M));
  while any(i),         % *See below
    i = M > 1 & ~s(M);
    c = c+i;
    M(i) = v(M(i));
  end;
  imagesc(c(spiral(n)))

* Nota: se si desidera consentire una metrica crapton di iterazioni non necessarie, è possibile modificare la riga while any(i), in for m=v, e salvare 5 byte.


Bello! Mi piace come usi cumsumper vettorializzare ed evitarennz(primes(...)
Luis Mendo

1
Se ho capito bene, non fa male iterare più volte del necessario (a scapito della velocità). Quindi puoi sostituirlo while any(i)con for m=M. Chi se ne frega se il codice impiega ore per l'esecuzione :-)
Luis Mendo

2
@LuisMendo: Certo, perché no? Ripete già una volta più del necessario, n^2qualcos'altro farà male! ;)
gnovice

1
Questo è lo spirito! Puoi anche mantenere la versione più veloce, ma il conteggio dei byte è quello del più breve
Luis Mendo

2

Python 3, 299 265 byte

Salvato 5 byte grazie ai suggerimenti di formattazione di Jonathan Frech e NoOneIsHere. Rimossi altri 34 byte rimuovendo una definizione di funzione chiamata solo una volta.

Questo è un po 'più lungo di alcuni altri, a causa del fatto che Python non ha un comando per determinare il primeness o spirale una matrice. Funziona relativamente rapidamente tuttavia, circa un minuto per n = 700.

from pylab import*
def S(n):
 q=arange(n*n+1);t=ones_like(q)
 for i in q[2:]:t[2*i::i]=0
 c=lambda i:0 if t[i]else 1+c(sum(t[2:i]));S=[c(x)for x in q]
 t=r_[[[S[1]]]]
 while any(array(t.shape)<n):m=t.shape;i=multiply(*m)+1;t=vstack([S[i:i+m[0]],rot90(t)])
 return t

Provalo con

n = 7
x = S(n)
imshow(x, interpolation='none')
colorbar()
show(block=False)


1
Una cosa veloce: puoi rimuovere lo spazio tra importe *.
NoOneIsHere

2

J, 121 byte

load 'viewmat'
a=:3 :'viewmat{:@((p:inv@{.,>:@{:)^:(-.@((=1:)+.1&p:)@{.)^:_)@(,0:)"0(,1+(i.@#+>./)@{:)@|:@|.^:(+:<:y),.1'

Definisce una funzione:

a=:3 :'viewmat{:@((p:inv@{.,>:@{:)^:(-.@((=1:)+.1&p:)@{.)^:_)@(,0:)"0(,1+(i.@#+>./)@{:)@|:@|.^:(+:<:y),.1' | Full fuction
                                                                     (,1+(i.@#+>./)@{:)@|:@|.^:(+:<:y),.1  | Creates the number spiral
              {:@((p:inv@{.,>:@{:)^:(-.@((=1:)+.1&p:)@{.)^:_)@(,0:)"0                                      | Applies S(n) to each element
       viewmat                                                                                             | View the array as an image

2

R, 231 byte

function(n){p=function(n)sum(!n%%2:n)<2;M=matrix(0,n,n);M[n^2%/%2+cumsum(c(1,head(rep(rep(c(1,-n,-1,n),l=2*n-1),rev(n-seq(n*2-1)%/%2)),-1)))]=sapply(1:(n^2),function(x){y=0;while(x>2&!p(x)){x=sum(sapply(2:x,p));y=y+1};y});image(M)}

Leggermente meno golfato:

function(n){
    p=function(n)sum(!n%%2:n)<2 #"is.prime" function
    M=matrix(0,n,n)             #empty matrix
    indices=n^2%/%2+cumsum(c(1,head(rep(rep(c(1,-n,-1,n),l=2*n-1),rev(n-seq(n*2-1)%/%2)),-1)))
    values=sapply(1:(n^2),function(x){
        y=0
        while(x>2&!p(x)){
            x=sum(sapply(2:x,p))
            y=y+1
            }
        y})
    M[indices]=values
    image(M) #Plotting
}

Funzione anonima. Uscita in una finestra grafica. La scala è sulla scala rossa con tonalità più scura uguale a 0 e tonalità più chiare che aumentano i valori.

Risultato per n = 101:

n = 101

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.