Mine værktøjer
Du er her: Forside Python program eksempler. Cherrypy sudoku

Cherrypy sudoku

Tilbage

Hent filen

Licens GPL

Implementation off sudoku in cherrypy Copyright Bauer Data.

#!/usr/bin/env python
# -*- coding: UTF-8 -*-
#
import sys
sys.path.append("/opt/share/cherry")
import random
import cherrypy
import sets
"""
   +-------+-------+-------+
   |       |       |       |
   |   1   |   2   |   3   |
   |       |       |       |
   +-------+-------+-------+
   |       |       |       |
   |   4   |   5   |   6   |
   |       |       |       |
   +-------+-------+-------+
   |       |       |       |
   |   7   |   8   |   9   |
   |       |       |       |
   +-------+-------+-------+
     En maengde pr square
   +-------+-------+-------+
   | 1 2 3 | 4 5 6 | 7 8 9 | row 1 = [1,2,3,4,5,6,7,8,9] en maengde pr. raekke
   | 5 2 9 | 8 4 1 | 3 6 7 | row 2 = [1,2,3,4,5,6,7,8,9]
   | 4 1 7 | 6 3 9 | 2 5 8 | row 3 = [1,2,3,4,5,6,7,8,9]
   +-------+-------+-------+
   | 8 4 2 | 5 9 7 | 6 1 3 | row 4 = [1,2,3,4,5,6,7,8,9]
   | 7 3 5 | 4 1 6 | 2 9 8 | row 5 = [1,2,3,4,5,6,7,8,9]
   | 9 6 1 | 8 2 3 | 5 4 7 | row 6 = [1,2,3,4,5,6,7,8,9]
   +-------+-------+-------+
   | 3 6 7 | 2 8 9 | 5 1 4 | row 7 = [1,2,3,4,5,6,7,8,9]
   | 4 8 5 | 6 1 7 | 2 3 9 | row 8 = [1,2,3,4,5,6,7,8,9]
   | 2 9 1 | 5 4 3 | 8 6 7 | row 0 = [1,2,3,4,5,6,7,8,9]
   +-------+-------+-------+
    En maengde pr colonne
     1 1 1   1 1 1   1 1 1
     2 2 2   2 2 2   2 2 2
     3 3 3   3 3 3   3 3 3
     4 4 4   4 4 4   4 4 4
     5 5 5   5 5 5   5 5 5
     6 6 6   6 6 6   6 6 6
     7 7 7   7 7 7   7 7 7
     8 8 8   8 8 8   8 8 8
     9 9 9   9 9 9   9 9 9

 All squares must contain the ciffers 1 through 9

 All rows may contain 1 throug 9

 All columns may contain 1 throug 9

 create a "def square():" who produce at legal square.
"""
sqfields=(
( 0, 1, 2,  9,10,11, 18,19,20 ),
( 3, 4, 5, 12,13,14, 21,22,23 ),
( 6, 7, 8, 15,16,17, 24,25,26 ),
(27,28,29, 36,37,38, 45,46,47 ),
(30,31,32, 39,40,41, 48,49,50 ),
(33,34,35, 42,43,44, 51,52,53 ),
(54,55,56, 63,64,65, 72,73,74 ),
(57,58,59, 66,67,68, 75,76,77 ),
(60,61,62, 69,70,71, 78,79,80 ),
)
class sudokusqr:
    """returns a random generated sudoku square"""
    def __init__(self,size=9,safe=True,debug=True):
        self.debug=debug
        self.sqsize=int(pow(size, 0.5))
        self.size=size
        self.squ={}
        self.row={}
        self.safe=True
        self.col={}
        self.generate_sudoku()
        self.f=open("sudoku_solutions_squares.txt","a")

    def init_sets(self):
        for i in range(self.size):
            self.squ[i]=[1,2,3,4,5,6,7,8,9]
            self.row[i]=[1,2,3,4,5,6,7,8,9]
            self.col[i]=[1,2,3,4,5,6,7,8,9]
        # square hold size*size fields.
        self.fields={}
        for i in range(self.size*self.size):
            rowno=i/self.size
            colno=i%self.size
            squno=i/self.sqsize%self.sqsize+i/27*3
            data=[self.row[rowno],self.col[colno],self.squ[squno]]
            # print i,rowno,colno,squno,data
            self.fields[i]=data
        self.square=["0"]*self.size*self.size

    def make_square(self,squareno):
        fields=sqfields[squareno]
        # print squareno,fields
        rollback=True
        rbcount=3
        while rollback:
            rollback=False
            for field in fields:
                # Fetch a random number from col and check if it is in squ and col.
                # if so remove number from row, col and squ set
                # and then place it in square[field]
                row,col,squ=self.fields[field]
                trail=0
                while True:
                    trail+=1
                    number=random.choice(squ)
                    if number in row and number in col:
                        row.remove(number)
                        col.remove(number)
                        squ.remove(number)
                        self.square[field]=str(number)
                        break
                        # print "trail > 20"
                        # print row,col,squ, number
                        # self.Print()
                    if trail > 10:
                        break
                if trail > 10:
                    rollback=True
                    # print "#"*40
                    # print "# No God",field
                    # print "#"*40
                    # print field, row,col,squ, number
                    # self.Print()
                    break
            if rollback:
                self.rollback(squareno)
                rbcount-=1
                if rbcount == 0:
                    return False
        return True

    def rollback(self,squareno):
        fields=sqfields[squareno]
        if self.debug: print "k%s" % squareno,
        for field in fields:
            number=int(self.square[field])
            if self.debug : print number,
            row,col,squ=self.fields[field]
            if number:
                self.square[field]=0
                row.append(number)
                col.append(number)
                squ.append(number)
        if self.debug : print

    def generate_sudoku(self):
        self.init_sets()
        sqrnumbers =[0,4,8,3,6,7,1,2,5]
        # print
        i=0
        while True:
            if self.make_square(sqrnumbers[i]): i+=1
            else:
                i-=1
                self.rollback(sqrnumbers[i])
            if i >= len(sqrnumbers):
                break
    def save(self):
        self.f.write("".join(self.square))
        self.f.write("\n")

    def prt_strg(self):
        return "".join(self.square)

    def Print(self):
        if self.safe:
            self.save()
            return
        for i in range(self.size*self.size):
            if i % (self.size*3)==0:
                print"\n+-------+-------+-------+\n|",
            else:
                if i % (self.size)==0:
                    print"\n|",
            print "%s" % self.square[i],
            if i%self.sqsize==2:
                print"|",

        print"\n+-------+-------+-------+"
class Sudoku(list):
    """read solution square 9*9 and eleminate 9*9 - 16 fields and write i on stdout"""

    def __init__(self, strg):
        list.__init__(self, [d[i*9:(i+1)*9] for i in range(9) for d in [[int(e) for e in strg ]]])

    def __repr__(self):
        return "\n".join([" ".join([str(c) for c in r]) for r in self])

    def prt_strg(self):
        return  "".join(["".join([str(c) for c in r]) for r in self])

    def prt_html(self):
        strg=self.prt_strg()
        htm=['<html><body><h1>Free Sudoku<h2><form action="checkplate" method="POST"><table border="1" cellpadding="4" cellspacing="6">']
        for sqr in range(9):
            if sqr % 3 ==0:
                htm.append('<tr>')
            sq='<td><table border="1" cellspacing="2"><tr> %s %s %s</tr><tr>%s %s %s</tr><tr>%s %s %s</tr></table></td>' % \
                tuple(['<td width=25>&nbsp;&nbsp;'+strg[field]+'&nbsp;&nbsp;</td>' for field in sqfields[sqr]])
            htm.append(sq.replace('&nbsp;&nbsp;0&nbsp;&nbsp;','<input type=text name="%s_%s" value="" size=1 maxlength=2> </input>' % (sqr,field)))
            if sqr % 3 ==2:
                htm.append('</tr>')
        htm.append('</table>')
        htm.append('<table><td valign="top">')
        # htm.append('<input type="submit" value="Check">')
        htm.append('<input type="reset"></form></td>')
        htm.append('<td valign="top"><form method="POST" action="index"><input type=submit value="Ny plade"></form>')
        htm.append('</td></table>')
        htm.append(self.footer())
        htm.append("""<script src="http://www.google-analytics.com/urchin.js" type="text/javascript">
</script>
<script type="text/javascript">
_uacct = "UA-541320-6";
urchinTracker();
</script>""")
        htm.append('</body></html>')
        return '\n'.join(htm)

    def footer(self):
        return """
        <p><a href="http://www.databassen.dk:8090/bauerdata/diverse-filer-til-download-mm/cherrypy-sudoku">Kildetekst til dette program</a>
        </p>
<span>Denne hjemmeside er sponseret af <a href="http://www.bauerdata.dk">Bauer Data.<br></a></span>
<script type="text/javascript"><!--
google_ad_client = "pub-6987251328342779";
google_ad_width = 728;
google_ad_height = 90;
google_ad_format = "728x90_as";
google_ad_type = "text_image";
google_ad_channel ="";
google_color_border = "DDB7BA";
google_color_bg = "FFF5F6";
google_color_link = "0000CC";
google_color_url = "008000";
google_color_text = "6F6F6F";
//--></script>
<script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script>
"""
    def save(self,filename="sudoku_plates.txt"):
        f=open(filename,"a")
        f.write("%s\n"%self.prt_strg())
        f.close()



    def grp(self, i, j):
        return    sets.Set(
             ( self[i][:]
                 + [self[k][j] for k in range(9)]
             + [self[k][l] for k in range(i/3*3, i/3*3+3) for l in range(j/3*3, j/3*3+3)]
             )
            )

    def next(self, i, j): return (i*9+j+1)/9, (i*9+j+1)%9

    def loop(self, i, j):
        if i<9: yield i, j
        while True:
            i, j = self.next(i, j)
            if i>=9: break
            yield i, j

