Bir Bejeweled / maç 3 oyununda bir hamle olup olmadığını belirleme


20

Arka fon

Bejeweled ve benzeri oyunlarda, oyuncu arka arkaya üç rengin eşleşmesi için 8x8 değerli bir ızgarada iki bitişik taşı (köşegen yok) değiştirmelidir. Taşlar yatay veya dikey olarak eşleştirilebilir. Oynanış, arka arkaya üç oyunun sonuçlanabileceği hiçbir hareket kalmayıncaya kadar devam eder, bu noktada oyun sona erer.

Görev

Amaç, bir Bejeweled oyununun henüz bitip bitmediğini belirleyen bir program yazmaktır. Başka bir deyişle, arka arkaya en az üç tane yapan olası bir hareket olup olmadığını kontrol etmelidir. Arka arkaya üçten fazla mücevher olabilir ve hala geçerli bir harekettir.

Giriş

Programınız standart giriş ile Bejeweled ızgarasının 8x8 gösterimini kabul etmelidir. Yedi mücevher renginin her biri 1'den 7'ye kadar bir rakamla temsil edilecektir. Her satır bir satır içerecek ve her biri 8 rakamdan oluşan 8 satır girilecektir. Örneklere bakın. Girdinin her zaman bu biçimi izleyeceğini ve hiçbir zaman art arda üç tane içermeyeceğini varsayabilirsiniz.

Çıktı

Program daha sonra çıktı almalı (standart çıktıya) yesveya nobir satırda üç veya daha fazla taşla sonuçlanacak en az bir geçerli hareket olup olmamasına bağlı olarak. Programınız ya tek bir örneği dışındaki çıkış şey olmamalıdır yesya no.

kurallar

Programınız harici dosyalar veya kaynaklar, komut satırı bağımsız değişkenleri kullanmamalı veya belirli bir dosya adı gerektirmemelidir. Kaynak kodunda en az bayt sayısı olan program kazanır.

Örnekler

Giriş:

12314131
13224145
54762673
61716653
61341144
23453774
27645426
75575656

Çıktı: yes

Giriş:

35261546
76421754
15743271
62135642
35617653
64565476
54427254
15635465

Çıktı: no

Bkz aşağıda MT0 yanıtını ek test durumları için.


Sadece satır mı yoksa sütun mu?
TheDoctor

@TheDoctor Sütunları da. "Arka arkaya üç" ifadesini kullandığımda, yatay veya dikey yönde sıralanması gerektiği anlamına gelir.
bdr9

@ bdr9 bunu düzenlemek isteyebilirsiniz
John Dvorak

@JanDvorak Bitti.
bdr9

Ayrıca, arka arkaya 4+ seçeneğine izin veriliyorsa düzenlemek de isteyebilirsiniz.
Justin

Yanıtlar:


12

Orijinal Çözüm: JavaScript - 261 255 228 227 179 153 Karakterler

/(\d)(\1(\d|.{6}|.{9})|(\d|.{6}|.{9})\1|.{7}\1(.|.{9})|(.|.{9})\1.{7}|(.{7,9}|.{17})\1.{8}|.{8}\1(.{7,9}|.{17}))\1/.test(s.replace(/\n/g,'A'))?'yes':'no'

Testine dize değişkeni olduğunu varsayarsak s(bir işlev yapmak fsonra ekleyin f=s=>sonra yerini bir istem girdi almak, aksi takdirde, kod ya başlangıcına sile prompt()).

Çıkışlar konsola gelir.

3 rd Çözüm: JavaScript (ECMAScript 6) - 178 Karakterler

p=x=>parseInt(x,36);for(t="2313ab1b8a2a78188h9haj9j8iaiir9r",i=v=0;s[i];i++)for(j=0;t[j];v|=s[i]==s[i+a]&s[i]==s[i+b]&i%9<8&(b>3|(i+b-a)%9<8))a=p(t[j++]),b=p(t[j++]);v?'yes':'no'

