ナンプレ(5)

こんなデータがあったとする。

12  3  4
5  6  7
8  9 
2  3  4
5  6  7
8  9 
2  3  4
5  6  7
8  9 
2  3  4
5  6  7
8  9 
2  3  4
5  6  7
8  9 
4  5  6
7  8  9
4  5  6
7  8  9
4  5  6
7  8  9
2  3  4
5  6  7
8  9 
2  3  4
5  6  7
8  9 
2  3  4
5  6  7
8  9 
12  3  4
5  6  7
8  9 
2  3  4
5  6  7
8  9 
4  5  6
7  8  9
4  5  6
7  8  9
4  5  6
7  8  9
4  5  6
7  8  9
4  5  6
7  8  9
4  5  6
7  8  9
4  5  6
7  8  9
4  5  6
7  8  9
4  5  6
7  8  9
231  4  5
6  7  8
2  3  4
5  6  7
8  9 
1  2  3
4  5  6
7  8  9
1  2  3
4  5  6
7  8  9
2  3  4
5  6  7
8  9 
1  2  3
4  5  6
7  8  9
1  2  3
4  5  6
7  8  9
1  3  4
5  6  7
8  9 
1  2  4
5  6  7
8  9 
1  2  3
4  5  6
7  8  9
2  3  4
5  6  7
8  9 
1  2  3
4  5  6
7  8  9
1  2  3
4  5  6
7  8  9
2  3  4
5  6  7
8  9 
1  2  3
4  5  6
7  8  9
1  2  3
4  5  6
7  8  9
1  3  4
5  6  7
8  9 
1  2  4
5  6  7
8  9 
1  2  3
4  5  6
7  8  9
2  3  4
5  6  7
8  9 
1  2  3
4  5  6
7  8  9
1  2  3
4  5  6
7  8  9
2  3  4
5  6  7
8  9 
1  2  3
4  5  6
7  8  9
1  2  3
4  5  6
7  8  9
1  3  4
5  6  7
8  9 
1  2  4
5  6  7
8  9 
1  2  3
4  5  6
7  8  9
2  3  4
5  6  7
8  9 
1  2  3
4  5  6
7  8  9
1  2  3
4  5  6
7  8  9
2  3  4
5  6  7
8  9 
1  2  3
4  5  6
7  8  9
1  2  3
4  5  6
7  8  9
1  3  4
5  6  7
8  9 
1  2  4
5  6  7
8  9 
1  2  3
4  5  6
7  8  9
2  3  4
5  6  7
8  9 
1  2  3
4  5  6
7  8  9
1  2  3
4  5  6
7  8  9
2  3  4
5  6  7
8  9 
1  2  3
4  5  6
7  8  9
1  2  3
4  5  6
7  8  9
1  3  4
5  6  7
8  9 
1  2  4
5  6  7
8  9 
1  2  3
4  5  6
7  8  9
2  3  4
5  6  7
8  9 
1  2  3
4  5  6
7  8  9
1  2  3
4  5  6
7  8  9
2  3  4
5  6  7
8  9 
1  2  3
4  5  6
7  8  9
1  2  3
4  5  6
7  8  9
1  3  4
5  6  7
8  9 
1  2  4
5  6  7
8  9 
1  2  3
4  5  6
7  8  9

2と3を含む右上の3×3のセルを考えると、1が入る可能性があるのは3の隣だけである。よってここには1が入る。3×3のセルだけでなく縦と横も考えた。



from math import *

class cNumberPlace:
def __init__(self, n):
if type(n) is int:
self.a = [ [ -1 for i in range(n) ] for j in range(n) ]
elif type(n) is str:
self.a = [ ]
f = open(n, "r")
self.a = [ line.strip('\n').split(',') for line in f.readlines() ]
f.close()
if type(self.a) is int:
print self.a
for row in self.a:
for j in range(len(row)):
if len(row[j]) == 0:
row[j] = -1
else:
row[j] = int(row[j])
self.length = len(self.a)
self.short_length = int(sqrt(self.length))
for row in self.a:
for j in range(len(row)):
if row[j] == -1:
row[j] = range(1, self.length + 1)

def __str__(self):
buff = ""
for row in self.a:
buff += str(row) + "\n"
return buff;

def strHTML(self):
buff = "<table border>\n"
for row in self.a:
buff += "<tr>"
for j in range(len(row)):
cell = row[j]
if type(cell) is int:
buff += "<td style=\"font-size:24;text-align:center\">"
buff += str(cell) + "</td>"
else:
buff += "<td style=\"font-size:9\">"
for i in range(len(cell)):
if i % self.short_length == 2:
buff += str(cell[i]) + "<br>"
else:
buff += str(cell[i]) + "  "
buff += "</td>"
buff += "</tr>\n"
buff += "</table>\n"
return buff;

def run(self):
for r in range(self.length):
for c in range(self.length):
cell = self.a[r][c]
if type(cell) is int:
self.run_to_remove(r, c)

for r in range(self.length):
self.run_to_fix_in_row(r)
for c in range(self.length):
self.run_to_fix_in_column(c)
for i in range(self.length):
self.run_to_fix_in_large_cell(i)

def run_to_remove(self, r, c):
num = self.a[r][c]
for cell in self.gen_in_row(r):
if type(cell) is list:
self.remove(cell, num)
for cell in self.gen_in_column(c):
if type(cell) is list:
self.remove(cell, num)
for cell in self.gen_in_large_cell(r, c):
if type(cell) is list:
self.remove(cell, num)

def run_to_fix_in_row(self, r):
pos = self.set_single_num_pos(self.gen_in_row(r))
for x in range(1, self.length + 1):
if pos[x] >= 0:
self.a[r][pos[x]] = x

def run_to_fix_in_column(self, c):
pos = self.set_single_num_pos(self.gen_in_column(c))
for x in range(1, self.length + 1):
if pos[x] >= 0:
self.a[pos[x]][c] = x

def run_to_fix_in_large_cell(self, i):
pos = self.set_single_num_pos(self.gen_in_large_cell2(i))
for x in range(1, self.length + 1):
if pos[x] >= 0:
self.a[i/3*3+pos[x]/3][(i%3)*3+pos[x]%3] = x

def set_single_num_pos(self, gen):
pos = [ -1 for i in range(self.length + 1) ]
counter = 0
for cell in gen:
if type(cell) is list:
for x in cell:
if pos[x] == -1:
pos[x] = counter
else:
pos[x] = -2
else:
pos[cell] = -2
counter += 1
return pos

def gen_in_row(self, r):
for c in range(self.length):
yield self.a[r][c]

def gen_in_column(self, c):
for r in range(self.length):
yield self.a[r][c]

def gen_in_large_cell(self, r0, c0):
r_start = r0 - (r0 % 3)
c_start = c0 - (c0 % 3)
for r in range(r_start, r_start + 3):
for c in range(c_start, c_start + 3):
yield self.a[r][c]

def gen_in_large_cell2(self, i):
r_start = i / 3 * 3
c_start = (i % 3) * 3
for r in range(r_start, r_start + 3):
for c in range(c_start, c_start + 3):
yield self.a[r][c]

def remove(self, cell, num):
for i in range(len(cell)):
if cell[i] == num:
cell[i:i+1] = [ ]
break

np = cNumberPlace("numplace2.csv")
np.run()
print np.strHTML();