`
庄表伟
  • 浏览: 1145807 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

来玩数独吧,抛砖引玉

阅读更多
以前没有学过ruby,这回练练手,用ruby写了一个“出数独题”的小程序。抛砖引玉,看看有没有解数独题的算法被引出来 

Table=Array.new(9)

def getNumber(a)
  return nil if a.length==0
  sum=a.length*10
  l=rand(sum)/10
  return a[l]
end

def setTable(i,j)
  if Table[i][j].class==Fixnum
    0.upto(8) {|pos| Table[i][pos].delete(Table[i][j]) if Table[i][pos].class==Array}
    0.upto(8) {|pos| Table[pos][j].delete(Table[i][j]) if Table[pos][j].class==Array}
    i1=6 if i<9
    i1=3 if i<6
    i1=0 if i<3
    j1=6 if j<9
    j1=3 if j<6
    j1=0 if j<3
    i1.upto(i1+2) do |i2|
      j1.upto(j1+2) do |j2|
	Table[i2][j2].delete(Table[i][j]) if Table[i2][j2].class==Array
      end
    end
  end
end

def resetTable
  0.upto(80) do |x|
    i=x/9
    j=x-i*9
    if Table[i][j].class==Array
      Table[i][j]=[1,2,3,4,5,6,7,8,9]
    end
  end
  0.upto(80) do |x|
    i=x/9
    j=x-i*9
    setTable(i,j)
  end
end

def setTableValue(x)
  return true if x>80
  i=x/9
  j=x-i*9
  num=getNumber(Table[i][j])
  tempa=Table[i][j]
  if num==nil
    return false
  else
    Table[i][j]=num
    setTable(i,j)
    if not setTableValue(x+1)
      Table[i][j]=tempa
      resetTable
      tempa.delete(num)
      Table[i][j]=tempa
      return setTableValue(x)
    else
      return true
    end
  end
end

def initTable
  0.upto(8) do |i|
    Table[i]=Array.new(9)
  end
  0.upto(8) do |i|
    0.upto(8) do |j|
     Table[i][j]=[1,2,3,4,5,6,7,8,9]
    end 
  end
  setTableValue(0)  
end

def getStr(num)
  if num.class==Array
    return '-'
  end
  return num.to_s
end

def showTable
  0.upto(8) do |i|
    0.upto(7) do |j|
      print getStr(Table[i][j])+' '
    end
    print getStr(Table[i][8])+"\n"
  end
end

def cutTable (x)
  0.upto(80) do |num|
    i=num/9
    j=num-i*9
    Table[i][j]=Array.new if rand < x
  end
end


initTable
cutTable(0.8)
showTable
分享到:
评论
25 楼 kim 2007-09-17  
刚接触数读,感觉满有意思的,感觉每一步都靠推算能出来的题设计起来好有难度ki
24 楼 Godlikeme 2007-07-24  
Readonly 写道
老庄,动态语言不是这样写的,你这完全就是披着ruby外衣的java...

其他偶也不多说了,转一行ruby的数独解法代码:
$*.map{|a|(i=a=~/0/)?(v=*?1..?9).fill{|j|v-=[a[j+i-k=i%9],a[k+j*=9],a[j%26+i-i%3-i%27+k]]}+v.map{|k|$*.<<$`<<k<<$'}:p(a)}

将这行代码保存为sudoku.rb,接受的数独题目为从左到右,从上到下的一行字符串(0代表空位),运行:
ruby sudoku.rb 200370009009200007001004002050000800008000900006000040900100500800007600400089001
得出答案:
"284375169639218457571964382152496873348752916796831245967143528813527694425689731"


这样的东西也好叫代码么?
23 楼 suave 2007-07-24  
ruby quiz里面有一个soduku的题目
22 楼 graying 2007-07-24  
想请问一下Readonly:“$*.<<”这个是什么意思啊……
21 楼 hamburg 2007-07-05  
说了这么多,也没有什么牛的,就是人家说好了一道题,叫你用程序实现,这有什么,牛人都去搞数学了,不要搞人家搞完的你在用程序实现?
20 楼 Lich_Ray 2007-07-05  
数独有难易程度之分,一般是先求出一个解,然后去掉其中一部分出题,Readonly说的意思是,这样来做题,只有一个解。
PS: 我觉得上面的程序给出解答的速度已经很快了,用回溯法,是不是就到头了呢?
19 楼 cookoo 2007-06-25  
Readonly 写道
数独的规则是要求只能有一个唯一解,老庄,Eastsun的筛法和raimundox的amb法,都是用随机数来产生,可能会产生多个解的题目,数独是解题容易出题难...

