Sator Kareleri için türkçe sözlük veritabanı arayışı

Aklıma takıldı yeri gelmişken bir şey sorayım. Pythonda aşağıdaki iki kod arasında hız farkı var mı?

if karışıkfonksiyon and karışıkfonksiyon2:

Veya


if karışıkfonksiyon:
    if karışıkfonksiyon2:

Kusura bakmayın cepten kod yapamadım güzel.

Yani birincinin false olması durumunda and li olan ikinci fonksiyona bakıyor mu?

This is a short-circuit operator, so it only evaluates the second argument if the first one is true.
Built-in Types — Python 3.12.1 documentation

1 Beğeni

Soyle yaptim, daha optimize etmeye calismadim:

def sator(words, length):
	words = list(filter(lambda w: len(w) == length, words))

	prefixes = [set(map(lambda w: w[:n+1], words)) for n in range(length)]
	pfx_set = set().union(*prefixes)

	indices = [0] * length

	class NoMoreRolls(Exception): pass
	def roll(digit):
		if digit < 0:
			raise NoMoreRolls()
		indices[digit] += 1
		if indices[digit] >= len(words):
			roll(digit - 1)
		else:
			for d in range(digit + 1, length):
				indices[d] = 0

	permutations = len(words)**length - 1
	try:
		while True:
			chosen = [words[i] for i in indices]
			progress = sum([indices[length-1-n] * len(words)**n for n in range(length)])
			print(f"÷ {progress / permutations:.6f} ({progress}/{permutations}) -> {chosen}", end="\r")

			def check_or_roll():
				for row in range(length):
					for col in range(length):
						vert = "".join([w[col:col+1] for w in chosen[:row+1]])
						if vert not in pfx_set:
							roll(row)
							return
				yield chosen
				roll(length - 1)

			yield from check_or_roll()

	except NoMoreRolls:
		pass

#with open('/usr/share/hunspell/tr_TR.dic', 'r') as f:
#	words = [w.strip().partition('/')[0].upper() for w in f.readlines()[1:]]

import json
with open('words.json', 'r') as f:
	words = [x['word'] for x in json.load(f)]

print(len(words), "words")

import random
#random.shuffle(words)

for i, sq in enumerate(sator(words, 5)):
	print(f"----- #{i} -----")
	print("\n".join(sq))
	print("----- ----- -----")

hunspell sozlugu feci, 370k kelime var!

Edit:

vert'i hesaplamak uzun suruyor diye str yerine tuple kullanmayi denedim, ama daha da yavasladi.

Sanirim en iyisi kendi Kelime sinifini kullanmak. Alfabe sabit oldugu icin tum kelimeler tek bir integer’a cevrilebilir, uzunluga dikkat edilirse. Yanlis hesaplamadiysam 6 harfli kelimeler 32 bite sigiyor. Prefix seti yerine 2^32 bitlik bitmap kullanilabilir; o zaman lookup O(1)'e duser ama sanki asil darbogaz vert'i uretmek.

1 Beğeni

Sözlük elimde olmadığı için deneyemiyorum.

Kaç tane 5 li sator karesi çıkıyor? Altılı veya yedili sator karesi var mı?

Bir de sözlüğü paylaşırsan sevinirim.

https://packages.debian.org/sid/hunspell-tr

Yukaridaki kodu calistirdin mi? Yakin zamanda bitecege benzemiyor…

Ama yukaridan ve soldan okunan kareleri ariyorum ben. Tersleri de almak icin kelimeleri palindromlara limitlemek lazim.

Bilgisayara geçince çalıştıracağım. Benim kodda 80 di sanırım beşli sator (palindrom satorlar hariç)

Evet, yanlis soyledim: Tersten de okunmasi icin palindrom olmasi sart degil.

Palindrome filtrelemesi koymadim, ama tersten okunma gereksinimi olunca, (insani surelerde calismanin yaninda):

Yukaridaki kodda ı/İ 'ler duzgun degil. Duzeltince:

words.json:
4 → 2079
5 → 415
6+ → yok

hunspell-tr:
4 → 17652
5 → 9561
6 → yok :frowning:

Beşliler words.json da nasıl o kadar fazla çıktı? Benim kod eksik sanırım o zaman.

Olabilir. Ben brute force’tan hallice, her dizilime bakiyorum.

6’li tersten okunabilir yok, → ve ↓ dizilimine bakiyorum simdi.