Aşağıdaki 2. çözümü aldım (belirli yapılandırmalardaki karakterleri kontrol etmek için düzenli ifadeler kullanır) ve düzenli ifadeler kullanmadan aynı yapılandırmalardaki özdeş karakterleri dizede kontrol etmek için yeniden çalıştım.

Baz-36 dizisi "2313ab1b8a2a78188h9haj9j8iaiir9r", yani çift - ofsetlerin çiftleri kontrol etmek veren 23sonuçlar kontrol i ise inci karakter (i + 2) aynı olan inci karakter ve (i + 3) inci karakter (normal ifade eşdeğer (.).\1\1- aynı olmayan karakterin yeni satır olmadığından emin olmak için bazı ek denetimlerle).

2 nd Çözüm: JavaScript (ECMAScript 6) - 204 Karakterler

p=x=>parseInt(x,18);g=a=>a?a>1?"(.|\\n){"+a+"}":".":"";f=(x,a,b)=>RegExp("(.)"+g(a)+"\\1"+g(b)+"\\1").test(x);for(t="10907160789879h8",i=v=0;t[i];v|=f(s,x,y)||f(s,y,x))x=p(t[i++]),y=p(t[i++]);v?'yes':'no'

Base-18 dizesinden alınan değer çiftlerini kullanarak birden fazla normal ifade oluşturur (daha fazla ayrıntı için aşağıya bakın) 10907160789879h8ve ORtüm testleri alır. Daha da azaltmak için, normal ifadelerin birinin diğerinin "tersi" olduğu çiftler halinde geldiğini not edebilirsiniz (OP'nin hiç olmayacaklarını belirttiği için 3'lü satırda Normal İfadeleri yatay ve dikey olarak görmezden gelmek - bu testleri 0088Base-18 dizesine ekte tekrar eklemek isterseniz ).

açıklama

Geçerli hamlelerin tüm olası yapılandırmalarını kapsayan 16 normal ifade ile başlayın:

REs=[
    /(\d)\1\1/,                 // 3-in-a-row horizontally
    /(\d).\1\1/,                // 3-in-a-row horizontally after left-most shifts right
    /(\d)\1.\1/,                // 3-in-a-row horizontally after right-most shifts left
    /(\d)(?:.|\n){9}\1\1/,  // 3-in-a-row horizontally after left-most shifts down
    /(\d)(?:.|\n){7}\1.\1/, // 3-in-a-row horizontally after middle shifts down
    /(\d)(?:.|\n){6}\1\1/,  // 3-in-a-row horizontally after right-most shifts down
    /(\d)\1(?:.|\n){6}\1/,  // 3-in-a-row horizontally after left-most shifts up
    /(\d).\1(?:.|\n){7}\1/, // 3-in-a-row horizontally after middle shifts up
    /(\d)\1(?:.|\n){9}\1/,  // 3-in-a-row horizontally after right-most shifts up
    /(\d)(?:.|\n){7,9}\1(?:.|\n){8}\1/, // 3-in-a-row vertically (with optional top shifting left or right)
    /(\d)(?:.|\n){7}\1(?:.|\n){9}\1/,   // 3-in-a-row vertically after middle shifts right
    /(\d)(?:.|\n){9}\1(?:.|\n){7}\1/,   // 3-in-a-row vertically after middle shifts left
    /(\d)(?:.|\n){8}\1(?:.|\n){7}\1/,   // 3-in-a-row vertically after bottom shifts right
    /(\d)(?:.|\n){8}\1(?:.|\n){9}\1/,   // 3-in-a-row vertically after bottom shifts left
    /(\d)(?:.|\n){17}\1(?:.|\n){8}\1/,  // 3-in-a-row vertically after top shifts down
    /(\d)(?:.|\n){8}\1(?:.|\n){17}\1/,  // 3-in-a-row vertically after bottom shifts up
];

