`
庄表伟
  • 浏览: 1145809 次
  • 性别: 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
分享到:
评论
5 楼 庄表伟 2007-06-24  
头撞墙,头自己去撞墙,
头自己头也不回的撞墙去了。。。

经Readonly指点,搜到一个地址:
http://markbyers.com/moinmoin/moin.cgi/ShortestSudokuSolver

楼上的几位,一同去撞墙吧。
4 楼 Readonly 2007-06-24  
老庄,动态语言不是这样写的,你这完全就是披着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"
3 楼 raimundox 2007-06-24  
这个东西用amb最合适了:

class Sudoku
  def initialize
    @square = Array.new(9) { Array.new(9) {0} }
    @amb = Amb.new
  end

  def find_sudoku
    9.times do |row|
       9.times do |col|
          candidate = @amb.choose(*range)
          @square[row][col] = 0
          @amb.assert(count_in_row(row, candidate) == 0)
          @amb.assert(count_in_col(col, candidate) == 0)
          @amb.assert(count_in_sub_square(row, col, candidate) == 0)
          @square[row][col] = candidate
       end
    end
  end

  def range
    result,range = [], [1,2,3,4,5,6,7,8,9]
    9.times do
       result << range[index = rand(range.size)]
       range.delete_at index
    end
    result
  end
 
  def count_in_row row, candidate
    @square[row].inject(0) {|count, num| (num == candidate) ? count + 1 : count}
  end

  def count_in_col col, candidate
    @square.inject(0) {|count, row| (row[col] == candidate) ? count + 1 : count}
  end

  def count_in_sub_square row, col, candidate
    start_row, start_col = row / 3, col / 3
    count = 0
    3.times {|i| 3.times {|j| count += 1 if @square[start_row * 3 + i][start_col * 3 + j] == candidate}}
    count
  end
 
  def create_sudoku number
    find_sudoku    
    number.times { @square[rand(9)][rand(9)] = 0}
  end

  def next
    begin
      @amb.failure
      create_sudoku
    rescue Amb::ExhaustedError
      raise 'no more Sudoku'
    end
  end

  def inspect
    result = ""
    9.times do |row|
       9.times {|col| result << (@square[row][col] == 0 ? '?' : @square[row][col].to_s) << ' '}
       result << "\n"
    end
    result
  end
end

sudoku = Sudoku.new
sudoku.create_sudoku 30
p sudoku



Amb的实现如下(zenspider的实现)

class Amb
  class ExhaustedError < RuntimeError; end

  def initialize
    @fail = proc { fail ExhaustedError, "amb tree exhausted" }
  end

  def choose(*choices)
    prev_fail = @fail
    callcc { |sk|
      choices.each { |choice|
    callcc { |fk|
      @fail = proc {
        @fail = prev_fail
        fk.call(:fail)
      }
      if choice.respond_to? :call
        sk.call(choice.call)
      else
        sk.call(choice)
      end
    }
      }
      @fail.call
    }
  end

  def failure
    choose
  end

  def assert(cond)
    failure unless cond
  end
end
2 楼 Eastsun 2007-06-23  
嘿嘿,偶还是新开个帖吧,赚点积分o(∩_∩)o...哈哈
http://www.iteye.com/post/318866
1 楼 Eastsun 2007-06-23  
嘿嘿,俺来个JAVA版的吧:
public class Solver{
    private static final int SIZE = Puzzler.SIZE;
    private Solver(){
    }
    /**
    * 数独求解
    *@param p 需要求解的数独
    *@return solvable 如果有解,则为true,并且将求得的一个解放置p
    */
    public static boolean solve(Puzzler p){
        int[][]    num =new int[SIZE][SIZE];
        boolean[][] rFlags =new boolean[SIZE][SIZE+1],
                    cFlags =new boolean[SIZE][SIZE+1],
                    zFlags =new boolean[SIZE][SIZE+1];
        for(int r=0;r<SIZE;r++)
            for(int c=0;c<SIZE;c++)
                if(p.isFixed(r,c)){
                    int t =p.getNumber(r,c);
                    num[r][c] =t;
                    rFlags[r][t] =true;
                    cFlags[c][t] =true;
                    zFlags[r/3*3+c/3][t] =true;
                }
                
        int r =0,c =0;
        
outLoop:
        for(;;){//&#
            if(p.isFixed(r,c)){
                c ++;
                if(c>=SIZE){
                    c =0;
                    r ++;
                    if(r>=SIZE) break outLoop;
                }
                continue outLoop;
            } //&#if(p.isFixed())
            int t =SIZE;
            for(c++;;){//&#
                if(t>=SIZE){
                    c --;
                    if(c<0){
                        c =SIZE -1;
                        r --;
                        if(r<0) break outLoop;
                    }
                    if(p.isFixed(r,c)) continue;
                    t =num[r][c];
                    if(t!=0){
                        rFlags[r][t] =false;
                        cFlags[c][t] =false;
                        zFlags[r/3*3+c/3][t] =false;
                        num[r][c] =0;
                    }
                }
                else{
                    t ++;
                    if(!(rFlags[r][t]||
                         cFlags[c][t]||
                         zFlags[r/3*3+c/3][t])
                         ) break;
                }
            }//&#for(c++;;);
            num[r][c] =t;
            rFlags[r][t] =true;
            cFlags[c][t] =true;
            zFlags[r/3*3+c/3][t] =true;   
            c ++;
            if(c>=SIZE){
                c =0;
                r ++;
                if(r>=SIZE) break outLoop;
            } 
        }
        if(r<0) return false;
        for(r=0;r<SIZE;r++)
            for(c=0;c<SIZE;c++)
                if(!p.isFixed(r,c)) p.setNumber(r,c,num[r][c]);
        return true;
    }
    
    public static void main(String[] args){
        Puzzler p =new Puzzler();
        System.out.println(solve(p));
        for(int r =0;r<SIZE;r++){
            for(int c=0;c<SIZE;c++) System.out.print(p.getNumber(r,c)+" ");
            System.out.println();
        }
    }
}

相关推荐

    使用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