def solve(s, k=0, l=0):
    """Backtracking solver"""
    for i, j in s.loop(k, l):
        if s[i][j] is 0:
            for val in sets.Set(range(1, 10)).difference(s.grp(i, j)):
                s[i][j]=val
                if solve(s,*s.next(i, j)): return s
            s[i][j]=0
            return
    return s

def get_random_pattern(n=9*9,p=20):
    sqsets={}
    for i in range(9):
        sqsets[i]=list(sqfields[i])
    # create solutions containing at least all 9 squares
    # first get a field from each square
    comb=[]
    for i in range(9):
        field=random.choice(sqsets[i])
        sqsets[i].remove(field)
        comb.append(field)

    # then get last p-9 fields random
    antal=0
    iset=range(9)
        # put square 4 raise the possibility to get more squares there
    iset.append(4)
    while antal <= p-9:
        antal+=1
        i=random.choice(iset)
        field=random.choice(sqsets[i])
        sqsets[i].remove(field)
        comb.append(field)
    return comb

def produce(square_solution):
    """return a resolution as a class Sudoku"""
    # print square_solution
    size=9
    rlist=["0"]*size*size
    fset=[x for x in range(81)]
    for field in get_random_pattern(p=27):
        rlist[field]=square_solution[field]
        fset.remove(field)
    orig_square=Sudoku(square_solution)
    # print Sudoku("".join(rlist)).prt_strg()
    solution=""
    while solution != orig_square:
        fnum=random.choice(fset)
        fset.remove(fnum)
        rlist[fnum]=str(orig_square[fnum/9][fnum%9])
        # print Sudoku("".join(rlist)).prt_strg()
        solution=solve(Sudoku("".join(rlist)))
        if  solution:
            # print "found"
            break
        else:
            # print "not found"
            return
    # print '<a>size=',81-rlist.count('0'),'</a>'
    return Sudoku("".join(rlist))


def main_solver(filename="sudoku_solutions_squares.txt"):

    f=open(filename,"r")
    for square_solution in f.xreadlines():
        # test
        # print square_solution
        produce(square_solution)

class SudokuPage:

    def initial_square(self,safe=True,debug=False):
        kvadrat=sudokusqr(safe=safe,debug=debug)
        # print kvadrat.prt_strg()
        self.solution=produce(kvadrat.prt_strg())
        # print solution
        self.solution.save()
        return self.solution.prt_html()

    def index(self):
        # make new sudoku
        return self.initial_square()
    index.exposed = True

    def set_parameters(self,pargs):
        args=[(x,pargs[x]) for x in pargs.keys()]
        self.parameters={}
        for key,value in args:
            self.parameters[key]=value

    def checkplate(self, komando = None,**kargs):
        self.set_parameters(kargs)
        return self.solution.prt_html()

    checkplate.exposed = True

cherrypy.root = SudokuPage()

if __name__ == '__main__':
    cherrypy.config.update(file = 'sudoku.conf')
    cherrypy.server.start()


« august 2018 »
søn man tir ons tor fre lør
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
Chat Rooms
Dyrk motion

Trim ballerup

 

Powered by Plone, the Open Source Content Management System