( Not: 3-in-a-satır yatay (0 regexs th ) ve dikey olarak 9 (parça th ) bu eşleme girişleri mevcut asla OP durumları gibi dışındadır. )

Bunların her birinin girişe karşı test edilmesi, söz konusu yapılandırmanın geçerli bir hareketinin bulunup bulunamayacağını belirler.

Bununla birlikte, düzenli ifadeler bu 6'yı vermek için birleştirilebilir:

/(\d)(?:.|(?:.|\n){9}|(?:.|\n){6})?\1\1/            // Tests 0,1,3,5
/(\d)\1(?:.|(?:.|\n){9}|(?:.|\n){6})?\1/            // Tests 0,2,6,8
/(\d)(?:.|\n){7}\1(?:.|(?:.|\n){9})\1/              // Tests 4,10
/(\d)(?:.|(?:.|\n){9})\1(?:.|\n){7}\1/              // Tests 7,11
/(\d)(?:(?:.|\n){7,9}|(?:.|\n){17})\1(?:.|\n){8}\1/ // Tests 9,14
/(\d)(?:.|\n){8}\1(?:(?:.|\n){7,9}|(?:.|\n){17})\1/ // Tests 9a,12,13,15

Bunlar daha sonra tek bir normal ifadede birleştirilebilir:

/(\d)(?:.|(?:.|\n){9}|(?:.|\n){6})?\1\1|(\d)\2(?:.|(?:.|\n){9}|(?:.|\n){6})?\2|(\d)(?:.|\n){7}\3(?:.|(?:.|\n){9})\3|(\d)(?:.|(?:.|\n){9})\4(?:.|\n){7}\4|(\d)(?:(?:.|\n){7,9}|(?:.|\n){17})\5(?:.|\n){8}\5|(\d)(?:.|\n){8}\6(?:(?:.|\n){7,9}|(?:.|\n){17})\6/

Hangi sadece girişe karşı test edilmesi gerekiyor.

Test Durumları

Diğer kişilerin yararlı bulabileceği bazı test senaryoları (yalnızca 1-7 rakamlarını kullanma giriş formatına uymaz, ancak bu kolayca düzeltilebilir ve sadece 8x4 ızgaradır - çünkü bu, tüm geçerli girişlerin testi için minimumdur. ).

Girdi dizesinden, üstündeki 16 normal ifadenin eşleştiği bir harita biçiminde.

Tests={
    "12345678\n34567812\n56781234\n78123456": -1, // No Match
    "12345678\n34969912\n56781234\n78123456": 1,    // 3-in-a-row horizontally after left-most shifts right 
    "12345678\n34567812\n59989234\n78123456": 2,    // 3-in-a-row horizontally after right-most shifts left
    "12345978\n34567899\n56781234\n78123456": 3,    // 3-in-a-row horizontally after left-most shifts down
    "12345978\n34569892\n56781234\n78123456": 4,    // 3-in-a-row horizontally after middle shifts down
    "12345678\n34967812\n99781234\n78123456": 5,    // 3-in-a-row horizontally after right-most shifts down
    "12399678\n34967812\n56781234\n78123456": 6,    // 3-in-a-row horizontally after left-most shifts up
    "12345678\n34597912\n56789234\n78123456": 7,    // 3-in-a-row horizontally after middle shifts up
    "12345998\n34567819\n56781234\n78123456": 8,    // 3-in-a-row horizontally after right-most shifts up
    "12945678\n34597812\n56791234\n78123456": 9,    // 3-in-a-row vertically after top shifts right
    "12349678\n34597812\n56791234\n78123456": 9,    // 3-in-a-row vertically after top shifts left
    "12345978\n34569812\n56781934\n78123456": 10,   // 3-in-a-row vertically after middle shifts right
    "92345678\n39567812\n96781234\n78123456": 11,   // 3-in-a-row vertically after middle shifts left
    "12945678\n34967812\n59781234\n78123456": 12,   // 3-in-a-row vertically after bottom shifts right
    "12349678\n34569812\n56781934\n78123456": 13,   // 3-in-a-row vertically after bottom shifts left
    "12395678\n34567812\n56791234\n78193456": 14,   // 3-in-a-row vertically after top shifts down
    "12345698\n34567892\n56781234\n78123496": 15,   // 3-in-a-row vertically after bottom shifts up
    "12345678\n34567899\n96781234\n78123456": -1,   // No match - Matches (.)\1.\1 but not 3 in a row
    "12345679\n99567812\n56781234\n78123456": -1,   // No match - Matches (.).\1\1 but not 3 in a row
};

