Anéis de árvores quadrados podem ser gerados a partir de números primos?

33

Aparentemente sim! Em três etapas fáceis.

Passo 1

Seja f ( n ) a função de contagem primária (número de primos menor ou igual a n ).

Defina a sequência inteira s ( n ) da seguinte maneira. Para cada número inteiro positivo n ,

  • Inicialize t para n .
  • Enquanto t não for primo nem 1, substitua t por f ( t ) e itere.
  • O número de iterações é s ( n ).

É garantido que o processo iterativo termine porque f ( n ) < n para todos os n .

Considere, por exemplo, n = 25. Inicializamos t = 25. Como esse não é um primo nem 1, calculamos f (25), que é 9. Esse valor se torna o novo valor para t . Como não é primo nem 1, continuamos: f (9) é 4. Continuamos novamente: f (4) é 2. Como esse é um primo, paramos aqui. Fizemos três iterações (de 25 para 9, depois para 4 e depois para 2). Assim s (25) é 3.

Os primeiros 40 termos da sequência são os seguintes. A sequência não está no 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

Dado um número inteiro positivo ímpar N , construa uma matriz N × N (matriz) enrolando a sequência finita s (1), s (2), ..., s ( N 2 ) para formar uma espiral quadrada para fora . Por exemplo, dado N = 5, a espiral é

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, substituindo os valores,

 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

etapa 3

Represente a matriz N × N como uma imagem com um mapa de cores cinza ou com outro mapa de cores do seu gosto. O mapa deve ser gradual, para que a ordem dos números corresponda a alguma ordem visualmente óbvia das cores. Os casos de teste abaixo mostram alguns exemplos de mapas de cores.

O desafio

Dado um número inteiro positivo ímpar N , produza a imagem descrita acima.

Regras

  • A espiral deve estar para fora, mas pode ser no sentido horário ou anti-horário, e pode começar a se mover para a direita (como no exemplo acima), esquerda, baixo ou para cima.

  • As escalas dos eixos horizontal e vertical não precisam ser as mesmas. Também etiquetas de eixo, barra de cores e elementos similares são opcionais. Desde que a espiral possa ser vista com clareza, a imagem é válida.

  • As imagens podem ser produzidas por qualquer meio padrão . Em particular, a imagem pode ser exibida na tela ou um arquivo gráfico pode ser produzido ou uma matriz de valores RGB pode ser impressa. Se estiver produzindo um arquivo ou uma matriz, publique um exemplo da aparência quando exibida.

  • Os meios e o formato de entrada são flexíveis, como de costume . Um programa ou uma função pode ser fornecida . As brechas padrão são proibidas .

  • O menor código em bytes vence.

Casos de teste

As imagens a seguir (clique para resolução total) correspondem a vários valores de N . Uma espiral no sentido horário e primeira direita é usada, como no exemplo acima. As imagens também ilustram vários mapas de cores válidos.

  • N = 301: insira a descrição da imagem aqui

  • N = 501: insira a descrição da imagem aqui

  • N = 701: insira a descrição da imagem aqui

Luis Mendo
fonte
Se uma matriz de valores de s(n)pode ser alimentada em alguma função / pacote de plotagem sem ser modificada (acho que imshowno matplotlib poderia lidar com isso, por exemplo), essa é uma forma de saída aceitável?
dylnan
@dylnan Claro, desde que plote a imagem na tela ou produza um arquivo que seja válido. De fato, gerei os exemplos com algo semelhante ao que você menciona. Apenas tenha cuidado com a escala de valores. Por exemplo, não é aceitável se todos os valores acima de 1 têm a mesma cor, como Matlab (e possivelmente Matplotlib de) imshowfaz
Luis Mendo
bom ponto. Não tenho certeza se imshowfaz isso.
dylnan
1
@ kamoroso94 Por favor, veja aqui
Luis Mendo
1
Sim, muito claro
Christopher

Respostas:

3

Dyalog APL, 94 bytes

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

assume ⎕IO=0

saída para n = 701 (convertida de .pgm para .png):

insira a descrição da imagem aqui

ngn
fonte
10

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

Raspou 12 bytes, graças a Ander e Andras, e muito obrigado a Luis por juntar os dois. Shaved 16 graças a Remco, 6 graças 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)))