好象更严格的说法是不止只有一个解,而且每一步解法都要能靠逻辑推出来(也就是每一步盘面上至少可以找到一个确定的数字)而不用被迫靠猜的。。。
18 楼 Eastsun 2007-06-25  
庄表伟 写道
Readonly 写道
数独的规则是要求只能有一个唯一解,老庄,Eastsun的筛法和raimundox的amb法,都是用随机数来产生,可能会产生多个解的题目,数独是解题容易出题难...


怎么才能生成只有一个解的数独呢?

目前的零散联想:
1、图的连通性,隐隐约约有点意思。
2、判断逻辑推理是否成立的冗余性,推理的真命题什么的。
3、最笨的办法,自己出题,自己试着穷举解,有多于一个解时,再加一个数,直到只有唯一解为止。


我想是不是可以弄出一个N元一次方程,比较容易看出的是每行每列,每个小九宫的数字和等于45,然后每个数字都属于1~9,
然后看这个方程是不是有唯一解,不过没仔细考虑这个是不是与原题等价,估计还要加其他约束条件.

不过及时把唯一性的弄出来了,这个数独难度的控制似乎也不好办.
17 楼 庄表伟 2007-06-25  
Readonly 写道
数独的规则是要求只能有一个唯一解,老庄,Eastsun的筛法和raimundox的amb法,都是用随机数来产生,可能会产生多个解的题目,数独是解题容易出题难...


怎么才能生成只有一个解的数独呢?

目前的零散联想:
1、图的连通性,隐隐约约有点意思。
2、判断逻辑推理是否成立的冗余性,推理的真命题什么的。
3、最笨的办法,自己出题,自己试着穷举解,有多于一个解时,再加一个数,直到只有唯一解为止。
16 楼 庄表伟 2007-06-25  
deafwolf 写道
我说,数独这东西,拿程序硬上,就没意思了啊

要写,也得写成下面那个flash里面的解法,要么直观法,要么候选数
flash里的是直观法,用来消磨时间相当合适


这个,作为程序员,还是以提供编程技艺为要吧。
单纯的消磨脑力,那很多事情,都能够消磨的,就不必玩编程算法了。

不过,那个flash地址收藏了,
15 楼 simohayha 2007-06-25  
看看这个:

http://perl.abigail.be/Talks/Sudoku/HTML/title.html

14 楼 Readonly 2007-06-25  
数独的规则是要求只能有一个唯一解,老庄,Eastsun的筛法和raimundox的amb法,都是用随机数来产生,可能会产生多个解的题目,数独是解题容易出题难...
13 楼 deafwolf 2007-06-25  
我说,数独这东西,拿程序硬上,就没意思了啊

要写,也得写成下面那个flash里面的解法,要么直观法,要么候选数
flash里的是直观法,用来消磨时间相当合适
12 楼 Eastsun 2007-06-25  
庄表伟 写道
Eastsun 写道
仔细看了一下代码,除了代码写的有点BT外,其算法也没什么特殊的,就是简单的回溯算法.


不像是简单的回溯吧,“j%26+i-i%3-i%27+k”这里面的26,就是个挺奇怪的数字。

