Tentukan apakah ada gerakan dalam game Bejeweled / match 3

20

Latar Belakang

Dalam permainan Bejeweled dan sejenisnya, pemain harus menukar dua permata yang berdekatan (tidak ada diagonal) dalam kotak permata 8x8 untuk mencocokkan tiga warna yang sama secara berurutan. Permata dapat dicocokkan secara horizontal atau vertikal. Gameplay berlanjut sampai tidak ada gerakan yang dapat dibuat menghasilkan tiga berturut-turut, di mana permainan berakhir.

Tugas

Tujuannya adalah untuk menulis program yang menentukan apakah permainan Bejeweled belum berakhir. Dengan kata lain, itu harus memeriksa untuk melihat apakah ada langkah yang mungkin membuat setidaknya tiga berturut-turut. Mungkin ada lebih dari tiga permata berturut-turut dan itu masih merupakan langkah yang valid.

Memasukkan

Program Anda harus menerima melalui input standar representasi 8x8 dari grid Bejeweled. Masing-masing dari tujuh warna permata akan diwakili oleh digit dari 1 hingga 7. Setiap baris akan berisi satu baris, dan 8 baris, masing-masing terdiri dari 8 digit, akan dimasukkan. Lihat contohnya. Anda dapat mengasumsikan bahwa input akan selalu mengikuti format ini, dan tidak akan pernah mengandung tiga berturut-turut.

Keluaran

Program kemudian harus menampilkan (ke keluaran standar) yesatau notergantung pada apakah ada atau tidak ada satu langkah yang valid yang akan menghasilkan tiga atau lebih permata berturut-turut. Program Anda tidak boleh mengeluarkan apa pun selain satu instance dari salah satu yesatau no.

Aturan

Program Anda tidak boleh menggunakan file eksternal atau sumber daya apa pun, argumen baris perintah, atau memerlukan nama file tertentu. Program dengan jumlah byte terkecil dalam kode sumbernya akan menang.

Contohnya

Memasukkan:

12314131
13224145
54762673
61716653
61341144
23453774
27645426
75575656

Keluaran: yes

Memasukkan:

35261546
76421754
15743271
62135642
35617653
64565476
54427254
15635465

Keluaran: no

Lihat jawaban MT0 di bawah ini untuk kasus uji tambahan.

bdr9
sumber
Apakah itu hanya baris, atau kolom juga.
TheDoctor
@TheDoctor Columns juga. Ketika saya menggunakan frasa "tiga berturut-turut", maksud saya mereka harus berbaris dalam arah horizontal atau vertikal.
Bdr9
@ bdr9 Anda mungkin ingin mengeditnya di
John Dvorak
@JanDvorak Selesai.
Bdr9
Juga mungkin ingin mengedit jika 4+ berturut-turut diizinkan.
Justin

Jawaban:

12

Solusi Asli: JavaScript - 261 255 228 227 179 153 Karakter

/(\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'

Dengan asumsi bahwa string untuk menguji ada dalam variabel s(untuk membuatnya berfungsi fkemudian tambahkan f=s=>ke awal kode atau, jika tidak, untuk mengambil input dari prompt lalu ganti sdengan prompt()).

Outputnya ke konsol.

3 rd Solusi: JavaScript (ECMAScript 6) - 178 Karakter

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'

Aku mengambil 2 nd solusi, di bawah ini, (yang menggunakan ekspresi reguler untuk memeriksa karakter dalam konfigurasi tertentu) dan ulang itu hanya memeriksa string untuk karakter identik dalam konfigurasi yang sama tanpa menggunakan ekspresi reguler.

String Base-36 "2313ab1b8a2a78188h9haj9j8iaiir9r"memberikan pasangan offset untuk diperiksa - yaitu pasangan23 hasil di cek jika saya th karakter identik dengan (i + 2) th karakter dan (i + 3) th karakter (setara dengan ekspresi reguler (.).\1\1- dengan beberapa pemeriksaan tambahan untuk memastikan bahwa karakter yang tidak identik bukanlah baris baru).

2 nd Solusi: JavaScript (ECMAScript 6) - 204 Karakter

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'

Buat beberapa ekspresi reguler (lihat di bawah untuk detail lebih lanjut) menggunakan pasangan nilai yang diambil dari string Base-18 10907160789879h8dan lakukan ORsemua pengujian. Untuk menguranginya lebih lanjut, Anda dapat mencatat bahwa ekspresi reguler datang berpasangan di mana satu adalah "kebalikan" dari yang lain (mengabaikan Ekspresi Reguler untuk 3-in-a-line secara horizontal dan vertikal sebagai OP menyatakan mereka tidak akan pernah hadir - jika Anda ingin menambahkan tes-tes itu kembali ke append 0088ke string Base-18).

Penjelasan

Mulai dengan 16 ekspresi reguler yang mencakup semua kemungkinan konfigurasi gerakan yang valid:

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
];

