View difference between Paste ID: JRKaqSed and xQ48ChzX
SHOW: | | - or go back to the newest paste.
1
===================================================================================================================
2
Input/Output
3
===================================================================================================================
4
IN:
5
059000483
6
000000012
7
010028000
8
098074020
9
040080030
10
070630540
11
000160050
12
620000000
13
735000860
14
15
OUT:
16
2 5 9 7 1 6 4 8 3
17
0 6 0 0 0 0 0 1 2
18-
0 1 0 0 2 8 0 0 0
18+
0 1 6 0 2 8 0 0 0
19
0 9 8 0 7 4 0 2 0
20
0 4 0 0 8 0 0 3 0
21-
0 7 0 6 3 0 5 4 0
21+
0 7 0 6 3 0 5 4 8
22
0 8 0 1 6 0 0 5 0
23
6 2 0 0 0 0 0 0 0
24
7 3 5 0 0 0 8 6 0
25
26
===================================================================================================================
27-
Main Function
27+
Main Function - Fixed Version
28
===================================================================================================================
29-
# Jethro Muller
29+
30-
# Assignment 9 - Q3: Sudoku Solver
30+
31-
# MLLJET001
31+
32-
# 12.05.2013
32+
33
    """Function that works with a 2D list as the parameter\nIt returns the list as a list of integers"""
34
    newLst = []
35
    for i in range(9):
36
        newLst.append([int(lst[i][j]) for j in range(9)])
37
    return newLst
38
39
def toIntList(lst):
40
    """Takes a list as the parameter\nIt returns the list as a list of integers"""
41
    return [int(lst[i]) for i in range(9) if type(lst[i])==str]
42
43
def inCol(gridN, i, colN):
44
    """Searches for int i in a column"""
45
    if i in makeCol(gridN, colN):
46
        return True
47
    else:
48
        return False
49
50
def makeCol(gridN, colN):
51
    """Creates the column grid from the grid\nReturns the column grid"""
52
    vertGrid = []
53
    for x in range(9):
54
        placeholder=[]
55
        for y in range(9):
56
            placeholder.append(gridN[y][x])
57
        vertGrid.append(placeholder)
58
    return vertGrid[colN-1]
59
60
def inSquare(nGrid,i, rowN, colN):
61
    """Searches for int i in a grid area"""
62
    if i in makeSquare(nGrid, rowN, colN):
63
        return True
64
    else:
65
        return False
66
67
def makeSquare(nGrid, rowN, colN):
68
    """Creates the specified block from the grid\nReturns the block"""
69
    newTest =[]    
70
    newLst = []
71
    
72
    for i in range(9):
73
        newLst.append([str(nGrid[i][j]) for j in range(9)])
74
    nGrid = newLst
75
    threeby3 = [[] for i in range(3)]
76
    for i in range(9):
77
        newTest.append("".join(nGrid[i]))
78
        for j, s, e in zip(range(3), [0,3,6], [3,6,9]):
79
            threeby3[j].append(newTest[i][s:e])
80
81
    final = [[] for i in range(9)]
82
    for i,j in zip(range(9),[0,1,2]*3):
83
        if i<=2:
84
            final[i] = threeby3[j][0:3]
85
        elif 3<=i<=5:
86
            final[i] = threeby3[j][3:6]
87
        elif 6<=i<=8:
88
            final[i] = threeby3[j][6:9]
89
    return final[determineBlock(rowN, colN)-1]
90
91
def determineBlock(rowN, colN):
92
    """Determines which block the number is in"""
93
    a,b,c = [1,2,3],[4,5,6],[7,8,9]
94
    if rowN in a and colN in a:
95
        return 1
96
    elif rowN in a and colN in b:
97
        return 2
98
    elif rowN in a and colN in c:
99
        return 3
100
    elif rowN in b and colN in a:
101
        return 4
102
    elif rowN in b and colN in b:
103
        return 5
104
    elif rowN in b and colN in c:
105
        return 6
106
    elif rowN in c and colN in a:
107
        return 7
108
    elif rowN in c and colN in b:
109
        return 8
110
    elif rowN in c and colN in c:
111
        return 9
112
113
def populate(grid):
114
    """Populates the grid by generating values and testing them for each position"""
115
    nGrid = []
116
    for i in range(9):
117
        nGrid.append([int(grid[i][j]) for j in range(9)])
118
    for i in range(9): # Rows
119
        rowSet = set(nGrid[i]) #Creates a unique list of numbers from each row
120
        if 0 in rowSet:
