Desafío de apilamiento secreto ">": calificación
Antecedentes
Tetris Grand Master 3 tiene un sistema de clasificación oculto basado en la forma de la pila al final del juego, que se llama Secret ">" Stacking Challenge . Consiste en llenar completamente las filas más bajas excepto el patrón en zigzag que comienza en la celda inferior izquierda y se extiende por todo el ancho:
#
.#########
#.########
##.#######
###.######
####.#####
#####.####
######.###
#######.##
########.#
#########.
########.#
#######.##
######.###
#####.####
####.#####
###.######
##.#######
#.########
.#########
El tablero se clasifica según la cantidad de líneas que siguen este patrón exacto desde la línea inferior. Tenga en cuenta que el orificio superior del patrón debe estar bloqueado con un bloque adicional. Si considera que la #
s y la .
s como patrón obligatorio (los espacios en blanco pueden ser cualquier cosa), puede obtener la puntuación de 19 solo si el patrón exacto anterior coincide con la línea inferior. De manera análoga, si el tablero coincide con este patrón
#
###.######
##.#######
#.########
.#########
pero no
#
####.#####
###.######
##.#######
#.########
.#########
entonces la puntuación es 4.
Para este desafío, considere una placa de tamaño arbitrario (que no sea de 20 celdas de alto y 10 de ancho). Podemos calificar la tabla para el mismo patrón: por ejemplo, si la tabla tiene un ancho de 4, este es el patrón para la puntuación 3:
#
##.#
#.##
.###
y este es el patrón para la puntuación 10:
#
###.
##.#
#.##
.###
#.##
##.#
###.
##.#
#.##
.###
Desafío
Dado el estado final del tablero de Tetris de tamaño arbitrario, califique el tablero usando el sistema anterior.
Puede tomar el tablero usando cualquier formato sensato para una matriz rectangular, donde cada celda contiene uno de dos valores distintos (para vacío y lleno respectivamente). Puede asumir que la cuadrícula es un tablero de Tetris válido (ninguna fila está completamente llena). Además, el ancho de la cuadrícula es de al menos 2.
Se aplican las reglas estándar de código de golf . El código más corto en bytes gana.
Casos de prueba
Para evitar posibles confusiones, los casos de prueba aquí se utilizan O
para los bloques y .
para espacios vacíos.
Input:
..O.O
OOOO.
OOO..
OO.OO
O.OOO
.OOOO
Output: 3
Input:
..
O.
.O
.O
O.
.O
O.
.O
Output: 4
Input:
.OOO
O.OO
OO.O
OO.O
OO.O
O.OO
.OOO
Output: 2 (any lines above the first non-conforming line are ignored;
doesn't get 3 because 3rd line's hole is not capped)
Input:
OOO.
.OOO
O.OO
OO.O
OOO.
OO.O
O.OO
Output: 0 (Wrong starting hole)
Input:
.OOO
O.OO
OO.O
OOO.
Output: 0 (Wrong starting hole)
Input:
.OOO
.OOO
Output: 0 (Hole is not covered)
Input:
OOO...O..O
.OOOOOOOOO
O.OOOOOOOO
OO.OOOOOOO
OOO.OOOOOO
OOOO.OOOOO
OOOOO.OOOO
OOOOOO.OOO
OOOOOOO.OO
OOOOOOOO.O
OOOOOOOOO.
OOOOOOOO.O
OOOOOOO.OO
OOOOOO.OOO
OOOOO.OOOO
OOOO.OOOOO
OOO.OOOOOO
OO.OOOOOOO
O.OOOOOOOO
.OOOOOOOOO
Output: 19
Respuestas
JavaScript (ES6), 84 bytes
Espera una lista de cadenas, con 1
espacios vacíos y 0
bloques.
f=(a,i=j=1<<a[k=0].length)=>(v='0b'+a.pop()+0)^i?v&i/k&&-1:1+f(a,i*=k=i&j?.5:i&2||k)
¡Pruébelo en línea!
¿Cómo?
Cada cadena de la matriz de entrada se rellena con un extra 0
y se interpreta como un número binario. La variable j
se inicializa en 2**W
, donde W
es el ancho del tablero. Usamos una máscara de bits i
inicializada para j
realizar un seguimiento de la posición esperada del agujero en el patrón.
Después de cada iteración, i
se multiplica por k
. Actualizamos el valor de k
siempre (i & j) != 0
(rebotando en el lado más a la izquierda) o (i & 2) != 0
(rebotando en el lado más a la derecha).
Ejemplo para W = 5
:
j = 0b100000
i = 0b100000 // -> set k to 1/2
i = 0b010000 // \
i = 0b001000 // }-> leave k unchanged
i = 0b000100 // /
i = 0b000010 // -> set k to 2
i = 0b000100 // \
i = 0b001000 // }-> leave k unchanged
i = 0b010000 // /
i = 0b100000 // -> set k to 1/2
...
Comentado
f = ( // f is a recursive function taking:
a, // a[] = input array
i = j = // i = hole bit mask, initialized to ...
1 << a[k = 0] // ... j = 2 ** W, where W is the width of the board
.length // k = bit mask multiplier, initialized to 0
) => //
( v = // pop the last value from a[], append a '0' and interpret
'0b' + a.pop() + 0 // it as a binary number saved in v
) ^ i ? // if v is not equal to i:
v & i / k // use the previous bit mask i / k to test whether there's
&& -1 // a hole in v above the last hole of the pattern, in
// which case we subtract 1 from the final result
: // else:
1 + // add 1 to the final result
f( // do a recursive call:
a, // pass a[] unchanged
i *= // multiply i by:
k = // the new value of k:
i & j ? // if we've reached the leftmost side:
.5 // set k to 1/2
: // else:
i & 2 // set k to 2 if we've reached the rightmost side,
|| k // or leave k unchanged otherwise
) // end of recursive call
Cáscara , 18 bytes
Lδ↑€…¢ŀT¹↑εΨ↑-↔m¥0
¡Pruébelo en línea!
Toma una matriz de 0-1.
Explicación
Hay tres apariciones de ↑
en este programa, y todas funcionan de manera diferente gracias a las funciones modificadoras δ
y Ψ
. De forma predeterminada, ↑α
espera α
ser una función unaria, toma una lista y devuelve el prefijo más largo de elementos para los que α
devuelve un valor verdadero. Ψ↑α
espera α
ser binario y devuelve el prefijo de elementos más largo x
para el que α x y
es verdadero, donde y
está el siguiente elemento. δ↑α
espera α
ser binario y toma dos listas en lugar de una. Devuelve el prefijo más largo de la segunda lista cuyos elementos y
satisfacen α x y
, donde x
es el elemento correspondiente de la primera lista.
Input is a list of lists of integers.
Example: [[0,1,1],[1,0,1],[1,1,0],[1,0,1],[1,1,0],[0,0,1],[0,1,1]]
m Map
¥0 indices where 0 occurs:
[[1],[1,2],[3],[2],[3],[2],[1]]
↔ Reverse:
[[1],[2],[3],[2],[3],[1,2],[1]]
↑ Take while
Ψ this element and the next
- have nonempty set difference:
[[1],[2],[3],[2],[3],[1,2]]
↑ Take while
ε this element is a singleton:
[[1],[2],[3],[2],[3]]
Call this list X.
ŀT¹ Indices of input transposed:
[1,2,3]
¢ Cycle infinitely:
[1,2,3,1,2,3,..]
… Rangify:
[1,2,3,2,1,2,3,2,1,..]
↑ Take from X while
δ the corresponding integer in this list
€ is an element of it:
[[1],[2],[3],[2]]
L Length: 4
Carbón , 52 bytes
WS⊞υι≔⮌υυP⪫υ¶W∧⁼.O⪫KD²↓ω⁼¹№§υⅉ.M✳⁻⁷⊗÷﹪ⅉ⊗⊖Lθ⊖Lθ≔ⅉθ⎚Iθ
¡Pruébelo en línea! El enlace corresponde a la versión detallada del código. Toma la entrada como una lista de cadenas de caracteres .
y terminada en una nueva línea O
. Explicación:
WS⊞υι
Ingrese la lista.
≔⮌υυ
Invierta la lista.
P⪫υ¶
Imprime la lista sin mover el cursor.
W∧
Repite mientras ambos ...
⁼.O⪫KD²↓ω
... el carácter debajo del cursor es ay .
el carácter debajo (porque la lista fue invertida) es an O
, y ...
⁼¹№§υⅉ.
... la línea de lista actual contiene exactamente uno .
:
M✳⁻⁷⊗÷﹪ⅉ⊗⊖Lθ⊖Lθ
Mueva el cursor en diagonal hacia abajo y hacia la derecha o hacia la izquierda según la fila.
≔ⅉθ⎚Iθ
Capture el primer índice de fila no válido (indexado con 0, es decir, igual al número de filas válidas), borre el lienzo e imprímalo como una cadena.
J , 57 42 bytes
Toma 0 para bloqueado, 1 para vacío.
[:#.~(|.@$2^|@}:@i:@<:)/@$=2#.[*[+_1|.!.2]
¡Pruébelo en línea!
Cómo funciona
[*[+_1|.!.2]
Mueva el tablero hacia abajo en uno (se empuja 2 en la parte superior para asegurarse de que los primeros lugares no cuenten). Luego, se agrega al tablero original y se multiplica por sí mismo. Básicamente, esto se reduce a: un lugar abierto válido permanece en 1, mientras que los inválidos se convierten en 2.
(|.@$2^|@}:@i:@<:)/@$
Dadas las dimensiones, obtenga el rango exclusivo -x … x - 1
para el ancho, por ejemplo, 4:, _3 _2 _1 0 1 2
y obtenga sus valores absolutos 3 2 1 0 1 2
. Cambie el tamaño de esa lista a la altura del tablero, gírela para que el 3 inicial se alinee con la última fila y 2^x
la lista:8 4 2 1 2 4 8 4 2…
=2#.
Interprete las filas como un número de base 2 y compárelo con la lista en zig-zag.
[:#.~
Y mediante la conversión de base reflexiva podemos contar los 1 iniciales, por lo que las filas iniciales son válidas.
Gelatina , 25 bytes
ZJŒḄṖṁLW€⁻"ⱮṚT€,Ḋ$ƊZḄCTḢ’
Un enlace monádico que acepta una lista de líneas donde cada línea es una lista de 1
s (vacía) 0
ys (llena) que produce un número entero no negativo (la puntuación).
¡Pruébelo en línea! O vea la suite de pruebas .
¿Cómo?
Crea una lista de los índices vacíos esperados para cada línea desde la parte inferior y la compara con cada una de las dos listas, (a) los índices vacíos reales y (b) los índices vacíos reales retirados de la cola. Los resultados de esta comparación se procesan luego para encontrar la puntuación.
ZJŒḄṖṁLW€⁻"ⱮṚT€,Ḋ$ƊZḄCTḢ’ - Link: list of lines, A
Z - transpose
J - range of length -> [1,2,...,w=#Columns]
ŒḄ - bounce -> [1,2,...,w-1,w,w-1,...,2,1]
Ṗ - pop -> [1,2,...,w-1,w,w-1,...,2]
L - length (A) -> h=#Lines
ṁ - mould like (repeat Ṗ result such that it is length h)
W€ - wrap each of these integers in a list (call this x)
Ɗ - last three links as a monad - i.e. f(A):
Ṛ - reverse (A)
T€ - for each (line) get the list of truthy ("empty") indices
$ - last two links as a monad - i.e. f(z=that):
Ḋ - dequeue (drop the leftmost)
, - (z) pair (that)
Ɱ - map across (the two results of f(A)) applying:
" - (x) zip with (result) applying:
⁻ - not equal?
Z - transpose - now we have leading [0,1]'s for valid rows
from the bottom up
Ḅ - convert from binary - now leading 1s for valid rows
C - complement (subtract (each) from one)
T - truthy indices
Ḣ - head
’ - decrement
05AB1E , 32 bytes
R©εDgݨû¨NèDU._ƶO®N>èX.__н*Θ}γнO
Ingrese como una matriz de 1 y 0, donde los 1 son espacios vacíos y los 0 son celdas llenas.
Pruébelo en línea. o verificar todos los casos de prueba .
Explicación:
R # Reverse the rows of the (implicit) input-matrix
© # Store it in variable `®` (without popping)
ε # Map over each row:
Dg # Get the width of the matrix
Ý # Push a list in the range [0,width]
¨ # Remove the last element to change the range to [0,width-1]
û # Palindromize it: [0,1,2,...,w-2,w-1,w-2,...,2,1,0]
¨ # Remove the last value: [0,1,2,...,w-2,w-1,w-2,...,2,1]
Nè # Index the map-index into this list
DU # Store a copy in variable `X`
._ # Rotate the current row that many times to the left
ƶ # Multiply each value by its 1-based index
O # And sum this list
® # Push the reversed input-matrix again from variable `®`
N>è # Index the map-index + 1 into this to get the next row
X._ # Also rotate it `X` amount of times towards the left
_ # Invert all booleans (1s becomes 0s, and vice-versa)
н # And only leave the first value
* # Multiply both together
Θ # And check that it's equal to 1 (1 if 1; 0 otherwise)
}γ # After the map: split the list into groups of adjacent equivalent values
н # Only leave the first group
O # And take the sum of that
# (after which it is output implicitly as result)