( Catatan: regex untuk 3-in-a-row secara horizontal (0 th ) dan vertikal (bagian dari 9 th ) tidak relevan karena OP menyatakan bahwa input yang cocok dengan input ini tidak akan pernah ada. )

Menguji masing-masing terhadap input akan menentukan apakah langkah yang valid dari konfigurasi itu dapat ditemukan.

Namun, ekspresi reguler dapat digabungkan untuk memberikan 6 ini:

/(\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

Ini kemudian dapat digabungkan menjadi satu ekspresi reguler:

/(\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/

Yang hanya perlu diuji terhadap input.

Uji Kasus

Beberapa kasus uji yang mungkin berguna bagi orang lain (tidak sesuai dengan format input dengan hanya menggunakan angka 1-7 tapi itu mudah diperbaiki dan hanya berupa grid 8x4 - karena itu adalah persyaratan minimum untuk pengujian semua input yang valid ).

Dalam format peta dari string input yang mana dari 16 ekspresi reguler di atasnya yang cocok.

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
};

Edit 1

Ganti \ds dengan .- menyimpan 6 karakter.

Edit 2

Ganti (?:.|\n)dengan [\s\S]dan hilangkan kelompok yang tidak menangkap tambahan dan perbarui kembali referensi (seperti yang disarankan oleh m-buettner ) dan tambahkan dalam output ya / tidak.

Edit 3

  • Menambahkan solusi ECMAScript 6 untuk membangun Ekspresi Reguler individual dari string Base-18.
  • Menghapus tes 3-in-a-row secara horizontal (seperti yang disarankan oleh m-buettner ).

Edit 4

Menambahkan solusi lain (lebih pendek) dan dua lagi test case yang tidak cocok.

Edit 5

  • Solusi asli yang diperpendek dengan mengganti baris baru dengan karakter non-numerik (seperti yang disarankan oleh VadimR ).

Edit 6

  • Solusi asli yang dipersingkat dengan menggabungkan bit dari ekspresi reguler (seperti yang disarankan oleh VadimR ).
MT0
sumber
1
Solusi bagus! Saya tidak akan berpikir bahwa regex bisa bekerja. Harap sertakan ?'yes':'no'dalam jumlah karakter Anda untuk keadilan, karena itu dalam persyaratan dan semua orang menggunakannya.
bdr9
Terima kasih atas kasus uji tambahan, saya menambahkan tautan ke jawaban Anda sehingga orang lain dapat melihatnya.
bdr9
Wah +1 untuk regex
DankMemes
H-mm, tidak ada pengubah dalam JS yang .cocok dengan karakter apa pun termasuk baris baru? Dengan Perl, regexp gabungan hanyalah 129 byte string (yang, karena malas, saya kompilasi dengan Regexp :: Assemble ), sehingga keseluruhan program Perl sekitar 150 byte.
user2846289
1
@VadimR Terima kasih, tetapi Anda bahkan bisa mengganti lebih jauh .{8}|.{9}dengan .{8,9}dan .{7}|.{8}dengan.{7,8}
MT0
3

Python 383

Hanya satu baris * * Python!

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)]))

* Yah, dengan titik koma, tapi itu masih non-sepele dalam python (python one-liners menyenangkan! )

KSab
sumber
3
Dipilih untuk pemahaman yang tidak bisa dimengerti :)
alexander-brett
2

Node.js - Solusi naif - 905 byte

Yah, belum ada jawaban jadi saya akan memposting solusi yang benar-benar naif di Node.js

Itu melewati setiap gerakan yang mungkin dan kemudian menguji papan yang dihasilkan untuk melihat apakah ada 3 berturut-turut.

Golfed (dengan kompiler penutupan google) (beberapa hal hacky di sana seperti! 0 dan! 1; Saya bahkan tidak yakin apa yang dilakukannya dengan swap XOR saya)

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");

Perhatikan bahwa saya menulis ini semua di ponsel saya dan tidak punya waktu untuk mengujinya atau apa pun. Komentari jika Anda melihat bug, saya akan memeriksanya sendiri nanti.

Versi dapat dibaca manusia pra-golf

// 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();
DankMemes
sumber
Hah saya benar-benar melewatkan posting pertama dalam 10 menit. Saya agak suka ini ...
DankMemes
Ah, metode yang sama persis saya gunakan (kode naif tapi kecil!). +1 karena lebih deskriptif daripada saya
KSab
Saya ingin tahu apakah ada algoritma yang lebih efisien ...
DankMemes
2

Perl, 114 96 95 93 92 87 86 85 byte

Termasuk + untuk -a0p

