Bu arada ufak bir hata yapmışım, bundan ötürü 4’lü sator karelerinde 14 tane eksik buldu. Ama sonradan başka bir hatayı fark ettim, onu da düzelttim. Sizin kodlarda da benzer bir hata vardı, onları da düzelttim.
Aşağıdaki kodların artık bütün sator karelerini buluyor olması lazım.
import json
from itertools import permutations, product
def read_json(filename):
with open(filename, encoding="utf-8") as f:
return json.load(f)
def filter_words(words, length):
data = [x for i in words if len(x := i["word"]) == length]
return [i for i in data if i[::-1] in data]
def possible_sator_words(x, y, index=(1, -2)):
cases = [i for i in x if y[index[0]] == i[0] and y[index[1]] == i[-1]]
if sum(map(abs, index)) == (len(y) if len(y) % 2 else len(y) - 1):
return cases
else:
return [cases, possible_sator_words(x, y, (index[0] + 1, index[1] - 1))]
def is_sator_square(lst):
return all(lst[m] == "".join([j[m] for j in lst]) for m in range(len(lst)))
def find_sator_squares(words, length):
words = filter_words(words, length)
array = []
for word in words:
if all(possibilities := possible_sator_words(words, word)) and len(possibilities) >= 1:
sator_group = [[word]] + (possibilities if length % 2 else [possibilities])
for p in product(*sator_group):
for perm in permutations(p, length - 2):
perm += tuple(j[::-1] for j in perm[:2])[::-1]
if (
is_sator_square(perm)
and
sorted(perm) not in array
and all(perm.count(i) == 1 for i in perm)
):
array += [sorted(perm)]
return array
Sizin yazdığınız kodlar ile aldığınız çıktıların içinde duplicate değerler de var. Yani listede hem, [x, y, z, m, n] hem de [n, m, z, y, x] gibi duplicate değerlere rastlıyoruz. Bunu önlemek için kodunuzda ufak değişiklikler yapacağım.
Mesela sizin 5’li sator karelerini bulan programı şöyle değiştirelim:
def sator5_procedural(words):
words = filter_words(words, 5)
output = []
for k1 in words:
if k1==k1[::-1]:
continue
for k2 in words:
if k2==k2[::-1]:
continue
if k1[1]!=k2[0] or k1[3]!=k2[4]:
continue
for k3 in words:
if k3!=k3[::-1] or k3[0]!=k1[2] or k3[1]!=k2[2]:
continue
k4 = k2[::-1]
k5 = k1[::-1]
array = [k1, k2, k3, k4, k5]
if sorted(array) not in output:
output.append(sorted(array))
return output
Şimdi de, fonksiyonları karşılaştıralım:
words = read_json("words.json")
five_sator1 = find_sator_squares(words, 5)
five_sator2 = sator5_procedural(words)
print(len(five_sator1)) # 22
print(len(five_sator2)) # 22
Şimdi de, 4’lü sator karelerini bulan programınızı fonksiyona alalım, benzer bir değişikliği onda da yapalım:
def sator4_procedural(words):
words = filter_words(words, 4)
output = []
for k1 in words:
for k2 in words:
if k1[1]!=k2[0] or k1[2]!=k2[3]:
continue
k3 = k2[::-1]
k4 = k1[::-1]
array = [k1, k2, k3, k4]
if sorted(array) not in output:
output.append(sorted(array))
return output
Şimdi fonksiyonları karşılaştıralım:
four_sator1 = find_sator_squares(words, 4)
four_sator2 = sator4_procedural(words)
print(len(four_sator1)) # 76
print(len(four_sator2)) # 78
Yazdığım fonksiyon, sizin yazdığınız fonksiyondan 2 eksik buldu. Bakalım bunlar neymiş:
for i in four_sator2:
if i not in four_sator1:
print(i)
Aşağıdaki elemanlar sizin listenizde fazladan bulunuyorlar.
['AKAK', 'AKAK', 'KAKA', 'KAKA']
['AMMA', 'AMMA', 'TAAT', 'TAAT']
Bunların da olmaması lazım sanırım?