Desafío de arte ASCII hexplosivo

20

En el juego de estrategia "Hexplode" , los jugadores se turnan para colocar fichas en un tablero hexagonal. Una vez que la cantidad de fichas es igual a la cantidad de fichas adyacentes, esa ficha explota y mueve todas las fichas a los vecinos circundantes. Puedes jugar el juego en línea aquí .

Me gusta este juego, pero a veces es difícil saber exactamente cuántas fichas hay en un mosaico específico; Siempre estoy contando el número de vecinos. Sería realmente conveniente si tuviera un arte ASCII para ayudarme a recordar cuántas fichas hay en cada mosaico.

Usted tiene que escribir un programa o función que toma un entero positivo como entrada, y produce esta representación ASCII del hexágono de tamaño N . Cada mosaico será el número de vecinos que tiene ese mosaico. Dado que 1 es un caso de esquina extraño con cero vecinos, solo tiene que manejar entradas mayores que 1.

Puede tomar este número en cualquier formato razonable, como STDIN, argumentos de función, argumentos de línea de comandos, de un archivo, etc. La salida también puede estar en cualquier formato razonable, como imprimir en STDOUT, escribir en un archivo, regresar una lista de cadenas, una cadena separada por una nueva línea, etc.

Aquí hay algunos resultados de muestra para las primeras 5 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

Y el patrón continúa de manera similar. Como de costumbre, se aplican las lagunas estándar, ¡y la respuesta con el conteo de bytes más bajo se coronará como el ganador!

Tablas de clasificación

Aquí hay un fragmento de pila para generar una tabla de clasificación regular y una descripción general de los ganadores por idioma.

Para asegurarse de que su respuesta se muestre, comience con un título, utilizando la siguiente plantilla de Markdown:

# Language Name, N bytes

¿Dónde Nestá el tamaño de su envío? Si mejora su puntaje, puede mantener los puntajes antiguos en el título, tachándolos. Por ejemplo:

# Ruby, <s>104</s> <s>101</s> 96 bytes

Si desea incluir varios números en su encabezado (por ejemplo, porque su puntaje es la suma de dos archivos o desea enumerar las penalizaciones de la bandera del intérprete por separado), asegúrese de que el puntaje real sea el último número en el encabezado:

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

También puede hacer que el nombre del idioma sea un enlace que luego aparecerá en el fragmento de la tabla de clasificación:

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

DJMcMayhem
fuente
1
Relacionado (pero preguntando sobre el proceso en lugar de la cantidad de vecinos).
trichoplax
1
Estoy tentado a aprender Hexagony solo por este desafío. ;)
Kevin Cruijssen

Respuestas:

11

MATL , 39 37 bytes

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

Pruébalo en línea! O verificar todos los casos de prueba .

Explicación

¡Puedo usar la convolución nuevamente!

Considere la entrada n = 3. El código primero crea una matriz de tamaño 4*n-3× nal agregar el vector de columna al vector [1; 2; ...; 9]de fila [1, 2, 3]con difusión. Esto significa calcular una matriz de matriz 2D de todas las adiciones por 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

Reemplazar números 1pares por números impares 0da el patrón de tablero de ajedrez

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

Esto se usará para generar (parte de) la cuadrícula hexagonal. Unos representarán puntos en la cuadrícula y los ceros representarán espacios.

La esquina superior derecha se elimina poniendo a cero todas las entradas por encima de la "diagonal" principal de la 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

En cuanto al elemento, al multiplicar esta matriz por una versión verticalmente invertida de sí misma, también se elimina la esquina inferior derecha. Transponer luego da

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

Esto comienza a parecerse a un hexágono. Usando simetría, la cuadrícula se extiende para producir la mitad 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

Ahora necesitamos reemplazar cada entrada igual a una por el número de vecinos. Para esto usamos convolución con un vecindario 3 × 5 (es decir, el núcleo es una matriz de unos 3 × 5). El 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

tiene dos problemas (que se resolverán más adelante):

  1. Los valores se han calculado para todas las posiciones, mientras que solo los necesitamos en las posiciones de los que están en la cuadrícula de cero uno.
  2. Para cada una de esas posiciones, el recuento de vecinos incluye el punto en sí, por lo que está desactivado por 1.

El código ahora se agrega 47a cada valor calculado. Esto corresponde a restar 1para resolver el problema (2) y sumar 48(ASCII para '0'), que convierte cada número en el punto de código de su correspondiente carácter.

La matriz resultante se multiplica por una copia de la cuadrícula cero. Esto resuelve el problema (1) anterior, haciendo que los puntos que no son parte de la cuadrícula hexagonal sean iguales a cero nuevamente:

 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, este conjunto de números se convierte en un conjunto de caracteres. Los caracteres cero se muestran como espacio, lo que da el resultado final:

  3 4 3  
 4 6 6 4 