Jalankan dengan input pada STDIN:

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

Ini menggabungkan solusi regex horisontal arah tunggal dengan rotasi

Penjelasan:

Dalam solusi ini saya akan berulang kali memutar dan melakukan 4 tes berikut:

/(.).\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

Di mana \C"karakter apa saja" (tidak seperti .ini termasuk baris baru). Kecuali itu \Csudah usang dan mengarah ke peringatan, jadi saya gunakan\H (ruang non-horisontal) yang cukup baik untuk menangkap semua angka dan baris baru.

Setelah 4 rotasi ini akan melakukan semua 16 tes yang diperlukan

-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)
Ton Hospel
sumber
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])

Ubah 8, 5 pada saluran 6, dan 8 pada saluran 9 untuk menangani ukuran input besar yang sewenang-wenang; juga tidak peduli apa nilai masing-masing, sehingga Anda bisa memberinya makan:

absdefgh
sdkljahs
lsdfjasd
fjdhsdas
dkjhfasd
sdfhaskd
sdkfhkas
weriuwqe

dan itu akan kembali yes.

Anotasi

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
alexander-brett
sumber
1

GNU sed 255 + 2 = 257B

Saya pikir ini tidak akan sebagus python tetapi sekarang: - / Saya sudah tanpa akses internet hari ini jadi saya sibuk sendiri dengan menyelesaikan ini sed :). Perlu dipanggil dengan flag -r, sed -rf command.sed < inputjadi saya menambahkan 2 pada skor saya.

: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

Bagaimana itu bekerja:

  1. Baca kisi menjadi satu baris karakter yang dipisahkan ruang
  2. Gunakan regu motherload untuk mengetahui apakah ada kecocokan di kolom pertama * - jika ya, tukar seluruh baris dengan 'ya' (mengakhiri program)
  3. Strip karakter pertama dari setiap kolom dan goto 2 jika kita lakukan
  4. Jika tidak (baris kosong) ganti seluruh baris dengan 'tidak'
alexander-brett
sumber
1

Ruby, 201 byte

Saya kecewa tidak melihat solusi untuk tantangan besar ini yang tidak menggunakan regex atau brute force (meskipun itu hebat), jadi saya menulis satu. Dibutuhkan input pada STDIN.

Algoritma aritmatika inti bitwise diturunkan dari jawaban fantastis ini pada Game Development Stack Exchange oleh @leander.

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 byte

Ini dia sebagai lambda yang mengambil string dan kembali trueatau 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}}}

Lihat di repl.it: https://repl.it/ColJ/2

Tidak dikelompokkan & penjelasan

->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
    }
  }
}

Kode ini berulang di atas angka "1" hingga "9." Setiap iterasi memiliki dua langkah terpisah:

Langkah pertama adalah transformasi papan, yang bisa Anda lihat di s.scan(n)blok dalam kode yang tidak ditandai. Ini mengubah papan menjadi array 8 bilangan bulat, satu untuk setiap baris, dengan memperlakukan angka yang cocok sebagai 1 dan semua yang lain sebagai 0 dalam string biner. Misalnya, ambil barisnya 12231123. Pada iterasi pertama, ini akan menjadi string biner 10001100(semua 1s menjadi — eh, tetap — 1s dan semua digit lainnya menjadi 0s), yang merupakan angka desimal 140. Pada iterasi kedua baris yang sama menjadi01100010 (semua 2s menjadi 2s dan semua digit lainnya menjadi 0s), atau desimal 98.

Secara bersamaan melakukan transformasi kedua, yang sama dengan yang pertama tetapi dengan papan diputar 90 derajat. Ini memungkinkan kami menggunakan logika yang sama untuk membuat kecocokan horizontal dengan pencocokan vertikal. Untuk kesederhanaan, itu menggabungkan dua papan menjadi satu panjang dengan nol di awal, tengah (untuk memisahkan dua papan), dan ujung untuk bantalan.

Langkah kedua adalah mencari kemungkinan kecocokan, yang dapat Anda lihat di each_cons(3).any?blok. Baris yang diubah (yang sekarang bilangan bulat 8-bit) diperiksa dalam kelompok (tumpang tindih) yang terdiri dari tiga baris ( x , y , z ) menggunakan aritmatika bitwise. Setiap kelompok diperiksa untuk melihat apakah kecocokan dapat dilakukan dalam baris y , baik dengan menggeser sepotong demi sepotong y atau dengan memindahkan sepotong menjadi y dari x atau z . Karena tidak ada "baris" sebelum dan sesudah baris papan asli dan yang diputar, kita tidak perlu memeriksa apakah kita berada di baris pertama atau terakhir dari papan.

Jika tidak ada kecocokan yang ditemukan, itu berlanjut ke iterasi berikutnya.

Jordan
sumber