Les cernes peuvent-ils être générés à partir de nombres premiers?

33

Apparemment oui! En trois étapes faciles.

Étape 1

Soit f ( n ) la fonction de comptage des nombres premiers (nombre de nombres premiers inférieur ou égal à n ).

Définissez la séquence entière s ( n ) comme suit. Pour chaque entier positif n ,

  • Initialliser t à n .
  • Tant que t n'est ni premier ni 1, remplacez t par f ( t ) et itérez.
  • Le nombre d'itérations est s ( n ).

La fin du processus itératif est garantie car f ( n ) < n pour tout n .

Considérons par exemple n = 25. Nous initiallisons t = 25. Comme ce n'est pas un nombre premier ni 1, nous calculons f (25), qui est 9. Ceci devient la nouvelle valeur de t . Ce n'est pas un nombre premier ni 1, nous continuons donc: f (9) vaut 4. Nous continuons encore: f (4) vaut 2. Comme c'est un nombre premier, nous nous arrêtons ici. Nous avons fait 3 itérations (de 25 à 9, puis à 4, puis à 2). Donc s (25) vaut 3.

Les 40 premiers termes de la séquence sont les suivants. La séquence n'est pas dans 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

Étape 2

Étant donné un entier positif impair N , construisez un tableau N × N (matrice) en enroulant la séquence finie s (1), s (2), ..., s ( N 2 ) pour former une spirale extérieure carrée . Par exemple, étant donné que N = 5, la spirale est

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)

ou, en substituant les valeurs,

 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

Étape 3

Représentez le tableau N × N sous forme d' image avec une carte de couleur grise ou avec une autre carte de couleur de votre goût. La carte doit être progressive, afin que l'ordre des nombres corresponde à un ordre des couleurs visuellement évident. Les cas de test ci-dessous montrent quelques exemples de nuanciers.

Le défi

Étant donné un entier positif impair N , produisez l'image décrite ci-dessus.

Règles

  • La spirale doit être vers l'extérieur, mais elle peut être dans le sens des aiguilles d'une montre ou dans le sens contraire, et peut commencer à se déplacer vers la droite (comme dans l'exemple ci-dessus), vers la gauche, vers le bas ou vers le haut.

  • Les échelles des axes horizontal et vertical ne doivent pas nécessairement être identiques. De plus, les étiquettes d'axe, la barre de couleur et les éléments similaires sont facultatifs. Tant que la spirale peut être clairement vue, l'image est valide.

  • Les images peuvent être sorties par n'importe quel moyen standard . En particulier, l'image peut être affichée à l'écran, ou un fichier graphique peut être produit, ou un tableau de valeurs RVB peut être sorti. Si vous exportez un fichier ou un tableau, postez un exemple de ce à quoi il ressemble lorsqu'il est affiché.

  • Les moyens de saisie et le format sont flexibles comme d’habitude . Un programme ou une fonction peut être fourni . Les échappatoires standard sont interdites .

  • Le code le plus court en octets gagne.

Cas de test

Les images suivantes (cliquez pour pleine résolution) correspondent à plusieurs valeurs de N . Une spirale dans le sens des aiguilles d'une montre, en commençant par la droite, est utilisée, comme dans l'exemple ci-dessus. Les images illustrent également plusieurs cartes de couleurs valides.

  • N = 301: entrez la description de l'image ici

  • N = 501: entrez la description de l'image ici

  • N = 701: entrez la description de l'image ici

Luis Mendo
la source
Si un tableau de valeurs de s(n)peut être introduit dans une fonction / package de traçage sans être modifié (je pense que imshowmatplotlib pourrait gérer cela par exemple), est-ce une forme de sortie acceptable?
Dylnan
@dylnan Bien sûr, tant qu'il trace l'image sur l'écran ou produit un fichier, il est valide. En fait, j'ai généré les exemples avec quelque chose de similaire à ce que vous mentionnez. Faites juste attention à la mise à l'échelle des valeurs. Par exemple , il n'est pas acceptable si toutes les valeurs supérieures à 1 sont données la même couleur, comme de Matlab (et peut - être Matplotlib de) imshowne
Luis Mendo
bon point. Je ne sais pas si imshowfait ça.
Dylnan
1
@ kamoroso94 S'il vous plaît voir ici
Luis Mendo le
1
Ouais très clair
Christopher

Réponses:

3

Dyalog APL, 94 octets

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

suppose ⎕IO=0

sortie pour n = 701 (converti de .pgm à .png):

entrez la description de l'image ici

ngn
la source
10

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

Rasé 12 octets, merci à Ander et Andras, et merci à Luis pour avoir mis les deux ensemble. Rasé 16 grâce à Remco, 6 grâce à 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)))

Résultat pour N=301( F(301)):