Resultado para N=301( F(301)):

insira a descrição da imagem aqui

Explicação:

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
fonte
8

Wolfram Language (Mathematica) , 124 bytes

Agradecemos a Martin Ender por salvar 12 bytes!

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

Experimente online!


A imagem gerada é:

Espiral

Fórmula de forma fechada do valor espiral extraído diretamente desta resposta minha.

user202729
fonte
5
#/2-.5salva um byte.
precisa saber é o seguinte
8
Haha, você está sugerindo isso para si mesmo?
Luis Mendo
6
@ user202729 Parece não funcionar.
precisa saber é o seguinte
18
Não tive a intenção de interromper seu diálogo interno :-P
Luis Mendo
Adie a definição de paté que você precise:...,{y,p=(1-#)/2,-p},{x,p,-p}
Martin Ender
7

MATLAB: 115 114 110 bytes

Um liner (executado no R2016b + como função no script ) 115 bytes

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

Colocar a função em um arquivo separado, conforme sugerido por flawr, e usar 1 byte adicional por regra de arquivo adicional

No arquivo s.m, 64 + 1 bytes para código + arquivo

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

Janela de comando para definir I, 45 bytes

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

Total: 110 bytes


Isso usa recursão em vez de whileloop, como as outras implementações do MATLAB ( gnovice , Adriaan ). Execute-o como um script (no R2016b ou mais recente), isso define a funçãoI que pode ser executada como I(n).

Versão estruturada:

% 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

Exemplo:

I(301)

enredo

Notas:

  • Também tentei tornar a sfunção anônima, é claro que reduziria significativamente a contagem. No entanto, existem 2 problemas:

    1. É difícil evitar recursões infinitas ao usar funções anônimas, pois o MATLAB não possui um operador ternário para oferecer uma condição de interrupção. Invocar um tipo de operador ternário (veja abaixo) também custa bytes, pois precisamos da condição duas vezes.

    2. Você precisa passar uma função anônima para si mesma se for recursiva (veja aqui ), que adiciona bytes.

    O mais próximo que cheguei disso usou as seguintes linhas, talvez possa ser alterado para funcionar:

    % 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
fonte
6

MATLAB - 126 121 * bytes

Tentei uma abordagem mais vetorizada do que Adriaan e consegui raspar mais bytes. Aqui está a solução de linha única:

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

E aqui está a solução bem formatada:

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 você deseja permitir um crapton métrico de iterações desnecessárias, pode alterar a linha while any(i), para for m=v, e salvar 5 bytes.

gnovice
fonte
Agradável! Eu gosto de como você usa cumsumpara vetorizar e evitarnnz(primes(...)
Luis Mendo
1
Se eu entendi direito, não custa repetir mais vezes do que o necessário (ao custo da velocidade). Então você pode substituir while any(i)por for m=M. Quem se importa se o código leva horas para correr :-)
Luis Mendo
2
@LuisMendo: Claro, por que não? Ele já itera mais uma vez do que o necessário, o que outras n^2iterações vão doer! ;)
gnovice
1
Esse é o espírito! Você também pode manter a versão de execução mais rápida, mas a contagem de bytes é a mais curta
Luis Mendo
2

Python 3, 299 265 bytes

Economizou 5 bytes graças às sugestões de formatação de Jonathan Frech e NoOneIsHere. Removidos 34 bytes adicionais removendo uma definição de função que foi chamada apenas uma vez.

Isso é um pouco mais longo do que alguns outros, devido ao python não ter um comando para determinar a primidez ou fazer espiral em uma matriz. No entanto, é executado relativamente rápido, cerca de um minuto para 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

Teste com

n = 7
x = S(n)
imshow(x, interpolation='none')
colorbar()
show(block=False)
user2699
fonte
1
Possíveis 294 bytes (não testados).
Jonathan Frech 03/02
1
Uma coisa rápida: você pode remover o espaço entre importe *.
NoOneIsHere
2

J, 121 bytes

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

Define uma função:

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
fonte
2

R, 231 bytes

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

Um pouco menos golfe:

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
}

Função anônima. Saída em uma janela gráfica. A escala está na escala vermelha, com a tonalidade mais escura igual a 0 e as tonalidades mais claras aumentando os valores.

Resultado para n = 101:

n = 101

plannapus
fonte