Düzenle 1

Değiştir \dile s .- 6 karakter kazandırır.

Düzenle 2

Ek yakalamayan gruplar ve güncellenmiş geri referanslar (?:.|\n)ile değiştirilir [\s\S]ve kaldırılır ( m-buettner tarafından önerildiği gibi ) ve evet / hayır çıktısında eklenir.

Düzenle 3

  • Bir Base-18 dizesinden tek tek Normal İfadeler oluşturmak için ECMAScript 6 çözümü eklendi.
  • Testleri 3'lü sırada yatay olarak ( m-buettner tarafından önerildiği gibi ) kaldırdı .

Düzenle 4

Başka (daha kısa) bir çözüm ve eşleşmeyen iki test örneği daha eklendi.

Düzenleme 5

Düzenle 6


1
Güzel çözüm! Normal ifadenin işe yarayabileceğini düşünmezdim. Lütfen ?'yes':'no'adalet için karakter sayınıza dahil edin, çünkü gereksinimlerdedir ve herkes bunu kullanmaktadır.
BDR9

Ek test durumları için teşekkürler, cevabınıza bir bağlantı ekledim, böylece diğer insanlar onları görebilir.
BDR9

Vay. Regex için +1
DankMemes

H-mm, JS'de .yeni satır dahil herhangi bir karakteri eşleştirmek için değiştirici yok mu? Perl ile kombine regexp sadece 129 byte'lık bir dizedir (tembel olarak Regexp :: Assemble ile derledim ), bu yüzden tüm Perl programı yaklaşık 150 bayttır.
user2846289

1
Teşekkür @VadimR ama daha da ileri yerine gidebilir .{8}|.{9}ile .{8,9}ve .{7}|.{8}ile.{7,8}
MT0

3

Piton 383

Sadece tek bir * Python serisi!

a=[list(l)for l in raw_input().split('\n')];z=any;e=enumerate;c=lambda b:z(all(p==b[y+v][x+u]for(u,v)in o)for y,r in e(b[:-2])for x,p in e(r[:-2])for o in [[(0,1),(0,2)],[(1,0),(2,0)]]);print z(c([[q if(i,j)==(m,n)else a[m][n]if(i,j)==(y+1,x+1)else p for j,p in e(r)]for i,r in e(a)])for y,t in e(a[1:-1])for x,q in e(t[1:-1])for n,m in((x+u,y+v)for u,v in[(1,0),(1,2),(0,1),(2,1)]))

* Şey, noktalı virgüllerle, ancak python'da hala önemsiz değil (python one-liners eğlenceli! )


3
Anlaşılmayan anlayışlar için seçildi :)
alexander-brett

2

Node.js - Saf çözüm - 905 bayt

Peki, henüz cevap yok, bu yüzden Node.js'de gerçekten naif bir çözüm göndereceğim

Olası her hareketten geçer ve daha sonra arka arkaya 3 olup olmadığını görmek için ortaya çıkan tahtayı test eder.

Golf (google kapatma derleyicisi ile) (0 ve! 1 gibi bazı hileli şeyler; XOR takasımla ne yaptığından bile emin değilim)