3 6 6 6 3
 4 6 6 4 
  3 4 3  
Luis Mendo
fuente
15

JavaScript (ES6), 118117 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`

Donde \nrepresenta un carácter de nueva línea literal. Explicación: supongamos n=4. Comenzamos con el siguiente cuadrado de dígitos separados por espacios:

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

Los primeros |n-i| 0s se eliminan, pero los espacios permanecen:

   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! Entonces es suficiente calcular el valor apropiado en lugar de cada uno 0verificando si estamos en la primera o última fila y / o columna. Editar: guardado 1 byte gracias a @Arnauld.

Neil
fuente
Usando parte de su fórmula, llegué a una versión de 107 bytes con / 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
@Arnauld me gusta eso 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])

Las pruebas están en ideone

Corre desde la parte superior hasta las filas del medio for r in range(n), construyendo cadenas:
- haciendo dos esquinas o dos bordes '34'[r%m>0]*2,;
- llenar por unirse a ellos con repetida '6'o '4', '46'[r>0]*(r+m-1);
- unir las esquinas y bordes con ' ';
- anteponiendo con espacios, ' '*(m-r);

Luego imprime esto y se refleja en la fila central unida por nuevas líneas, print'\n'.join(t+t[-2::-1])

Jonathan Allan
fuente
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

Esto se ve bastante desordenado y algo golfable ...

Sp3000
fuente
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);}}}

Sin golf

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

Estoy seguro de que el horrible bloque if-else anidado se puede reescribir para que sea más pequeño, pero no puedo entenderlo en este momento. Cualquier sugerencia es bienvenida :-)

Actualizar

  • Seguí la sugerencia de Kevin Cruijssen y usé decodificación en lugar de parseInt.
  • Reescribió algunos ifs utilizando el operador ternario.
  • Más operadores ternarios.
  • Moar operadores ternarios! ¡Creo que he creado un monstruo!
  • Reescribió el bloque if-else con respecto a la impresión.
Master_ex
fuente
1
No he examinado tan de cerca el método que usas, pero algunos pequeños consejos de golf para tu código actual: Integer.parseIntse pueden jugar Integer.decode. l=(h*4-3-s.trim().length())/2;if(l==0)se puede jugar al golf if((l=(h*4-3-s.trim().length())/2)==0). Además, es completamente aceptable simplemente publicar un método sin clase (a menos que la pregunta indique lo contrario), por lo que, en void f(int i){...use i...}lugar de interface J{static void main(String[]r){...i=Integer.decode(r[0])...use i...}, eso también debería ahorrarle unos pocos bytes. Cuando tenga más tiempo, buscaré más.
Kevin Cruijssen
@KevinCruijssen: Gracias por sus sugerencias. l=(h*4-3-s.trim().length())/2;if(l==0)es en realidad la misma longitud con if((l=(h*4-3-s.trim().length())/2)==0).
Master_ex
2

05AB1E , 44 bytes

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

Explicación

Como la parte superior e inferior del hexágono se reflejan, solo necesitamos generar la parte superior.
Entonces, para una entrada de X necesitamos generar X filas. Eso es lo que hace el bucle principal.

F                                        }

Luego hacemos la parte central de las filas.
Esto es 4 para la primera fila y 6 para el resto (ya que solo estamos haciendo la parte superior).
Concatenamos este número con un espacio ya que el patrón requerirá un espacio entre los números.

N_i4ë6}ð«

Luego repetimos esta cadena X-2 + N veces, donde N es la fila actual indexada en 0 y antepone un espacio en el lado izquierdo.

¹ÍN+×ðì

Después de esto es hora de las esquinas. Serán 3 para la primera y última fila y 4 para las filas del medio.

N_N¹<Q~i3ë4}.ø

Ahora debemos asegurarnos de que las filas estén alineadas correctamente agregando espacios al frente de cada fila. El número de espacios agregados será X-1-N .

¹<N-ð×ì

Ahora que hemos terminado la parte superior de la cuadrícula, agregamos las filas a una lista, creamos una copia invertida y eliminamos el primer elemento de esa copia (ya que solo necesitamos la fila central una vez), luego combinamos estas 2 listas juntas y impresión.

)¦«»

Pruébalo en línea!

Solución adicional, también 44 bytes:

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

Rubí, 87 bytes

La función anónima toma n como argumento y devuelve una matriz de cadenas.

->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}}

Sin golf en el programa de prueba

Entrada a través de stdin. Escribe toda la forma en stdout. Bastante autoexplicativo.

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
fuente
1

V , 60 bytes

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

Pruébalo en línea!

Esto es realmente demasiado tiempo. Aquí hay un hexdump, ya que contiene caracteres no imprimibles:

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
fuente
1

Raqueta, 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))))

Pruebas:

(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

Versión detallada:

(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
fuente