O kadar cok olasilik var ki, kac (milyon, bin) yilda biter hesaplayamiyorum.

Ama kaldigi yerden devam etme ozelligi ekledim. Isterseniz bolusebiliriz :slight_smile:

import random
import time

def sator(words, length, reversible=True, start_from=None):
	words = list(filter(lambda w: len(w) == length, words))

	if reversible:
		words_set = set(words)
		words = list(filter(lambda word: "".join(reversed(word)) in words_set, words))

	alphabet = sorted(list(set([l for w in words for l in w])))
	word_to_tuple = lambda word: tuple(map(alphabet.index, word))
	tuple_to_word = lambda tup: ''.join(map(lambda i: alphabet[i], tup))

#	words = list(map(word_to_tuple, words))

	prefixes = [set(map(lambda w: w[:n+1], words)) for n in range(length)]
	pfx_set = set().union(*prefixes)

	if start_from is not None:
		indices = start_from
	else:
		indices = [0] * length

	class NoMoreRolls(Exception): pass
	def roll(digit):
		if digit < 0:
			raise NoMoreRolls()
		indices[digit] += 1
		if indices[digit] >= len(words):
			roll(digit - 1)
		else:
			for d in range(digit + 1, length):
				indices[d] = 0

	permutations = len(words)**length - 1
	try:
		while True:
			chosen = [words[i] for i in indices]

			if random.random() < .01:
				progress = sum([indices[length-1-n] * len(words)**n for n in range(length)])
				print(f"÷ {progress / permutations:.6f} -> {chosen} ({indices})", end="\r")
#				print(f"÷ {progress / permutations:.6f} -> {tuple(map(tuple_to_word, chosen))}", end="\r")

			def check_or_roll():
				for row in range(length):
					for col in range(length):
						vert = "".join([w[col] for w in chosen[:row+1]])
#						vert = tuple(w[col] for w in chosen[:row+1])
						if vert not in pfx_set:
							roll(row)
							return
				yield chosen
#				yield tuple(map(tuple_to_word, chosen))
				roll(length - 1)

			yield from check_or_roll()

	except NoMoreRolls:
		pass

toupper_tr = lambda word: word.replace('ı', 'I').replace('i', 'İ').upper()

with open('/usr/share/hunspell/tr_TR.dic', 'r') as f:
	words = [toupper_tr(w.strip().partition('/')[0]) for w in f.readlines()[1:]]

#import json
#with open('/tmp/words.json', 'r') as f:
#	words = [x['word'] for x in json.load(f)]

print(len(words), "words")
#random.shuffle(words)

for i, sq in enumerate(sator(words, 6, False, start_from=[0, 0, 0, 0, 0, 0])):
	print(f"----- #{i} -----")
	print("\n".join(sq))
	print("----- ----- -----")

Aşağıdaki gibi bir algoritma izledim. Senin de bulduğun gibi 175 tane 5’li sator karesi buldu ancak 4’lü sator karesi sayısı senin bulduğundan daha az.

4’lü sator karesi: 145
5’li sator karesi: 175

Algoritma şöyle:

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)
    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):
                        yield perm
words = read_json("words.json")
print(len(list(find_sator_squares(words, length=4))))  # 145
print(len(list(find_sator_squares(words, length=5))))  # 175
1 Beğeni

words.json’dan buldugum 399 adet 5’li:

QlpoOTFBWSZTWca8kvUAIJHWbAAQQIQ+L906AIAAAUAADgBgCV7yp8ZBAgh47BTtba3nADCiDVTT
Hv1VQYQDJoDJ/qG/VKoGCDI0wUAAAAAEp+qSKnqnoynpojaACIpKf6lNqnmpMAACklIlPUCG1HoP
VGnuqgOwKoD28vMJLaEltCS2hJbtG7tG7tG7tH+1ZX3q666o3do/6XObRxzm0clzm0fbOc5Ru7R9
feTvXHC1ghjjI6NAEgpollCYbXxN3m3wzvaN3aOpc5tHHObRyXOaEmOtaZC2hJ3bybrjhawQxxkd
GgCRU0W0JhtdyW6pho2vvvsbAHgAegyVf80do2jaNo2jaNo30qnKvMdCzQsZWNJi4xRdXclsX5Kv
hfH1jbY22AoKCj3893d3es7qpXXagoKCjvvd3q7rMV12oKCgNvfvu709y9e8bq7sbnyD/ZEPoYLG
I1hrKNoTBYLAwNWrVqarNWFtEsYpjMaWCxDBYLQtotSMZjJq1bNbWGNNkZLIUr2+GV6CrwiIiIiI
iIiIqy+OZ65mXlXz8wAAADz3Td0A3dN3R43Ks1ERERERxqNaiKI1qNaiLK+flZnko9q+WZ31/gAA
AAPSr0srKlVKH3KoXg/wMMMYww22wwxjDDWsMMMP4Ec5mcOrqzNszMzMzM4dXVw6urMxjGMzM4dX
Vw6urbM4dXLh1dXDq6s1maSQxgADGJbVtVyqyvWvXLLPXKz4199AYAYAYAYAYEEAAAAFQAAAAVAA
Ukm0kkkm6SSSTb49e3Ll/c/RUmsMlgK0wyAFaxis0qqqqANrzuu7vV3apNYZLAVphkAK1jFZoAGZ
mZvp7AFKMNxRTsKKdgB6oA+QgggggggggIICCCDIICCAgiAyzAAAAAAAAAAAAAAAALxmZVmyIpIj
OrEU5UGqnMkAkkVOANAbm3fKSwAAAAAAAAAAAAAAAAbX5K+Az5e82NmzSYcPB4Qgr3daWySUW2ls
klAHgE/wJUG/DVM2fG3I7VM2dtwrmVmZmJZiZXizJsiKSIzLy9PGm9lrNWyastSDbISMhsC8AQAP
QH7hGCPuosiYhj91ZCJ0A6C9A6i/8Dg4OTkguHIsPAA86ioqKioqKioqqZXLndf04dQAAAAAAAAC
AKqqqqd5JOMkmMkmEkkvsI/0kP2w4fapODzqhzBlKew9Bg5SmFgsLKSZRMGVJ4rqql4k8Vyr1lNx
LgzFLlY4KysrxPQK/UfmfqfCPofCfI8Dw0r5i+SHDiYeh7Tw8IekmCuEsJhyvE9K9FDytAat6VBl
PSezxXt6Bz2rxXiWxNivAvacLhyfVULqoX/Qv7Af2JB7D4K7qvf5IsH1+3OIsHOc4iwc5ziLBzlz
iLBzdUFBERERVAABERERVAANzOZnOIioAoIsHnnnmbLbeeekk+6r1YmYmZJMxVLM9v0IIIIIIIII
IIIIIIIAAAAAAAAA2222CeiH8K5X2V4r2rK+AP2A4D/4u5IpwoSGNeSXqA==

sat5_words.txt.bz2.b64

@aib senin beşli satorları incelediğimde şöyle olanlar da var.

['TAKAT', 'ALAKA', 'KAPAK', 'AKALA', 'SAKAT']
['TAKAT', 'ALAKA', 'KAPAK', 'AKALA', 'TAKAS']

Bunlar sator olmuyor gibi.

Benim 173 4lü satorum base64 halinde.

