前段时间看到“69岁农民3天破解世界最难数独游戏”,然后在看了那个号称世界最难的数独题目之后,就打算抽空编程解决。今晚抽出一个晚上,大约四五个小时的时间,中间还间歇在clash of clans上造兵和进攻(好吧我承认这不是一个好习惯)。最终,很好地解决了。下面贴出源代码。

unit uSudoku;

interface

uses
Classes, sysutils, forms, windows, dialogs; type
TMapArray = array[.., ..] of Integer;
TSudokuMap = class(TObject)
private
FMap_init: TMapArray;
FMap: TMapArray;
iAnswer: integer;
function checknow(x,y: Integer): boolean;
function get_next_x_y(var xx, yy: Integer): Boolean;
public
ssResults: TStrings;
constructor Create;
destructor Destroy; override;
procedure init(ss: tstrings);
function map_output: string;
procedure onDone();
function go(x,y: Integer): boolean;
end; implementation { TSudokuMap } // 检查当前坐标处的数字是否合法
function TSudokuMap.checknow(x, y: Integer): boolean;
var
i: integer;
ix, iy, xx0, yy0: integer;
begin
result := true; // 检查横向冲突情况
if result then
begin
for i := to do
if (i<>x) and (FMap[i,y]=FMap[x,y]) then
begin
result := false;
break;
end;
end; // 检查竖向冲突情况
if result then
begin
for i := to do
if (i<>y) and (FMap[x,i]=FMap[x,y]) then
begin
result := false;
break;
end;
end; // 检查自己所在9宫格冲突情况
if result then
begin
xx0 := (x-) div * ;
yy0 := (y-) div * ;
for ix := to do
for iy := to do
if ((ix+xx0<>x) or (iy+yy0<>y)) and (FMap[ix+xx0,iy+yy0]=FMap[x,y]) then
begin
result := false;
break;
end;
end;
end; constructor TSudokuMap.Create;
begin
inherited;
iAnswer := ;
ssResults := TStringList.Create;
end; destructor TSudokuMap.Destroy;
begin
FreeAndNil(ssResults);
inherited;
end; function TSudokuMap.get_next_x_y(var xx, yy: Integer): Boolean;
begin
if yy< then
yy := yy+
else
begin
yy := ;
xx := xx+;
end; result := xx<=;
end; // 求解,结果放于ssResults中
function TSudokuMap.go(x, y: Integer): boolean;
var
i: integer;
xx, yy: integer;
begin
if FMap_init[x,y]> then
begin
result := checknow(x,y);
if Result then
begin
xx := x; yy := y;
if get_next_x_y(xx, yy) then
result := go(xx, yy);
end;
end
else
begin
for i := to do
begin
FMap[x,y] := i;
result := checknow(x,y);
if Result then
begin
xx := x; yy := y;
if get_next_x_y(xx, yy) then
begin
result := go(xx, yy);
//if result then break;
end
else
break;
end;
end;
end; if (x=) and (y=) and Result then
onDone(); // 如果本次遍历从1到9均不成功,则将FMap[x,y]复原,以免影响后续计算
if (not Result) then FMap[x,y] := FMap_init[x,y];
end; {-------------------------------------------------------------------------------
主要用于生成数独初始map。输入参数形如:
005300000
800000020
070010500
400005300
010070006
003200080
060500009
004000030
000009700
-------------------------------------------------------------------------------}
procedure TSudokuMap.init(ss: tstrings);
var
s: string;
x, y: integer;
begin
for x := to do
begin
s := ss[x-];
for y := to do
begin
FMap[x,y] := strtoint(s[y]);
FMap_init[x,y] := FMap[x,y];
end;
end;
end; {-------------------------------------------------------------------------------
将FMap以如下形式输出:
. . 5 3 . . . . .
8 . . . . . . 2 .
. 7 . . 1 . 5 . .
...
-------------------------------------------------------------------------------}
function TSudokuMap.map_output: string;
const CR=##;
var
x, y: integer;
s: string;
ch: string;
begin
s := '';
for x := to do
begin
for y := to do
begin
ch := inttostr(FMap[x,y]);
if ch='' then ch:='.';
s := s+ch+' ';
end;
s := s + CR;
end;
Result := s;
end; procedure TSudokuMap.onDone;
var
filename: string;
begin
Inc(iAnswer);
ssResults.Add(IntToStr(iAnswer));
ssResults.Add(map_output);
end; end.

调用代码:

procedure TForm1.go(memo1: TMemo);
var
Sudoku: TSudokuMap;
begin
Sudoku := TSudokuMap.create;
Sudoku.init(Memo1.lines);
mmo1.Text := sudoku.map_output;
sudoku.go(,);
Caption := 'OK! '+datetimetostr(now);
mmo4.Lines.Assign(Sudoku.ssResults);
end; procedure TForm1.btn3Click(Sender: TObject);
begin
go(mmo3);
end;

对于这道题目,程序瞬间解出答案。为了精确计算,我重复了1000次,耗时27秒。

本来还希望能找出一种以上的解,结果只有一解:

1 4 5 3 2 7 6 9 8
8 3 9 6 5 4 1 2 7
6 7 2 9 1 8 5 4 3
4 9 6 1 8 5 3 7 2
2 1 8 4 7 3 9 5 6
7 5 3 2 9 6 4 8 1
3 6 7 5 4 2 8 1 9
9 8 4 7 6 1 2 3 5
5 2 1 8 3 9 7 6 4

===========================

另外,新闻稿上老人解的那道题 http://news.qq.com/a/20130526/005425.htm

这道题录入程序后,用了一秒钟得到唯一解:

8 1 2 7 5 3 6 4 9
9 4 3 6 8 2 1 7 5
6 7 5 4 9 1 2 8 3
1 5 4 2 3 7 8 9 6
3 6 9 8 4 5 7 2 1
2 8 7 1 6 9 5 3 4
5 2 1 9 7 4 3 6 8
4 3 8 5 2 6 9 1 7
7 9 6 3 1 8 4 5 2

而老人把第四行的5改为8后,花了3个月时间才解出来。按照他的改法,程序共发现了133种解法,老人给出的解法是我的第122解。希望老人知道了之后不要太伤心哦~

我来解数独(附delphi源码)的更多相关文章

  1. SpringBoot学习入门之Hello项目的构建、单元测试和热部署等(配图文,配置信息详解,附案例源码)

    前言: 本文章主要是个人在学习SpringBoot框架时做的一些准备,参考老师讲解进行完善对SpringBoot构建简单项目的学习汇集成本篇文章,作为自己对SpringBoot框架的总结与笔记. 你将 ...

  2. 在WebBrowser中执行javascript脚本的几种方法整理(execScript/InvokeScript/NavigateScript) 附完整源码

    [实例简介] 涵盖了几种常用的 webBrowser执行javascript的方法,详见示例截图以及代码 [实例截图] [核心代码] execScript方式: 1 2 3 4 5 6 7 8 9 1 ...

  3. Asp.net MVC集成Google Calendar API(附Demo源码)

    Asp.net MVC集成Google Calendar API(附Demo源码) Google Calendar是非常方便的日程管理应用,很多人都非常熟悉.Google的应用在国内不稳定,但是在国外 ...

  4. winserver的consul部署实践与.net core客户端使用(附demo源码)

    winserver的consul部署实践与.net core客户端使用(附demo源码)   前言 随着微服务兴起,服务的管理显得极其重要.都知道微服务就是”拆“,把臃肿的单块应用,拆分成多个轻量级的 ...

  5. spring事务详解(三)源码详解

    系列目录 spring事务详解(一)初探事务 spring事务详解(二)简单样例 spring事务详解(三)源码详解 spring事务详解(四)测试验证 spring事务详解(五)总结提高 一.引子 ...

  6. [源码]Delphi源码免杀之函数动态调用 实现免杀的下载者

    [免杀]Delphi源码免杀之函数动态调用 实现免杀的下载者 2013-12-30 23:44:21         来源:K8拉登哥哥's Blog   自己编译这份代码看看 过N多杀软  没什么技 ...

  7. QQ2008自动聊天精灵delphi源码

    QQ2008自动聊天精灵delphi源码   unit Unit1;interfaceuses Windows, Messages, SysUtils, Variants, Classes, Grap ...

  8. C#代码生成器附百度云盘源码地址

    今晚闲着没事,写了个代码生成器,在这里只做个抛砖引玉,后面可以继续扩展功能,下方附百度云盘源码地址. 使用数据库:sqlserver 编译器:vs2015 废话不多说,上界面: 程序主界面: 数据库: ...

  9. 转换GMT秒数为日期时间格式-Delphi源码

    转换GMT秒数为日期时间格式-Delphi源码.收藏最近在写PE分析工具的时候,需要转换TimeDateStamp字段值为日期时间格式,这是Delphi的源码. //把GMT时间的秒数转换成日期时间格 ...

随机推荐

  1. codeforces 690C3 C3. Brain Network (hard)(lca)

    题目链接: C3. Brain Network (hard) time limit per test 2 seconds memory limit per test 256 megabytes inp ...

  2. CodeForces937B:Vile Grasshoppers(素数性质)

    The weather is fine today and hence it's high time to climb the nearby pine and enjoy the landscape. ...

  3. Objective-C基础知识

    内联函数 “内联函数”是一个很老的概念,在其他语言譬如C++语言中也出现了.所谓“内联函数”指的是“有函数的结构,但不具备函数的性质,类似于宏替换功能的代码块”. 在实际应用中,常常把规模较小.逻辑较 ...

  4. AFNetworking 2.0教程

    在iOS 7中,Apple更新了iOS中的网络基础架构,新推出的网络基础架构是NSURLSession(原来的网络基础架构NSURLConnection). iOS开发中往往会涉及网络数据处理,像其他 ...

  5. C:static 关键字、静态变量、跨类访问数据

    static 在OC中的使用 参考1   参考2   参考3   参保4    参考5 跨类访问成员 参考 +号方法就是类方法(静态方法),说明不用创建对象,可以直接通过类型去直接调用这个方法,在OC ...

  6. 039--CSS

    一.CSS定义 CSS 规则由两个主要的部分构成:选择器,以及一条或多条声明. ''' selector { property: value; property: value; ... propert ...

  7. Cg profiles,如何使用CGC编译Cg语言(转)

    抄“GPU Programming And Cg Language Primer 1rd Edition” 中文名“GPU编程与CG语言之阳春白雪下里巴人” 计算机只能理解和执行由0.1序列(电压序列 ...

  8. git 保存文件目录

    Ubuntu中git clone就保存在你命令行现在所在的目录里 所以最好推荐 先用cd这个命令去自己想保存的目录 之后再git clone

  9. Ubuntu 设置文件默认打开的应用

    右键单击该文件,然后点击属性,打开属性面板 然后进入open with的选项,选择应用后,点击 set as default

  10. 双拓扑排序 HDOJ 5098 Smart Software Installer

    题目传送门 /* 双拓扑排序:抄的,以后来补 详细解释:http://blog.csdn.net/u012774187/article/details/40736995 */ #include < ...