Skip to content

Instantly share code, notes, and snippets.

@AlvinLaiPro
Forked from taylortao/正则高尔夫
Created December 2, 2018 13:24
Show Gist options
  • Save AlvinLaiPro/418875bd4b445a38a143bb4e21bef4a5 to your computer and use it in GitHub Desktop.
Save AlvinLaiPro/418875bd4b445a38a143bb4e21bef4a5 to your computer and use it in GitHub Desktop.
正则高尔夫
非常有意思的一组正则小游戏,http://regex.alf.nu/
积分规则:匹配左边(一个10分),不匹配右边的(错误一个扣10分),式子长度越短越好,1个字符扣1分。
中间有被难到的题目参考了Gist: https://gist.github.com/Davidebyzero/9221685
我看懂了的,顺便也记录一下我的理解。
Regex: short of regular expression.
Warmup
foo,哈哈,送分题
Anchors
You are deducted one point per character you use, and ten if you match something you shouldn’t.
我写的是ick$,后来发现还有k$,太坏了。。。考察点是:start/end of string anchors.
Ranges
The test vectors were generated by grepping /usr/dict/words. Can you tell?
题目描述太重要了,^[a-f]*$,考察点是范围,边界。
Backrefs
This doesn’t really work as a tutorial. Not really clear what you’re supposed to do here.
考察”反向引用(backreference)”:匹配前面匹配成功过的括号表达式的值,\1,backslash one。
比较直观的答案是(.{3,}).*\1,还有更短的:(...).*\1
(abc) capture group
\1 backreference to group #1
(?:abc) non-capturing group
Abba
Let’s pretend this one is not a rehash of the last one.
虽然感觉是上面题目的简化版的补集,但是难度陡增。
首先很容易写出(.)(.)\2\1,然后呢?
(?=abc) positive lookahead
(?!abc) negative lookahead
(.)(.)(?!\2\1)不行
(.)(.)(?!\2\1).{2,}勉强干掉了两个
^(?!.*(.)(.)\2\1) That’s it.
看答案里还有更短的abba 里面一定含有bb,用^(?!.*(.)\1)匹配出大部分,然后剩下两个找规律ef。195 points,太坏了。。。
A man
a plan — You’re allowed to cheat a little. Even in hard mode, words will be no longer than 13 characters.
结合前面几个点:^(.)(.).*\2\1$, 176 points。答案是:^(.)[^p].*\1$,真的是cheat a little。
Prime
The length is not part of the string. I should probably have chosen a different color.
prime and composites
检查合数的算法: ^x?$|^(xx+?)\1+$,其中,(xx+?)是枚举除数,\1的个数+1表示倍数。
更有趣的是,正则表达式还可以用来解方程:11x + 2y + 5z = 115是否有自然数解:^(.*)\1{10}(.*)\2{1}(.*)\3{4}$能否匹配成功一个含有115个字符的字符串。
(参考: blog link)
所以求合数的补集^(?!(xx+?)\1+$),启用非贪婪模式是为了找到每个素数除子,其实并没有必要,可以直接简化为^(?!(xx+)\1+$)
Four
You can get an extra point by ignoring the name of this level.
一开始写的是:(.)(.*\1){3},发现总有一只漏网之鱼,后来发现相同字母之间只能隔一个其它字符,改成:(.)(.\1){3}
Order
Cheat.
题目描述是什么鬼。。。
我只想到了这: ^a*b*c*d*e*f*g*h*i*j*k*l*m*n*o*p*q*r*s*t*u*v*w*x*y*z*$,156 points。想着去掉几个没用的字符,让字符短一点。
^a*b*c*d*e*f*g*h*i*l*m*n*o*p*r*s*t*w*y*z*$ 168 points。
答案是: ^.{5}[^e]?$ 。。。 三条黑线有木有
Triples
Multiples of 7 are left as an exercise for the reader.
胡诌一个 00|55|02|44 259 points。
正确解法构造状态机,转化为正则,太复杂了,参见:link to Zhihu
小节
后面的就开始各种胡诌了
Glob
找不到区别,继续胡诌一个: (.)\1|o|ea 130 points
Balance
This one is also impossible, but there’s a finite number of test cases
既然是impossible,就乱来吧。<<<< 221 Points
Powers
In hard mode, you have to recognize any power of two.
根据幂的特性,写出了如下表达式:
^((((((((((x)\10?)\9?)\8?)\7?)\6?)\5?)\4?)\3?)\2?)\1?$
虽然正确,但是长度太长,56 points
Long count
对左边的数字求了个独有的子集:
0011 0100 0101 0110 0111 1000 1001 1010 1011 1100 1101 1110 1111
骗到206 points
Alphabetical
resent 骗到94 points
Powers 2 — Or 3.
暴力
^(x{1}|x{3}|x{9}|x{27}|x{81}|x{243}|x{729}|x{2187}|x{6561}|x{19683}|x{59049})$
39 points
最后得了2847分,不会再爱了。
后面几个题需要很强大的观察能力。不想试图理解答案了。
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment