Bulmacayı Kaydırabilir miyim?


38

Her hücrenin bir Aveya a olduğu, dikdörtgen bir metin ızgarası alan bir program veya işlev yazın B. Tüm Ahücreler basit bir şekilde bağlı bir şekil oluşturacak, yani hepsi deliksiz olarak ortogonal olarak bağlanacaktır (diyagonal olarak komşu harfler bağlı olarak sayılmaz). Aynı şekilde, tüm Bhücreler basit bir şekilde bağlantılı bir şekil oluşturur. Izgara her zaman en az bir Ave en az bir tane içerecektir B.

Şebekenin gerçekte Ave Bbölümleriyle temsil edilen iki blok şeklinde ince plastik parçası olduğunu düşünün . Masanın üzerine düz bir şekilde yerleştirildiyse, her ikisi de masanın üzerinde tamamen düz dururken iki parça birbirinden kaydırılabilir mi?

Eğer iki ve şekiller bu şekilde birbirinden ayrılarak ayrılabilirse , gerçek değeri yazdırın ya da iade edin . Değilse, sahte bir değer yazdırın veya döndürün .AB

Örneğin, giriş

AAA
ABB
AAA

kesinliklidir çünkü BBbölüm sağa kaydırılabilir, böylelikle ayrılarak A:

AAA
A    BB
AAA

Ancak, giriş

AAAA
ABBA
ABAA

kaymasına bir yolu yoktur, çünkü falsy olan Ave Bonları üst üste kalmadan ayrı kısımları.

Bayt cinsinden en kısa kod kazanır. İstenirse, yerine ve yerine iki farklı yazdırılabilir ASCII karakteri kullanabilirsiniz .AB

Truthy Örnekleri (boş satırlarla ayrılmış)

BBB
BAA
BBB

BA

A
B

AB
AB

AAA
BBB

AAAAB
ABBBB

ABBA
ABBA
AAAA

AAAAAABBBBBBBBB
AABBBBBBBBBBBBB
AAAAAAAAAABBBBB
AABBBBBBBBBBBBB
AAAAAAAAAAAAAAB

AAAAAAAAAAAA
ABABABABABAB
BBBBBBBBBBBB

BAAAAABB
BBAAABBB
BBBABBBB
BBBABBBB
BBBABBBB
BBBBBBBB
BBBBBBBB

AAA
BAA
AAA

Sahte Örnekler

BBBB
BAAB
BABB

BBBB
BAAB
AABB

BBBBBBB
BBBBBAB
AAAAAAB
BBBBBBB

BAAA
BABA
BBBA
AABA
AAAA

AAAAAAA
ABBBBBA
AAAAABA
BBBBBBA

BAAAAABB
BBAAABBB
BBBABBBB
BBBABBBB
BBBAABBB
BBBBBBBB
BBBBBBBB

AAA
ABA
BBA
ABA
AAA

Yanıtlar:


9

Salyangozlar, 14