SEFMxLANCkFLxLBMDQpMxLBLQQ0KxLBMQUgNCg0KSEFMxLANCkFNQUwNCkxBTUENCsSwTEFIDQoNCkhBTMSwDQpBTUFMDQpMQU1BDQrEsExBSA0KDQpIQUzEsA0KQU3EsEwNCkzEsE1BDQrEsExBSA0KDQpIQUzEsA0KQVRPTA0KTE9UQQ0KxLBMQUgNCg0KSEFMxLANCkFWQUwNCkxBVkENCsSwTEFIDQoNCkFLQUsNCktBRkENCkFGQUsNCktBS0ENCg0KQUtBSw0KS0FLQQ0KQUtBSw0KS0FLQQ0KDQpBS0FLDQpLQVJBDQpBUkFLDQpLQUtBDQoNCkFLQUsNCktBWUENCkFZQUsNCktBS0ENCg0KQUtBSw0KS0lOQQ0KQU5JSw0KS0FLQQ0KDQpBS0FLDQpLSVNBDQpBU0lLDQpLQUtBDQoNCkFLQUsNCktJVEENCkFUSUsNCktBS0ENCg0KQUtBSw0KS0lZQQ0KQVlJSw0KS0FLQQ0KDQpBS8SwTA0KS0FOxLANCsSwTkFLDQpMxLBLQQ0KDQpBS8SwTQ0KS0FOxLANCsSwTkFLDQpNxLBLQQ0KDQpBS09SDQpLQVJPDQpPUkFLDQpST0tBDQoNCkFNQUwNCk3EsEtBDQpBS8SwTQ0KTEFNQQ0KDQpBTUFMDQpNxLBaQQ0KQVrEsE0NCkxBTUENCg0KQU1BTA0KTcSwS0ENCkFLxLBNDQpMQU1BDQoNCkFNQUwNCk3EsFpBDQpBWsSwTQ0KTEFNQQ0KDQpBTcSwTA0KTUFMxLANCsSwTEFNDQpMxLBNQQ0KDQpBTcSwTA0KTUFOxLANCsSwTkFNDQpMxLBNQQ0KDQpBTcSwTA0KTUFaxLANCsSwWkFNDQpMxLBNQQ0KDQpBUkFLDQpSQUNBDQpBQ0FSDQpLQVJBDQoNCkFSQUsNClJPS0ENCkFLT1INCktBUkENCg0KQVJBSw0KUk9NQQ0KQU1PUg0KS0FSQQ0KDQpBUkFQDQpSQUNBDQpBQ0FSDQpQQVJBDQoNCkFSQVANClJPS0ENCkFLT1INClBBUkENCg0KQVJBUA0KUk9NQQ0KQU1PUg0KUEFSQQ0KDQpBUkFaDQpSQUNBDQpBQ0FSDQpaQVJBDQoNCkFSQVoNClJPS0ENCkFLT1INClpBUkENCg0KQVJBWg0KUk9NQQ0KQU1PUg0KWkFSQQ0KDQpTTEFWDQpMQU1BDQpBTUFMDQpWQUxTDQoNClNMQVYNCkxBTUENCkFNQUwNClZBTFMNCg0KU0xBVg0KTEFWQQ0KQVZBTA0KVkFMUw0KDQpTTEFWDQpMxLBLQQ0KQUvEsEwNClZBTFMNCg0KU0xBVg0KTMSwTUENCkFNxLBMDQpWQUxTDQoNClNMQVYNCkxPVEENCkFUT0wNClZBTFMNCg0KVEFBVA0KQU1NQQ0KQU1NQQ0KVEFBVA0KDQpUxLBLRQ0KxLBOQUsNCktBTsSwDQpFS8SwVA0KDQpUUk9LDQpSVUxPDQpPTFVSDQpLT1JUDQoNClRST0wNClJVTE8NCk9MVVINCkxPUlQNCg0KVkFMUw0KQUvEsEwNCkzEsEtBDQpTTEFWDQoNClZBTFMNCkFNQUwNCkxBTUENClNMQVYNCg0KVkFMUw0KQU1BTA0KTEFNQQ0KU0xBVg0KDQpWQUxTDQpBTcSwTA0KTMSwTUENClNMQVYNCg0KVkFMUw0KQVRPTA0KTE9UQQ0KU0xBVg0KDQpWQUxTDQpBVkFMDQpMQVZBDQpTTEFWDQoNClpBUkENCkFDQVINClJBQ0ENCkFSQVoNCg0KWkFSQQ0KQUtPUg0KUk9LQQ0KQVJBWg0KDQpaQVJBDQpBTU9SDQpST01BDQpBUkFaDQoNCkVLxLBQDQpLQU7EsA0KxLBOQUsNClDEsEtFDQoNCkVLxLBUDQpLQU7EsA0KxLBOQUsNClTEsEtFDQoNCkVMQU4NCkxBTUENCkFNQUwNCk5BTEUNCg0KRUxBTg0KTEFNQQ0KQU1BTA0KTkFMRQ0KDQpFTEFODQpMQVZBDQpBVkFMDQpOQUxFDQoNCkVMQU4NCkzEsEtBDQpBS8SwTA0KTkFMRQ0KDQpFTEFODQpMxLBNQQ0KQU3EsEwNCk5BTEUNCg0KRUxBTg0KTE9UQQ0KQVRPTA0KTkFMRQ0KDQpFTUFODQpNxLBLQQ0KQUvEsE0NCk5BTUUNCg0KRU1BTg0KTcSwWkENCkFaxLBNDQpOQU1FDQoNCkVNRUsNCk3EsERFDQpFRMSwTQ0KS0VNRQ0KDQpFTkVLDQpOQUxFDQpFTEFODQpLRU5FDQoNCkVORUsNCk5BTUUNCkVNQU4NCktFTkUNCg0KRU5FSw0KTkVSRQ0KRVJFTg0KS0VORQ0KDQpFUMSwSw0KUEFUxLANCsSwVEFQDQpLxLBQRQ0KDQpFUkVLDQpSRVlFDQpFWUVSDQpLRVJFDQoNCkVSRU4NClJFWUUNCkVZRVINCk5FUkUNCg0KRVRFSw0KVMSwS0UNCkVLxLBUDQpLRVRFDQoNCkxBTUENCkFLxLBNDQpNxLBLQQ0KQU1BTA0KDQpMQU1BDQpBS8SwTQ0KTcSwS0ENCkFNQUwNCg0KTEFNQQ0KQVrEsE0NCk3EsFpBDQpBTUFMDQoNCkxBTUENCkFaxLBNDQpNxLBaQQ0KQU1BTA0KDQpMxLBLQQ0KxLBOQUsNCktBTsSwDQpBS8SwTA0KDQpMxLBNQQ0KxLBMQU0NCk1BTMSwDQpBTcSwTA0KDQpMxLBNQQ0KxLBOQU0NCk1BTsSwDQpBTcSwTA0KDQpMxLBNQQ0KxLBaQU0NCk1BWsSwDQpBTcSwTA0KDQpMT1JUDQpPTFVSDQpSVUxPDQpUUk9MDQoNCk9SQUsNClJBQ0ENCkFDQVINCktBUk8NCg0KT1JBSw0KUk9LQQ0KQUtPUg0KS0FSTw0KDQpPUkFLDQpST01BDQpBTU9SDQpLQVJPDQoNCktBS0ENCkFGQUsNCktBRkENCkFLQUsNCg0KS0FLQQ0KQUtBSw0KS0FLQQ0KQUtBSw0KDQpLQUtBDQpBTklLDQpLSU5BDQpBS0FLDQoNCktBS0ENCkFSQUsNCktBUkENCkFLQUsNCg0KS0FLQQ0KQVNJSw0KS0lTQQ0KQUtBSw0KDQpLQUtBDQpBVElLDQpLSVRBDQpBS0FLDQoNCktBS0ENCkFZQUsNCktBWUENCkFLQUsNCg0KS0FLQQ0KQVlJSw0KS0lZQQ0KQUtBSw0KDQpLQUxQDQpBS8SwTA0KTMSwS0ENClBMQUsNCg0KS0FMUA0KQU1BTA0KTEFNQQ0KUExBSw0KDQpLQUxQDQpBTUFMDQpMQU1BDQpQTEFLDQoNCktBTFANCkFNxLBMDQpMxLBNQQ0KUExBSw0KDQpLQUxQDQpBVE9MDQpMT1RBDQpQTEFLDQoNCktBTFANCkFWQUwNCkxBVkENClBMQUsNCg0KS0FSQQ0KQUNBUg0KUkFDQQ0KQVJBSw0KDQpLQVJBDQpBS09SDQpST0tBDQpBUkFLDQoNCktBUkENCkFNT1INClJPTUENCkFSQUsNCg0KS0FSSQ0KQUNBUg0KUkFDQQ0KSVJBSw0KDQpLQVJJDQpBS09SDQpST0tBDQpJUkFLDQoNCktBUkkNCkFNT1INClJPTUENCklSQUsNCg0KS0FSTw0KQUNBUg0KUkFDQQ0KT1JBSw0KDQpLQVJPDQpBS09SDQpST0tBDQpPUkFLDQoNCktBUk8NCkFNT1INClJPTUENCk9SQUsNCg0KS0VNRQ0KRUTEsE0NCk3EsERFDQpFTUVLDQoNCktFTkUNCkVMQU4NCk5BTEUNCkVORUsNCg0KS0VORQ0KRU1BTg0KTkFNRQ0KRU5FSw0KDQpLRU5FDQpFUkVODQpORVJFDQpFTkVLDQoNCktFUkUNCkVZRVINClJFWUUNCkVSRUsNCg0KS0VURQ0KRUvEsFQNClTEsEtFDQpFVEVLDQoNCkvEsFBFDQrEsFRBUA0KUEFUxLANCkVQxLBLDQoNCklSQUsNClJBQ0ENCkFDQVINCktBUkkNCg0KSVJBSw0KUk9LQQ0KQUtPUg0KS0FSSQ0KDQpJUkFLDQpST01BDQpBTU9SDQpLQVJJDQoNCsSwTEFIDQpMQU1BDQpBTUFMDQpIQUzEsA0KDQrEsExBSA0KTEFNQQ0KQU1BTA0KSEFMxLANCg0KxLBMQUgNCkxBVkENCkFWQUwNCkhBTMSwDQoNCsSwTEFIDQpMxLBLQQ0KQUvEsEwNCkhBTMSwDQoNCsSwTEFIDQpMxLBNQQ0KQU3EsEwNCkhBTMSwDQoNCsSwTEFIDQpMT1RBDQpBVE9MDQpIQUzEsA0KDQrEsExBTQ0KTEFNQQ0KQU1BTA0KTUFMxLANCg0KxLBMQU0NCkxBTUENCkFNQUwNCk1BTMSwDQoNCsSwTEFNDQpMQVZBDQpBVkFMDQpNQUzEsA0KDQrEsExBTQ0KTMSwS0ENCkFLxLBMDQpNQUzEsA0KDQrEsExBTQ0KTMSwTUENCkFNxLBMDQpNQUzEsA0KDQrEsExBTQ0KTE9UQQ0KQVRPTA0KTUFMxLANCg0KS09SVA0KT0xVUg0KUlVMTw0KVFJPSw0KDQrEsE1BUg0KTcSwS0ENCkFLxLBNDQpSQU3EsA0KDQrEsE1BUg0KTcSwWkENCkFaxLBNDQpSQU3EsA0KDQrEsMWeQVINCsWeSVJBDQpBUknFng0KUkHFnsSwDQoNCsSwxZ5BUg0KxZ7EsEZBDQpBRsSwxZ4NClJBxZ7EsA0KDQrEsFRBUA0KVEFCQQ0KQUJBVA0KUEFUxLANCg0KxLBUQVANClRFTEENCkFMRVQNClBBVMSwDQoNCsSwVEFQDQpUVU5BDQpBTlVUDQpQQVTEsA0KDQrEsFpBTQ0KWkFSQQ0KQVJBWg0KTUFaxLANCg0KxLBaQU4NClpBUkENCkFSQVoNCk5BWsSwDQoNCk5BTEUNCkFLxLBMDQpMxLBLQQ0KRUxBTg0KDQpOQUxFDQpBTUFMDQpMQU1BDQpFTEFODQoNCk5BTEUNCkFNQUwNCkxBTUENCkVMQU4NCg0KTkFMRQ0KQU3EsEwNCkzEsE1BDQpFTEFODQoNCk5BTEUNCkFUT0wNCkxPVEENCkVMQU4NCg0KTkFMRQ0KQVZBTA0KTEFWQQ0KRUxBTg0KDQpOQU1FDQpBS8SwTQ0KTcSwS0ENCkVNQU4NCg0KTkFNRQ0KQVrEsE0NCk3EsFpBDQpFTUFODQoNCk5BWsSwDQpBUkFaDQpaQVJBDQrEsFpBTg0KDQpORVJFDQpFWUVSDQpSRVlFDQpFUkVODQoNClJBTcSwDQpBS8SwTQ0KTcSwS0ENCsSwTUFSDQoNClJBTcSwDQpBWsSwTQ0KTcSwWkENCsSwTUFSDQoNClJBxZ7EsA0KQUbEsMWeDQrFnsSwRkENCsSwxZ5BUg0KDQpSQcWexLANCkFSScWeDQrFnklSQQ0KxLDFnkFSDQoNClJPS0ENCk9SQUsNCktBUk8NCkFLT1INCg0KTUFMxLANCkFLxLBMDQpMxLBLQQ0KxLBMQU0NCg0KTUFMxLANCkFNQUwNCkxBTUENCsSwTEFNDQoNCk1BTMSwDQpBTUFMDQpMQU1BDQrEsExBTQ0KDQpNQUzEsA0KQU3EsEwNCkzEsE1BDQrEsExBTQ0KDQpNQUzEsA0KQVRPTA0KTE9UQQ0KxLBMQU0NCg0KTUFMxLANCkFWQUwNCkxBVkENCsSwTEFNDQoNCk1BWsSwDQpBUkFaDQpaQVJBDQrEsFpBTQ0KDQpNxLBLQQ0KxLBOQUsNCktBTsSwDQpBS8SwTQ0KDQpQQVJBDQpBQ0FSDQpSQUNBDQpBUkFQDQoNClBBUkENCkFLT1INClJPS0ENCkFSQVANCg0KUEFSQQ0KQU1PUg0KUk9NQQ0KQVJBUA0KDQpQQVTEsA0KQUJBVA0KVEFCQQ0KxLBUQVANCg0KUEFUxLANCkFMRVQNClRFTEENCsSwVEFQDQoNClBBVMSwDQpBTlVUDQpUVU5BDQrEsFRBUA0KDQpQxLBLRQ0KxLBOQUsNCktBTsSwDQpFS8SwUA0KDQpQTEFLDQpMQU1BDQpBTUFMDQpLQUxQDQoNClBMQUsNCkxBTUENCkFNQUwNCktBTFANCg0KUExBSw0KTEFWQQ0KQVZBTA0KS0FMUA0KDQpQTEFLDQpMxLBLQQ0KQUvEsEwNCktBTFANCg0KUExBSw0KTMSwTUENCkFNxLBMDQpLQUxQDQoNClBMQUsNCkxPVEENCkFUT0wNCktBTFANCg0KMTcz

