Desafio da arte ASCII hexplosiva

20

No jogo de estratégia "Hexplode" , os jogadores se revezam colocando fichas em um tabuleiro hexagonal. Uma vez que o número de tokens seja igual ao número de blocos adjacentes, esse bloco é hexodificado e move todos os toques para os vizinhos vizinhos. Você pode jogar o jogo online aqui .

Eu gosto deste jogo, mas às vezes é difícil saber exatamente quantos tokens vão em um bloco específico; Eu estou sempre contando o número de vizinhos. Seria realmente conveniente se eu tivesse uma arte ASCII para me ajudar a lembrar quantos tokens vão em cada bloco.

Você precisa escrever um programa ou função que recebe um inteiro positivo como entrada e produz esta representação ASCII de hexágono de tamanho N . Cada bloco será o número de vizinhos que o bloco possui. Como 1 é um caso de canto estranho com zero vizinhos, você só precisa manipular entradas maiores que 1.

Você pode levar esse número em qualquer formato razoável, como STDIN, argumentos de função, argumentos de linha de comando, de um arquivo etc. A saída também pode estar em qualquer formato razoável, como imprimir em STDOUT, gravar em um arquivo, retornar uma lista de strings, uma nova linha separada, etc.

Aqui está um exemplo de saída para as 5 primeiras entradas:

2)

 3 3
3 6 3
 3 3


3)

  3 4 3
 4 6 6 4
3 6 6 6 3
 4 6 6 4
  3 4 3


4)

   3 4 4 3
  4 6 6 6 4
 4 6 6 6 6 4
3 6 6 6 6 6 3
 4 6 6 6 6 4
  4 6 6 6 4
   3 4 4 3

5)

    3 4 4 4 3
   4 6 6 6 6 4
  4 6 6 6 6 6 4
 4 6 6 6 6 6 6 4
3 6 6 6 6 6 6 6 3
 4 6 6 6 6 6 6 4
  4 6 6 6 6 6 4
   4 6 6 6 6 4
    3 4 4 4 3

6)

     3 4 4 4 4 3
    4 6 6 6 6 6 4
   4 6 6 6 6 6 6 4
  4 6 6 6 6 6 6 6 4
 4 6 6 6 6 6 6 6 6 4
3 6 6 6 6 6 6 6 6 6 3
 4 6 6 6 6 6 6 6 6 4
  4 6 6 6 6 6 6 6 4
   4 6 6 6 6 6 6 4
    4 6 6 6 6 6 4
     3 4 4 4 4 3

E o padrão continua de maneira semelhante. Como de costume, as brechas padrão se aplicam e a resposta com a menor contagem de bytes será coroada a vencedora!

Classificação

Aqui está um snippet de pilha para gerar uma classificação regular e uma visão geral dos vencedores por idioma.

Para garantir que sua resposta seja exibida, inicie-a com um título, usando o seguinte modelo de remarcação:

# Language Name, N bytes

onde Nestá 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

Se você quiser incluir vários números no cabeçalho (por exemplo, porque sua pontuação é a soma de dois arquivos ou você deseja listar as penalidades do sinalizador de intérpretes separadamente), verifique se a pontuação real é o último número no cabeçalho:

# Perl, 43 + 2 (-p flag) = 45 bytes

Você também pode transformar o nome do idioma em um link que será exibido no snippet do placar de líderes:

# [><>](http://esolangs.org/wiki/Fish), 121 bytes

DJMcMayhem
fonte
11
Relacionado (mas perguntando sobre o processo e não o número de vizinhos).
Trichoplax
11
Estou tentado a aprender hexagonia apenas por causa deste desafio. ;)
Kevin Cruijssen 5/09/16

Respostas:

11

MATL , 39 37 bytes

4*3-:!G:+o~YRtP*!tPw4LY)vtI5&lZ+47+*c

Experimente online! Ou verifique todos os casos de teste .

Explicação

Eu uso convolução novamente!

Considere entrada n = 3. O código primeiro cria uma matriz de tamanho 4*n-3× nadicionando o vetor de coluna [1; 2; ...; 9]ao vetor de linha [1, 2, 3]com broadcast. Isso significa calcular uma matriz de matriz 2D de todas as adições em pares:

 2  3  4
 3  4  5
 4  5  6
 5  6  7
 6  7  8
 7  8  9
 8  9 10
 9 10 11
10 11 12

Substituir números pares por 1e números ímpares 0fornece o padrão quadriculado

1 0 1
0 1 0
1 0 1
0 1 0
1 0 1
0 1 0
1 0 1
0 1 0
1 0 1

Isso será usado para gerar (parte da) grade hexagonal. Uns representam pontos na grade e zeros representam espaços.

