原来的解决方案:JavaScript的- 261 255 228 227个 179 153字符
/(\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'
假设要测试的字符串在变量中s
(使其成为一个函数,f
然后将其添加f=s=>
到代码的开头,否则,从提示符处获取输入,然后替换s
为prompt()
)。
输出到控制台。
3 RD解决方案:的JavaScript(ECMAScript的6) - 178点的字符
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'
我采用了下面的第二种解决方案(使用正则表达式来检查某些配置中的字符),并对其进行了重做以仅检查字符串中是否具有相同配置中的相同字符,而不使用正则表达式。
Base-36字符串"2313ab1b8a2a78188h9haj9j8iaiir9r"
提供了要检查的偏移量对-即,该对23
导致检查第 i 个字符是否与第(i + 2)个字符以及第(i + 3)个字符相同(与正则表达式等效)(.).\1\1
-进行一些附加检查,以确保不相同的字符不是换行符)。
2 第二解决方案:的JavaScript(ECMAScript的6) - 204的字符
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字符串中10907160789879h8
获取的值对构建多个正则表达式(请参见下文以获取更多详细信息),并接受OR
所有测试的。为了进一步简化,您可以注意到正则表达式成对出现,其中一个是另一个的“反向”(忽略水平和垂直3合一行的正则表达式,因为OP表示它们永远不会出现-如果您想将这些测试重新添加0088
到Base-18字符串的后面)。
说明
从16个正则表达式开始,涵盖所有有效动作的可能配置:
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
];
(注:regexs 3-在一个排水平(0 次)和垂直方向的9的(一部分个)是不相关的OP指出输入匹配这些决不会存在。)
对这些输入进行测试将确定是否可以找到该配置的有效移动。
但是,可以将正则表达式组合起来以得到以下6个:
/(\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
然后可以将它们组合成单个正则表达式:
/(\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/
只需对输入进行测试。
测试用例
其他人可能会觉得有用的一些测试用例(不符合仅使用数字1-7的输入格式,但是这种格式很容易纠正,并且只有8x4网格-因为这是测试所有有效输入的最低要求)。
从输入字符串到它上面的16个正则表达式匹配的映射格式。
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
};
编辑1
将\d
s 替换为.
-保存6个字符。
编辑2
替换(?:.|\n)
与[\s\S]
除去额外的非捕获组并更新反向引用(如通过建议M-布特尼)和在有/无输出加入。
编辑3
- 添加了ECMAScript 6解决方案,以从Base-18字符串构建单个正则表达式。
- 删除了水平3 合一测试(如m-buettner所建议)。
编辑4
添加了另一个(更短的)解决方案和两个不匹配的测试用例。
编辑5
- 通过用非数字字符替换换行符来缩短原始解决方案(如VadimR所建议)。
编辑6
- 通过组合正则表达式的位来缩短原始解决方案(如VadimR所建议)。