4lü satorlarda kodu gereksiz uzatıyormuşum. Son halinde 166 a düştü 4lü satorlar.

import words

dort = []
toplam = 0
kelimeler = words.kelime
for k in kelimeler:
    if len(k)==4 and k[::-1] in kelimeler:
        dort.append(k)

for k1 in dort:
    for k2 in dort:
        if k1[1]!=k2[0] or k1[2]!=k2[3]:
            continue
        k3 = k2[::-1]
        k4 = k1[::-1]
        print(k1,k2,k3,k4,sep="\n")
        print()
        toplam += 1                

print(toplam)

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?

1 Beğeni

Hmm, neden olmuyor ?

TAKAT
ALAKA
KAPAK
AKALA
SAKAT

ilk baştaki TAKAS olsaydı sator olurdu.

anladım @dildeolupbiten , ama diğer yandan sator karelerinin farklı dizilimi farklı sator karesi mi olur yoksa tek benzersiz durum mu önemli bilemedim.

import words

dort = []
toplam = 0
kelimeler = words.kelime
for k in kelimeler:
    if len(k)==4 and k[::-1] in kelimeler:
        dort.append(k)

for k1 in dort:
    for k2 in dort:
        if k1[1]!=k2[0] or k1[2]!=k2[3]:
            continue
        k3 = k2[::-1]
        k4 = k1[::-1]
        if k3==k2 or k4==k1: # şuraya kontrol ekledim aynı kelimeler olmasın diye.
            continue
        print(k1,k2,k3,k4,sep="\n")
        print()
        toplam += 1                