Array.prototype.a=function(){for(var f=[],d=0;d<this.length;d++)f[d]=this[d].a?this[d].a():this[d];return f};for(var a=[],b=0;8>b;b++)a[b]=[];for(b=2;b<process.argv.length;b++)for(var c=process.argv[b].split(""),e=0;e<c.length;e++)a[b-2][e]=parseInt(c[e],10);function h(){for(var d=l,f=0;f<d.length-2;f++)for(var g=0;g<d[f].length-2;g++){var k=d[f][g];if(k==d[f+1][g]&&k==d[f+2][g]||k==d[f][g+1]&&k==d[f][g+2])return!0}return!1}function m(){console.log("yes");process.exit()}for(b=0;b<a.length;b++)for(e=0;e<a[b].length;e++){var l=a.a();0!=b&&(l[b-1][e]^=l[b][e],l[b][e]^=l[b-1][e],l[b-1][e]^=l[b][e],h()&&m(),l=a.a());b!=a.length-1&&(l[b+1][e]^=l[b][e],l[b][e]^=l[b+1][e],l[b+1][e]^=l[b][e],h()&&m(),l=a.a());0!=e&&(l[b][e-1]^=l[b][e],l[b][e]^=l[b][e-1],l[b][e-1]^=l[b][e],h()&&m(),l=a.a());e!=a[b].length-1&&(l[b][e+1]^=l[b][e],l[b][e]^=l[b][e+1],l[b][e+1]^=l[b][e],h()&&m(),l=a.a())}console.log("no");

Tüm bunları cep telefonuma yazdığımı ve test etmek için zamanım olmadığını veya başka bir şey olmadığını unutmayın. Herhangi bir hata görürseniz yorum yapın, daha sonra kendim kontrol edeceğim.

Golf öncesi insan tarafından okunabilir versiyon

// set it up
Array.prototype.clone = function() {
    var arr = [];
    for( var i = 0; i < this.length; i++ ) {
        if( this[i].clone ) {
             arr[i] = this[i].clone();
        } else {
             arr[i] = this[i];
        }
    }
};
var board=[];
for(var i=0;i<8;i++)board[i]=[];
for(var i=2;i<process.argv.length;i++){
    var row=process.argv[i].split("");
    for(var j=0;j<row.length;j++)board[i-2][j]=parseInt(row[j], 10);
}
// function to test
function testBoard(arr){
    for(var i=0;i<arr.length-2;i++){
        for(var j=0;j<arr[i].length-2;j++){
            var val=arr[i][j];
            if(val==arr[i+1][j] && val==arr[i+2][j])return true;
            if(val==arr[i][j+1] && val==arr[i][j+2])return true;
        }
    }
    return false;
}
// functions to exit
function yay(){console.log("yes");process.exit();}
function nay(){console.log("no");}
// super slow naive solution time
for(var i=0;i<board.length;i++){
    for(var j=0;j<board[i].length;j++){
        var newboard=board.clone();
        if(i!=0){
            newboard[i-1][j]=newboard[i-1][j]^newboard[i][j];// whoa, it's a
            newboard[i][j]=newboard[i-1][j]^newboard[i][j];  // cool algorithm
            newboard[i-1][j]=newboard[i-1][j]^newboard[i][j];// at least this 
                                                             // isn't all naive
            if(testBoard(newboard))yay();
            newboard=board.clone();
        }
        if(i!=board.length-1){
            newboard[i+1][j]=newboard[i+1][j]^newboard[i][j];
            newboard[i][j]=newboard[i+1][j]^newboard[i][j];
            newboard[i+1][j]=newboard[i+1][j]^newboard[i][j];
            if(testBoard(newboard))yay();
            newboard=board.clone();
        }
        if(j!=0){
            newboard[i][j-1]=newboard[i][j-1]^newboard[i][j];
            newboard[i][j]=newboard[i][j-1]^newboard[i][j];
            newboard[i][j-1]=newboard[i][j-1]^newboard[i][j];
            if(testBoard(newboard))yay();
            newboard=board.clone();
        }
        if(j!=board[i].length-1){
            newboard[i][j+1]=newboard[i][j+1]^newboard[i][j];
            newboard[i][j]=newboard[i][j+1]^newboard[i][j];
            newboard[i][j+1]=newboard[i][j+1]^newboard[i][j];
            if(testBoard(newboard))yay();
            newboard=board.clone();
        }
    }
}
nay();

