Uma serpente de fluxo, também conhecida como curva de Gosper , é uma curva fractal, que cresce exponencialmente em tamanho a cada ordem / iteração de um processo simples. Abaixo estão os detalhes sobre a construção e alguns exemplos para vários pedidos:
Encomenda 1 Flow Snake :
____
\__ \
__/
Encomenda 2 Flow Snake :
____
____ \__ \
\__ \__/ / __
__/ ____ \ \ \
/ __ \__ \ \/
\ \ \__/ / __
\/ ____ \/ /
\__ \__/
__/
Encomenda 3 Flow Snake :
____
____ \__ \
\__ \__/ / __
__/ ____ \ \ \ ____
/ __ \__ \ \/ / __ \__ \
____ \ \ \__/ / __ \/ / __/ / __
____ \__ \ \/ ____ \/ / __/ / __ \ \ \
\__ \__/ / __ \__ \__/ / __ \ \ \ \/
__/ ____ \ \ \__/ ____ \ \ \ \/ / __
/ __ \__ \ \/ ____ \__ \ \/ / __ \/ /
\ \ \__/ / __ \__ \__/ / __ \ \ \__/
\/ ____ \/ / __/ ____ \ \ \ \/ ____
\__ \__/ / __ \__ \ \/ / __ \__ \
__/ ____ \ \ \__/ / __ \/ / __/ / __
/ __ \__ \ \/ ____ \/ / __/ / __ \/ /
\/ / __/ / __ \__ \__/ / __ \/ / __/
__/ / __ \ \ \__/ ____ \ \ \__/ / __
/ __ \ \ \ \/ ____ \__ \ \/ ____ \/ /
\ \ \ \/ / __ \__ \__/ / __ \__ \__/
\/ / __ \/ / __/ ____ \ \ \__/
\ \ \__/ / __ \__ \ \/
\/ \ \ \__/ / __
\/ ____ \/ /
\__ \__/
__/
Construção
Considere a ordem 1 Flow Snake a ser construída com um caminho contendo 7 arestas e 8 vértices (rotulados abaixo. Ampliado para viabilidade):
4____5____6
\ \
3\____2 7\
/
0____1/
Agora, para cada próximo pedido, basta substituir as bordas por uma versão girada desse padrão original de pedido 1. Use as três regras a seguir para substituir as arestas:
1 Para uma aresta horizontal, substitua-a pela forma original como está:
________
\ \
\____ \
/
____/
2 Para uma /
aresta ( 12
na construção acima), substitua-a pela seguinte versão girada:
/
/ ____
\ / /
\/ /
/
____/
3 Para uma \
aresta ( 34
e 67
acima), substitua-a pela seguinte versão girada:
/
/ ____
\ \ \
\ \ \
\ /
\/
Por exemplo, o pedido 2 com vértices do pedido 1 rotulado terá a aparência de
________
\ \
________ \____ \6
\ \ / /
\____ \5___/ / ____
/ \ \ \
4___/ ________ \ \ \7
/ \ \ \ /
/ ____ \____ \2 \/
\ \ \ / /
\ \ \3___/ / ____
\ / \ / /
\/ ________ \/ /
\ \ /
\____ \1___/
/
0___/
Agora, para qualquer ordem superior, basta dividir o nível atual em arestas de comprimentos 1 /
, 1 \
ou 2 _
e repetir o processo. Observe que, mesmo após a substituição, os vértices comuns entre duas arestas consecutivas ainda coincidem.
Desafio
- É necessário escrever uma função de um programa completo que receba um único número inteiro
N
via argumento STDIN / ARGV / function ou o equivalente mais próximo e imprima a ordemN
Flow Snake em STDOUT. - O número inteiro de entrada é sempre maior que
0
. - Não deve haver espaços à esquerda que não façam parte do padrão.
- Não deve haver espaços finais ou espaços finais suficientes para preencher o padrão e preencher completamente o retângulo mínimo.
- A nova linha à direita é opcional.
Curiosidades
- Flow Snakes é um jogo de palavras de Snow Flakes, que esse padrão se assemelha à ordem 2 e acima
- O Flow e Snakes realmente desempenham um papel no padrão, pois o padrão é constituído por um único caminho que flui por todo lado.
- Se você observar com cuidado, o padrão da ordem 2 (e também mais alto) compreende rotações do padrão da ordem 1 giradas no vértice comum da aresta atual e da aresta anterior.
- Existe uma variante não ASCII de Flow Snakes que pode ser encontrada aqui e em vários outros locais.
Este é o código-golfe, pelo que o código mais curto em bytes ganha!
Entre os melhores
O primeiro post da série gera uma tabela de classificação.
Para garantir que suas respostas sejam exibidas, inicie todas as respostas com um título, usando o seguinte modelo de remarcação:
# Language Name, N bytes
onde N
está o tamanho do seu envio. Se você melhorar sua pontuação, poderá manter as pontuações antigas no título, identificando-as. Por exemplo:
# Ruby, <s>104</s> <s>101</s> 96 bytes
Respostas:
CJam, 144 bytes
Nova linha adicionada para evitar a rolagem. Experimente online
O programa funciona em várias etapas:
fonte
Python 2,
428411388 bytesEste foi bem complicado. Os padrões não mantêm suas proporções após cada etapa, o que significa que é muito difícil produzir processualmente uma imagem de seu antecessor. O que esse código faz, embora seja bastante ilegível depois de um intenso golfe matemático, é realmente traçar a linha do início ao fim usando a
D
função recursivamente definida .O tamanho também era um problema, e acabei começando no meio de um
5*3**n
quadrado de lado e cortando as coisas depois, embora, se eu puder pensar em uma maneira melhor de calcular o tamanho, eu possa mudá-lo.fonte
r=[s*[" "]for i in range(s)]
->r=[[" "]*s]*s]
raspa alguns bytes #*
repete objetos mutáveis .l
, alternandoprint'\n'.join()
para impressão dentro de um loop for, usandoreturn[...][t]+x,
e removendo os parênteses(t%2)
. Além disso, você pode usarmin(c.find('\\')%s for c in S)
se alterar o nome da listaS
para que não substitua o valor inicial des
.JavaScript ( ES6 ), 356
362 370Essa é difícil ...
Cada forma é armazenada como um caminho. Existem 6 blocos de construção básicos (3 + 3 para trás)
0
diagonal para cima, esquerda para baixo, para a direita (4
para trás)1
diagonal inferior esquerda para cima direita (5
para trás)2
horizontal da esquerda para a direita (6
para trás)Para cada um, há uma etapa de substituição a ser aplicada ao aumentar a ordem:
0
->0645001
(para trás4
->5441024
)1
->2116501
(para trás5
->5412556
)2
->2160224
(para trás6
->0664256
)valores pré-preenchidos no
h
matriz, mesmo que os elementos 4..6 possam ser obtidos de 0..2 usandoPara obter a forma para a ordem especificada, o caminho é construído na variável p, aplicando as substituições repetidamente. Então o loop principal itera na variável p e desenha a forma dentro da matriz g [], onde cada elemento é uma linha.
Começando na posição (0,0), cada índice pode se tornar negativo (índice y em pedidos altos). Evito que os índices y negativos mudem toda a matriz g sempre que encontrar um valor y negativo. Eu não me importo se o índice x se torna negativo, como nos índices negativos de JS são permitidos, apenas um pouco mais difícil de gerenciar.
Na última etapa, eu varro a matriz principal usando .map, mas para cada linha eu preciso usar um loop explícito para (;;) usando a
b
variável que contém o menor índice x alcançado (que será <0).No
console.log
Na versão, existe uma nova linha à mão, que pode ser facilmente transformada em uma nova linha posterior, trocando duas linhas, como na versão do snippet.Snippet útil para testar (no Firefox):
fonte
Haskell, 265 bytes
(Nota: no GHC antes da 7.10, você precisará adicionar
import Control.Applicative
ou substituirabs<$>
pormap abs$
.)Execute online no Ideone.com
f n :: Int -> IO ()
desenha o nível dan
serpente. O desenho é calculado na ordem de bitmap, e não ao longo da curva, o que permite que o algoritmo seja executado no espaço O (n) (ou seja, logarítmico no tamanho do desenho). Quase metade dos meus bytes são gastos computando qual retângulo desenhar!fonte
Perl,
334 316309Parâmetro obtido na entrada padrão. Teste- me .
fonte
Haskell,
469419390385365 bytesa função f :: Int-> IO () pega um número inteiro como entrada e imprime a serpente de fluxo
fonte
$
na definição dek
e substituir(!!)a
com o(a!!)
qual pode se livrar de alguns parênteses. Fora isso, você parece conhecer muitos truques sozinho. NiceC,
479474468427 bytesAcho que não há como derrotar os caras do Perl e do Haskell, mas como ainda não há submissão em C:
Para economizar espaço em uma chamada atoi (), o número de argumentos passados para o programa é usado para o nível.
O programa é executado em O (n ^ 3) ou pior; primeiro, o caminho é calculado uma vez para encontrar as coordenadas mín / máx; depois, para cada par (x, y) é calculado uma vez para encontrar o caractere naquele local específico. Terrivelmente lento, mas economiza na administração de memória.
Exemplo executado em http://codepad.org/ZGc648Xi
fonte
X,Y,K,L,M,N,i,j,c;
vez deint X,Y,K,L,M,N,i,j,c;
e emmain(l)
vez devoid main(int l)
Python 2,
523502475473467450437 bytesPffft, me custou umas 3 horas, mas foi divertido de fazer!
A idéia é dividir a tarefa em várias etapas:
Aqui está o código na forma não-destruída:
Edit: eu mudei o idioma para python 2, para ser compatível com a minha resposta para o número 3 (e também economiza mais 6 bytes)
fonte
l.extend(x)
paral+=x
. Além disso, você provavelmente pode usar codegolf.stackexchange.com/questions/54/... em vez do.split()
que você usa (eu fiz algo semelhante em minha resposta)extend
Pari / GP, 395
Fazendo um loop sobre x, posições de caracteres y e calculando qual caractere imprimir. Tentativas moderadas de minimização, pontuadas com espaço em branco e comentários removidos.
Cada caractere é o primeiro ou o segundo de uma célula hexagonal. A localização da célula é um número complexo z dividido na base b = 2 + w com os dígitos 0, 1, w ^ 2, ..., w ^ 5, onde w = e ^ (2pi / 6) sexta raiz da unidade. Esses dígitos são mantidos como 1 a 7 distintos e, em seguida, são levados de alto a baixo através de uma tabela de estados para rotação líquida. Isso está no estilo do código do flownake de Ed Shouten (
xytoi
), mas apenas para rotação líquida, não transformando dígitos em um índice "N" ao longo do caminho. As extensões são relativas a uma origem 0 no centro da forma. Contanto que o limite não seja um ponto final, eles estão no meio de um hexágono de 2 caracteres e apenas 1 desses caracteres é necessário. Mas quando o início e / ou o fim da cobra são necessários 2 caracteres, o limite X é k = 0 início e k <3 final. Pari possui "quads" como o sqrt (-3), mas o mesmo pode ser feito com partes reais e imaginárias separadamente.fonte