print(toplam)

O zaman benim kod sator karesi bulmuyor.

Harf dizgisinden ziyade kelimelere bakiyor. Soldan ve yukaridan (ve opsiyonel olarak terslerinden) okunabilen 10 kelime buluyor.

Hepsinin farkli kelime olmasi da iyi bir kisitlamaymis. Magic square gibi.

1 Beğeni

Hayır hayır bariz şekilde duplicate:

['KİNİŞ', 'İSEVİ', 'NEDEN', 'İVESİ', 'ŞİNİK'], 
['KİNİŞ', 'İVESİ', 'NEDEN', 'İSEVİ', 'ŞİNİK']

Bu ikisi aynı sator karesi aslında.

1 Beğeni

Formül bu.

Beb hala matematik görüyorum.

Merkezde Harf, Etrafında simetri “ENE -ENE” , “ENET-ENET”, köşelerde ters simetri “RO-OR”, “SA-AS”, “OR-RO” , “OP-PO”

Matematik görüyorum. Sürekli matematik. :slight_smile:

Dizilimi çözünce bu partterne kombinasyon yapıp sözlükte var mı diye bakmak kolay gibi.

Yada gidip TENET filmini bir daha seyredeyim bakayım. Christopher Nolan şu an Oppenhaimer’ı izlettiriyor ama ben yine de işin felsefesine bakıp TENET seyretmekte de fayda görüyor, SATOR’n adamlarıyla mücadele ediyordu anlarız sebebini…

EDIT:

Koşullar netleşiyor…

Simetrik matix görüyorum…

Orta kelimeler ters ve düz okunuşu aynı kelimeler olabiliyor.

Matriks köşegenlerim sınırları çiziyor…

Sesli harf olasılıkları ile sessiz harf olasılıkların daha da da kısıtlıyor aramaları.

Hissediyorum matematiksel patternler çok yok yaklaşıyor…

2 Beğeni