O objetivo deste desafio é representar graficamente uma caminhada no plano, onde a direção de cada etapa é determinada pela primalidade de pela paridade de sua expansão binária. Especificamente,
- A direção inicial é fixa, digamos Norte.
- Todas as etapas têm o mesmo comprimento .
- A direção da etapa pode ser norte, oeste, sul ou leste e é determinada da seguinte maneira:
- Se não for primo, a direção não muda.
- Se for primo e a expansão binária de tiver um número par de unidades, vire à direita.
- Se for primo e a expansão binária de tiver um número ímpar de unidades, vire à esquerda.
Como exemplo , assuma que a direção inicial é Norte. Os primeiros passos são:
- não é primo. Então, avançamos um passo na direção atual, que é o norte.
- é primo e sua expansão binária,,
10
tem e número ímpar de unidades. Então, vire à esquerda e agora estamos de frente para o oeste. Nós damos um passo nessa direção. - é primo e sua expansão binária,,
11
tem e número par de unidades. Então, viramos à direita e agora estamos voltados para o norte. Nós damos um passo nessa direção. - não é primo. Então, avançamos um passo na direção atual, que é o norte.
O desafio
Entrada : positivo inteiro .
Saída : plotagem da caminhada step, conforme definido acima.
Regras adicionais
- A direcção inicial pode ser livremente escolhida (e não necessariamente do Norte), mas deve ser a mesma para todos os .
- A regra de giro pode ser oposta à descrita acima, ou seja, vire à direita para paridade ímpar e à esquerda para par; mas tem que ser o mesmo para todos os .
- A saída deve ser uma representação gráfica da caminhada. Por exemplo:
- A caminhada pode ser desenhada com segmentos de linha.
- Os pontos visitados podem ser mostrados com um marcador, como um ponto; com ou sem conectar segmentos de linha.
- É possível fornecer uma imagem rasterizada de duas cores, uma cor correspondente aos pontos visitados e outra para os não visitados.
- As escalas dos eixos horizontal e vertical não precisam ser as mesmas. Também etiquetas de eixo e elementos semelhantes são opcionais. Desde que a caminhada possa ser vista com clareza, o enredo é válido.
- Observe que alguns pontos são visitados mais de uma vez. O enredo não é sensível a isso. Por exemplo, se os segmentos de linha são mostrados no gráfico, cada segmento de unidade é exibido da mesma forma, não importando quantas vezes ele foi percorrido.
- O código deve funcionar para quaisquer
N
recursos ilimitados. É aceitável se, na prática, falhar bastanteN
devido a limitações de tempo, memória ou tipo de dados. - Entrada e saída são flexíveis, como de costume. Em particular, qualquer um dos meios padrão para a saída de imagens pode ser usado.
- O código mais curto em bytes vence.
Casos de teste
Os seguintes gráficos usam o Norte como direção inicial; até a paridade vira à direita; e a caminhada é representada com segmentos de linha.
N = 7
:
N = 3000
:
N = 20000
:
N = 159000
:
N = 1200000
:
N = 11000000
:
code-golf
graphical-output
integer
primes
Luis Mendo
fonte
fonte
[graphical-output]
é permitida? Alguma razão em particular para a saída ASCII não permitida, como a minha resposta agora excluída do carvão vegetal?Respostas:
Marreta 0.4 ,
2220 bytesDescomprime nesta função da Wolfram Language:
Ungolfed
Primeiro, definimos uma função que retorna o ângulo para girar a cada passo:
ThueMorse
é a paridade da soma dos dígitos binários. Usamos,-1^(...)
e não2*...-1
por uma razão um pouco complicada: a Wolfram Language converte automaticamente expressões aritméticas na fonte em uma forma canônica, para que expressões como2/x
sejam armazenadas comoTimes[2, Power[x, -1]]
. Isso faz com que a frequência sejaPower
muito alta e, portanto, a comprime muito barato.(A multiplicação
Boole@PrimeQ@
é um pouco mais longa e aBoole
conversão implícita de booleanos não havia sido implementada no momento do desafio.)A partir daqui, do Mathematica
AnglePath
eListPlot
faça exatamente o que precisamos:No aplicativo interativo, a saída é um objeto gráfico vetorial escalável.
fonte
MATL ,
252421 bytesExperimente no MATL online
Obrigado a @LuisMendo por uma boa sessão de golfe no chat que finalmente levou a esta versão de 21 bytes, sugerindo
Eq*^
Explicação
Exemplo para :k=12345
fonte
C (gcc) , 179 bytes
Experimente online!
Uma função. O primeiro argumento é N, o segundo argumento é um buffer de tamanho alocado de pelo menos bytes. Uma imagem quadrada é gravada nesse buffer, seu comprimento lateral é retornado. Na imagem, é um pixel branco, é um pixel preto.4n2+4n+1
0
1
C (gcc) , 219 bytes
Experimente online!
Uma função. O primeiro argumento é N, o segundo argumento é um buffer de tamanho alocado pelo menos bytes. Uma imagem quadrada no formato PBM é gravada no buffer.4n2+4n+2×⌊log10(2n+1)⌋+9
Produção cortada para 20000:
Ambas as versões começam com o oeste e vire à direita no ímpar, à esquerda no par.
Tentei os casos de teste maiores com nenhum deles, já que a saída com 20000 era de ~ 1,5 GB e 150000 teria sido de ~ 90 GB. Tudo isso é armazenado na memória enquanto o programa é executado.
Explicação da parte superior:
fonte
0
ponteiro médio ou nulo no caso de C).Wolfram Language (Mathematica) ,
989691777663 bytes-14 bytes: obrigado a @lirtosiast por me mostrar como usar
AnglePath
...-13 bytes: ... e
ThueMorse
!exemplo de uso:
Explicação passo a passo:
If[PrimeQ@#, 2 ThueMorse@# - 1, 0] &
é uma função que pega o índice da etapa e retorna 0 para não primos, -1 para primos binários pares e +1 para primos binários ímpares.ThueMorse@#
substitui a solução anteriorTotal[#~IntegerDigits~2]
(que é a mesma, módulo 2).Array[Pi/2*%,#]
faz uma lista dessa função com o índice passando de 1 para o argumento da função (20000 no exemplo) e multiplica cada elemento por π / 2 para transformá-lo em um ângulo de mudança de direção (radianos). Agora temos 0 para não primos, -π / 2 para primos binários pares e + π / 2 para primos binários ímpares.AnglePath[%]
converte esta lista de ângulos de mudança de direção em um caminho. Esta instrução substitui o uso duplo da solução anteriorAccumulate
.ListPlot[%]
converte a lista de posições em um gráfico de pontos XY. Se uma linha for preferida, useListLinePlot
. Essas funções de plotagem têm muitas opções para melhorar a aparência das plotagens.fonte
MATL,
31302826 bytes3 bytes salvos graças a @LuisMendo
2 bytes economizados graças a @Sanchises
Experimente no MATL Online
Explicação
Esta solução usa números complexos para representar os componentes X e Y do plano 2D
Neste ponto, temos quatro pontos (
(0, 1), (-1, 0), (0, -1), (1, 0)
) em uma matriz representada por números complexos. Estas são as quatro direções cardeais. Agora queremos usá-los para "andar".Essencialmente, a maneira como isso funciona é que começamos a dirigir na direção zero (o elemento 0 da matriz que é
(-1, 0)
). Para cada etapa, precisamos determinar a alteração nesse cabeçalho. Usaremos números inteiros para rastrear essa alteração. Se queremos virar "para a direita", incrementamos esse número inteiro em 1 (referenciando o próximo elemento na matriz de 4 pontos) e, se queremos ir para a "esquerda", decrementamos esse número inteiro em 1 (referenciando o elemento anterior no Matriz de 4 pontos). Se queremos continuar em nosso caminho, mantemos o valor inteiro constante (referenciando o mesmo elemento na matriz de 4 pontos).Esta parte do código cria uma matriz de todos aqueles
0
,-1
e1
valores.Agora, temos uma matriz de diferenças entre números inteiros sucessivos, para que possamos calcular a soma acumulada dessas para obter os índices que podemos usar para procurar a direção em cada etapa da matriz original de 4 elementos.
Convenientemente, o MATL possui uma indexação abrangente, de modo que o índice se
5
aproxima do início de uma matriz de 4 elementos. Podemos usar isso para nossa vantagem, para que possamos incrementar e decrementar esse número inteiro sem nos preocupar com o fato de que a matriz de direção de referência é de apenas 4 elementos.Agora temos uma variedade de direções de etapas, para que possamos calcular a soma cumulativa dessas instruções para traçar o caminho que foi seguido.
fonte
Perl 6 ,
213181bytes{my @p = [\ +] [\ *] ({{. is-prime ??. base (2) .comb (~ 1)% 2 ?? i !! - i !! 1 + 0i} (+ + $)} ... *) [^ $ _]; {"<svg viewBox = '{. min xx 2, .elems xx 2}' >>. & {" L {.re} {.im} " }} 'fill =' none 'stroke =' black '/> "} (minmax | @p» .reals)}Experimente online!
(Realmente conseguiu reduzir este aqui!)
Esta função gera no formato SVG.
{ -{ .is-prime * .base(2).comb(~1) R** -1 || i }(++$)i } ... *
é uma sequência infinita de mudanças de direção para cada etapa, na forma de números complexos, em que1
significa "continue na mesma direção",i
significa "vire à esquerda" e-i
significa "vire à direita".[^$_]
limita essa sequência ao número de etapas fornecidas como argumento da função.[\*]
digitaliza essa sequência com multiplicação (complexa), transformando a lista de mudanças de direção relativa em uma lista de direções absolutas.[\+]
varre essa sequência com adição (complexa), produzindo uma lista das coordenadas visitadas.».reals
converte essa lista de números complexos em listas de dois elementos de suas partes reais e imaginárias.A imagem SVG é apenas um único
path
elemento.Saída (convertida em PNG) para N = 20000:
fonte
C, 321 bytes
Experimente online!
Comecei a trabalhar nisso antes que a outra resposta C fosse publicada, mas achei que também poderia postar a minha. Essa é muito mais longa, mas também recorta a imagem de saída nas dimensões do resultado automaticamente.
A função é chamada como
f(n)
e a saída é stdout no formato netpbm.Exemplo de saída para n = 1000:
O teste principal é essencialmente o usado na resposta de Lynn para um desafio diferente , que se baseia no teorema de Wilson .
O teste de paridade usa uma adaptação do método de contagem de bits de Kernighan .
Como o teste principal é muito lento, e o algoritmo executa novamente toda a função de geração de caminho para cada pixel desenhado, qualquer entrada muito superior a 1000 vezes no TIO.
fonte
LOGO,
177171 bytesPara usar, fazer algo parecido com isso :
Desculpe, mas não consegui capturar saída de amostra. Explicação:
Este é um procedimento recursivo que gira 180 ° para cada bit definido em seu parâmetro, que efetivamente calcula a paridade de sua expansão binária.
Este é um teste de primalidade muito básico. Após o revestimento especial 1, o procedimento retornará antecipadamente se um fator for encontrado. Se, no entanto, o valor atual for considerado primo, ele vira à direita e, em seguida, usa o procedimento acima para transformar isso em uma curva à esquerda, conforme apropriado.
Este é apenas um loop simples para testar todos os números até a
n
primalidade e mover dois pixels após cada um.fonte
Geléia , 41 bytes
Experimente online!
fonte
JavaScript -
675668660632556534 BytesA primeira vez aqui no CodeGolf, começou inicialmente com ~ 1500 Bytes Code. Golfeou para
menos da metade,quasemais de um terço. Sinta-se livre para continuar jogando golfe. Bytes contados com: esta ferramentaPrincípio:
Desenha em uma tela de tamanho fixo com N e comprimento de traçado variável como entrada.
Editar% s:
-07 Bytes - remove if
-08 bytes perdidos - mude para if / else
-28 Bytes - altere para tenary if / else
-76 Bytes - teste principal mais curto (tempo de execução / 3)
-22 Bytes - use esta função principal (tempo de execução * 4)
Código de golfe:
Código ungolfed com espaços em branco:
Exemplos:
fonte
Vermelho ,
515480471 bytes-1 byte graças a Kevin Cruijssen!
Uma parte significativa do código (~ 160 bytes) lida com a normalização das coordenadas, para que os gráficos caibam inteiramente na tela, independentemente do tamanho da entrada.
Direção inicial: sul.
Aqui está o resultado para
n = 3000
n = 20000
fonte
if j%(k + 1)
eif j% 2 = 1
, mas há espaços necessários para a maioria dos outros operadores (+
,/
, etc.). O espaço também pode ser removido no módulo depick[-90 90]s% 2
? Na verdade, por que também não há espaços necessáriosas-pair k/1 - t * c k/2 - v * c
para o/
?s% 2
, obrigado! Não sei por que, mas o módulo%
é o único operador para o qual o espaço à sua frente pode ser descartado, se precedido por uma palavra (variável). Nasas-pair k/1 - t * c k/2 - v * c
barras/
servem a propósitos completamente diferentes - eles sãopath
s.k
é umpair
ek/1
é o primeiro elemento (também pode ser selecionado pork/x
, oupick k 1
). Espaços são necessários em quase todos os lugares, as exceções existem()[]{}
, porque não há ambiguidade.word
nomes (Red
não temvariables
, tudo é umword
valor ou (ou algum bloco de sintaxe como[...]
ou(...)
).) Então:a*4: 45
-> uma palavraa*4
recebe um valor 45.%
é usado como marcador para ofile!
tipo de dados e talvez seja por isso que não pode ser usado emword
nomes, mas pode violar as regras dos outros operadores aritméticos/
tenham um propósito diferente lá e os símbolos possam ser usados sem espaços nas variáveis (ouwords
como aparentemente são chamados de Red). Obrigada pelo esclarecimento. :) E feliz por poder (principalmente acidentalmente) salvar um byte para o arquivos% 2
. :)Processando, mais de 140 bytes
Pode não cumprir claramente visto
fonte