Atlal / garood.py
mghareeb32's picture
More stable?
3d2a0a3
from collections import defaultdict
import yaml
from collections import namedtuple
import heapq
import numpy as np
_log_file = None
def print(txt=""):
global _log_file
if _log_file is None:
_log_file = open("garood.tmp", "w")
_log_file.write(f"{txt}\n")
_log_file.flush()
_config = None
def config():
global _config
if _config is None:
with open("garood.yaml") as file:
_config = yaml.safe_load(file)
return _config
def en2ar(en):
print(en)
ar2en = config()["harf"]["ar"]
rev = {v["en"]: k for k, v in ar2en.items()}
ans = []
for e in en:
if e == "_":
ans.append(" ")
elif e in rev:
ans.append(rev[e])
elif e == '#':
ans.append('?')
return "".join(ans)
def g2v(G):
ans = []
for g in G:
if g == '_':
del ans[-1]
ans.append(". ")
else:
ans.append("-")
return "".join(ans)
def ar_gen_en(ar):
print(ar)
ar2en = config()["harf"]["ar"]
en = []
for i in range(len(ar)):
if ar[i] not in ar2en: continue
ch = ar2en[ar[i]]["en"]
if i+1 < len(ar) and ar[i+1] in " ู‹ ู ูŒ".replace(" ", ""):
if ch == 'A':
en.append("aN_")
else:
en.append(ch)
en.append("N_")
else:
en.append(ch)
return "".join(en)
def en_gen_enhr(ar):
en = []
hr = []
for i in range(len(ar)):
if not ar[i].isupper(): continue
en.append(ar[i])
if i+1 < len(ar) and ar[i+1] in "s_iao":
if ar[i+1] == 's' or i+2 < len(ar) and ar[i+2] == 's':
hr.append('_')
hr.append('x')
en.append(ar[i])
else:
hr.append(ar[i+1])
else:
hr.append('x')
return "".join(en), "".join(hr)
def bh_gen_combinations(combs, combs_i, result, tmp):
if combs_i == len(combs):
cost = int(np.prod([x[0] for x in tmp]))
comb = [x[1] for x in tmp]
result.append((cost, comb))
else:
for comb in combs[combs_i]:
tmp.append(comb)
bh_gen_combinations(combs, combs_i+1, result, tmp)
tmp.pop()
return result
State = namedtuple("State", ["bh_i", "acts_i", "acts"])
def state_to_str(s, EN):
if s is None: return None
ans = []
acts_i = 0
while acts_i < s.acts_i:
action = (s.acts >> ((s.acts_i - acts_i - 1) * AX_BITS)) & AX_MASK
if action == AX_HRK:
ans.append(EN[acts_i])
elif action == AX_SKN:
ans.append(EN[acts_i])
ans.append("_")
elif action == AX_HDF:
pass
elif action == AX_MDD:
ans.append(EN[acts_i])
ans.append("#")
ans.append("_")
elif action == AX_SHD:
ans.append(EN[acts_i])
ans.append("_")
ans.append(EN[acts_i])
else:
print("WHAT!!!")
# advance loop
acts_i += 1
return "".join(ans)
AX_BITS = 3
AX_MASK = 0b111
AX_HRK = 0b000
AX_SKN = 0b001
AX_HDF = 0b010
AX_MDD = 0b011
AX_SHD = 0b100
def state_next(EN, HR, BH, s):
if BH[s.bh_i:].startswith("??") and not EN[s.acts_i:].startswith("A"):
cost_hrk = 1
if HR[s.acts_i:].startswith("_"): cost_hrk = 10
yield cost_hrk, State(bh_i=s.bh_i+1, acts_i=s.acts_i+1, acts=(s.acts << AX_BITS) | AX_HRK)
if BH[s.bh_i:].startswith("?_"):
cost_skn = 1
if not HR[s.acts_i:].startswith("_") and not HR[s.acts_i:].startswith("x"): cost_skn = 10
yield cost_skn, State(bh_i=s.bh_i+2, acts_i=s.acts_i+1, acts=(s.acts << AX_BITS) | AX_SKN)
cost_hdf = 20
if EN[s.acts_i:].startswith("A") and HR[s.acts_i+1:].startswith("_"): cost_hdf = 1
yield cost_hdf, State(bh_i=s.bh_i, acts_i=s.acts_i+1, acts=(s.acts << AX_BITS) | AX_HDF)
if EN[s.acts_i:].startswith("AL"):
cost_al = 1
if HR[s.acts_i:].startswith("xx_x"):
yield cost_al, State(bh_i=s.bh_i, acts_i=s.acts_i+2,
acts=(((s.acts << AX_BITS) | AX_HDF) << AX_BITS) | AX_HDF)
if HR[s.acts_i:].startswith("x_"):
yield cost_al, State(bh_i=s.bh_i, acts_i=s.acts_i+1,
acts=((s.acts << AX_BITS) | AX_HDF))
if BH[s.bh_i:].startswith("??_") and not EN[s.acts_i:].startswith("A"):
cost_madd = 15
if s.acts_i == len(EN) - 1: cost_madd //= 4
yield cost_madd, State(bh_i=s.bh_i+3, acts_i=s.acts_i+1, acts=(s.acts << AX_BITS) | AX_MDD)
def state_search(EN, HR, BH):
q = []
heapq.heappush(q, (0, State(bh_i=0, acts_i=0, acts=0)))
best_c = -1
best = []
while len(q) > 0:
c1, s1 = heapq.heappop(q)
if best_c >= 0 and c1 > best_c: continue
if s1.bh_i == len(BH) and s1.acts_i == len(EN):
best_c = c1
best.append(s1)
continue
if s1.bh_i >= len(BH) or s1.acts_i >= len(EN): continue
# print(f"{c1: 2d} `{state_to_str(s1, EN)}` {EN[s1.acts_i]} {BH[s1.bh_i:]}")
for c2, s2 in state_next(EN, HR, BH, s1):
new_c = c1+c2
if new_c <= MAX_C:
heapq.heappush(q, (new_c, s2))
return best_c, best
def bh_gen(combs, EN, HR, verbose=False):
if verbose:
print(HR)
print(EN)
BHs = bh_gen_combinations(combs, 0, [], [])
best = []
for BH_cost, BH in BHs:
c, ss = state_search(EN, HR, ''.join(BH))
for s in ss:
best.append((BH_cost + c, s))
ans = defaultdict(lambda: set())
for c, s in sorted(best):
ans[c].add(s)
if verbose:
print(f"{c:3d} {state_to_str(s, EN)}")
return ans
MAX_C = 40
def bh_gen_best(combs, EN, HR, verbose=False):
ans = bh_gen(combs, EN, HR, verbose)
cost_list = list(ans.keys())
if len(cost_list) < 1: return -1, None
ans = ans[cost_list[0]]
if len(ans) != 1 or cost_list[0] > MAX_C: return -1, None
return cost_list[0], next(iter(ans))
if __name__ == "__main__":
BH = config()['bahr']['kamil_1']
with open("garood.gold", "w", encoding="utf-8") as file:
for i, AR in enumerate("""
ู‡ูŽู„ู’ ุบูŽุงุฏูŽุฑูŽ ุงู„ุดู‘ูุนูŽุฑูŽุงุกู ู…ูู†ู’ ู…ูุชูŽุฑูŽุฏูŽู‘ู…ู
ุฃูŽู…ู’ ู‡ูŽู„ู’ ุนูŽุฑูŽูู’ุชูŽ ุงู„ุฏู‘ูŽุงุฑูŽ ุจูŽุนู’ุฏูŽ ุชูŽูˆูŽู‡ูู‘ู…ู
ุฃูŽุนู’ูŠูŽุงูƒูŽ ุฑูŽุณู’ู…ู ุงู„ุฏู‘ูŽุงุฑู ู„ูŽู…ู’ ูŠูŽุชูŽูƒูŽู„ู‘ูŽู…ู
ุญูŽุชู‘ูŽู‰ ุชูŽูƒูŽู„ู‘ูŽู…ูŽ ูƒูŽุงู„ู’ุฃูŽุตูŽู…ู‘ู ุงู„ู’ุฃูŽุนู’ุฌูŽู…ู
ูŠูŽุง ุฏูŽุงุฑูŽ ุนูŽู€ุจู’ู€ู„ูŽุฉูŽ ุจูุงู„ู’ุฌูŽู€ูˆูŽุงุกู ุชูŽูƒูŽู„ูŽู‘ู…ูŠ
ูˆูŽุนูŽู…ููŠ ุตูŽุจูŽุงุญุงู‹ ุฏูŽุงุฑูŽ ุนูŽู€ุจู’ู€ู„ูŽุฉูŽ ูˆูŽุงุณู’ู€ู„ูŽู€ู…ูŠ
ููŽูˆูŽู‚ูŽู€ูู’ุชู ูููŠู’ู‡ูŽุง ู†ูŽุงู‚ูŽุชููŠ ูˆูŽูƒูŽุฃูŽู†ูŽู‘ู‡ูŽุง
ููŽุฏูŽู†ูŒ ู„ูุฃูŽู‚ู’ุถููŠูŽ ุญูŽุงุฌูŽุฉูŽ ุงู„ู’ู…ูุชูŽู„ูŽูˆูู‘ู…ู
ูˆูŽุชูŽุญูู„ู‘ู ุนูุจู’ู„ูŽุฉู ุจูุงู„ู’ุฌูŽูˆุงุกู ูˆูŽุฃูŽู‡ู’ู„ูู†ูŽุง
ุจูุงู„ู’ุญูŽุฒู’ู†ู ููŽุงู„ุตู‘ูŽู…ู‘ูŽุงู†ู ููŽุงู„ู’ู…ูุชูŽุซูŽู„ู‘ูู…ู
ุญูŽูŠูู‘ูŠู’ุชู ู…ูู† ุทูŽู„ูŽู„ู ุชูŽู‚ุงุฏูŽู…ูŽ ุนูŽู‡ุฏูู‡ู
ุฃูŽู‚ู’ูˆูŽู‰ ูˆูŽุฃูŽู‚ู’ููŽุฑูŽ ุจูŽุนู’ุฏูŽ ุฃูู…ูู‘ ุงู„ู’ู‡ูŽูŠู’ุซูŽู…ู
ุญูŽู„ู‘ูŽุชู’ ุจูุฃูŽุฑู’ุถู ุงู„ุฒู‘ูŽุงุฆูุฑููŠู†ูŽ ููŽุฃูŽุตู’ุจูŽุญูŽุชู’
ุนูŽุณูุฑุงู‹ ุนูŽู„ูŽูŠูŽู‘ ุทูู„ุงุจููƒู ุงูุจู†ุฉูŽ ู…ูŽุฎุฑูŽู…ู
ุญูŽุชู‘ูŽู‰ ุชูŽูƒูŽู„ู‘ูŽู…ูŽ ูƒูŽุงู„ู’ุฃูŽุตูŽู…ู‘ู
ุญูŽุชู‘ูŽู‰ ุชูŽูƒูŽู„ู‘ูŽู…ูŽ ูƒูŽุงู„ู’ุฃูŽุตูŽู…ู‘ู ุงู„ู’ุฃูŽุนู’ุฌูŽ
ุญูŽุชู‘ูŽู‰ ุชูŽูƒูŽู„ู‘ูŽู…ูŽ ูƒูŽุงู„ู’ุฃูŽุตูŽู…ู‘ู ุงู„ู’ุฃูŽุนู’
ุญูŽุชู‘ูŽู‰ ุชูŽูƒูŽู„ู‘ูŽู…ูŽ ูƒูŽุงู„ู’ุฃูŽุตูŽู…ู‘ู ุงู„ู’ุฃูŽ
ู‚ูŽุฏู’ ุณูŽุงู…ูŽุฑูŽ ุงู„ู’ุฃูŽุตู’ุญูŽุงุจูŽ ูููŠ ูŠูŽูˆู’ู…ู ุงู„ู’ุญูŽุฑู’ุจู
ุญูŽุชู‘ูŽู‰ ุชูŽูƒูŽู„ู‘ูŽู…ูŽ ูƒูŽุงู„ู’ุฃูŽุตูŽู…ู‘ู ุงู„ู’ุฃูŽุนู’ุฌูŽู…ู ุงู„ู’ุฃูŽุนู’ุฌูŽู…ู
""".strip().split("\n")):
EN, HR = en_gen_enhr(ar_gen_en(AR))
c, s = bh_gen_best(BH, EN, HR, i==13)
garood = state_to_str(s, EN)
print(garood)
file.write(f"{AR}\n")
file.write(f"{garood}\n")