o(t\B+~)+!(t\B

Bulmaca ayrılabilirse, girişin alanını yazdırır. Aksi takdirde, 0 yazdırır.

Daha büyük örnekler için biraz yavaş, çünkü ızgara alanında faktoring zaman alır.

         ,, the program will print the number of starting cells matching this pattern
o        ,, pick a cardinal direction
(
    t    ,, teleport to any cell on the grid
    \B+  ,, match "B" 1 or more times, moving in the direction set by 'o'.
         ,, when a cell is matched, it gets slimed and can't be matched again.
    ~    ,, match an out-of-bounds cell
)+       ,, do parenthesized instructions 1 or more times
!(       ,, the following must not match:
    t\B  ,, teleport to some cell and match 'B'

4
“Biraz yavaş ..” . Snails adlı bir dilden beklediğinizden emin değilim ...
Bassdrop Cumberwubwubwub 14:15

4
@Bas Şimdi, yaralara tuz ovmak için hiçbir sebep yok.
Trasiva

21

CJam, 33 32 20 19 17 bayt

@ Sp3000 ve @ MartinBüttner'den büyük destekle revize edilmiş versiyon:

qN/_z]{:e`z,3<}/|

Çevrimiçi deneyin

Katılımlar

  • @ Sp3000, orijinal algoritmam için kritik bir basitleştirme önerdi.
  • @ MartinBüttner, çılgın golf becerilerini revize edilmiş yaklaşıma uyguladı; bu da sadeleştirmeyi düşündükten sonra bile elde edebileceğimden daha kısa bir kodla sonuçlandı.

Algoritma ve Kanıt

Aşağıda, yatayda kaymakta olan bulmacanın kriterleri açıklanmaktadır. Dikey durum, satırlar yerine sütunlara bakılarak veya karakter matrisinin çevrilerek ve satırlara tekrar bakılarak belirlenebilir.

Aynı harfin azami bir sırası için "stretch" terimini kullanacağım. Örneğin, aşağıdaki satırlar sırasıyla 1, 2 ve 3 uzatmaya sahiptir:

AAAAAAAA
BBBAAAAA
AABBBAAA

Ayrılamayacak bir satır / bulmaca için "kilitli" terimini de kullanacağım.

Kilit gözlem, bulmacanın yalnızca tüm satırların en fazla 2 uzaması durumunda kayar olmasıdır . Veya tersi çevrilmişse, sadece 2'den fazla uzanan bir satır varsa ve eğer varsa kilitlenir .

Aşağıdakiler katı bir matematik kanıtı olarak nitelenmeyebilir, ancak bunun neden böyle olması gerektiğine dair ikna edici bir açıklama getirdiğine inanıyorum.

2'den fazla esneme sırasına sahipse, bulmacanın kilitlendiğini görmek kolaydır. 3 uzatma ile üst üste bakmak:

BBBAAB

Astreç streçler arasında kilitli olduğu için yapbozun kaymasını önlediği açıktır B. Bu, sıranın kilitli olduğu anlamına gelir, bu da sırayla bütün bulmacayı birbirine kilitler.

İspatın zıt yönü tam olarak belli değil. Tüm satırların yalnızca 1 veya 2 uzanma olduğu kilitli bir bulmaca olmadığını göstermemiz gerekir. Birkaç gözlemle başlayarak:

  • Yalnızca 1 uzatmalı satırlar, her iki yönde de çarpışma olmadan kayabilecekleri için bir yapbozun birbirine kilitlenmesine katkıda bulunmaz.
  • 2 menziller tüm satırları aynı sırada varsa Ave B, bulmaca açıkça kenetlenmiş değildir. Bu durumda, tüm Ahücreler tüm Bhücrelerin dışında kalır veya tam tersidir ve iki parçayı birbirinden kaydırırken çarpışma olmaz.

Tek zor durum, 2 farklı düzene sahip sıralara sahip olduğumuz bulmacalardır. Bu tür bulmacaların verilen şartnamelerde bulunmadığını göstereceğim . Bunu göstermek için ., joker karakterler olan , bu yapılandırmaya sahip kısmi bir bilmeceye bakalım :

.......
AAABBBB
.......
BBAAAAA
.......

Şimdi, şartname hem söylüyor Ave Bhücreler sadece tüm geçerli bulmaca bağlanır. AYukarıdaki kısmi bulmacaya bağlı hücreleri yapmak için iki seçeneğimiz var:

  1. BÖrneğin , uzantılarından birinin etrafında dönüyoruz :

    ..AAAAAA
    AAABBBBA
    .......A
    BBAAAAAA
    ........
    

    Bunu yapmak için, kaçınılmaz bir şekilde satırlardan birini 3 uzatmak için genişletiyoruz, bu nedenle bu bize asla tüm satırların en fazla 2 uzatmaya sahip olduğu geçerli bir bilmece sunmayacak.

  2. Onları doğrudan bir yola bağlarız:

    .......
    AAABBBB
    ..A....
    BBAAAAA
    .......
    

    AHücreler artık sadece bağlanır ve 2'den fazla menziller ile hiçbir satır hala vardır. Bununla birlikte, Bhücrelerin de basit bir şekilde bağlanması gerekir. Doğrudan yol şimdi bağlı Ahücreler tarafından engellenir ve Bhücreleri bağlamanın tek yolu, hücre uzantılarından birinin etrafında dolaşmaktır A. Bu, 3 genişletme satırları oluşturmadan bunu yapamayacağımız vaka 1'e geri döner.

Uzamaları saymak için uygulama CJam RLE operatörünü kullanır.

Kod açıklaması

qN/     Get input and split at newlines.
_z      Make a transposed copy.
]       Wrap the original and transposed puzzle in an array so that we can
        loop over the two.
{       Start of loop over original and transposed puzzle.
  :e`     Apply RLE to all rows.
  z,      Transpose the matrix with the RLE rows, and take the element count of the
          result. Or in other words, take the column count. This will be the length
          of the longest row after RLE.
  3<      Check the length for less than 3.
}/      End of loop over original and transposed puzzle.
|       Or the results of the two.

9

JavaScript (ES6), 108 107 98 91 82 bayt

a=>!(T=[],R=/AB+A|BA+B/).test([...a].map((c,i)=>T[i%-~a.search`
`]+=c))|!R.test(a)

Canlı demo . Firefox'ta test edildi. Girdiyi yeni satır sınırlı dizge olarak alır.

Düzenlemeler:

  • \nDeğişmez bir yeni satıra geçerek 1 bayt kurtarıldı .
  • RegExp sınamasını bir diziye dönüştürmek yerine doğrudan çok satırlı dizgede yaparak 9 bayt kurtardı.
  • Dize bölmek için hareket eden! içine gfonksiyon ve dizi doğrudan Normİfd aramak yerine kullanarak find.
  • Başka bir 9 byte kaydederek, artitik sıralamaya devam etti. Transpoze almadan önce diziyi yeni satırlara bölmek yerine dizinde bir modül yaptınız.

Nasıl çalışır

Önceki versiyon:

a=>(T=[],a.split`
`.map(s=>s.split``.map((c,i)=>T[i]+=c)),!T.find(g=s=>/AB+A|BA+B/.test(s)))|!g(a)
  1. Girdiyi alın ave yeni satırlara dizge dizisine bölün.
  2. Devret ave sakla T. Kullanım mapher öğesi üzerinde yineleme yapmak a, bir karakter diziye dize bölmek ve kullanmak mapeklenecek tekrar iiçin sıraya inci karakter iinci hattı T. Her bir unsuru Tbaşlatılamadığından, bunun gibi bir şeye bakacak "undefinedAAABBA", ancak bu önemli değil.
  3. Desene guyan bir RegExp tabanlı test işlevi oluşturun /AB+A|BA+B/. Eşleşirse, parçalar belirli bir yöne kilitlenir, çünkü o zaman Biki veya daha fazla As arasına sıkıştırılmış bir dizi s vardır .
  4. gBloğun tüm öğelerini test etmek için test işlevini ave Tbir eşleşmeyi kullanarak devrik yapısını test edin find. Her ikisi de eşleşirse, parçalar her iki yönde de kilitlenir, bu nedenle sahte bir değer, aksi halde bir truthy değeri verilir.

5

Javascript (ES6), 118

slidey=
// code
a=>!a.match(R=/AB+A|BA+B/)||!(a=a.split`
`.map(b=>b.split``))[0].map((_,c)=>a.map(d=>d[c])).some(e=>e.join``.match(R))

// IO
var S =document.getElementById('S');
S.onkeyup = _=> document.getElementById('P').innerText = slidey(S.value);

document.getElementById('P').innerText = slidey(S.value);
<textarea id='S'>BAAAAABB
BBAAABBB
BBBABBBB
BBBABBBB
BBBABBBB
BBBBBBBB
BBBBBBBB</textarea>
<p id='P'></p>

Açıklama:

a=> !/* check string horizontally */ || !/* check string vertically by transposing it and
                                            running the same horizontal check */

a=> !a.match(R=/AB+A|BA+B/) || !/* ... */
// check for lines containing something like BAAAAAB or ABBBBBBBA
// this is the only way something can get blocked horizontally
// eg AAAAAAA
//    AAABAAA <<< note the B in the middle of As here
//    AAABBBB <<< blocked from being pulled out horizontally
//    AAAAAAA

a=> /* ... */ ||!( a = a.split('\n').map(b=> b.split('')) ) // split a into 2D array
    [0].map((_,c)=>a.map(d=>d[c])) // transpose it
    .some(e=>e.join``.match(R)) // run the check again using `some` to go line by line
                                // which is shorter than .join().match() outside

a=> !/* returns null if no horizontal obstacles and an array if there are */
    || !/* same thing */
// negate both to cast to a boolean (false if obstacles, true if not)
// an input can only be unslidable if both directions are blocked
// so (no obstacles vertically? || no obstacles horizontally?) gives the answer

Sıçanlar! Beni yen.
intrepidcoder 14:15

5

JavaScript (ES6) 72 74

2 bayt düzenle thx @NotthatCharles kaydetti

Sezgisel bir anlayışa sahibim, eğer bir parça sadece bir adım adım kayabilirse, o zaman serbesttir. Mevcut test durumları bunu onaylar.

Bu yüzden her yöne sadece bir adım kontrol ediyorum.

Kullanılan karakterler:
A ve B gibi yazdırılabilir 2 karakteri kullanmak için 1 ve 0 2 bayt daha

Aşağıdaki pasajı EcmaScript 6 uyumlu bir tarayıcıda çalıştırmayı test edin (spread operatörünü - IE Firefox)

f=s=>[w=~s.search`
`,-w,-1,1].some(o=>![...s].some((x,p)=>x+s[p+o]==10))

// 4 bytes more- for any symbol, not just 1 and 0 (for instance A and B):
g=s=>[w=~s.search`
`,-w,-1,1].some(o=>![...s].some((x,p)=>x+s[p+o]=='AB'))

//TEST
console.log=x=>O.innerHTML+=x+'\n'

testOk = [
 '111\n100\n111',
 '10',
 '0\n1',
 '01\n01',
 '000\n111',
 '00001\n01111',
 '0110\n0110\n0000',
 '000000111111111\n001111111111111\n000000000011111\n001111111111111\n000000000000001',
 '000000000000\n010101010101\n111111111111',
 '10000011\n11000111\n11101111\n11101111\n11101111\n11111111\n11111111',
 '000\n100\n000'
]

testKo = [
 '1111\n1001\n1011',
 '1111\n1001\n0011',
 '1111111\n1111101\n0000001\n1111111',
 '1000\n1010\n1110\n0010\n0000',
 '0000000\n0111110\n0000010\n1111110',
 '10000011\n11000111\n11101111\n11101111\n11100111\n11111111\n11111111',
 '000\n010\n110\n010\n000'
]

console.log('Expecting true')
testOk.forEach(t=>console.log(t+'\n'+f(t)+'\n'))
console.log('Expecting false')
testKo.forEach(t=>console.log(t+'\n'+f(t)+'\n'))
<pre id=O></pre>


Bu sadece bir dahi. Bir profesyonel tarafından tekrar dövüldü. :-)
ETHproductions

s[p+o]=='0'biraz uzun görünüyor. 1-s[p+o]En azından ile değiştirilebilir s[p+o]==0mi?
ETHProductions,

@ETHproductions evet, uzun, biraz daha düşünmeye değer. '\ N' (dikey kenarlık, 0'a dönüşür) ve tanımsız (üst ve alt kenarlık,
NaN'ye

=='A'tarafından değiştirilebilir <'B'. Aynı şey =='B'
değil

Ayrıca, yapamaz x+s[p+o]=='AB'mısın?
Charles,

3

Mathematica 100 69 bayt

@Martin Buttner sayesinde devasa 31 byte kurtarıldı,

g=Max[Length/@Split/@#]<3&;g[c=Characters@StringSplit@#]||g@Thread@c&

Girişi karakter matrisi olarak biçimlendirir; Aynı zamanda matrisin bir devri yapar. Eğer matris ya da transpozisyonu her satırda 2'den fazla koşuya sahip değilse, bulmaca kayabilir.

{a,a,b,b,b} 2 harf harften oluşur.

{a,a,b,a,a} 3 harf harften oluşur.

{a,a,b,a,a,a,b,b,b,b,b,b,b,b} 4 harf harften oluşur.


2

Dyalog APL, 22 bayt

(∨/{∧/2>+/2≠/⍵}¨)⊂∘⍉,⊂

Burada dene. Bu, 2B karakter dizisini alan ve 1kayan örnekler için ve 0kayan olmayan karakterler için döndüren bir işlevdir . Algoritma diğer cevapların çoğuna benzer: matrisi kontrol edin ve satırının hiçbir satırın bitişik birden fazla farklı harf içermediğini aktarmasını sağlayın. 4x3 giriş matrisi için

AAAA
ABBB
AAAB

işlev olarak çağrılabilir

f ← (∨/{∧/2>+/2≠/⍵}¨)⊂∘⍉,⊂
f 4 3 ⍴ 'AAAAABBBAAAB'

hangi sonuçlanır 1.

açıklama

⊂∘⍉,⊂   The matrix and its transpose.
{...}¨   For each of them:
  2≠/⍵   On each row, replace each adjacent pair with 1 if they differ, with 0 otherwise
  2>+/    Take the sum on each row and check that it's less than 2
  ∧/     AND over all rows
∨/      OR over the resulting two values

1

JavaScript (ES6), 94 bayt

x=>!(y=/AB+A|BA+B/).test(x)|(z=[],x.split`
`.map(b=>b.split``.map((c,i)=>z[i]+=c)),!y.test(z))

Aynı boyutta alternatif yöntem:

x=>(t=s=>!/AB+A|BA+B/.test(s),z=[],x.split`
`.map(b=>b.split``.map((c,i)=>z[i]+=c)),t(x)|t(z))

Bu 1bir truthy girişi ve sahte için geri döner 0. Başka cevaplar gönderilmeden önce bu konuda çalışmaya başladım. Ayrıca başlangıçta ES7'nin dizi anlamalarını kullanmayı denedim, ancak bu yöntem bu yöntemden 10 karakter daha uzun sürdü.

Denemek:

a=x=>!(y=/AB+A|BA+B/).test(x)|(z=[],x.split`
`.map(b=>b.split``.map((c,i)=>z[i]+=c)),!y.test(z))

P.onclick=_=>Q.innerHTML='Result: '+a(O.value)
<textarea id=O cols="20" rows="8">AAAAAABBBBBBBBB
AABBBBBBBBBBBBB
AAAAAAAAAABBBBB
AABBBBBBBBBBBBB
AAAAAAAAAAAAAAB</textarea>
<button id=P>Test</button>
<p id=Q>Result: </p>

Önerilerinizi bekliyoruz!


B.split`` yerine [... b] kullanarak 3 bayt kaydeder, ancak yalnızca bazı tarayıcılarda çalışır.
intrepidcoder
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.