121
            rowSet.remove(0)
122
        for j in range(9): #Columns
123
            toAdd=[]
124
            if nGrid[i][j] ==0:
125
                # Creates a unique set of numbers from 1-9 that aren't in the row, column or 3X3 Square
126
                for k in [op for op in range(1,10) if op not in rowSet and (inCol(nGrid, op, j+1)==False and inSquare(nGrid, op, i+1, j+1)==False)]:
127-
            toAdd = []
127+
128
            if len(toAdd)==1:# If there is only one value in that list, it adds it to the grid
129
                nGrid[i][j]=toAdd[0]
130
                toAdd = []
131
            elif len(toAdd)!=0:
132
                print("Row:",i,"Col:",j,"toAdd:",toAdd)
133
                finalCheck = additionalCheck(nGrid, toAdd, i+1, j+1)
134
                if finalCheck!=False and finalCheck!=0:
135
                    nGrid[i][j] = finalCheck
136-
                if finalCheck!=False:
136+
                    finalCheck = 0
137
    print()
138
    print("Old: ")
139
    printGrid(toIntList2D(grid))
140
    print("New: ")
141
    printGrid(toIntList2D(nGrid))
142
    return nGrid
143
144
145
def additionalCheck(grid, toCheck, rowN, colN):
146
    """The final check before moving on the the next square"""
147
    rowCol = [[1,2,3],[4,5,6],[7,8,9]]
148-
    print("To Add:",toCheck)
148+
149
    toAd=[]
150
    for i in range(len(rowCol)):
151-
    toAdd=[]
151+
152
            setRC = set(rowCol[i])
153
            setRC.remove(rowN)
154
            nRow = list(setRC)
155
        if colN in rowCol[i]:
156
            setRC = set(rowCol[i])
157
            setRC.remove(colN)
158
            nCol = list(setRC)
159
    for k in toCheck:
160
        if (k in grid[nRow[0]-1]) and (k in grid[nRow[1]-1]) and (inCol(grid, k, nCol[0])==True and inCol(grid, k, nCol[1])==True) and k not in grid[rowN] and inCol(grid, k, colN)==False:
161-
    print("Row:",nRow)
161+
            toAd.append(k)
162-
    print("Col:",nCol)
162+
    if len(toAd)==1:
163
        return toAd[0]
164-
        if (k in grid[nRow[0]-1]) and (k in grid[nRow[1]-1]) and (inCol(grid, k, nCol[0])==True and inCol(grid, k, nCol[1])==True) and inSquare(grid, k, rowN, colN)==False:
164+
165-
            toAdd.append(k)
165+
166-
    if len(toAdd)==1:
166+
167-
        return toAdd[0]
167+
168
def printGrid(grid):
169
    """Prints the grid in a user friendly format"""
170
    for i in range(len(grid)):
171
        print(" ".join([str(k) for k in grid[i]]))
172
173
174
def main():
175
    fi = open("sudoku.txt", "r")
176
    inFile = fi.read()
177
    grid = [list(i) for i in inFile.split("\n")]
178
    if testSudoku(grid)==True:
179
        printGrid(grid)
180
    else:
181-
    print(inFile)
181+
182
            newGrid = populate(grid)
183
            grid=newGrid[:]
184
            if testSudoku(grid)==True:
185
                printGrid(grid)
186
                break
187
        
188
main()
189
190
191
===================================================================================================================
192
Test Function
193
===================================================================================================================
194
195
def testSudoku(testGrid):#HORIZONTAL CHECK
196
    for i in testGrid:
197
        if len(set(i))!=9:
198
            return False
199
            
200
    #CREATE VERTICAL
201
    vertGrid = []
202
    for x in range(9):
203
        placeholder=[]
204
        for y in range(9):
205
            placeholder.append(testGrid[y][x])
206
        vertGrid.append(placeholder)
207
        
208
        
209
    #VERTICAL CHECK
210
    for i in vertGrid:
211
        if len(set(i))!=9:
212
            return False
213
            
214
    #CHECK 3X3
215
    ##Join
216
    newTest =[]
217
    threeby3 = list([] for i in range(9))
218
    for i in range(9):
219
        newTest.append("".join(testGrid[i]))
220
        for j, s, e in zip(range(3), [0,3,6], [3,6,9]):
221
            threeby3[i].append(newTest[i][s:e])
222
        "".join(threeby3[i])
223
224
    for i in threeby3:
225
        if len(set("".join(i)))!=9:
226
            return False
227
    
228
    return True