Reto Tomado de mi concurso de desafío de código de la universidad
Este es en realidad el Día 0, pero el desafío de ayer fue demasiado fácil y puede ser una trampa de otra pregunta aquí.
Tetris es un videojuego que se hizo popular en los años 80. Consiste en colocar una serie de piezas con diferentes formas que caen en un tablero, para que encajen de la manera más compacta posible.
En este problema asumiremos una secuencia de piezas que caen, cada una en una determinada posición y con una determinada orientación que no se puede cambiar. Las piezas se apilan a medida que caen y las filas completas no se eliminan (como en el juego original). El objetivo es determinar la altura final de cada columna del tablero después de que caen todas las piezas.
Hay un total de 7 piezas diferentes, que se muestran en la figura:
Desafío
Dada una lista de piezas, muestre la altura de todas las columnas del tablero después de que todas las piezas caigan
Una pieza consta de tres números: I, R y P. El primer número, I, es el identificador de la pieza (un número entre 1 y 7, en el mismo orden que en la figura). El segundo número, R, es la rotación de la pieza. Puede tomar los valores 0, 90, 180 o 270 y representa el ángulo de rotación de la pieza en el sentido antihorario. El tercer número, P, indica la posición de la pieza. Representa la columna a la izquierda ocupada por la pieza (puede ser un índice 1 o 0. Especifique).
Ejemplo y caso de prueba (1 índice)
- Dado
[[1, 0, 1], [4, 0, 1], [5, 90, 4]]
- Salida
[3, 3, 1, 3, 2]
- Dado
[[6, 270, 4], [1, 180, 5], [1, 90, 6], [7, 0, 4]]
- Salida
[0, 0, 0, 9, 9, 8, 3, 3]
[[3,0,1],[3,180,3]]
Salida dada[1,1,4,4,4]
[[2,180,1],[2,0,3]]
Salida dada[2,2,4,3,3]
Notas
- Este es el código de golf
- La fila / columna puede ser 1 o 0 índice. Por favor especifica.
- Puede redefinir los valores de entrada (tal vez desee llamar a la pieza 1 como A, etc.). En ese caso, especifique
Preguntas
¿Podemos usar 4 valores distintos en lugar de un ángulo en grados ?: Sí
¿Se supone que debemos manejar "agujeros" si una pieza no encaja exactamente sobre los anteriores ?: Sí
¿Es acotada la altura o el ancho del tablero? No. Ni el ancho ni la altura están delimitados
Gracias @Arnauld por las imágenes y los casos de prueba *. *
I
,R
yP
ser introducidos en un orden diferente?Respuestas:
JavaScript (Node.js) ,
286 284 270266 bytesLas piezas y las posiciones están indexadas en 0. Los ángulos están en .[ 0..3 ]
Pruébalo en línea! o pruebe una versión mejorada que también muestre el tablero final.
Codificación de forma
Todas las piezas se almacenan exactamente como 4 nibbles (4x4 bits) con las filas ordenadas en orden inverso y el píxel más a la izquierda asignado al bit menos significativo. En otras palabras, la representación binaria de la forma se refleja tanto vertical como horizontalmente.
Ejemplo:
Función hash y tabla de búsqueda
Dada una pieza , una rotación y una fila , utilizamos la siguiente función hash para obtener el índice de máscara de bits correspondiente de una tabla de búsqueda:p ∈ [ 0..6 ] r ∈ [ 0..3 ] y∈ [ 0..3 ] norte
Solo las primeras entradas se almacenan explícitamente. Todo lo demás se establece en .82 0 0
Estas entradas se empaquetan como:
que se expande a los siguientes 82 mordiscos:
El uso de hexadecimal en el formato final solo se requiere para las dos representaciones horizontales de la pieza , por lo tanto, en la cadena anterior.yo
"ff"
Los parámetros de la función hash fueron forzados por la fuerza bruta de una manera que optimiza los ceros iniciales y finales. El hecho de que la cadena se pueda comprimir un poco más usando
1e12
los ceros en el medio y una conversión de base-16 a base-4 para la parte derecha es solo un efecto secundario bienvenido pero inesperado. :-)Aquí hay una demostración del proceso de desembalaje para todas las piezas y todas las rotaciones.
Comentado
fuente
C (clang) ,
253239221212 bytesPruébalo en línea!
ps En realidad, el tamaño del código es de 221 bytes (pero 212 caracteres) debido a los caracteres UNICODE codificados en UTF-8. Pero tio.run lo trata como un código de 212 bytes ...
El tamaño del código en mi computadora es de 209 caracteres (218 bytes). Pero no pude reemplazar
\225
por char visible en tio.run 😞Código sin golf
Descripción
Busquemos la línea base superior ( TBL ) de cada figura y describámosla como un número de celdas debajo de TBL para cada posición horizontal. También describamos el número de celdas (altura) sobre TBL ( HAT ).
P.ej:
Describamos TBL y HAT para cada figura y cada ángulo de rotación:
Ahora deberíamos codificar estos números como una secuencia de 2 bits y colocarlos en una matriz (reemplazando
4 0
por3 1
un ángulo de 90 ° de "línea" para que quepa en 2 bits; el resultado será el mismo y disminuirá los anchos en 1).Codificaremos en orden: ancho (en 2 LSB), TBL , HAT (hacia atrás para bucle hacia atrás). Ej
2 2 1 1 0
para 270 ° ángulo de T-figura será codificado como1 0 1 2 1
(última 1 es ancho-1 ):0b0100011001 = 281
.actualizado 12.02:
a) He convertido una matriz en una cadena y he guardado 18 caracteres (puede ver el código anterior de 239 bytes ) :))
b) Más optimización, el código se reduce en 9 caracteres.
Este es mi último intento (¡creo que sí, jaja!) 😀
fuente
<s> ... </s>
.Lisp común, 634 bytes
Verboso
Pruébalo
Las piezas son listas circulares de listas de números. Cada una de estas sublistas representa un lado de la forma, los números indican qué tan lejos están del lado opuesto. Se dejan de izquierda a derecha cuando ese lado está en la parte inferior, de derecha a izquierda cuando está en la parte superior, de arriba a abajo cuando está a la izquierda y de abajo a arriba cuando está a la derecha. Estas opciones de diseño eliminan la necesidad de escribir código para la rotación. Desafortunadamente, la falta de código de rotación no parece haber compensado las largas representaciones de formas, o la lógica algo complicada que usé para calcular las nuevas alturas de columna.
La rotación es un número entero no negativo. 0 = 0 grados, 1 = 90 grados, 2 = 180 grados, 4 = 270 grados
fuente
C # (compilador interactivo de Visual C #) , 308 bytes
Pruébalo en línea!
OK, eso fue una locura ... envié una respuesta que utilizaba técnicas de código de golf de rutina. Pero cuando vi lo que otros enviaban, me di cuenta de que había una mejor manera.
Cada
(shape, rotation)
tupla se codifica en un literal de cadena C # con duplicados eliminados. El proceso de codificación captura cada una de estas configuraciones en 2 bytes.La altura de almacenamiento más baja de 3 bits y el siguiente ancho de almacenamiento de 3. Como cada uno de estos valores nunca es más de 4, pueden leerse directamente desde los 3 bits sin ninguna conversión. Aquí hay unos ejemplos:
A continuación, cada columna se almacena en 3 bits. Lo más útil para mí fue almacenar el número de cuadrados faltantes en la parte superior e inferior de la columna.
Nunca faltan más de 2 cuadrados en la parte superior o inferior, y nunca faltan más de 1 cuadrado en ambos al mismo tiempo. Dado este conjunto de restricciones, se me ocurrió la siguiente codificación:
Como tenemos que tener en cuenta como máximo 3 columnas con cuadrados faltantes arriba o abajo, podemos codificar cada
(shape, rotation)
tupla en 15 bits.Por último, se han eliminado las formas duplicadas. El siguiente ejemplo muestra cómo múltiples
(shape,rotation)
tuplas pueden producir salidas duplicadas para la misma forma en diferentes rotaciones:Todas las salidas únicas se determinan y guardan en ay se
byte[]
convierten en un literal de cadena C #. Para buscar rápidamente dónde se basa una formaI
yR
, los primeros 7 bytes de la matriz consisten en una clave de búsqueda codificada.A continuación hay un enlace al programa que utilicé para comprimir las piezas.
Pruébalo en línea!
Código menos golfizado y comentado:
fuente
Carbón , 98 bytes
Pruébalo en línea! El enlace es a la versión detallada del código. Toma la entrada como una matriz de valores [P, R, I], donde I es de 0 a 6, R es de 0 o 3 y P también está indexado a 0. Explicación:
Pase sobre las piezas de entrada.
Extraiga la descripción de la pieza actual y la rotación. (Vea abajo.)
Extraer la posición.
Asegúrese de que haya suficiente espacio horizontal para colocar la pieza.
Asegúrese de que haya suficiente espacio vertical para colocar la pieza.
Calcule las nuevas alturas de las columnas afectadas.
Cuando se hayan procesado todas las piezas, envíe la lista final de alturas de columna en líneas separadas.
La cadena comprimida representa la cadena original
00001923001061443168200318613441602332034173203014614341642430137
. Aquí los2
s sonI
separadores y los1
s sonR
separadores. Por lo tanto, las piezas se decodifican de la siguiente manera:Los
R
valores faltantes se rellenan automáticamente de forma cíclica con carbón. Cada dígito se asigna a dos valores, voladizo y altura total, de acuerdo con la siguiente tabla:El voladizo y la altura total se relacionan con las alturas de las columnas de la siguiente manera: dada una pieza que queremos colocar en una posición determinada
e
, es posible colocar la pieza aunque una de las columnas sea más alta quee
. La cantidad de espacio libre está dada por el voladizo. La nueva altura de la columna después de colocar la pieza es simplemente la posición colocada más la altura total.Ejemplo: Supongamos que comenzamos colocando una
5
pieza en la columna 1. Dado que todavía no hay nada más, la pieza se coloca en la posición 0 y las columnas 1 y 3 ahora tienen altura 1 mientras que la columna 2 tiene altura 2. Entonces queremos colocar una6
pieza con1
rotación en la columna 0. Aquí podemos colocar esta pieza en la posición 0; aunque la columna 1 tiene una altura de 1, la pieza tiene un saliente de 1, por lo que hay suficiente espacio para colocarla. La columna 0 termina con una altura de 2 y la columna 1 termina con una altura de 3.fuente