O canto superior direito é removido zerando todas as entradas acima da "diagonal" principal da matriz:

1 0 0
0 1 0
1 0 1
0 1 0
1 0 1
0 1 0
1 0 1
0 1 0
1 0 1

A multiplicação de elementos desta matriz por uma versão invertida verticalmente remove também o canto inferior direito. A transposição dá então

1 0 1 0 1 0 1 0 1
0 1 0 1 0 1 0 1 0
0 0 1 0 1 0 1 0 0

Isso começa a parecer um hexágono. Usando simetria, a grade é estendida para produzir a metade superior:

0 0 1 0 1 0 1 0 0
0 1 0 1 0 1 0 1 0
1 0 1 0 1 0 1 0 1
0 1 0 1 0 1 0 1 0
0 0 1 0 1 0 1 0 0

Agora precisamos substituir cada entrada igual a uma pelo número de vizinhos. Para isso, usamos a convolução com uma vizinhança 3 × 5 (ou seja, o núcleo é uma matriz 3 × 5). O resultado,

2 3 4 5 5 5 4 3 2
4 5 7 7 8 7 7 5 4
4 6 7 8 7 8 7 6 4
4 5 7 7 8 7 7 5 4
2 3 4 5 5 5 4 3 2

tem dois problemas (que serão resolvidos posteriormente):

  1. Os valores foram calculados para todas as posições, enquanto que apenas precisamos deles nas posições das posições na grade zero-um.
  2. Para cada uma dessas posições, a contagem de vizinhos inclui o próprio ponto, e é desativado por 1.

O código agora adiciona 47a cada valor calculado. Isso corresponde à subtração 1para resolver o problema (2) e adição 48(ASCII para '0'), que converte cada número no ponto de código do seu caractere correspondente.

A matriz resultante é então multiplicada por uma cópia da grade zero-um. Isso resolve o problema (1) acima, tornando os pontos que não fazem parte da grade hexagonal iguais a zero novamente:

 0  0 51  0 52  0 51  0  0
 0 52  0 54  0 54  0 52  0
51  0 54  0 54  0 54  0 51
 0 52  0 54  0 54  0 52  0
 0  0 51  0 52  0 51  0  0

Finalmente, essa matriz de números é convertida em uma matriz de caracteres. Zero caracteres são exibidos como espaço, o que dá o resultado final:

  3 4 3  
 4 6 6 4 
3 6 6 6 3
 4 6 6 4 
  3 4 3  
Luis Mendo
fonte
15

JavaScript (ES6), 118 117 bytes

n=>[...Array(m=n+--n)].map((_,i,a)=>a.map((_,j)=>(k=j-(i>n?i-n:n-i))<0?``:k&&++j<m?i/2%n?6:4:3+!i%n).join` `).join`\n`

Onde \nrepresenta um caractere literal de nova linha. Explicação: Suponha n=4. Começamos com o seguinte quadrado de dígitos separados por espaço:

0 0 0 0 0 0 0
0 0 0 0 0 0 0
0 0 0 0 0 0 0
0 0 0 0 0 0 0
0 0 0 0 0 0 0
0 0 0 0 0 0 0
0 0 0 0 0 0 0

Os primeiros |n-i| 0s são excluídos, mas os espaços permanecem:

   0 0 0 0
  0 0 0 0 0
 0 0 0 0 0 0
0 0 0 0 0 0 0
 0 0 0 0 0 0
  0 0 0 0 0
   0 0 0 0

Hexágono instantâneo! Basta calcular o valor apropriado no lugar de cada um 0, verificando se estamos na primeira ou na última linha e / ou coluna. Editar: salvou 1 byte graças a @Arnauld.

Neil
fonte
Usando algumas de suas fórmulas, cheguei a uma versão de 107 bytes com / console.log ():n=>{for(i=n+--n;i--;)console.log(' '.repeat(l=i>n?i-n:n-i)+(j=3+!l%n)+` ${l-n?6:4}`.repeat(2*n-l-1)+' '+j)}
Arnauld 4/16
@ Arnauld Eu gosto disso 3+!i%n!
Neil
7

Python 2, 125 123 bytes

def h(n):m=n-1;t=[' '*(m-r)+' '.join(('46'[r>0]*(r+m-1)).join('34'[r%m>0]*2))for r in range(n)];print'\n'.join(t+t[-2::-1])

Os testes estão em ideone

Percorre o topo até as linhas do meio for r in range(n), construindo cordas:
- fazendo dois cantos ou duas arestas '34'[r%m>0]*2;
- enchimento, ligando-os com repetida '6'ou '4', '46'[r>0]*(r+m-1);
- unir os cantos e bordas com ' ';
- precedido de espaços ' '*(m-r);

