Nós tivemos um par de desafios sobre a espiral Ulam. Mas isso não basta.
Neste desafio, traçaremos uma espiral Ulam triangular (em oposição à espiral Ulam quadrada usual). Aqui está um esboço de como é a espiral.
Como sabemos, a espiral de Ulam organiza todos os números naturais em uma espiral externa e marca apenas aqueles que são primos. Portanto, no esboço acima, apenas os números que aparecem em preto (os números primos) seriam mostrados.
O desafio
Aceite um número N como entrada e exiba a espiral triangular Ulam até esse número.
- A entrada pode ser stdin ou argumento de função.
- A espiral deve girar na direção positiva (ou seja, no sentido anti-horário), como na figura acima.
- Qualquer uma das curvas de 120 graus da figura acima seria válida e a curva pode ser diferente para diferentes entradas. Mas o lado mais baixo dos triângulos implícitos deve ser horizontal, pois as únicas curvas permitidas são (múltiplos de) 120 graus.
- O código deve ser executado teoricamente (com tempo e memória suficientes) para qualquer N até o permitido por qualquer cálculo intermediário que você faça com o tipo de dados padrão.
double
basta; não há necessidade de tipos inteiros grandes. - Todas as funções internas são permitidas.
- Não aceitarei minha própria resposta (não que eu ache que seria a mais curta de qualquer maneira ...).
Formatos de saída
Escolha uma das seguintes opções.
Exiba um gráfico com um marcador (ponto, círculo, cruz, o que você preferir) em números primos e nada em números não primos. A escala não precisa ser a mesma para os dois eixos. Ou seja, os triângulos implícitos não precisam ser equilaterais. Eixos, linhas de grade e rótulos de eixo são opcionais. Apenas os marcadores nos números primos são necessários.
Um exemplo de saída para N = 12 seria o seguinte (compare com o esboço acima). O segundo gráfico é um exemplo mais interessante, correspondendo a N = 10000.
- Produza um arquivo de imagem com o descrito acima, em qualquer formato de imagem conhecido (como png, tiff, bmp).
Exiba a espiral como arte ASCII , usando um único caractere de sua escolha para números primos e espaço em branco para não números primos, com um espaço em branco para separar as posições numéricas na mesma linha. Espaços iniciais ou finais ou novas linhas são permitidos. Por exemplo, o caso N = 12 usando
o
como caractere seriao · · · o · o · · · o · o
onde é claro que apenas a
o
marca nos números primos seria realmente exibida. Os·
números não primos são mostrados aqui apenas para referência.
Critério de vitória
A recompensa real é ver por si mesmo esses incríveis padrões de código, o código mais curto vence.
fonte
Respostas:
CJam,
4942 bytesEntrada como um único inteiro em STDIN. Saída como uma grade ASCII com
0
para números primos. A rotação da espiral não é consistente: o maior número de espiral estará sempre na linha inferior.Teste aqui.
Explicação
A idéia básica é representar o triângulo como uma matriz 2D irregular durante o cálculo. Você obtém essa matriz revertendo as linhas e alinhando todas as linhas à esquerda:
Seria representado como
Como espelhamos a linha, queremos enrolar a espiral no sentido horário . Isso é conveniente, porque tudo o que precisamos fazer é girar o triângulo no sentido anti-horário e preceder a próxima sub-lista em ordem. Podemos girar o array irregular, invertendo todas as linhas e transpondo-o:
Então aqui está o código. Um detalhe que eu gostaria de chamar a atenção é o último bit que cria o layout triangular. Eu acho isso bastante bacana. :)
fonte
MATL ,
4836 bytesUsa a versão atual (9.3.0) .
Experimente online!
Não faço ideia de como o compilador online consegue converter a saída gráfica em ASCII, mas issoproduz um gráfico ASCII aproximado, graças a um recurso Octave suportado pelo compilador online!Editar (4 de abril de 2016): a função
Y[
foi renomeadak
desde o release 13.0.0. O link para o compilador online incorpora essa alteração, para que o código possa ser testado.Exemplo
produz a saída gráfica (versão MATLAB mostrada):
Explicação
O código usa números complexos para rastrear o caminho seguido pela espiral. Como pode ser visto na primeira figura do desafio, cada perna reta da espiral é um segmento com comprimento crescente 1, 2, 3, 4 ... e ciclicamente aumentando a orientação 120 graus, 240 graus, 0 graus, 0 graus, 120 graus. ..
O código primeiro gera os deslocamentos complexos individuais de cada número inteiro para o próximo. Esses deslocamentos complexos têm magnitude 1 e ângulo
2*pi/3
,4*pi/3
ou0
(em radianos). Assim, eles podem ser facilmente gerados como exponenciais imaginários. Para isso, a sequência inteira 0,1,2,2,3,3,3,4,4,4,4 ... é usada primeiro.Essa sequência inteira é quase como a sequência "n aparece n vezes" ( OEIS A002024 ) e pode ser obtida como
floor(sqrt(2*n)+.5)
onden
está 0,1,2,3, .... A multiplicação por2j*pi/3
, ondej
está a unidade imaginária, produz os deslocamentos complexos desejados.Os deslocamentos são acumulados para calcular as posições correspondentes aos números inteiros na espiral. O primeiro número inteiro na espiral, ou seja
1
, está arbitrariamente localizado na posição1
no plano complexo.Finalmente, as posições correspondentes a números não primos são descartadas e o restante é plotado no plano complexo.
fonte
.png
arquivo a ser mostrado pelo @AlexA página webplot(1:5)
) e produz saída de texto e gráfico !! matl.tryitonline.net/#code=NTpYRw&input= @AlexA. Como é isso??O desenho deve ser feito com
LaTeX / PGF, 527
594bytes527 bytes é o documento completo como acima, ou seja, incluindo preâmbulo e parâmetro (aqui 4000, então ~ 523 sem parâmetro). Produz um arquivo PDF.
Idéia básica: bem, basta desenhar. Usa uma transformação de matriz para uma grade triangular. O único problema é que também os pontos são afetados (e esticados) pela transformação. Então, eu escolho marcadores de elipse :) o que quero dizer com isso é claro na segunda imagem (n = 250, 5pt).
Outra ressalva: só pode lidar com um pouco menos de 5000 por causa do tamanho máximo da pilha do TeX. A primeira imagem é para n = 4000. Aparentemente, é possível aumentar o tamanho da pilha , eu não tentei.
Usa PGFs
isprime()
.Ungolfed:
fonte
lualatex
ou algum outro compilador de alocação dinâmica deve permitir que você ignore o tamanho da pilha, se eu entender corretamente o seu comentário correspondente. Portanto, não é uma limitação da sua resposta, apenas da maioria das implementações em que você a executaria.Mathematica, 94 bytes
Resultado
fonte
Python, 263 bytes
Sendo novo no Python, certamente há espaço para melhorias :)
Exemplo:
fonte
s=[];X=[];Y=[];i=1;x=0;y=0
paras=X=Y=[];i=1;x=y=0;
x=y=0
.R, 137 bytes
Usa apenas funções internas, mesmo para números primos. Dada sua abordagem vetorizada em vez de iterativa, é rápida, mas não pode lidar com grandes números.
Golfe:
Ungolfed:
Exemplo:
fonte