entrez la description de l'image ici

Explication:

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
Adriaan
la source
8

Wolfram Language (Mathematica) , 124 octets

Merci à Martin Ender d' avoir économisé 12 octets!

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

Essayez-le en ligne!


L'image générée est:

Spirale

Formule fermée de la valeur en spirale extraite directement de cette réponse .

utilisateur202729
la source
5
#/2-.5enregistre un octet.
user202729
8
Haha, vous le suggérez?
Luis Mendo le
6
@ user202729 Ne semble pas fonctionner.
user202729
18
Je n'avais pas l'intention d'interrompre votre dialogue intérieur :-P
Luis Mendo le
Différez la définition de pjusqu'à ce que vous en ayez besoin:...,{y,p=(1-#)/2,-p},{x,p,-p}
Martin Ender
7

MATLAB: 115 114 110 octets

Une doublure (exécutée dans R2016b + en tant que fonction dans un script ) 115 octets

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

En plaçant la fonction dans un fichier séparé, comme suggéré par flawr, et en utilisant le 1 octet supplémentaire par règle de fichier supplémentaire

Dans le fichier s.m, 64 + 1 octets pour le code + le fichier

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

Fenêtre de commande à définir I, 45 octets

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

Total: 110 octets


Ceci utilise la récursivité au lieu de whileboucler, comme le font les autres implémentations de MATLAB ( gnovice , Adriaan ). Exécutez-le en tant que script (dans R2016b ou plus récent), cela définit la fonction Iqui peut être exécutée comme I(n).

Version structurée:

% 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

Exemple:

I(301)

terrain

Remarques:

  • J'ai essayé de rendre la sfonction anonyme aussi, bien sûr, cela réduirait considérablement le nombre. Cependant, il y a 2 problèmes:

    1. Il est difficile d'éviter une récursion infinie lors de l'utilisation de fonctions anonymes, car MATLAB ne dispose pas d'un opérateur ternaire pour offrir une condition de rupture. Éviter un opérateur ternaire (voir ci-dessous) coûte également des octets car nous avons besoin de la condition deux fois.

    2. Vous devez passer une fonction anonyme à elle-même si elle est récursive (voir ici ) qui ajoute des octets.

    Le plus proche que je suis venu à cela utilisé les lignes suivantes, peut-être qu'il peut être modifié pour fonctionner:

    % 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);
Wolfie
la source
6

MATLAB - 126 121 * octets

J'ai tenté une approche plus vectorisée qu'Adriaan et j'ai réussi à réduire le nombre d'octets. Voici la solution mono-ligne:

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

Et voici la solution bien formatée:

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

* Remarque: si vous êtes prêt à permettre une crapton métrique d'itérations inutiles, vous pouvez modifier la ligne while any(i), à for m=v, et enregistrer 5 octets.

Gnovice
la source
Agréable! J'aime la façon dont vous utilisez cumsumpour vectoriser et éviternnz(primes(...)
Luis Mendo le
1
Si je comprends bien, il n’est pas mal d’itérer plus de fois que nécessaire (au prix de la vitesse). Donc, vous pouvez remplacer while any(i)par for m=M. Qui se soucie de savoir si le code prend des heures à courir :-)
Luis Mendo le
2
@ LuisMendo: Bien sûr, pourquoi pas? Il répète déjà une fois de plus que nécessaire, ce qui peut n^2faire mal à une autre itération! ;)
gnovice
1
C'est l'idée! Vous pouvez également garder la version la plus rapide, mais le nombre d'octets est celui de la version la plus courte
Luis Mendo le
2

Python 3, 299 265 octets

Sauvegardé de 5 octets grâce aux suggestions de formatage de Jonathan Frech et NoOneIsHere. Suppression de 34 octets supplémentaires en supprimant une définition de fonction appelée une seule fois.

Ceci est un peu plus long que d'autres, car python n'a pas de commande pour déterminer la primauté, ni un tableau en spirale. Il fonctionne relativement rapidement cependant, environ une minute pour 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

Testez le avec

n = 7
x = S(n)
imshow(x, interpolation='none')
colorbar()
show(block=False)
utilisateur2699
la source
1
294 octets possibles (non testés).
Jonathan Frech
1
Une chose rapide: vous pouvez supprimer l'espace entre importet *.
NoOneIsHere le
2

J, 121 octets

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

Définit une fonction:

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
Bolce Bussiere
la source
2

R, 231 octets

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

Un peu moins joué au golf:

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
}

Fonction anonyme. Sortie dans une fenêtre graphique. L'échelle est sur l'échelle rouge, la teinte la plus sombre est égale à 0 et les teintes plus claires augmentent les valeurs.

Résultat pour n = 101:

n = 101

planificateur
la source