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 |