Em seguida, imprime isso e é refletido na linha do meio unida por novas linhas, print'\n'.join(t+t[-2::-1])

Jonathan Allan
fonte
4

Python 2, 96 bytes

n=input();m=n-1
while n+m:n-=1;j=abs(n);c='34'[0<j<m];print' '*j+c+' '+'46  '[j<m::2]*(2*m+~j)+c

Isso parece muito bagunçado e um pouco jogável ...

Sp3000
fonte
3

Java, 375 363 361 339 329 317 293 bytes

interface J{static void main(String[]r){int i=0,k,h=Integer.decode(r[0]),a=1,l,n=0;for(;i++<h*2-1;n+=a){if(n==h-1)a=-1;String s="";for(k=0;k<n+h;k++,s+=" ")s+=n==0?k==0||k==n+h-1?3:4:k!=0&&k!=n+h-1?6:n==h-1?3:4;l=(h*4-3-s.trim().length())/2;System.out.printf((l==0?"%":"%"+l)+"s%s\n","",s);}}}

Ungolfed

interface J {
    static void main(String[] r) {
        int i = 0, k, h = Integer.decode(r[0]), a = 1, l, n = 0;
        for (; i++ < h * 2 - 1; n += a) {
            if (n == h - 1) {
                a = -1;
            }
            String s = "";
            for (k = 0; k < n + h; k++, s += " ") {
                s += n == 0 ? k == 0 || k == n + h - 1 ? 3 : 4 : k != 0 && k != n + h - 1 ? 6 : n == h - 1 ? 3 : 4;
            }
            l = (h * 4 - 3 - s.trim().length()) / 2;
            System.out.printf((l == 0 ? "%" : "%" + l) + "s%s\n", "", s);
        }
    }
}

Uso :

$ java J 5
    3 4 4 4 3     
   4 6 6 6 6 4    
  4 6 6 6 6 6 4   
 4 6 6 6 6 6 6 4  
3 6 6 6 6 6 6 6 3 
 4 6 6 6 6 6 6 4  
  4 6 6 6 6 6 4   
   4 6 6 6 6 4    
    3 4 4 4 3

Estou certo de que o horrível bloco aninhado if-else pode ser reescrito para ser menor, mas não consigo descobrir no momento. Todas as sugestões são bem-vindas :-)

Atualizar

  • Seguiu a sugestão de Kevin Cruijssen e usou decodificação em vez de parseInt.
  • Reescreva alguns ifs usando o operador ternário.
  • Operadores mais ternários.
  • Moar operadores ternários! Eu acho que criei um monstro!
  • Reescreva o bloco if-else em relação à impressão.
Master_ex
fonte
11
Eu não olhei tão de perto o método que você usa, mas algumas pequenas dicas de golfe para o seu código atual: você Integer.parseIntpode jogar golfe Integer.decode. l=(h*4-3-s.trim().length())/2;if(l==0)pode ser jogado golfe para if((l=(h*4-3-s.trim().length())/2)==0). Além disso, é completamente aceitável postar apenas um método sem classe (a menos que a pergunta indique o contrário); portanto, ao void f(int i){...use i...}invés de interface J{static void main(String[]r){...i=Integer.decode(r[0])...use i...}, isso também deve economizar alguns bytes. Quando tiver mais tempo, procurarei mais.
Kevin Cruijssen 5/09/16
@KevinCruijssen: Obrigado por suas sugestões. l=(h*4-3-s.trim().length())/2;if(l==0)é realmente o mesmo comprimento com if((l=(h*4-3-s.trim().length())/2)==0).
Master_ex 5/09/16
2

05AB1E , 44 bytes

FN_i4ë6}ð«¹ÍN+×ðìN_N¹<Q~i3ë4}.ø¹<N-ð×ì})¦«»

Explicação

Como as partes superior e inferior do hexágono são espelhadas, precisamos gerar apenas a parte superior.
Portanto, para uma entrada de X , precisamos gerar X linhas. É isso que o loop principal faz.

F                                        }

Então fazemos a parte central das linhas.
Isso é 4 na primeira linha e 6 no restante (como estamos fazendo apenas na parte superior).
Concatenamos esse número com um espaço, pois o padrão exigirá espaçamento entre os números.

N_i4ë6}ð«

Em seguida, repetimos essa sequência X-2 + N vezes, em que N é a linha atual indexada em 0 e adicionamos um caractere de espaço no lado esquerdo.

¹ÍN+×ðì

Depois disso, é hora das curvas. Serão 3 na primeira e na última linha e 4 na linha do meio.

