El hermoso cajón de patrones
Buenos dias PPCG!
El otro día, cuando estaba tratando de ayudar a alguien en Stack Overflow, una parte de su problema me dio una idea para este desafío.
En primer lugar, verifique la siguiente forma:
Donde todos los números negros son el índice de los puntos en la forma y todos los números azul oscuro son el índice de los enlaces entre los puntos.
Ahora, dado un número hexadecimal de 0x00000 a 0xFFFFF, debe dibujar una forma en la consola usando solo el espacio de caracteres y "■" (también está bien usar el carácter "o").
Estos son algunos ejemplos en los que se ingresa el número hexadecimal y se genera la forma:
0xE0C25 :
■ ■ ■ ■ ■ ■ ■ ■ ■
■ ■
■ ■
■ ■
■ ■ ■ ■ ■ ■
■ ■
■ ■
■ ■
■ ■ ■ ■ ■
0xC1043 :
■ ■ ■ ■ ■ ■ ■ ■ ■
■
■
■
■
■
■
■
■ ■ ■ ■ ■ ■ ■ ■ ■
0xE4F27 :
■ ■ ■ ■ ■ ■ ■ ■ ■
■ ■ ■
■ ■ ■
■ ■ ■
■ ■ ■ ■ ■ ■ ■ ■ ■
■ ■ ■
■ ■ ■
■ ■ ■
■ ■ ■ ■ ■ ■ ■ ■ ■
0xF1957 :
■ ■ ■ ■ ■ ■ ■ ■ ■
■ ■ ■ ■
■ ■ ■ ■
■ ■ ■ ■
■ ■ ■
■ ■ ■ ■
■ ■ ■ ■
■ ■ ■ ■
■ ■ ■ ■ ■ ■ ■ ■ ■
0xD0C67 :
■ ■ ■ ■ ■ ■ ■ ■ ■
■ ■
■ ■
■ ■
■ ■ ■ ■ ■ ■
■ ■ ■
■ ■ ■
■ ■ ■
■ ■ ■ ■ ■ ■ ■ ■ ■
0x95E30 :
■ ■ ■ ■ ■ ■
■ ■ ■ ■
■ ■ ■ ■
■ ■ ■ ■
■ ■ ■ ■ ■ ■ ■ ■ ■
■ ■
■ ■
■ ■
■ ■
0x95622 :
■ ■ ■ ■ ■ ■
■ ■ ■
■ ■ ■
■ ■ ■
■ ■ ■ ■ ■ ■ ■ ■ ■
■
■
■
■ ■ ■ ■ ■
0xC5463 :
■ ■ ■ ■ ■ ■ ■ ■ ■
■ ■
■ ■
■ ■
■ ■ ■ ■ ■
■ ■
■ ■
■ ■
■ ■ ■ ■ ■ ■ ■ ■ ■
0xE5975 :
■ ■ ■ ■ ■ ■ ■ ■ ■
■ ■ ■ ■
■ ■ ■ ■
■ ■ ■ ■
■ ■ ■
■ ■ ■ ■ ■
■ ■ ■ ■ ■
■ ■ ■ ■ ■
■ ■ ■ ■ ■ ■
0xB5E75 :
■ ■ ■ ■ ■ ■
■ ■ ■ ■ ■
■ ■ ■ ■ ■
■ ■ ■ ■ ■
■ ■ ■ ■ ■ ■ ■ ■ ■
■ ■ ■ ■
■ ■ ■ ■
■ ■ ■ ■
■ ■ ■ ■ ■ ■
0xF4C75 :
■ ■ ■ ■ ■ ■ ■ ■ ■
■ ■ ■ ■
■ ■ ■ ■
■ ■ ■ ■
■ ■ ■ ■ ■ ■
■ ■ ■ ■
■ ■ ■ ■
■ ■ ■ ■
■ ■ ■ ■ ■ ■
0xF5D75 :
■ ■ ■ ■ ■ ■ ■ ■ ■
■ ■ ■ ■ ■
■ ■ ■ ■ ■
■ ■ ■ ■ ■
■ ■ ■ ■ ■ ■
■ ■ ■ ■ ■
■ ■ ■ ■ ■
■ ■ ■ ■ ■
■ ■ ■ ■ ■ ■
Aquí hay algunas explicaciones sobre cómo funciona:
0xFFFFF(16) = 1111 1111 1111 1111 1111(2)
Aquí tiene 20 bits, cada bit dice si existe un enlace o no.
El índice del bit más significativo (MSB) es 0 (referencia de imagen) o el bit menos significativo (LSB) es 19 (referencia de imagen nuevamente).
Así es como funciona para la primera forma dada como ejemplo:
0xE0C25(16) = 1110 0000 1100 0010 0101(2)
Lo que significa que tendrá los siguientes enlaces existentes: 0,1,2,8,9,14,17,19.
Si resalta las líneas en la imagen de referencia con esos números, le dará esta forma:
■ ■ ■ ■ ■ ■ ■ ■ ■
■ ■
■ ■
■ ■
■ ■ ■ ■ ■ ■
■ ■
■ ■
■ ■
■ ■ ■ ■ ■
Aquí hay una implementación de Python simple y sin golf si necesitas más ayuda:
patterns = [
0xE0C25, 0xC1043, 0xE4F27, 0xF1957,
0xD0C67, 0x95E30, 0x95622, 0xC5463,
0xE5975, 0xB5E75, 0xF4C75, 0xF5D75
]
def printIfTrue(condition, text = "■ "):
if condition:
print(text, end="")
else:
print(" "*len(text), end="")
def orOnList(cube, indexes):
return (sum([cube[i] for i in indexes]) > 0)
def printPattern(pattern):
cube = [True if n == "1" else False for n in str(bin(pattern))[2::]]
for y in range(9):
if y == 0: printIfTrue(orOnList(cube, [0, 2, 3]))
if y == 4: printIfTrue(orOnList(cube, [2, 4, 9, 11, 12]))
if y == 8: printIfTrue(orOnList(cube, [11, 13, 18]))
if y in [0, 4, 8]:
printIfTrue(cube[int((y / 4) + (y * 2))], "■ ■ ■ ")
if y == 0: printIfTrue(orOnList(cube, [0, 1, 4, 5, 6]))
if y == 4: printIfTrue(orOnList(cube, [3, 5, 7, 9, 10, 13, 14, 15]))
if y == 8: printIfTrue(orOnList(cube, [12, 14, 16, 18, 19]))
printIfTrue(cube[int((y / 4) + (y * 2)) + 1], "■ ■ ■ ")
elif y in [1, 5]:
for i in range(7):
if i in [2, 5]:
print(" ", end=" ")
printIfTrue(cube[y * 2 + (1 - (y % 5)) + i])
elif y in [2, 6]:
for i in range(5):
if i in [1, 2, 3, 4]:
print(" ", end=" ")
if i in [1, 3]:
if i == 1 and y == 2:
printIfTrue(orOnList(cube, [3, 4]))
elif i == 3 and y == 2:
printIfTrue(orOnList(cube, [6, 7]))
if i == 1 and y == 6:
printIfTrue(orOnList(cube, [12, 13]))
elif i == 3 and y == 6:
printIfTrue(orOnList(cube, [15, 16]))
else:
printIfTrue(cube[(y * 2 - (1 if y == 6 else 2)) + i + int(i / 4 * 2)])
elif y in [3, 7]:
for i in range(7):
if i in [2, 5]:
print(" ", end="")
ri, swap = (y * 2 - 2) + (1 - (y % 5)) + i, [[3, 6, 12, 15], [4, 7, 13, 16]]
if ri in swap[0]: ri = swap[1][swap[0].index(ri)]
elif ri in swap[1]: ri = swap[0][swap[1].index(ri)]
printIfTrue(cube[ri])
if y == 0: printIfTrue(orOnList(cube, [1, 7, 8]))
if y == 4: printIfTrue(orOnList(cube, [6, 8, 10, 16, 17]))
if y == 8: printIfTrue(orOnList(cube, [15, 17, 19]))
print()
for pattern in patterns:
printPattern(pattern)
Por supuesto, no es perfecto y es bastante largo para lo que debería hacer, ¡y esa es la razón exacta por la que estás aquí!
Haciendo este programa ridículamente corto :)
Este es el código de golf, por lo que gana la respuesta más corta.
fuente
Respuestas:
JavaScript (ES6),
202188187 bytesCómo funciona
Trabajamos en una cuadrícula
g
de 9 filas de 10 caracteres. La cuadrícula se llena inicialmente con espacios, con un LineFeed cada 10 caracteres.Cada segmento está definido por una posición inicial y una dirección.
Las instrucciones están codificadas de la siguiente manera:
Cada segmento está codificado como un entero:
Por ejemplo, el segmento # 3 comienza en la posición 55 y usa la tercera dirección. Por lo tanto, está codificado como
(55 << 2) | 3 == 223
.A continuación se muestra la lista resultante de enteros, desde el segmento # 19 al segmento # 0:
Una vez codificado en delta, comenzando en 356, se convierte en:
Que finalmente se codifica como:
fuente
Python 3, 289 bytes
Nada inteligente, solo codificación.
fuente
"trq|t...a|eca".split("|")
ser"tqr t...a eca".split()
?.split()
destruye||
.Ruby, 116 bytes
Esto se basa en un par de patrones que observé. En primer lugar, el patrón se repite cada 9 líneas. En segundo lugar, si los puntos de inicio de las líneas horizontales se eligen apropiadamente, las direcciones x cambian continuamente de derecha a izquierda, recta.
Sin golf en el programa de prueba
Creo que hay una solución de 112 bytes que usa una cadena de 20 caracteres y algo de decodificación para definir los parámetros de las 20 líneas. Intentaré esto más tarde si tengo tiempo.
fuente
PHP,
142150149 bytesimprime la forma tanto como sea necesario; es decir, si la parte inferior está vacía, se cortará.
Corre con
php -nr '<code>' <input>
. No prefijo entradaPruébelo en línea
Agregue 11 bytes para no cortar: inserte
,$r[80]=" "
después$r=""
.codificación explicada
Cada línea se puede describir con un punto de partida y una de las cuatro direcciones.
Dibujando en una cuadrícula de 9x9, la posición inicial varía de
0,0
a8,4
; o, combinado, de0
a8*9+4=76
. Afortunadamente, todos los puntos de partida[0,4,8,36,40,44,72,76]
son divisibles por 4; por lo que el código de dirección[0..3]
puede exprimirse en los bits 0 y 1 -> no se necesita ningún desplazamiento.Para un cálculo fácil del movimiento del cursor,
0
se toma para el este (solo dirección sin movimiento vertical) y[1,2,3]
para el sudoeste, sur, sudeste, donde el desplazamiento es9
(para el movimiento vertical) más[-1,0,1]
->[8,9,10]
->delta=code?code+7:1
.La dirección para la primera y última línea es este, lo que da como resultado códigos que van de 0 a 76
[0+0,4+0,0+2,0+3,4+1,4+2,4+3,8+1,8+2,...,44+1,44+2,72+0,76+0]
; y bitor xor 96 en cada valor da como resultado códigos ascii imprimibles y sin problemas[96,100,98,99,101,102,103,105,106,68, 72,70,71,73,74,75,77,78,40,44]
->`dbcefgijDHFGIJKMN(,
. El código utiliza el LSB para el bit 0, mientras que la línea 0 corresponde al MSB, por lo que la cadena debe invertirse. FinitoDescompostura
algo de golf explicado
^96
no tiene efecto en los dos bits inferiores, puede ignorarse al extraer la dirección; Por lo tanto, no es necesario almacenar el valor en una variable, lo que ahorra 5 bytes en el cursor init.~3
lugar de124
guardar un byte y permite el próximo golf:$k=3
dentro de la$p
asignación ahorra dos bytesy no daña la condición previa (ya que el valor superior todavía tiene un dígito).
chunk_split
es la forma más corta de insertar los saltos de línea.Ni siquiera quiero saber cuánto más tomaría cualquier otra cosa.
7+($c&3?:-6)
es un byte más corto que$c&3?$c%4+7:1
.hexdec()
(8 bytes) para satisfacer la restricción de entrada.fuente
JavaScript,
184183178168167 bytesOriginalmente tenía 206 bytes, pero la respuesta de @ Arnauld me inspiró a investigar una solución de matriz unidimensional. Editar: Guardado 1 byte gracias a @ edc65. Guardado
515 bytes gracias a @Arnauld. Se guardó un byte adicional al ajustar la elección de los personajes.fuente
[0,1,2,3,4]
es más corto[67,65,52,36,51,50,34,49,48,35,33,20,4,19,18,2,17,16,3,1]
y[0,2,4,6,8].map(i=>a[(e&102)*4+(e&17||15)*i]='o')
[..."ecVFUTDSREC6&54$32%#"]
y[0,2,4,6,8].map(i=>a[(e&102)*4+(e&17||15)*i]='o',e=e.charCodeAt()-34)
para guardar 10 bytes más.~
lugar de-34
(lamentablemente me caigo de '\', por eso no guardo 2 bytes).Lote, 491 bytes
Nota: La última línea termina con un espacio. Poner un
if
condicional con una variable dentro de unfor
bucle está más allá del lote, por lo que necesita su propia subrutina. Como no hace nada visible, caigo en él para salir. Las~
comillas entre comillas en el bucle externo permiten que el bucle interno recorra los números. Los números son simplemente las máscaras de bits para todos los lugares donde seo
deben dibujar s.fuente
C,
267262260256 caracteresContando escapes como 1 personaje
k es una búsqueda que se refiere a qué cuadros poner una 'o'.
Pruébalo en línea!
fuente
Befunge, 468 bytes
Pruébalo en línea!
La primera línea lee una cadena de stdin, evaluándola como un número hexadecimal. El resto del código es esencialmente un doble bucle sobre las coordenadas x / y de la cuadrícula, con un cálculo booleano masivo que determina si se
o
debe emitir un para cada ubicación.Básicamente, hay una condición separada para cada uno de los 20 puntos de la cuadrícula, por ejemplo (los primeros cuatro):
Y luego, una vez que hemos calculado los 20, O juntos, y si ese resultado es verdadero, sacamos un
o
, de lo contrario, sacamos un espacio.Befunge no tiene nada en el camino de las operaciones de manipulación de bits, por lo que para extraer los bits de la entrada, solo estamos evadiendo repetidamente
n%2
y luego an/=2
medida que avanzamos a través de los 20 cálculos de condición.fuente