Gizli ">" İstifleme Zorluğu: derecelendirme
Arka fon
Tetris Grand Master 3 , Gizli ">" İstifleme Mücadelesi olarak adlandırılan, oyunun sonunda yığının şekline göre gizli bir derecelendirme sistemine sahiptir . Sol alttaki hücreden başlayan ve tüm genişliğe yayılan zikzak deseni haricinde en alttaki satırların tamamen doldurulmasından oluşur:
#
.#########
#.########
##.#######
###.######
####.#####
#####.####
######.###
#######.##
########.#
#########.
########.#
#######.##
######.###
#####.####
####.#####
###.######
##.#######
#.########
.#########
Tahta, alt satırdan bu tam deseni takip eden kaç satıra göre derecelendirilir. Desendeki en üstteki deliğin fazladan bir blok parçasıyla kapatılması gerektiğini unutmayın. #
S ve .
s'leri zorunlu kalıp olarak kabul ederseniz (boşluklar herhangi bir şey olabilir), 19 puanını ancak yukarıdaki modelin alt satırdan tam olarak eşleşmesi durumunda alabilirsiniz. Benzer şekilde, kart bu modele uyuyorsa
#
###.######
##.#######
#.########
.#########
Ama değil
#
####.#####
###.######
##.#######
#.########
.#########
o zaman skor 4'tür.
Bu zorluk için, rastgele boyutta bir tahta düşünün (20 hücre yüksekliğinde ve 10 hücre genişliğinden farklı). Tahtayı aynı kalıp için derecelendirebiliriz: örneğin, tahtanın genişliği 4 ise, bu, puan 3'ün kalıbıdır:
#
##.#
#.##
.###
ve bu, skor 10'un kalıbı:
#
###.
##.#
#.##
.###
#.##
##.#
###.
##.#
#.##
.###
Meydan okuma
Tetris panelinin rastgele boyuttaki son durumu göz önüne alındığında, yukarıdaki sistemi kullanarak panoyu derecelendirin.
Tahtayı, her hücrenin iki farklı değerden birini içerdiği dikdörtgen bir matris için herhangi bir mantıklı formatı kullanarak alabilirsiniz (sırasıyla boş ve dolu için). Izgaranın geçerli bir Tetris tahtası olduğunu varsayabilirsiniz (hiçbir satır tamamen doldurulmamıştır). Ayrıca ızgaranın genişliği en az 2'dir.
Standart kod-golf kuralları geçerlidir. Bayt cinsinden en kısa kod kazanır.
Test durumları
Olası karışıklığı önlemek için, buradaki test senaryoları O
bloklar ve .
boş alanlar için kullanılır.
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
Yanıtlar
JavaScript (ES6), 84 bayt
1
Boş alanlar ve 0
bloklar için dizelerin bir listesini bekler .
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)
Çevrimiçi deneyin!
Nasıl?
Giriş dizisindeki her dizge bir ekstra ile doldurulur 0
ve ikili sayı olarak yorumlanır. Değişken j
, panonun genişliği 2**W
nerede olacak şekilde başlatılır W
. i
Modeldeki j
deliğin beklenen konumunu takip etmek için başlatılmış bir bit maskesi kullanıyoruz .
Her yinelemeden sonra i
ile çarpılır k
. Her k
zaman (i & j) != 0
(en sol tarafta (i & 2) != 0
sıçrayan ) veya (en sağdaki zıplayan ) değerini güncelliyoruz .
Örnek 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
...
Yorum yaptı
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
Kabuk , 18 bayt
Lδ↑€…¢ŀT¹↑εΨ↑-↔m¥0
Çevrimiçi deneyin!
0-1 matrisi alır.
Açıklama
↑
Bu programda üç oluşum vardır ve bunların hepsi değiştirici işlevleri sayesinde farklı çalışır δ
ve Ψ
. Varsayılan olarak, tekli bir işlev olmayı ↑α
bekler α
, bir listeyi alır ve kendisi α
için doğru bir değer döndüren öğelerin en uzun önekini döndürür. Ψ↑α
beklediği α
ikili olacak ve elementlerin en uzun önek döndüren için x
hangi α x y
nerede, truthy olan y
bir sonraki unsurdur. ikili δ↑α
olmasını bekler α
ve bir yerine iki liste alır. Öğeleri y
karşılayan ikinci listenin en uzun önekini döndürür α x y
, burada x
birinci listenin karşılık gelen öğesi bulunur.
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
Kömür , 52 bayt
WS⊞υι≔⮌υυP⪫υ¶W∧⁼.O⪫KD²↓ω⁼¹№§υⅉ.M✳⁻⁷⊗÷﹪ⅉ⊗⊖Lθ⊖Lθ≔ⅉθ⎚Iθ
Çevrimiçi deneyin! Bağlantı, kodun ayrıntılı sürümüne yöneliktir. Girişi, karakter dizilerinin .
ve O
karakterlerinin yeni satır sonlu listesi olarak alır . Açıklama:
WS⊞υι
Listeyi girin.
≔⮌υυ
Listeyi ters çevirin.
P⪫υ¶
İmleci hareket ettirmeden listeyi yazdırın.
W∧
İkisi de tekrarlayın ...
⁼.O⪫KD²↓ω
... imlecin altındaki karakter a'dır .
ve aşağıdaki karakter (çünkü liste ters çevrilmiştir) O
, ve ...
⁼¹№§υⅉ.
... mevcut liste satırı tam olarak bir tane içerir .
:
M✳⁻⁷⊗÷﹪ⅉ⊗⊖Lθ⊖Lθ
İmleci, satıra bağlı olarak çapraz olarak aşağı ve sağa veya sola hareket ettirin.
≔ⅉθ⎚Iθ
İlk geçersiz satır dizinini yakalayın (0 dizinli, dolayısıyla geçerli satırların sayısına eşit), tuvali temizleyin ve bir dize olarak yazdırın.
J , 57 42 bayt
Bloke için 0, boş için 1 alır.
[:#.~(|.@$2^|@}:@i:@<:)/@$=2#.[*[+_1|.!.2]
Çevrimiçi deneyin!
Nasıl çalışır
[*[+_1|.!.2]
Tahtayı bir aşağı kaydırın (üstteki noktaların sayılmadığından emin olmak için 2 üste itilir.) Sonra orijinal tahtaya eklenir ve kendisiyle çoğalır. Bu temelde şu şekilde azalır: geçerli bir açık nokta 1 kalır, geçersiz olanlar 2 olur.
(|.@$2^|@}:@i:@<:)/@$
Boyutlar göz önüne alındığında, -x … x - 1
örneğin 4: için özel genişlik aralığını _3 _2 _1 0 1 2
ve mutlak değerlerini alın 3 2 1 0 1 2
. Bu listeyi panonun yüksekliğine göre yeniden boyutlandırın, döndürün böylece ilk 3 son satıra ve 2^x
listeye hizalanır :8 4 2 1 2 4 8 4 2…
=2#.
Satırları 2 temelli sayı olarak yorumlayın ve zig-zag listesiyle karşılaştırın.
[:#.~
Ve dönüşlü taban dönüştürme ile baştaki 1'leri sayabiliriz, yani baştaki satırlar geçerlidir.
Jöle , 25 bayt
ZJŒḄṖṁLW€⁻"ⱮṚT€,Ḋ$ƊZḄCTḢ’
Her satırın bir 1
s (boş) ve 0
s (doldurulmuş) listesi olduğu ve negatif olmayan bir tam sayı (puan) veren satırların bir listesini kabul eden bir monadik Bağlantı .
Çevrimiçi deneyin! Veya test süitine bakın .
Nasıl?
Her satır için en alttan beklenen boş dizinlerin bir listesini oluşturur ve bunu iki listenin her biriyle (a) gerçek boş dizinler ve (b) kuyruğa alınmış gerçek boş dizinler ile karşılaştırır. Bu karşılaştırmanın sonuçları daha sonra puanı bulmak için işlenir.
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 bayt
R©εDgݨû¨NèDU._ƶO®N>èX.__н*Θ}γнO
1'lerin boş boşluklar ve 0'ların dolu hücreler olduğu 1'ler ve 0'lardan oluşan bir matris olarak giriş.
Çevrimiçi deneyin. veya tüm test durumlarını doğrulayın .
Açıklama:
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)