前段时间看到“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. 【Selenium】测试流程和框架

    流程: 分析自动化测试需求→制定自动化测试计划→设计自动化测试用例→搭建环境→编写脚本→分析结果→维护脚本 框架: 线性测试.模块化测试.数据驱动.关键字驱动

  2. Prime Cryptarithm

    链接 分析:对于三位数我们限定为[100,999],两位数我们限定为[10,99],然后我们依次判断是否满足乘法式且各个数位是否在数列中,若都满足+1 /* PROB:crypt1 ID:wangha ...

  3. maven 简单入门教学实战手册

    Maven那点事儿(Eclipse版)   前言: 由于最近工作学习,总是能碰到Maven的源码.虽然平时工作并不使用Maven,但是为了学习一些源码,还是必须要了解下.这篇文章不是一个全面的Mave ...

  4. spring+mybatis下delete和insert返回值-2147482646

    <bean id="sqlSessionTemplate" class="org.mybatis.spring.SqlSessionTemplate"&g ...

  5. PhpStorm之服务器篇

    打开编辑器,依次点击 Tools->Deloyment->Configuration,进入连接服务器的配置页面 2.点击左上角的 + ,配置一个新的服务器 3.填写添加之后服务器的名称,并 ...

  6. Moctf--没时间解释了

    记录一道简单的题目. 打开后就张这个样子,,然后看到url为index2.php---->所以我们把它改为index.php(用burp抓包才行,这是一个302跳转). 看到它提示我们要uplo ...

  7. 51nod 1428【贪心】

    思路: 就是先排序,然后对每个取最小的结束时间. #include <bits/stdc++.h> using namespace std; typedef long long LL; c ...

  8. Codeforces 378C

    DFS连通块,思路就是搜到底,然后一个一个回溯(填上X)上来 #include <iostream> #include <stdio.h> #include <strin ...

  9. [Shader 着色器]冰霜效果的思考和实现

    http://game.ceeger.com/forum/read.php?tid=23209&fid=2 由于最近要做一个冰系的角色,就想能不能做一些冰霜效果.那么就试试吧,先弄一张原图: ...

  10. poj 2774 Long Long Message【SA】

    把两个串接到一起求一个SA,然后找最大的sa[i]和sa[i-1]不是一个串的he[i] #include<iostream> #include<cstdio> #includ ...