Um gráfico *** ameoba **** é um tipo de árvore cujos nós todos têm valores de 0 a algum número inteiro não negativo N e qualquer nó específico com valor x <N se conecta a x + 1 nós distintos com valores x + 1
Gráfico de Ameoba para N = 3: (Denotado A 3 )
Observe que os 2 não têm permissão para compartilhar nenhum dos 3; exatamente três 3 devem "pertencer" a cada 2.
Desafio
Sua tarefa é "aumentar" indutivamente esses gráficos de ameoba em uma grade bidimensional, minimizando avidamente a distância de Manhattan entre os nós:
- Caso base: Um 0 é simplesmente o gráfico
0
. - Etapa indutiva: Um N + 1 é gerado colocando iterativamente os novos nós com valor de N + 1 o mais próximo possível dos nós de valores de N na estrutura A N existente . (Só pode ser o mais próximo possível, pois os pontos mais próximos já podem estar preenchidos.)
Para a etapa indutiva, o procedimento geral que você deve seguir é:
for each existing node P with value N:
for each new N+1 valued node Q you need to connect to P: //this loops N+1 times
find the set of vacant spots that are minimally distant from P //by Manhattan distance
place Q in any of these vacant spots
(Um procedimento diferente com saída indistinguível é bom.)
Exemplo de crescimento para A 4 :
A0 is always the same:
0
For A1 I happen to put the 1 to the right of the 0 (it has to go on one of the 4 open sides):
01
For A2 I happen to put the two 2's above and to the right of the 1:
2
012
For A3 I find that one of the six 3's I must place cannot be directly next to a 2, so I put in one of the next closest places:
3
323
0123
33 <-- this 3 is distance two away from its 2
The process continues in A4. Note that I'm iterating over each 3 and placing four 4's next to it or as close as possible, then moving to the next 3 (the order of 3's does not matter):
444
443444
4323444
4012344
44334
4444
44
Always keep in mind that nodes cannot be "shared".
Programa
O programa que você escreve deve receber um número de 0 a 8 (inclusive) e gerar um gráfico válido de ameoba, usando o padrão de crescimento indutivo explicado acima.
O que acontece além de 8 não importa.
(A 8 contém 46234 nós que o estão pressionando. Qualquer coisa além de A 8 seria muito longe. Agradecemos a Martin Büttner por perceber isso.)
A entrada deve vir de stdin ou a linha de comando e a saída deve ir para stdout ou um arquivo.
Exemplos (tirados diretamente de cima)
Input: 0
Output:
0
Input: 1
Output:
01
Input: 2
Output:
2
012
Input: 3
Output:
3
323
0123
33
Input: 4
Output:
444
443444
4323444
4012344
44334
4444
44
* Esse tipo de gráfico já pode ter um nome. Eu admito que acabei de inventá-los. ;)
Respostas:
Mathematica,
353288285275 bytesUngolfed:
Aqui está um exemplo de saída para
n = 5
:A entrada
8
leva cerca de 4,5 minutos.Para uma rápida descrição do meu algoritmo:
Estou usando duas tabelas de consulta
f
eg
. O primeiro é apenas um mapa esparso contendo as células não vazias. A última é uma lista que contém todos os pares de coordenadas para cada valor de célula (acho que nem preciso acompanhar os antigos aqui). Estou percorrendo as coordenadasg
para estender todas as células da última iteração. Para fazer isso, percorro as distâncias de Manhattan, criando todos os vetores possíveis para cada distância e verificando se a célula resultante ainda está vazia (nesse caso, eu a preencho). Repita até que novas células tenham sido criadas.Quando termino, encontro as coordenadas mínima e máxima
g
e crio uma grade apropriada, que é preenchida pesquisando as célulasf
. O resto é apenas juntar tudo em uma única sequência com quebras de linha.fonte
C -
309305301275 bytesMeh, muito tempo ... se ao menos alguém pudesse digitar
#D
ou algo assim#define
, então C seria realmente ótimo. É claro que os-D
sinalizadores do compilador são possíveis, mas isso me parece uma trapaça, ter caracteres diferentes dos que estão no arquivo de origem.Instruções de execução:
Seja cuidadoso! A primeira tecla pressionada após o início do programa constitui a entrada. Após uma entrada de caractere que não seja de 0 a 8, quem sabe que coisas indefinidas acontecerão.
Versão sem golfe (mas já pensando em golfe futuro):
Edit: eu percebi que, desde que movi as declarações para fora de main (), as matrizes não podem mais ser alocadas na pilha, por isso estou livre para usar a memória de maneira profusa, sem risco de transbordamento.
fonte
Ruby - 296
Ligeiramente não-destruído.
fonte
APL (Dyalog) (121)
Características de desempenho: é O (n!). No meu sistema, até n = 5 é instantâneo; n = 6 leva um segundo, n = 7 leva um minuto en = 8 leva uma hora.
Versão sem golfe
Teste:
Explicação:
{
...}⎕
: leia uma linha do teclado, avalie-a e passe o resultado para a função.0::0
: se o outro código gerar um erro, retorne um único0
. Isso ocorre porque a matemática falha ao tentar calcular o tamanho de um gráfico com 0 nós, o que acontece quando a saída deve ser0
. (A versão anterior tinha⍵=0:0
, (se a entrada for0
retornar,0
faça o gráfico), mas0::0
(apenas tente e retorne0
se falhar) é mais curta.)M←⌈4×.5*⍨3÷⍨+/!⍳⍵
: supondo que a saída seja um círculo aproximado (isso funciona), some os fatoriais de1
até⍵
(= área da saída), divida por 3 (perto o suficiente para pi), pegue a raiz quadrada (dando o raio de saída), multiplique por 4, e pegue o teto. Isso fornece o dobro do diâmetro do círculo, para que a saída se encaixe com espaço de sobra. Guarde isso emM
.V←,⍳⍴Z←' '⍴⍨2/M
: crie uma matriz de espaços M-por-M e armazene-aZ
. Isso manterá a saída. Armazene uma lista das coordenadas de todos os elementos emV
.Z[G;G←⌈M÷2]←'0'
: defina o elemento do meio deZ
como0
.Z⊢{
...}¨⍳⍵
: retorneZ
, após aplicar a seguinte função aos números1
em⍵
:⍵∘{
...}V/,Z=⍕⍵-1
: para cada elementoZ
com o valor do nó anterior:⍵∘{
...}⍺/⍺
: para o nó atual, N vezes,⊃F[⍋+/¨|(F←V/⍨,Z=' ')-⊂⍺]
: obtenha o espaço livre mais próximo do nó atual,(
...⌷Z)←⍕⍵
: e configure esse espaçoZ
para o valor do nó atual.fonte