Hah aslında ilk gönderiyi 10 dakika kaçırdım. Ben böyle olsa gibi ...
DankMemes

Ah, aynı yöntemi kullandım (saf ama küçük kod!). Benden çok daha açıklayıcı olduğu için +1
KSab

Daha verimli bir algoritma olup olmadığını merak ediyorum ...
DankMemes

2

Perl, 114 96 95 93 92 87 86 85 bayt

İçin + içerir -a0p

STDIN üzerindeki giriş ile çalıştırın:

bejeweled.pl
12314131
13224145
54762673
61716653
61341144
23453774
27645426
75575656
^D

bejeweled.pl:

#!/usr/bin/perl -a0p
$i/s%.%chop$F[$i++&7]%eg>3|/(.)((.|\H{6}|\H{9})\1|\H{7}\1.)\1/||redo;$_=$1?yes:n.o

Bu, tek yönlü yatay regex çözeltisini rotasyonlarla birleştirir

Açıklama:

Bu çözümde tekrar tekrar döneceğim ve aşağıdaki 4 testi yapacağım:

/(.).\1\1/,      // 3-in-a-row horizontally after left-most shifts right
/(.)\C{9}\1\1/,  // 3-in-a-row horizontally after left-most shifts down
/(.)\C{7}\1.\1/, // 3-in-a-row horizontally after middle shifts down
/(.)\C{6}\1\1/,  // 3-in-a-row horizontally after right-most shifts down

\C"Herhangi bir karakter" nerede (bunun aksine .satırsonu içerir). Bunun dışında \Ckullanımdan kaldırılmıştır ve uyarılara yol açmaktadır, bu nedenle \Htüm basamakları ve satırsonu yakalayacak kadar iyi (yatay olmayan boşluk) kullanıyorum.

4 rotasyondan sonra, gerekli olan 16 testin tümü yapılacaktır.

-p                            Read lines from STDIN, print $_ at the end
-0                            No line ending => slurp ALL of STDIN
-a                            Split $_ into @F. Since there are no spaces
                              on the rows this means each element of @F is
                              1 row

    s%.%chop$F[$i++&7]%eg     Replace each row by the removed last column
                              This is therefore a left rotation. Very short
                              but at the cost of using @F. To make sure that
                              @F gets refilled from $_ each time I won't be
                              able to use while, until, eval or do$0 for the
                              loops but have to use redo. That costs a few
                              bytes but less than having to do my own split
$i/                      >3   The previous regex replacement always
                              returns 64 and each time through the loop $i is
                              increased by 64. So if this division reaches
                              4 all rotations have been done

/(.)((.|\H{6}|\H{9})\1|\H{7}\1.)\1/ This is the 4 regexes mentioned above
  ||redo                      Stop the loop if the regex matches or we
                              rotated 4 times
$_=$1?yes:n.o                If the regex matched $1 will be one of the
                              color digits (which cannot be 0) and this will
                              assign "yes" to $_. If the regex didn't match
                              in 4 times $1 will get its value from the last
                              succesful regex in scope which will be the one
                              from the rotation, but that one doesn't have
                              any () so $1 will be unset. So in case there
                              is no move $_ will be set to "no" (which needs
                              to be constructed because "no" is a keyword)

1

Python3, 314B

