[python] Řešení Sudoku
Jakub Vojáček
jakohv na seznam.cz
Středa Listopad 7 21:38:22 CET 2007
Ahoj
Pracuji na programu řešícím Sudoku. Udělal jsem část programu, která postupuje podobně jako když to řeším já (zjištuje, to kde která čísla být nesmí a podle toho doplní). Pokud ale tato část nebyla schopna doplnit celou mřížku, musím ji doplnit jiným mechanismem.
Zkusil jsem naprogramovat mechanism na zkoušení všech možných variant. Postupně procházím celým polem a pokud narazím na políčko, které bylo na začátku prázdné, zvětším jeho hodnotu +1. Potom testuju zda upravné políčko "pasuje" do sudoku (jestli není v řadě, čáře, čtverci 2x). Pokud pasuje, posunu se v poli dál, pokud ne opakuje se celý cyklus kdy zvětšuju hodnotu políčka o jedno. Pokud hodnota políčka překročí maximální povolenou hodnotu, vynuluju ho a vracím se zkoušet o jedno políčko zpět.
Takto vypadá algrotitmus:
# -*- coding: cp1250 -*-
import copy
from math import sqrt
def vypis(co,sirka):
ctverec=int(sqrt(sirka))
for x in range(len(co)):
if x % ctverec == 0 and x != 0:
print int(2.5*sirka)*"-","\n",
for y in range(len(co[x])):
if y % ctverec == 0 and y != 0:
print "|",
print co[x][y],
print ""
class SudokuDores:
def __init__(self):
pass
def find_vzad(self,pos):
pos=self.nuly.index(pos)-1
if pos < 0:return -1
pos=self.nuly[pos]
return pos
def pasuje(self, x,y,co):
#hor:
if co in self.zadani[x]:
return False
s=[]
#ver
for prvek in self.zadani:
s.append(prvek[y])
if co in s:
return False
#rec
cx,cy=x/self.ctverec,y/self.ctverec
s=[]
for x in range((cx*self.ctverec+self.ctverec)-cx*self.ctverec):
for y in range((cy*self.ctverec+self.ctverec)-cy*self.ctverec):
s.append(self.zadani[x][y])
s.sort()
if co in s and range(1,self.sirka+1) != s:
return False
return True
def pocitej(self, zadani):
self.zadani=zadani
self.kontrola=copy.deepcopy(self.zadani)
self.sirka=len(self.zadani[0])
self.ctverec = int(sqrt(self.sirka))
self.nuly=[]
cislo=0
for prvek in self.zadani:
for x in prvek:
if x == 0:
self.nuly.append(cislo)
cislo=cislo+1
pos=0
while pos >= 0:
if pos >= self.sirka**2-1:
print "Nalezeno řešení:"
vypis(self.zadani,self.sirka)
break
x=pos/self.sirka
y=pos%self.sirka
if self.kontrola[x][y] == 0:
h=self.zadani[x][y]+1
if h > self.sirka:
self.zadani[x][y] = 0
pos=self.find_vzad(pos)
else:
if self.pasuje(x,y,h):
pos=pos+1
self.zadani[x][y]=h
else:
pos=pos+1
def je_ok(self, seznam):
_=range(1,self.sirka+1)
s=[]
for prvek in seznam:
s.append(prvek)
for prvek in _:
if s.count(prvek) > 1 and prvek != 0:
return False
return True
def je_sudoku(self, _zadani):
zadani=copy.deepcopy(_zadani)
for radek in zadani:
if not self.je_ok(radek):
return False
zadani=copy.deepcopy(_zadani)
for x in range(self.sirka):
s=[]
for p in range(len(zadani)):
s.append(zadani[p][x])
if not self.je_ok(s):
return False
return True
if __name__ == "__main__":
zadani1=[
[2,0,4,0,1,0,0,0,0],
[6,1,5,0,0,0,0,0,4],
[0,0,0,9,6,0,0,0,0],
[3,0,7,0,0,1,0,0,0],
[0,4,0,0,0,0,0,5,0],
[0,0,0,4,0,0,9,0,3],
[0,0,0,0,3,9,0,0,0],
[1,0,0,0,0,0,6,2,0],
[5,7,2,0,8,0,3,0,9],
]
zadani2=[
[0,0,2,0],
[2,0,1,4],
[0,1,3,2],
[0,0,0,0],
]
r=SudokuDores()
r.pocitej(zadani2)
Pokud ho spustíte, spočítá správně sudoku o 4 sloupcích. Ale pokud mu zadám "zadani1" nedojdu k žádnému výsledku.
Kde je chyba?
Děkuji
Jakub 'Blujacker' Vojáček
------------- další část ---------------
HTML příloha byla odstraněna...
URL: http://www.py.cz/pipermail/python/attachments/20071107/ef61781a/attachment.htm
Další informace o konferenci Python