这个26是那个ruby版的吧?我不懂ruby,不晓得是不是与java的是同一种算法.
11 楼 Eastsun 2007-06-25  
呵呵,我来给那个JAVA版的做个注释:
/**
* Eastsun注释
*/
class S{
    /**
    * 尝试在b[]的第p-1个位置放置数字
    */
    static void r(char[]b,int p){
        long u=0;     //该long的第k(1至9)位bit代表当前位置是否可以放置数字k(是0否1)
        if(--p<0) System.out.print(b);  //如果p-1<0说明所有位置已经放置好,已经求得一解
        else if(b[p]>48) r(b,p);        //>48,说明该位置是已经填好数字的,不需要尝试
        else{
            for(int i=81;i-->0;)
               u|=
                  // (p-i)%9==0 :就是说p与i是同一列
                  // p/9^i/9==0 :就是说p与i是同一行
                  // p/27^i/27|p%9/3^i%9/3==0: 就是p与i在同一个小九宫
                  // 为什么是这样子?简单的数学题,呵呵.
                  //我来解释一下最后一个,p/27==i/27相当于把大九宫按行分成3下,0~2行,3~5行,6~8行三部分,
                  // 检查p与i是否属于同一个部分
                  // p%9是看p属于那一列,p%9/3是看p属于0~2列,3~5列,6~8列的那一部分
                  // so,p/27^i/27|p%9/3^i%9/3==0时,p与i属于同一小九宫
                  (p-i)%9*(p/9^i/9)*(p/27^i/27|p%9/3^i%9/3)  
                     ==0?
                     1L<<b[i]:         //==0,说明这个位置对当前位置有影响,将u的该位置1
                     0;
            for(b[p]=58;--b[p]>48;)
               if((u>>b[p]&1)<1)       //u>>b[p]&1 <1也就是u>>b[p]&1==0,说明这个b[p]是合理的,
                      r(b,p);          //试探下一个
            //注意这个循环结束条件是 !--b[p]>48,也就是b[p]=='0',最后又将b[p]恢复到'0'不会影响回溯条件.
        }
    }
    public static void main(String[] a){
        //从第80个位置开始试探.
        r(a[0].toCharArray(),81);
    }
}

10 楼 庄表伟 2007-06-25  
Eastsun 写道
仔细看了一下代码,除了代码写的有点BT外,其算法也没什么特殊的,就是简单的回溯算法.


不像是简单的回溯吧,“j%26+i-i%3-i%27+k”这里面的26,就是个挺奇怪的数字。
9 楼 Eastsun 2007-06-24  
仔细看了一下代码,除了代码写的有点BT外,其算法也没什么特殊的,就是简单的回溯算法.
8 楼 Elminster 2007-06-24  
要玩儿算法题,就不要看数独游戏这种鼎鼎有名的东西,早就被无数人用各种方式嚼过无数遍,不管你怎么玩,最后一定都是撞墙。
7 楼 cookoo 2007-06-24  
这也太离谱了吧,one-liner可不是动态语言的风格。

raimundox借助于backtracking库的程序是这类约束问题直观的解法。

6 楼 Eastsun 2007-06-24  
Oh,my god~