import itertools as T,copy
r=[]
K=range(8)
J=[list(input())for w in K]
P=T.product
f=lambda A:["yes"for b in[A[m][n:]for m,n in P(K,K[:6])]if b[0]==b[1]==b[2]]
for i,j,x in P(K,K,[0,1]):
 t=j+1-x
 if i+x<8and t<8:B=copy.deepcopy(J);B[i][j],B[i+x][t]=B[i+x][t],B[i][j];r+=f(B)+f(list(zip(*B)))
r+=["no"]
print(r[0])

İsteğe bağlı olarak büyük giriş boyutlarını işlemek için 8, 5 satır 6 ve satır 8 üzerindeki 8s değerlerini değiştirin; ayrıca her bir değerin ne olduğu umurunda değildir, böylece onu besleyebilirsiniz:

absdefgh
sdkljahs
lsdfjasd
fjdhsdas
dkjhfasd
sdfhaskd
sdkfhkas
weriuwqe

ve geri dönecek yes.

Açıklamalar

import itertools as T,copy 
            # itertools.product is going to save us lots of for loops
r=[]        # result
K=range(8)  # we can use range(8) everywhere, so this saves more than the usual R=range
J=[list(input())for w in K] 
            # input handling: keep everything as a length-1 string to avoid map(int,input())
P=T.product
f=lambda A:["yes"for b in[A[m][n:]for m,n in P(K,K[:6])]if b[0]==b[1]==b[2]] 
            # check the condition horiontally only. K[:6] is the same as range(5)
            # A[m][n:n+3] would be neater, but not actually needed
for i,j,x in P(K,K,[0,1]): 
            # <3 itertools.product! 3 for-loops without it.
            # NB we're only going right and downwards
 t=j+1-x
 if i+x<8and t<8: 
            # don't want out-of-bounds errors at the edges
  B=copy.deepcopy(J) 
            # preserve the reference array
  B[i][j],B[i+x][t]=B[i+x][t],B[i][j] 
            # do the switch
  r+=f(B)+f(list(zip(*B))) 
            # do the test. you could end up with lots of 'yes's in r.
            # zip(*B) takes the transpose, so that f checks the columns too
r+=["no"]   # happens to ensure that r is nonempty
print(r[0]) # only prints no if r was empty before the last line

1

GNU sed 255 + 2 = 257B

Ben bunun python kadar iyi olmayacağını düşündüm ama şimdi: - / Bugün internet erişimi olmadan oldum bu yüzden sed bunu çözerek kendimi işgal :). -R bayrağı ile çağrılması gerekiyor, yani sed -rf command.sed < inputbenim puan 2 ekledi.

:a
$!N
s/\n/ /g
ta
:b
/^((\w)(\w\2\2|\2\w\2|\w\2\w* \w\2|\2\w* \w\w\2|\w* (\2\w* \w* \2|\w* \2\w* \2|\w\2\2|\w\2\w* \2|\2\w* \w\2|\w\2\w* \w\2))|\w((\w)(\w* \6\w\6|\6\w* \6|\w* (\6\w \w\6|\w\6\w* \6|\6\w* \6))|\w(\w)\w* \9\9))/c\yes
s/\w(\w*)/\1/g
tb
c\no

Nasıl çalışır:

  1. Izgarayı boşlukla ayrılmış tek bir satırda okuyun
  2. İlk sütunda bir eşleşme olup olmadığını öğrenmek için motherload normal ifadesini kullanın * - evet ise, tüm satırı 'evet' olarak değiştirin (programı sonlandırın)
  3. Her sütundaki ilk karakteri soyun ve eğer yaparsak 2'ye git
  4. Eğer yapmadıysak (satır boşsa) tüm satırı 'hayır' ile değiştirirsek

1

Yakut, 201 bayt

(Bu harika olmasına rağmen) regex veya kaba kuvvet kullanmayan bu büyük meydan okuma için herhangi bir çözüm görmekten hayal kırıklığına uğradım, bu yüzden bir tane yazdım. STDIN üzerine girdi alır.

