shudu="
0 0 9 | 0 0 0 | 8 0 5
0 0 0 | 1 4 5 | 0 0 0
7 0 5 | 0 9 0 | 0 0 3
---------------------
0 7 0 | 0 3 0 | 0 4 0
0 0 0 | 4 0 6 | 0 0 0
0 3 0 | 0 2 0 | 0 6 0
---------------------
8 0 0 | 0 0 0 | 1 0 7
0 0 0 | 6 8 1 | 0 0 0
5 0 3 | 0 0 0 | 6 0 0
"
#转换关系
# block = (line-1)/3*3+1+(row-1)/3
# index = (line-1)%3*3+1+(row-1)%3
# line = (block-1)/3*3+1+(index-1)/3
a = []
def init(a, shudu)
#init arrary a[][]=[1...9]
for index in 1..9
a[index] = []
for subindex in 1..9
a[index][subindex]=[1,2,3,4,5,6,7,8,9]
end
end
#fill the number into arrary
inputlines=shudu.split("\n")
cur = 1
inputlines.each do |line|
regex=/(\d) (\d) (\d) \| (\d) (\d) (\d) \| (\d) (\d) (\d)/
arr = line.scan(regex)
if(arr.size>0)
arr[0].each_with_index{|m,i|
if(m.to_i!=0)
block = (cur-1)/3*3+1+i/3
index = (cur-1)%3*3+1+i%3
a[block][index]=m.to_i
end
}
end
if line=~ regex then cur = cur +1 end
end
#clear same number in same block/row/line
for num in 1..9
kitout(a,num)
end
end
def kitout(a, num)
for block in 1..9
index = block_has_num(a, num, block)
if(index > 0)
delete_num_in_block(a, num, block)
delete_num_in_same_line(a, num, block, index)
delete_num_in_same_row(a, num, block, index)
end
end
end
def block_has_num(a, num, block)
for index in 1..9
return index if a[block][index] == num
end
return 0
end
def delete_num_in_block(a, num, block)
for index in 1..9
a[block][index].delete(num) if a[block][index].is_a?(Array)
end
end
def delete_num_in_same_line(a, num, block, index)
cur = (block-1)/3
for i in cur*3+1..(cur+1)*3
subcur=(index-1)/3
for j in subcur*3+1..(subcur+1)*3
a[i][j].delete(num) if a[i][j].is_a?(Array)
end
end
end
def delete_num_in_same_row(a, num, block, index)
for i in 0..2
cur = (block+2)%3 +1+ 3*i
for j in 0..2
subcur=index%3+3*j
a[cur][subcur].delete(num) if a[cur][subcur].is_a?(Array)
end
end
end
def loop_find_and_delete(a)
findcount = 0
for num in 1..9
findcount = findcount + findout(a, num)
end
return findcount
end
#对具体number进行遍历block确认
def findout(a, num)
findCount = 0
for block in 1..9
index = find_block_certain_num(a, block, num)
if(index > 0)
a[block][index] = num
delete_num_in_block(a, num, block)
delete_num_in_same_line(a, num, block, index)
delete_num_in_same_row(a, num, block, index)
findCount = findCount + 1
end
end
return findCount
end
#找到区块中确定的值
def find_block_certain_num(a, block, num)
count = 0
tempIndex = 0
for index in 1..9
return 0 if a[block][index] == num
return index if(a[block][index]==[num])
if (a[block][index].is_a?(Array)) and (a[block][index].include?(num))
count = count +1
tempIndex = index
end
end
if(count == 1)
return tempIndex
end
return 0
end
#填充一个数字时,相关行、列,小块做处理
def fill_a_num(a, block, index, num)
a[block][index] = num
delete_num_in_block(a, num, block)
delete_num_in_same_line(a, num, block, index)
delete_num_in_same_row(a, num, block, index)
end
#判断是否是正确结果
def check_result(a)
failFlag = false
numCount = 0
for block in 1..9
for index in 1..9
if a[block][index].size == 0 # this kind []
failFlag = true
break
end
numCount = numCount + 1 if a[block][index].is_a?(Integer) # calculate the total certain number
end
end
return "back" if(failFlag)
return "pass" if(numCount==81)
return "next"
end
#从两个数中挑选一个进行尝试
def decide_one_num_between_two(a)
check = check_result(a)
if(check=="back")
#puts " ==fail=="
return false
end
if(check=="pass")
#puts " ==pass=="
print_result(a)
return true
end
#puts " ==next=="
for block in 1..9
for index in 1..9
if a[block][index].size == 2
numberList = a[block][index]
for times in 0..1
# deepcopy array a
tempArray = a + []
for x in 1..9
tempArray[x] = a[x]+[]
for y in 1..9
tempArray[x][y] = a[x][y]+[] if a[x][y].is_a?(Array)
tempArray[x][y] = a[x][y] if a[x][y].is_a?(Integer)
end
end
#print "block:#{block} index:#{index} number:#{numberList[times]}"
#choose one number
fill_a_num(tempArray, block, index, numberList[times])
while(loop_find_and_delete(tempArray)>0) do {} end
return if (decide_one_num_between_two(tempArray))
end
return
end
end
end
end
def print_array(a)
for index in 1..9
puts "--#{index}"
for subindex in 1..9
puts "--|--#{subindex}:#{a[index][subindex]}"
end
end
end
def print_result(a)
for i in 1..9
for j in 1..9
block = (i-1)/3*3+1+(j-1)/3
index = (i-1)%3*3+1+(j-1)%3
print "%d " % a[block][index] if a[block][index].is_a?(Integer)
print "0 " if a[block][index].is_a?(Array)
print "| " if j%3==0 and j < 8
end
print "\n"
print "---------------------\n" if i%3==0 and i < 8
end
puts "*"*22
end
init(a, shudu)
#print_result(a)
while(loop_find_and_delete(a)>0)do{}end
#print_array(a)
decide_one_num_between_two(a)
测试结果
可运行文件下载链接:点我下载