Los basicos:
Considere los siguientes tetrominós y el campo de juego vacío:
0123456789 IOZTLSJ [] [] # ## ## ### # ## # [] # ## ## # # ## # [] # ## ## [] # [] [==========]
Las dimensiones del campo de juego son fijas. Los números en la parte superior están aquí para indicar el número de columna (ver también la entrada).
Entrada:
1 . Se le da un campo de juego específico (basado en lo anterior) que ya se puede llenar parcialmente con tetrominós (esto puede estar en un archivo separado o proporcionado a través de stdin).
Entrada de muestra:
[] [] [] [] [# # #] [## ######] [==========]
2 . Se le da una cadena que describe (separada por espacios) qué tetromino insertar (y desplegar) en qué columna. No es necesario rotar los tetrominós. La entrada se puede leer desde stdin.
Entrada de muestra:
T2 Z6 I0 T7
Puede asumir que la entrada está 'bien formada' (o producir un comportamiento indefinido cuando no lo está).
Salida
Procese el campo resultante (las líneas 'completas' deben desaparecer) e imprima el recuento de puntuación (cada línea eliminada representa 10 puntos).
Salida de muestra basada en la entrada de muestra anterior:
[] [] [] [# ###] [# ###] [##### ####] [==========] 10
Ganador:
Solución más corta (por número de caracteres del código). Los ejemplos de uso son buenos. ¡Diviértete jugando al golf!
Editar : agregó una recompensa de +500
reputación para llamar más la atención sobre los buenos esfuerzos que los que respondieron ya hicieron (y posiblemente algunas nuevas soluciones a esta pregunta) ...
fuente
Respuestas:
GolfScript - 181 caracteres
Las nuevas líneas no son necesarias. La salida está en la salida estándar, aunque hay algunos errores en stderr.
\10
debe reemplazarse por el carácter ASCII correspondiente para que el programa tenga 181 caracteres.E / S de muestra:
Compresión Tetromino: las
piezas se almacenan como tres dígitos base 8. Esta es una representación binaria simple, por ejemplo
T=[7,2,0], S=[6,3,0], J=[2,2,3]
.[1]
se utiliza para laI
pieza en compresión, pero se establece explícitamente en[1,1,1,1]
later (es decir,4*
en el código). Todas estas matrices se concatenan en una sola matriz, que se convierte en un número entero y luego en una cadena (base 126 para minimizar los caracteres no imprimibles, la longitud y no encontrar utf8). Esta cadena es muy corta:"R@1(XBc_"
.Entonces, la descompresión es sencilla. Primero hacemos una conversión base 126 seguida de una conversión base 8 (
"~\10"{base}/
es decir, iteramos"~\10"
y hacemos una conversión base para cada elemento). La matriz resultante se divide en grupos de 3, la matriz paraI
es fija (3/~4*
). Luego convertimos cada elemento a base 2 y (después de eliminar los ceros) reemplazamos cada dígito binario con el carácter de ese índice en la cadena" #"
(2base{" #"=}%...-1%
- tenga en cuenta que necesitamos revertir la matriz, de lo contrario2
se convertiría en"# "
lugar de" #"
).Formato tablero / pieza, dejando caer piezas
El tablero es simplemente una matriz de cuerdas, una para cada línea. No se trabaja inicialmente en esto, por lo que podemos generarlo con
n/(
la entrada. Las piezas también son matrices de cadenas, rellenas con espacios a la izquierda para su posición X, pero sin espacios finales. Las piezas se colocan anteponiéndolas a la matriz y probando continuamente si hay una colisión.La prueba de colisión se realiza iterando a través de todos los personajes de la pieza y comparándola con el personaje de la misma posición en el tablero. Queremos considerar
#
+=
y#
+#
como colisiones, por lo que probamos si ((piecechar & 3) & boardchar) es distinto de cero. Mientras hacemos esta iteración, también actualizamos (una copia de) el tablero con ((piecechar & 3) | boardchar), que establece correctamente el valor para los pares#
+,
+
#
,+
[
. Usamos este tablero actualizado si hay una colisión después de mover la pieza hacia abajo en otra fila.Eliminar filas llenas es bastante simple. Eliminamos todas las filas para las que
"= "&
devuelve falso. Una fila llena no tendrá ni=
o, por lo que la conjunción será una cadena en blanco, lo que equivale a falso. Luego contamos el número de filas que se han eliminado, sumamos el recuento a la puntuación y anteponemos esa cantidad de
"[ ... ]"
s. Generamos esto de forma compacta tomando la primera fila de la cuadrícula y reemplazándola#
con.
Bonificación
Dado que calculamos cómo se vería el tablero en cada posición de la pieza a medida que cae, ¡podemos mantenerlos en la pila en lugar de eliminarlos! Para un total de tres caracteres más, podemos generar todas estas posiciones (o dos caracteres si tenemos los estados del tablero a espacio simple).
fuente
Perl,
586523483472427407404386387356353caracteres(Necesita Perl 5.10 para el
//
operador definido-or ).Toma toda la entrada de stdin.
Todavía necesita algo de golf en serio.Tenga en cuenta que ^ Q representa ASCII 17 (DC1 / XON), ^ C representa ASCII 3 y ^ @ representa ASCII 0 (NUL).
Versión comentada:
Edición 1: algo de golf serio, corrección de errores de salida.
Edición 2: algo de inserción, fusionó dos bucles en uno para un ahorro neto de (redoble de batería ...) 3 caracteres, golf misceláneo.
Edición 3: algunas eliminaciones de subexpresiones comunes, un poco de fusión constante y una expresión regular ajustada.
Edición 4: cambio de representación de tetrominós en un vector de bits empaquetado, golf misceláneo.
Edición 5: traducción más directa de la letra tetromino al índice de la matriz, use caracteres no imprimibles, golf misceláneo.
Edición 6: corrección de errores en la línea superior de limpieza, introducida en r3 (edición 2), detectada por Nakilon. Utilice más caracteres no imprimibles.
Edición 7: utilícelo
vec
para obtener datos de tetromino. Aprovecha que el campo de juego tiene dimensiones fijas.if
declaración =>if
modificador, la fusión de bucles de la edición 2 comienza a dar sus frutos. Úselo//
para el caso de puntuación 0.Edición 8: se corrigió otro error, introducido en r6 (edición 5), detectado por Nakilon.
Edición 9: no cree nuevas referencias al borrar líneas, simplemente mueva las referencias a través del corte de matriz. Fusiona dos
map
en uno. Regex más inteligente. "Más inteligente"for
. Campos de golf varios.Edición 10: matriz de tetromino en línea, versión comentada agregada.
fuente
Ruby -
427 408 398 369359fuente
Script de shell bash (
301304 caracteres)ACTUALIZACIÓN: se corrigió un error que involucraba piezas que se extendían hasta la fila superior. Además, la salida ahora se envía a la salida estándar y, como beneficio adicional, es posible ejecutar el script nuevamente para continuar jugando un juego (en cuyo caso debe sumar la puntuación total usted mismo).
Esto incluye caracteres no imprimibles, por lo que he proporcionado un volcado hexadecimal. Guárdelo como
tetris.txt
:Luego, en el símbolo del sistema de bash, preferiblemente con en
elvis
lugar devim
instalado comovi
:Cómo funciona
El código se autoextrae de manera similar a como lo hacen los programas ejecutables comprimidos usando el
gzexe
script. Las piezas de Tetromino se representan como secuencias de comandos del editor vi. El recuento de caracteres se utiliza para detectar colisiones y el recuento de líneas se utiliza para calcular la puntuación.El código descomprimido:
El código original antes de jugar al golf:
fuente
Python:
504519 caracteres(Solución Python 3)
Actualmente requiere establecer la entrada en el formato que se muestra en la parte superior (el código de entrada no se cuenta). Lo expandiré para leer desde el archivo o stdin más tarde.Ahora funciona con un mensaje, simplemente pegue la entrada (8 líneas en total).No estoy seguro de poder ahorrar mucho más allí. Se pierden muchos caracteres de la transformación a campos de bits, pero eso ahorra muchos más caracteres que trabajar con las cadenas. Además, no estoy seguro de poder eliminar más espacios en blanco allí, pero lo intentaré más tarde.No podrá reducirlo mucho más; después de tener la solución basada en bitfield, volví a las cadenas, ya que encontré una manera de comprimirlo más (¡guardé 8 caracteres en el bitfield!). Pero dado que olvidé incluir el
L
y tuve un error con los puntos adentro, mi conteo de caracteres solo sube suspiro ... Quizás encuentre algo más tarde para comprimirlo un poco más, pero creo que estoy cerca del final. Para el código original y comentado, consulte a continuación:Versión original:
fuente
Rubí 1.9,
357355353339330310309 caracteresTenga en cuenta que los
\000
escapes (incluidos los bytes nulos en la tercera línea) deben reemplazarse con su equivalente no imprimible real.Entrada de muestra:
Uso:
o
fuente
?\s
.C,
727 [...] 596 581 556 517 496 471 461457 caracteresEste es mi primer código de golf, creo que el recuento de caracteres puede ser
muchomenor, sería bueno si los golfistas experimentados me pudieran dar algunas pistas.La versión actual también puede manejar campos de juego con diferentes dimensiones.La entrada puede tener saltos de línea en formato DOS / Windows y Unix.El código era bastante sencillo antes de la optimización, los tetrominós se almacenan en 4 enteros que se interpretan como una matriz de (7 * 3) x4 bits, el campo de juego se almacena como está, los mosaicos se eliminan y las líneas completas se eliminan al inicio y después de cada caída de baldosas.
No estaba seguro de cómo contar los caracteres, así que utilicé el código con todos los saltos de línea innecesarios eliminados.
EDITAR 596 => 581: Gracias a KitsuneYMG, todo excepto la
%ls
sugerencia funcionó perfectamente, además, noté que enputch
lugar deputchar
se puede usar (degetch
alguna manera no funciona) y eliminé todos los paréntesis en#define G
.EDITAR 581 => 556: No estaba satisfecho con los bucles restantes
for
y anidadosF
, por lo que hubo algunas combinaciones, cambios y eliminación de bucles, bastante confuso pero definitivamente valió la pena.EDITAR 556 => 517: Finalmente encontré una manera de hacer
a
una matriz int. Algunos seN;
fusionaron conc
,break
ya no .EDITAR 496 => 471: Ancho y alto del campo de juego arreglados ahora.
EDITAR 471 => 461: Modificaciones menores,
putchar
usado de nuevo comoputch
no es una función estándar.EDITAR: Corrección de errores, las líneas completas se eliminaron antes de la caída del mosaico en lugar de después , por lo que las líneas completas podrían dejarse al final. Fix no cambia el recuento de caracteres.
fuente
for
como#define F(x,m) for(x=0;x++<m;)
? Funciona en C # ...: PF(x,3){printf("%i",x}
imprime en12
lugar de012
con este cambio. Podría cambiar afor(x=-1;x++<m;)
, pero esto no guarda nada :)(c=getchar())
y eliminar todas las líneas c = N ahorrando 6 caracteres. A menos que me equivoque sobre esto, debería bajar a 585Python 2.6+ -
334322316 caracteres397368366 caracteres sin comprimir#coding:l1 exec'xÚEPMO!½ï¯ i,P*Ýlš%ì‰=‰Ö–*†þz©‰:‡—Lò¾fÜ”bžAù,MVi™.ÐlǃwÁ„eQL&•uÏÔ‹¿1O6ǘ.€LSLÓ’¼›î”3òšL¸tŠv[ѵl»h;ÁºŽñÝ0Àë»Ç‡ÛûH.ª€¼âBNjr}¹„V5¾3Dë@¼¡•gO. ¾ô6 çÊsÃЮürÃ1&›ßVˆùZ`Ü€ÿžcx±ˆ‹sCàŽ êüRô{U¯ZÕDüE+³ŽFA÷{CjùYö„÷¦¯Î[0þøõ…(Îd®_›â»E#–Y%’›”ëýÒ·X‹d¼.ß9‡kD'.decode('zip')
Se requiere la nueva línea única y la he contado como un carácter.
La palabrería de la página de códigos del navegador puede evitar que se pueda copiar y pegar correctamente este código, por lo que puede generar el archivo a partir de este código:
s = """ 23 63 6F 64 69 6E 67 3A 6C 31 0A 65 78 65 63 27 78 DA 45 50 4D 4F 03 21 10 BD EF AF 20 69 2C 50 2A 02 DD 6C 9A 25 EC AD 07 8D 89 07 3D 89 1C D6 96 2A 86 05 02 1B AD FE 7A A9 89 3A 87 97 4C F2 BE 66 DC 94 62 9E 41 F9 2C 4D 56 15 69 99 0F 2E D0 6C C7 83 77 C1 16 84 65 51 4C 26 95 75 CF 8D 1C 15 D4 8B BF 31 4F 01 36 C7 98 81 07 2E 80 4C 53 4C 08 D3 92 BC 9B 11 EE 1B 10 94 0B 33 F2 9A 1B 4C B8 74 8A 9D 76 5B D1 B5 6C BB 13 9D 68 3B C1 BA 8E F1 DD 30 C0 EB BB C7 87 DB FB 1B 48 8F 2E 1C AA 80 19 BC E2 42 4E 6A 72 01 7D B9 84 56 35 BE 33 44 8F 06 EB 40 BC A1 95 67 4F 08 2E 20 BE F4 36 A0 E7 CA 73 C3 D0 AE FC 72 C3 31 26 9B DF 56 88 AD F9 5A 60 DC 80 FF 9E 63 78 B1 88 8B 73 43 E0 8E A0 EA FC 52 F4 7B 55 8D AF 5A 19 D5 44 FC 45 2B B3 8E 46 9D 41 F7 7B 43 6A 12 F9 59 F6 84 F7 A6 01 1F AF CE 5B 30 FE F8 F5 85 28 CE 64 AE 5F 9B E2 BB 45 23 96 59 25 92 9B 94 EB FD 10 D2 B7 58 8B 64 BC 2E DF 39 87 6B 44 27 2E 64 65 63 6F 64 65 28 27 7A 69 70 27 29 """ with open('golftris.py', 'wb') as f: f.write(''.join(chr(int(i, 16)) for i in s.split()))
Pruebas
intetris
Las líneas nuevas deben ser de estilo Unix (solo salto de línea). Un salto de línea final en la última línea es opcional.
Probar:
Este código descomprime el código original y lo ejecuta con
exec
. Este código descomprimido pesa 366 caracteres y se ve así:import sys r=sys.stdin.readlines();s=0;p=r[:1];a='[##########]\n' for l in r.pop().split(): n=int(l[1])+1;i=0xE826408E26246206601E>>'IOZTLSJ'.find(l[0])*12;m=min(zip(*r[:6]+[a])[n+l].index('#')-len(bin(i>>4*l&31))+3for l in(0,1,2)) for l in range(12): if i>>l&2:c=n+l/4;o=m+l%4;r[o]=r[o][:c]+'#'+r[o][c+1:] while a in r:s+=10;r.remove(a);r=p+r print''.join(r),s
Se requieren nuevas líneas y son de un carácter cada una.
No intente leer este código. Los nombres de las variables se eligen literalmente al azar en busca de la compresión más alta (con diferentes nombres de variables, vi hasta 342 caracteres después de la compresión). A continuación se muestra una versión más comprensible:
import sys board = sys.stdin.readlines() score = 0 blank = board[:1] # notice that I rely on the first line being blank full = '[##########]\n' for piece in board.pop().split(): column = int(piece[1]) + 1 # "+ 1" to skip the '[' at the start of the line # explanation of these three lines after the code bits = 0xE826408E26246206601E >> 'IOZTLSJ'.find(piece[0]) * 12 drop = min(zip(*board[:6]+[full])[column + x].index('#') - len(bin(bits >> 4 * x & 31)) + 3 for x in (0, 1, 2)) for i in range(12): if bits >> i & 2: # if the current cell should be a '#' x = column + i / 4 y = drop + i % 4 board[y] = board[y][:x] + '#' + board[y][x + 1:] while full in board: # if there is a full line, score += 10 # score it, board.remove(full) # remove it, board = blank + board # and replace it with a blank line at top print ''.join(board), score
El quid está en las tres líneas crípticas que dije que explicaría.
La forma de los tetrominós está codificada en el número hexadecimal allí. Se considera que cada tetrónimo ocupa una cuadrícula de celdas de 3x4, donde cada celda está en blanco (un espacio) o completa (un signo de número). Luego, cada pieza se codifica con 3 dígitos hexadecimales, cada uno de los cuales describe una columna de 4 celdas. Los dígitos menos significativos describen las columnas más a la izquierda y el bit menos significativo de cada dígito describe la celda más alta de cada columna. Si un bit es 0, entonces esa celda está en blanco, de lo contrario es un '#'. Por ejemplo, el I tetronimo se codifica como
00F
, con los cuatro bits del dígito menos significativo activados para codificar los cuatro signos numéricos en la columna más a la izquierda, y la T es131
, con el bit superior establecido a la izquierda y a la derecha, y los dos bits superiores colocados en el medio.El número hexadecimal completo se desplaza un bit hacia la izquierda (multiplicado por dos). Esto nos permitirá ignorar el bit más bajo. Explicaré por qué en un minuto.
Entonces, dada la pieza actual de la entrada, encontramos el índice en este número hexadecimal donde comienzan los 12 bits que describen su forma, luego lo desplazamos hacia abajo para que los bits 1–12 (saltando el bit 0) de la
bits
variable describan la pieza actual.La asignación
drop
determina cuántas filas desde la parte superior de la cuadrícula caerá la pieza antes de aterrizar en otros fragmentos de pieza. La primera línea encuentra cuántas celdas vacías hay en la parte superior de cada columna del campo de juego, mientras que la segunda encuentra la celda ocupada más baja en cada columna de la pieza. Lazip
función devuelve una lista de tuplas, donde cada tupla consiste en el n ° de células de cada elemento en la lista de entrada. Entonces, usando la placa de entrada de muestra,zip(board[:6] + [full])
devolverá:[ ('[', '[', '[', '[', '[', '[', '['), (' ', ' ', ' ', ' ', ' ', ' ', '#'), (' ', ' ', ' ', ' ', '#', '#', '#'), (' ', ' ', ' ', ' ', ' ', '#', '#'), (' ', ' ', ' ', ' ', ' ', ' ', '#'), (' ', ' ', ' ', ' ', ' ', '#', '#'), (' ', ' ', ' ', ' ', ' ', '#', '#'), (' ', ' ', ' ', ' ', '#', '#', '#'), (' ', ' ', ' ', ' ', ' ', '#', '#'), (' ', ' ', ' ', ' ', ' ', '#', '#'), (' ', ' ', ' ', ' ', '#', '#', '#'), (']', ']', ']', ']', ']', ']', ']') ]
Seleccionamos la tupla de esta lista correspondiente a la columna apropiada, y buscamos el índice de la primera
'#'
en la columna. Es por eso que agregamos una fila "completa" antes de llamarzip
, para queindex
tenga un retorno sensato (en lugar de lanzar una excepción) cuando la columna está en blanco.Luego, para encontrar el más bajo
'#'
en cada columna de la pieza, cambiamos y enmascaramos los cuatro bits que describen esa columna, luego usamos labin
función para convertir eso en una cadena de unos y ceros. Labin
función solo devuelve bits significativos, por lo que solo necesitamos calcular la longitud de esta cadena para encontrar la celda ocupada más baja (bit de conjunto más significativo). Labin
función también antepone'0b'
, así que tenemos que restar eso. También ignoramos el bit menos significativo. Es por eso que el número hexadecimal se desplaza un bit hacia la izquierda. Esto es para tener en cuenta las columnas vacías, cuyas representaciones de cadena tendrían la misma longitud que una columna con solo la celda superior llena (como la pieza T ).Por ejemplo, las columnas de la I tetromino, como se mencionó anteriormente, son
F
,0
, y0
.bin(0xF)
es'0b1111'
. Después de ignorar'0b'
, tenemos una longitud de 4, que es correcta. Perobin(0x0)
es0b0
. Después de ignorar'0b'
, todavía tenemos una longitud de '1, que es incorrecta. Para dar cuenta de esto, hemos agregado un bit adicional al final, para que podamos ignorar este bit insignificante. Por lo tanto,+3
en el código está ahí para tener en cuenta la longitud extra que ocupa al'0b'
principio y el bit insignificante al final.Todo esto ocurre dentro de una expresión generadora para tres columnas (
(0,1,2)
), y tomamos elmin
resultado para encontrar el número máximo de filas que la pieza puede caer antes de tocar en cualquiera de las tres columnas.El resto debería ser bastante fácil de entender leyendo el código, pero el
for
ciclo que sigue a estas asignaciones agrega la pieza al tablero. Después de esto, elwhile
ciclo elimina filas completas, reemplazándolas con filas en blanco en la parte superior y suma la puntuación. Al final, la pizarra y la puntuación se imprimen en la salida.fuente
Python, 298 caracteres
Supera todas las soluciones de lenguaje no esotérico hasta ahora (Perl, Ruby, C, bash ...)
... y ni siquiera usa artimañas para comprimir códigos.
En el ejemplo de prueba
sale
PD. Se corrigió un error señalado por Nakilon a un costo de +5
fuente
Golfscript 260 caracteres
Estoy seguro de que esto podría mejorarse, soy un poco nuevo en Golfscript.
Los finales de las líneas son relevantes (no debería haber uno al final). De todos modos, estos son algunos de los casos de prueba que utilicé:
Tenga en cuenta que no hay final de línea en el archivo de entrada, un final de línea rompería el script tal como está.
fuente
O'Caml
809782 Caracteresfuente
Common Lisp
667657645 caracteresMi primer intento en el golf de código, por lo que probablemente hay muchos trucos que aún no conozco. Dejé algunas líneas nuevas allí para mantener algo de "legibilidad" residual (conté las líneas nuevas como 2 bytes, por lo que al eliminar 6 líneas nuevas innecesarias se obtienen 12 caracteres más).
En la entrada, primero ponga las formas y luego el campo.
Pruebas
fuente
Rubí
505 479 474 442 439426 caracteresUn primer intento. Lo he hecho con IronRuby. Estoy seguro de que se puede mejorar, ¡pero realmente debería trabajar un poco hoy!
Pruebas
Editar ahora usando rubí normal. Tengo la salida de las paredes ...
fuente
Otro en Ruby,
: **573546caracteresPruebas:
fuente
a.each{|x|s=a.max_by(&:size).size;x[s-=1]||=' 'while s>0}