相关推荐

    使用EXCEL玩数独游戏的软件

    本人使用EXCEL编制的一个简单的使用EXCEL玩数独游戏。要求不高,只要有EXCEL软件即可。

    数独编辑器 可玩“杀手数独”喔

    小巧的数独编辑器,现在可以编辑标准数独、宫格数独、锯齿数独、超级数独(或者叫窗口数独)、杀手数独、时钟数独等,并且数独的尺寸不限定为3x3,比如宫格数独可以编辑3x2及3x4等等的地图尺寸。压缩包中附带了若干...

    数独游戏数独游戏数独游戏数独游戏数独游戏数独游戏数独游戏.rar

    数独游戏数独游戏数独游戏数独游戏数独游戏数独游戏数独游戏数独游戏数独游戏数独游戏数独游戏数独游戏数独游戏数独游戏数独游戏数独游戏数独游戏数独游戏数独游戏数独游戏数独游戏数独游戏数独游戏数独游戏数独游戏...

    数独验证器_sudoku验证器_数独验证_数独_

    数独是一种广受欢迎的逻辑游戏,它通过填充一个9×9的网格,使得每一行、每一列以及每一个3×3的小宫格内都包含从1到9的所有数字且每个数字不重复,以此来锻炼玩家的逻辑思维和推理能力。本项目提供了一个数独验证器...

    数独代码 数独代码 数独代码

    数独代码数独代码数独代码数独代码数独代码数独代码数独代码数独代码数独代码数独代码数独代码数独代码数独代码数独代码数独代码数独代码数独代码数独代码数独代码数独代码数独代码数独代码数独代码数独代码数独代码...

    数独9X9_MATLAB数独_数独9x9在线_9x9数独_数独_求解9X9数独_

    数独是一种广受欢迎的逻辑游戏,它通过填充一个9×9的网格,使得每一行、每一列以及每一个小的3×3宫格内的数字1到9都只出现一次,来达到解谜的目的。MATLAB作为一种强大的数值计算和编程环境,可以用来编写程序解决...

    采用java来实现数独游戏的求解

    本项目以Java为编程语言,实现了数独游戏的求解算法,不依赖递归,主要利用了Java的IO流来读取数独矩阵。 在Java中,我们通常使用二维数组来表示数独的矩阵。首先,我们需要一个函数来读取数独矩阵。IO流,特别是`...

    关于数独游戏的C++解法

    每个9x9方格的数独游戏都有唯一的解,利用C++可以写出一个代码求出这一唯一解,并输出

    labview_数独实现

    在本文中,我们将深入探讨如何使用LabVIEW(Laboratory Virtual Instrument Engineering Workbench)这一强大的图形化编程环境来实现数独游戏。LabVIEW是由美国国家仪器公司(National Instruments)开发的一款适用...

    原创数独填色高效解法

    填色法的基本思想是通过给数独格子着色来帮助找到唯一解。它通过模拟可能的数字填充,减少回溯的可能性,从而提高了解题速度。 描述中提到“C开发,高效数独算法,一般难度都在微秒级内解决!”这表明这个算法在...

    九宫格(数独)软件 数独

    标题中的“九宫格(数独)软件 数独”指的是一个专门用于玩数独游戏的计算机软件。数独是一种逻辑推理游戏,源自18世纪的瑞士,流行于21世纪初,规则简单却富有挑战性。它通常在9x9的网格中进行,分为9个3x3的小宫格,...

    数独游戏(大家没事下着玩玩,测试一下自己有没有超过5岁的智力)

    标题和描述虽然简洁,但足以引发我们对数独游戏的兴趣,让我们来看看其中蕴含的知识点。 首先,数独游戏的基本规则是:在一个9x9的方格中,分为9个3x3的小宫格,已有一些数字填入,玩家需要根据这些数字,用1到9的...

    数独算法,数独游戏

    "Thread"可能是关于多线程处理的部分,这可能意味着游戏允许用户在同一时间进行多个数独谜题,或者使用多线程来优化算法的性能,比如通过并行计算加速解题过程。在多线程编程中,需要考虑线程安全,确保数据在并发...

    杀手数独100题.doc

    杀手数独游戏可以使用软件来实现,例如:使用Python或Java等编程语言来编写杀手数独游戏的算法和界面。 8. 杀手数独的数学基础: 杀手数独游戏的数学基础是组合数学和图论,涉及到排列组合、图形理论等知识领域。 ...

    数独并行求解源码

    这个项目是针对Intel线程优化大赛设计的,意味着它着重于利用多核处理器的性能来提高数独问题的求解速度。 在并行计算领域,当一个任务被分解成多个子任务,这些子任务可以同时执行,从而缩短整体计算时间。对于...

    数独终结者 标准数独计算器

    在本程序中,可能使用二维数组来表示数独盘面,以便高效地进行计算。 四、编译环境 项目使用Visual Studio 2008进行编译,这是微软的经典IDE,集成了开发、调试、测试等功能,对于C++开发者来说非常友好。选择这个...

    网页版数独计算器

    在这个上下文中,`sudo_xx.c`可能包含了实现数独求解器的函数,这些函数可能采用了回溯法、递归或其它算法来确保填入的数字符合数独规则。数独求解器可以自动填充未完成的数独盘面,帮助用户找到唯一解决方案。 总...

    数独计算器 数独游戏 数独秒算

    数独计算器 数独游戏 数独秒算 本数独游戏 采用分为闯关模式和 随机模式,随机模式中的题库更多,闯关模式会随着 关数的增加而越来越难。2个互不影响。 另外还有个数独计算器,妙算数独。 修复了上次数独计算器的2...

    Python数独游戏源代码

    在Python中,这可以通过二维数组或列表来表示数独盘面,并使用递归或回溯算法来解决。 8. **用户界面**: Pygame提供了丰富的图形界面元素,可以创建按钮、文本框、提示信息等,以增强用户的游戏体验。在"main.py...

    winform数独C#的数独游戏

    winform数独C#的数独游戏 本程序基于.netframework使用C#语言开发,实现功能: 1、各个难度随机出题(New); 2、数独解题提示(Compute); 3、输入的合法性校验; 思路分享 说一下开发步骤及思路: 1、验证合法性...

Global site tag (gtag.js) - Google Analytics