智能数独高尔夫
这个问题的要点是创建最短的不过慢数独求解器。 这被定义为:当棋盘上有只能是一位数字的点时不要递归。
这是我迄今为止在 python 中最短的:
r=range(81)
s=range(1,10)
def R(A):
bzt={}
for i in r:
if A[i]!=0: continue;
h={}
for j in r:
h[A[j]if(j/9==i/9 or j%9==i%9 or(j/27==i/27)and((j%9/3)==(i%9/3)))else 0]=1
bzt[9-len(h)]=h,i
for l,(h,i)in sorted(bzt.items(),key=lambda x:x[0]):
for j in s:
if j not in h:
A[i]=j
if R(A):return 1
A[i]=0;return 0
print A;return 1
R(map(int, "080007095010020000309581000500000300400000006006000007000762409000050020820400060"))
我将最后一行作为 cmd 行输入的一部分,它可以更改为:
import sys; R(map(int, sys.argv[1]);
这与其他数独高尔夫挑战类似,只是我想消除不必要的递归。 任何语言都可以接受。 挑战开始了!
The point of this question is to create the shortest not abusively slow Sudoku solver. This is defined as: don't recurse when there are spots on the board which can only possibly be one digit.
Here is the shortest I have so far in python:
r=range(81)
s=range(1,10)
def R(A):
bzt={}
for i in r:
if A[i]!=0: continue;
h={}
for j in r:
h[A[j]if(j/9==i/9 or j%9==i%9 or(j/27==i/27)and((j%9/3)==(i%9/3)))else 0]=1
bzt[9-len(h)]=h,i
for l,(h,i)in sorted(bzt.items(),key=lambda x:x[0]):
for j in s:
if j not in h:
A[i]=j
if R(A):return 1
A[i]=0;return 0
print A;return 1
R(map(int, "080007095010020000309581000500000300400000006006000007000762409000050020820400060"))
The last line I take to be part of the cmd line input, it can be changed to:
import sys; R(map(int, sys.argv[1]);
This is similar to other sudoku golf challenges, except that I want to eliminate unnecessary recursion. Any language is acceptable. The challenge is on!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
我并没有真正做太多的改变——算法是相同的,但这里有一些你可以对你的 python 代码进行的进一步的微观优化。
不需要 !=0,在布尔上下文中 0 为 false。
a if c else b 如果不需要短路,则比使用 [a,b][c] 更昂贵,因此可以使用
h[ [0,A[j]][j /9..布尔条件的其余部分]
。 更好的是利用这样的事实:在错误情况下您需要 0,因此乘以布尔值(视为0*A[j]
(即 0)或1 *A[j]
(即A[j]
)。您可以省略数字和标识符之间的空格,例如“
9 或
” ->“9or
”。 >"您可以省略要排序的键() 由于您对第一个元素进行排序,因此普通排序实际上会产生相同的顺序(除非您依赖于稳定性,但事实并非如此)
您可以通过省略 . items() 调用,然后将下一行中的 h,i 分配给 z[l]
你只使用 s 一次 - 使用变量没有意义。 您还可以通过选择适当的 r 切片来避免使用 range() (r[1:10])
j not in h
可以变为(j in h)-1
(依赖于整数上下文中的 True == 1)[编辑] 您还可以用字典构造函数和生成器表达式替换第一个 for 循环的 h 构造。 这使您可以将逻辑压缩到一行,总共节省 10 个字节。
更一般地说,您可能需要考虑更改算法以减少嵌套级别的方法。 python 中的每个级别每行都会提供一个额外的字节,该字节会累积。
这是我到目前为止所得到的(我已经切换到每个缩进 1 个空格,以便您可以获得所需字符的准确图片。目前它的权重为
288278,这仍然相当大。I haven't really made much of a change - the algorithm is identical, but here are a few further micro-optimisations you can make to your python code.
No need for !=0, 0 is false in a boolean context.
a if c else b is more expensive than using [a,b][c] if you don't need short-circuiting, hence you can use
h[ [0,A[j]][j/9.. rest of boolean condition]
. Even better is to exploit the fact that you want 0 in the false case, and so multiply by the boolean value (treated as either0*A[j]
(ie. 0) or1*A[j]
(ie.A[j]
).You can omit spaces between digits and identifiers. eg "
9 or
" -> "9or
"You can omit the key to sorted(). Since you're sorting on the first element, a normal sort will produce effectively the same order (unless you're relying on stability, which it doesn't look like)
You can save a couple of bytes by omitting the .items() call, and just assign h,i in the next line to z[l]
You only use s once - no point in using a variable. You can also avoid using range() by selecting the appropriate slice of r instead (r[1:10])
j not in h
can become(j in h)-1
(relying on True == 1 in integer context)[Edit] You can also replace the first for loop's construction of h with a dict constructor and a generator expression. This lets you compress the logic onto one line, saving 10 bytes in total.
More generally, you probably want to think about ways to change the algorithm to reduce the levels of nesting. Every level gives an additional byte per line within in python, which accumulates.
Here's what I've got so far (I've switched to 1 space per indent so that you can get an accurate picture of required characters. Currently it's weighing in at
288278, which is still pretty big.269个字符,它找到了所有的解决方案。 用法(不计入字符数):
269 characters, and it finds all solutions. Usage (not counted in char count):
我刚刚在这里对 python 进行了一些修剪:
这是一个庞大的 410 个字符,如果不计算空格则为 250 个。 如果你把它变成perl,你无疑会比我的更好!
I've just trimmed the python a bit here:
This is a hefty 410 characters, 250 if you don't count whitespace. If you just turn it into perl you'll undoubtedly be better than mine!