Temel bitsel aritmetik algoritması, @leander tarafından Game Development Stack Exchange'deki bu harika cevaptan türetilmiştir .

s=$<.read
$><<(?1..?9).any?{|n|a=[0]*19
s.scan(n){i=$`.size
a[i/9+1]+=2**(i%9)
a[i%9+10]+=2**(i/9)}
a.each_cons(3).any?{|x,y,z|q=y&y<<1
l=q<<1
q>>=2
y&(l<<1|q>>1)|(q|l|(y&y<<2)>>1)&(x|z)>0}}?"yes":"no"

Ruby lambda, 181 bayt

Burada bir string alır ve döndüren bir lambda gibidir trueveya false:

->s{(?1..?9).any?{|n|a=[0]*19
s.scan(n){i=$`.size
a[i/9+1]+=2**(i%9)
a[i%9+10]+=2**(i/9)}
a.each_cons(3).any?{|x,y,z|q=y&y<<1
l=q<<1
q>>=2
y&(l<<1|q>>1)|(q|l|(y&y<<2)>>1)&(x|z)>0}}}

Repl.it sitesinde görün: https://repl.it/ColJ/2

Ungolfed ve açıklama

->s{
  (?1..?9).any? {|n|
    a = [0] * 19

    s.scan(n) {
      i = $`.size
      a[i/9+1] += 2**(i%9)
      a[i%9+10] += 2**(i/9)
    }

    a.each_cons(3).any? {|x,y,z|
      q = y & y << 1
      l = q << 1
      q >>= 2
      y & (l << 1 | q >> 1) |
        (q | l | (y & y << 2) >> 1) &
        (x | z) > 0
    }
  }
}

Kod "1" ile "9" arasındaki rakamlar üzerinden yinelenir. Her yinelemenin iki ayrı adımı vardır:

İlk adım, s.scan(n)çözülmemiş koddaki blokta görebileceğiniz tahta dönüşümüdür . Eşleşen basamakları 1s ve diğerlerini 0'lık bir ikili dizede ele alarak, her satır için bir tane olmak üzere 8 tamsayıdan oluşan bir diziye dönüştürür. Örneğin, satırı ele alalım 12231123. İlk yinelemede, bu ikili dize olur 10001100(1'lerin tümü - er, kal - 1s ve diğer tüm rakamlar 0s olur), bu ondalık sayı 140'tır. İkinci yinelemede aynı satır olur 01100010(2'lerin tümü 2s olur ve diğer tüm basamaklar 0s olur) veya ondalık 98 olur.

Aynı anda birinciyle aynı olan ancak tahta 90 derece döndürülmüş olan ikinci bir dönüşüm gerçekleştirir. Bu, yatay eşleşmeleri dikey olanlarla yapmak için aynı mantığı kullanmamızı sağlar. Basitlik için, iki kartı başlangıçta, ortasında (iki kartı ayırmak için) ve dolgu için sonda tek bir uzun olana birleştirir.

İkinci adım, each_cons(3).any?blokta görebileceğiniz olası eşleşmeleri aramaktır. Dönüştürülmüş satırlar (şu anda 8 bitlik tamsayılardır), üç sıralı ( x , y , z ) gruplar halinde (üst üste binen) bitsel aritmetik kullanılarak kontrol edilir. Her bir grup bir eşleşme satır yapılabilir olmadığını görmek için kontrol edilmektedir, y , ya da sıralı olarak bir parça kaydırılması ile y ya da bir parçasını kaydırılması ile y den x veya z . Hem orijinal hem de döndürülmüş panoların satırlarından önce ve sonra sıfır "satır" olduğundan, bir tahtanın ilk veya son satırında olup olmadığımızı kontrol etmek zorunda değiliz.

Herhangi bir eşleşme bulunamazsa, sonraki yinelemeye devam eder.

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.