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 f
kemudian tambahkan f=s=>
ke awal kode atau, jika tidak, untuk mengambil input dari prompt lalu ganti s
dengan 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 10907160789879h8
dan lakukan OR
semua 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 0088
ke 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 \d
s 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 ).