N_N¹<Q~i3ë4}.ø

Agora, precisamos garantir que as linhas estejam alinhadas corretamente, adicionando espaços à frente de cada linha. O número de espaços adicionados será X-1-N .

¹<N-ð×ì

Agora que já temos a parte superior da grade, adicionamos as linhas a uma lista, criamos uma cópia invertida e removemos o primeiro item dessa cópia (como precisamos apenas da linha central uma vez), depois juntamos essas duas listas e impressão.

)¦«»

Experimente online!

Solução adicional, também 44 bytes:

ÍÅ10.øvN_i4ë6}ð«¹ÍN+×ðìyi4ë3}.ø¹<N-ð×ì})¦«»
Emigna
fonte
2

Ruby, 87 bytes

A função anônima recebe n como argumento e retorna uma matriz de seqüências de caracteres.

->n{(1-n..n-=1).map{|i|j=i.abs
" "*j+(e=j%n>0?"4 ":"3 ")+["6 ","4 "][j/n]*(2*n-1-j)+e}}

Ungolfed in program program

Entrada através de stdin. Grava toda a forma em stdout. Bastante auto-explicativo.

f=->n{
  (1-n..n-=1).map{|i|            #reduce n by 1 and iterate i from -n to n
    j=i.abs;                     #absolute magnitude of i
    " "*j+                       #j spaces +
    (e=j%n>0?"4 ":"3 ")+         #start the string with 3 or 4 +
    ["6 ","4 "][j/n]*(2*n-1-j)+  #2*n-1-j 6's or 4`s as appropriate +
    e                            #end the string with another 3 or 4
  }
}

puts f[gets.to_i]
Level River St
fonte
1

V , 60 bytes

Àé x@aA4 xr3^.òhYpXa 6^òkyHç^/:m0
Pç 3.*6/^r4$.
òÍ6 4./6

Experimente online!

Isso é realmente muito longo. Aqui está um hexdump, pois contém caracteres não imprimíveis:

0000000: c0e9 2078 4061 4134 201b 7872 335e 2ef2  .. x@aA4 .xr3^..
0000010: 6859 7058 6120 361b 5ef2 6b79 48e7 5e2f  hYpXa 6.^.kyH.^/
0000020: 3a6d 300a 50e7 2033 2e2a 362f 5e72 3424  :m0.P. 3.*6/^r4$
0000030: 2e0a f2cd 3620 9334 852e 2f36            ....6 .4../6
DJMcMayhem
fonte
1

Raquete, 487 bytes

(λ(n c e o)(let((sp(append(range(- n 1)-1 -1)(reverse(range(- n 1)0 -1))))
(mm(append(range(- n 2)(-(+ n(- n 1))2))(range(-(+ n(- n 1))2)(-(- n 1)2)-1)))
(r""))(for((i sp)(j mm))(define str"")(for((ss i))(set! str(string-append str" ")))
(set! str(string-append str(if(or(= i 0)(= i(- n 1))(= i(* 2(- n 1))))c e)" "))
(for((jj j))(set! str(string-append str(if(= j(- n 2))e o)" ")))(set! r(if(or(= i 0)
(= i(- n 1))(= i(* 2(- n 1))))c e))(set! str(string-append str r))(displayln str))))

Teste:

(f 4 "3" "4" "6") 

   3 4 4 3
  4 6 6 6 4
 4 6 6 6 6 4
3 6 6 6 6 6 3
 4 6 6 6 6 4
  4 6 6 6 4
   3 4 4 3

(f 5 "o" "*" "-") 

    o * * * o
   * - - - - *
  * - - - - - *
 * - - - - - - *
o - - - - - - - o
 * - - - - - - *
  * - - - - - *
   * - - - - *
    o * * * o

Versão detalhada:

(define(f1 n c e o)
  (let ((sp(append(range(sub1 n) -1 -1)
                  (reverse(range(sub1 n) 0 -1))))
        (mm(append(range(- n 2)(-(+ n(sub1 n)) 2))
                  (range(-(+ n(sub1 n)) 2)(-(sub1 n)2) -1) ))
        (r ""))
    (for((i sp)(j mm))
      (define str "")
      (for((ss i))(set! str(string-append str " ")))
      (set! str(string-append str
                              (if(or(= i 0)(= i(sub1 n))
                                    (= i(* 2(sub1 n)))) c e)
                              " "))
      (for((jj j))
        (set! str(string-append str
                                (if(= j(- n 2)) e o)
                                " ")))
      (set! r(if(or(= i 0)
                   (= i(sub1 n))
                   (= i(* 2(sub1 n)))) c e))
      (set! str(string-append str r))
      (displayln str))))
rnso
fonte