diff --git a/SorokinAD/[1]lab_1/MP_BST.py b/SorokinAD/[1]lab_1/MP_BST.py new file mode 100644 index 0000000..b187bbe --- /dev/null +++ b/SorokinAD/[1]lab_1/MP_BST.py @@ -0,0 +1,252 @@ +from MP_records import records +import random as rd +import time +import csv +import codecs +import sys + +sys.setrecursionlimit(15000) + + +# ---------- Binary Search Tree ---------- +# Узел: +# { +# "name": name, +# "phone": phone, +# "left": None, +# "right": None +# } + + +def bst_insert(root, name, phone): + """ + Вставляет новую запись или обновляет телефон по имени. + Возвращает корень дерева. + """ + if root is None: + return { + "name": name, + "phone": phone, + "left": None, + "right": None + } + + if name == root["name"]: + root["phone"] = phone + + elif name < root["name"]: + root["left"] = bst_insert(root["left"], name, phone) + + else: + root["right"] = bst_insert(root["right"], name, phone) + + return root + + +def bst_find(root, name): + """ + Поиск телефона по имени. + """ + if root is None: + return None + + if name == root["name"]: + return root["phone"] + + if name < root["name"]: + return bst_find(root["left"], name) + + return bst_find(root["right"], name) + + +def bst_find_min(node): + """ + Возвращает узел с минимальным именем. + """ + current = node + + while current["left"] is not None: + current = current["left"] + + return current + + +def bst_delete(root, name): + """ + Удаляет запись по имени. + Возвращает новый корень дерева. + """ + if root is None: + return None + + if name < root["name"]: + root["left"] = bst_delete(root["left"], name) + + elif name > root["name"]: + root["right"] = bst_delete(root["right"], name) + + else: + # Узел без левого потомка + if root["left"] is None: + return root["right"] + + # Узел без правого потомка + if root["right"] is None: + return root["left"] + + # Узел с двумя потомками + successor = bst_find_min(root["right"]) + + root["name"] = successor["name"] + root["phone"] = successor["phone"] + + root["right"] = bst_delete(root["right"], successor["name"]) + + return root + + +def bst_inorder(root, result): + """ + Центрированный обход дерева. + """ + if root is None: + return + + bst_inorder(root["left"], result) + + result.append((root["name"], root["phone"])) + + bst_inorder(root["right"], result) + + +def bst_list_all(root): + """ + Возвращает список записей в отсортированном порядке. + """ + result = [] + bst_inorder(root, result) + return result + + +# ---------- Benchmark helpers ---------- + +def build_bst(records_list): + root = None + + for name, phone in records_list: + root = bst_insert(root, name, phone) + + return root + + +def measure_bst(records_list, mode_name, repeats=5): + rows = [] + + insertion_times = [] + finding_times = [] + deletion_times = [] + + for run_number in range(1, repeats + 1): + data = records_list[:] + + if mode_name == "случайный": + rd.shuffle(data) + + # А. Вставка + root = None + + start = time.perf_counter() + + for name, phone in data: + root = bst_insert(root, name, phone) + + end = time.perf_counter() + + insertion_time = end - start + insertion_times.append(insertion_time) + + # Б. Поиск + existing_names = [name for name, phone in rd.sample(data, 100)] + missing_names = [f"None_{i}" for i in range(10)] + + search_names = existing_names + missing_names + rd.shuffle(search_names) + + start = time.perf_counter() + + for name in search_names: + bst_find(root, name) + + end = time.perf_counter() + + finding_time = end - start + finding_times.append(finding_time) + + # В. Удаление + delete_names = rd.sample(existing_names, 50) + + start = time.perf_counter() + + for name in delete_names: + root = bst_delete(root, name) + + end = time.perf_counter() + + deletion_time = end - start + deletion_times.append(deletion_time) + + rows.append(["BinarySearchTree", mode_name, "вставка", run_number, insertion_time]) + rows.append(["BinarySearchTree", mode_name, "поиск", run_number, finding_time]) + rows.append(["BinarySearchTree", mode_name, "удаление", run_number, deletion_time]) + + rows.append(["BinarySearchTree", mode_name, "вставка", "среднее", sum(insertion_times) / repeats]) + rows.append(["BinarySearchTree", mode_name, "поиск", "среднее", sum(finding_times) / repeats]) + rows.append(["BinarySearchTree", mode_name, "удаление", "среднее", sum(deletion_times) / repeats]) + + return rows + + +def save_results(rows, filename="results.csv"): + with codecs.open(filename, "a+", "utf-16") as file: + writer = csv.writer(file) + writer.writerows(rows) + + +def run_shuffled(records_shuffled): + rows = measure_bst(records_shuffled, "случайный") + save_results(rows) + return rows + + +def run_sorted(records_sorted): + rows = measure_bst(records_sorted, "отсортированный") + save_results(rows) + return rows + + +# ---------- Manual tests ---------- + +def test(): + root = None + + root = bst_insert(root, "Ivan", "111") + root = bst_insert(root, "Anna", "222") + root = bst_insert(root, "Petr", "333") + root = bst_insert(root, "Maria", "444") + + print(bst_find(root, "Anna")) # 222 + print(bst_find(root, "Unknown")) # None + + root = bst_insert(root, "Anna", "999") + print(bst_find(root, "Anna")) # 999 + + root = bst_delete(root, "Ivan") + + print(bst_list_all(root)) + + +if __name__ == "__main__": + records_shuffled, records_sorted = records() + + run_shuffled(records_shuffled) + run_sorted(records_sorted) diff --git a/SorokinAD/[1]lab_1/MP_hash-table.py b/SorokinAD/[1]lab_1/MP_hash-table.py new file mode 100644 index 0000000..2484cc3 --- /dev/null +++ b/SorokinAD/[1]lab_1/MP_hash-table.py @@ -0,0 +1,456 @@ +from MP_records import records +import string +import random as rd +import time +import csv +import codecs + +def polynomial_hash(word): + p=11111 + m=(10**9)+9 + hashh=0 + for i in range(len(word)): + hashh+=ord(word[i])*(p**i) + hashh=hashh%m + return hashh + +def hash_to_index(hashh,length): + #print(hashh) + #if len(str(hashh))>4: + #hashh=int(str(hashh)[3:]) + while hashh>length: + hashh=hashh%(length) + return hashh + +def ll_insert(table,name,phone,index): + if table[index]==None: + entry={"name":name,"phone":phone,"next":None} + table[index]=entry + return table + else: + entry={"name":name,"phone":phone,"next":None} + if table[index]["phone"]==phone: + table[index]["name"]=name + return table + if table[index]["next"]==None: + table[index]["next"]=entry + return table + else: + nexxt=table[index]["next"] + if nexxt["phone"]==phone: + nexxt["name"]=name + return table + while nexxt["next"]!=None: + nexxt=nexxt["next"] + if nexxt["phone"]==phone: + nexxt["name"]=name + return table + nexxt["next"]=entry + return table + +def ht_insert(table,name,phone): + index=hash_to_index(polynomial_hash(name), len(table)) + ll_insert(table,name,phone,index) + return table + +def ht_find(table, name): + index=hash_to_index(polynomial_hash(name), len(table)) + if table[index]!=None: + if table[index]["name"]==name: + return table[index]["phone"] + elif table[index]["next"]!=None: + if table[index]["next"]["name"]==name: + return table[index]["next"]["phone"] + else: + nexxt=table[index]["next"] + while nexxt["next"]!=None: + nexxt=nexxt["next"] + if nexxt["name"]==name: + return nexxt["phone"] + return None + +def ht_delete(table,name): + index=hash_to_index(polynomial_hash(name), len(table)) + if len(table)>0: + if table[index]["name"]==name: + if table[index]["next"]!=None: + table[index]=table[index]["next"] + return table + else: + table[index]=None + return table + elif table[index]["next"]!=None: + if table[index]["next"]["name"]==name: + if table[index]["next"]["next"]!=None: + table[index]["next"]=table[index]["next"]["next"] + return table + else: + table[index]["next"]=None + return table + elif table[index]["next"]["next"]!=None: + nexxt1=table[index]["next"] + nexxt2=nexxt1["next"] + if nexxt2["name"]==name: + if nexxt2["next"]!=None: + nexxt1["next"]=nexxt2["next"] + return table + else: + nexxt1["next"]=None + return table + while nexxt2["next"]!=None: + nexxt1=nexxt2 + nexxt2=nexxt1["next"] + if nexxt2["name"]==name: + if nexxt2["next"]!=None: + nexxt1["next"]=nexxt2["next"] + return table + else: + nexxt1["next"]=None + return table + +def bad_sort(names,phones): + names1=[] + phones1=[] + while len(names)>0: + min_=names[0].encode() + ph=phones[0] + for i in range(len(names)): + nm=names[i].encode() + if nm0: + for i in range (0,N-n): + j=i + while j+n(names[j+n].encode()): + t=names[j] + t1=phones[j] + names[j]=names[j+n] + phones[j]=phones[j+n] + names[j+n]=t + phones[j+n]=t1 + j=i + else: + j+=n + n=n//2 + return names,phones + +def ht_listall(table): + names=[] + phones=[] + pointer=0 + while pointer0: + for i in range (0,N-n): + j=i + while j+narr[j+n]: + t=arr[j] + arr[j]=arr[j+n] + arr[j+n]=t + j=i + else: + j+=n + n=n//2 + return arr + +def records(): + phones=[] + first=0 + second=0 + third=0 + fourth=0 + for i in range(10000): + phones.append(str(first)+str(second)+str(third)+str(fourth)) + fourth+=1 + if fourth==10: + third+=1 + fourth=0 + if third==10: + second+=1 + third=0 + if second==10: + first+=1 + second=0 + phones2=phones.copy() + + f=open("names.txt","r") + count=0 + names=[] + while count<5000: + name=f.readline() + names.append(name[:len(name)-1]) + names.append(name[:len(name)-1]) + count+=1 + f.close() + + names_sorted=names.copy() + for i in range(10000): + names_sorted[i]=names_sorted[i].encode() + Shell(names_sorted) + for i in range(10000): + names_sorted[i]=names_sorted[i].decode() + + records_shuffled=[] + records_sorted=[] + count=0 + while count<10000: + name_var=rd.randint(0,len(names)-1) + phone_var=rd.randint(0,len(phones2)-1) + records_shuffled.append((names[name_var],phones[count])) + records_sorted.append((names_sorted[count],phones2[phone_var])) + names.remove(names[name_var]) + phones2.remove(phones2[phone_var]) + count+=1 + + rd.shuffle(records_shuffled) + return records_shuffled, records_sorted +#print(records_shuffled) +#print(records_sorted) + diff --git a/SorokinAD/[1]lab_1/graphs_lab.xlsx b/SorokinAD/[1]lab_1/graphs_lab.xlsx new file mode 100644 index 0000000..a68855c Binary files /dev/null and b/SorokinAD/[1]lab_1/graphs_lab.xlsx differ diff --git a/SorokinAD/[1]lab_1/names.txt b/SorokinAD/[1]lab_1/names.txt new file mode 100644 index 0000000..4550f85 --- /dev/null +++ b/SorokinAD/[1]lab_1/names.txt @@ -0,0 +1,5000 @@ +Casigu +Cacugi +Sisok +Lanigaruzo +Qoqugenupe +Deyurab +Paji +Gaki +Koto +Pudoyivoc +Xibagov +Bojicoci +Falagoyebo +Qico +Nedazu +Pituvoba +Meko +Gubovizup +Gerol +Fewad +Nuxefi +Xikif +Qagofesiyi +Fezaxovaw +Riyizejo +Pora +Nuhocaka +Fowuduhibi +Sozil +Yade +Hizado +Worule +Sege +Xovebih +Jela +Rawilaye +Bayaninut +Kocomubo +Yakibihoj +Qemih +Xikoyam +Yodu +Kexor +Fakome +Cobex +Gunikone +Kohofuzipo +Keke +Gabufodik +Nonelade +Weleliyo +Guranaloh +Kukumesaz +Ragi +Nimo +Sovec +Zizoqehe +Nujijopud +Dulobogagi +Loquj +Yuwemi +Qehe +Poteluhawa +Lamokud +Dabayatob +Mucelogaji +Bogewuza +Cudon +Mivexoya +Qewumec +Kofipa +Moki +Fuxa +Zozaducoye +Kosalekixa +Qocimelus +Gadebenav +Jihup +Pera +Kubi +Lovequ +Suyuxu +Yipohudik +Sumodig +Dasayacew +Tabe +Cabe +Vegaro +Zaqa +Nolib +Binuginemo +Jiyucozi +Nipiyoy +Nufew +Veto +Yumi +Femekesa +Giyutabo +Cozemizo +Zeqig +Sacen +Mapafox +Pusezaz +Kuwovow +Zadoqay +Zorajaf +Quve +Yesope +Kepakehac +Tunen +Sizagavigo +Qelefa +Yavulayo +Cucuvil +Telaforuxe +Qurazazeji +Cofeno +Puzanizala +Fowa +Nogikehuw +Hosab +Nafere +Qehiba +Hemu +Wesopezu +Hiquyotiza +Fojiwoyave +Duca +Gasoji +Kuxe +Liyefipel +Sujacat +Hatoh +Qasulifuz +Fapaf +Loderina +Wige +Jesa +Cacapaqo +Ticoluqo +Biwopipaq +Qore +Rinire +Podizur +Yevus +Jagaxuzi +Nahoy +Nuwoze +Nuribofon +Rahag +Pehe +Wuyawo +Buxopu +Lidomugati +Rehacov +Tapusa +Nivuyo +Bekuve +Beyequr +Japalaz +Dupowivib +Wokida +Likarixe +Jesi +Zihojeye +Xehibizi +Pofaf +Huwofok +Bilo +Kusicag +Suhu +Biwiyobet +Totun +Zidini +Sosac +Yikaw +Kolan +Yezaxubu +Cebiso +Fetatipu +Cera +Giwunatum +Qusaduwa +Bapejeq +Zotutaji +Sumonubah +Doda +Yohujeqet +Zarogetovi +Jehakohika +Hojicuticu +Davotanoco +Xetenat +Vepamepava +Kuxi +Foqoyilos +Wefup +Kusi +Mopayi +Bifurojomi +Yexa +Qitedu +Doxafe +Xukevuso +Heqawod +Geweke +Moxufeno +Rivunuzore +Huvic +Satuxe +Yomuvanaye +Tutor +Nifa +Wivuxol +Mufohuzax +Babe +Numewaqop +Docadufud +Xujahohe +Honogic +Geliyaco +Pakekahuj +Dute +Benenu +Zaluti +Gufuremoqi +Cawurudu +Zaveco +Dilofal +Daloyuy +Pepuduwape +Gepehiheso +Gotuqeca +Nofo +Heducadudi +Mizu +Hicalu +Paqemugadu +Cucoyijodi +Nutebilura +Deped +Sifuvoz +Welutiful +Gekav +Yelobi +Firapir +Sitocafir +Wegi +Yagodihi +Holijased +Xopixeco +Jaharov +Susujamey +Lapuyam +Hafor +Huhunina +Hewerixo +Yivikoto +Quviye +Jebowalive +Xufejok +Wesunejaso +Leto +Xaxe +Haje +Cuqepeyop +Laxapu +Qetigak +Vuhonal +Siha +Bojagazu +Wisi +Fuwiz +Zicayihux +Ragif +Xinudu +Nokumiyix +Jivihe +Lukuzoj +Fovox +Cowigaruf +Yaxa +Doyiki +Jofe +Hiposec +Zode +Femuqa +Xaruw +Getapoc +Xewif +Calahokido +Xapijixu +Kalonuvaq +Hekopuy +Rayocim +Xeri +Pukiwehite +Yufajo +Rotadeceni +Xizifuvufi +Duvereyuya +Camihized +Dasobajoke +Yeluhejoz +Cajubizo +Pexohu +Nonot +Tanubakaru +Kowoyuq +Qikucuj +Rawuqey +Gukicas +Xusefamof +Sute +Woxaj +Wuxofamepe +Zevuqeza +Damoh +Givilujico +Hudazuduq +Beloqurem +Dopa +Bebas +Buqu +Rohibi +Gadequyipi +Cotecuxil +Vobawaju +Tayojudiz +Sofazucuku +Sexiromuc +Rojux +Xusa +Nuno +Dunil +Dasag +Gibepid +Pifuviv +Yidikiyeze +Gesati +Jilo +Vero +Sonefih +Fujaqevox +Suvaliza +Luri +Togom +Vipa +Gohef +Gihi +Kunez +Hovenep +Hulanihoqa +Fezuruw +Kakozetiw +Pilav +Yecived +Bekera +Kiwaces +Bokez +Helu +Bebex +Perayuxe +Suliriv +Gifu +Kuseso +Hehub +Kuhipaxid +Ruwahequ +Xanu +Takibuwe +Witakelihi +Zuqoxina +Nufedivo +Yusu +Hiwomoduh +Cihopanalu +Gapic +Rurasabuj +Puxa +Gugivajad +Caxatol +Bubuc +Yonenalina +Xojafasodi +Fokavufa +Jafaq +Sexes +Yiwanuse +Lolasali +Yihe +Ciza +Cowewomo +Casexepop +Zolo +Cigat +Dewumenega +Xumoqulepo +Volayizi +Wepunaba +Hore +Jaziho +Soku +Laneh +Zoyizah +Daxira +Yifuqecezu +Zizera +Viremaxe +Roqe +Noduz +Yejol +Bumutijibe +Meterayow +Lowonadiw +Hekejisi +Higobodasi +Hirujusalo +Fukofa +Dihiyizu +Xizumumi +Cobuwafa +Pohibe +Caminizuqi +Sexiyaqe +Vucoyokig +Giqoxinoru +Zakivosoge +Wutok +Hoyedabe +Rupuwi +Rewor +Nuwejuzawo +Bequzazut +Yatoxoq +Qeqar +Potedaqiy +Sedi +Xemonu +Wasocosog +Vutigexuqa +Verecisaw +Fahacelazo +Loqohepoh +Wufe +Qasacaqeh +Cefahuqih +Capoqawit +Besi +Yukuyeraca +Yivucugamu +Wiyesunad +Panotob +Zubu +Zupofepu +Wuweriqir +Ciyatag +Rojusec +Wixevopuk +Liperuj +Yaxayo +Fiquq +Jufihocega +Dojixaguvo +Xijareg +Mininalo +Bomonogi +Xucu +Duya +Sepoxumaho +Sutib +Zepoxal +Civu +Nazoya +Webugare +Pavo +Mizezarit +Hodayuve +Xeqixaqow +Tihuqakiyi +Visuy +Dopug +Vofehiyoz +Lofakatibu +Cekonuki +Tutox +Tugo +Fokifi +Jocidinihe +Qaxa +Fufutemim +Muju +Guxisav +Jefaxefo +Hinetan +Gafeg +Wagucul +Yoqazalo +Laqukid +Suqe +Nubi +Luvu +Sesuf +Cinizokos +Gijaj +Yepu +Siki +Sotofis +Nocojexat +Jobegafaz +Qewine +Citofe +Culuwoza +Nugud +Lanisawid +Mehuhab +Xitoqetik +Jegez +Jura +Qijupi +Hole +Hiqukawora +Wekolixaw +Rahugoy +Miyiwex +Kesoj +Nefoyocico +Qodim +Fosoqi +Gejip +Nuvuleyul +Bixuwe +Rizaluto +Nizu +Zexiw +Bisezec +Xahaqude +Vuyiyosoke +Vevewevusa +Mocic +Duyidoki +Kaluvohow +Givaka +Zidexoduq +Conec +Pigifoni +Sapesih +Lifiquxewu +Dapo +Cucexuga +Pumusigo +Vuduzodici +Fazenez +Lacewenip +Jufixoqi +Muqobopab +Takit +Befabezuv +Rowadutol +Sidipon +Qawipu +Satu +Sihusixic +Rohoruxuti +Vucidu +Xevajani +Fetalosuru +Zocadazol +Xalu +Fikawagit +Joha +Lixonuso +Zozenur +Qaxexivexa +Resotavab +Godiyokeje +Zocijisuv +Yasulid +Vadidupux +Guzatex +Pomefa +Fuqororofe +Pegifusogo +Bubukeq +Mapipiruji +Niyocoxep +Calakikoy +Gere +Vubi +Wusori +Nalexoli +Negat +Hudube +Karen +Politiye +Wefecejom +Bubakec +Kexeju +Sotiliy +Yotahujige +Budatayaxa +Giweki +Doliqusur +Kuvujey +Tesisivo +Yaquril +Begi +Jalaquyul +Jezudohom +Leyi +Vuxetatuce +Cotav +Qosal +Vepover +Yixasut +Birefone +Hase +Poso +Bobedu +Hepagunuc +Vali +Tototoze +Yularux +Cural +Qabosate +Fumibuvuz +Jojuyuture +Dayajuka +Zomerefu +Vejavir +Domuqu +Qake +Tacox +Kuhacu +Miwoxova +Buletodax +Xacel +Moxohopas +Jaka +Tira +Zurige +Rapagimuke +Quya +Xicibupo +Hikuqomew +Davubaboqo +Wakada +Haqipajec +Lahehi +Fegu +Wodeq +Sufix +Xubizar +Hukoxemiqo +Mosadaro +Qece +Bocenamipe +Rixiqife +Vahitus +Yakixav +Huyayina +Mamemuwan +Nuwurud +Xoxiy +Mexadona +Rolebukeq +Katoqeh +Hoberul +Ruyonamupa +Qetidaj +Kizamibugu +Tucob +Biyeci +Jexuwivo +Cofisubeh +Dujohahen +Jedehofuf +Rohated +Guzote +Vucipakari +Zibutumuqo +Tisuz +Qewaba +Darilo +Kete +Jice +Rijewosas +Wajinecaxo +Vofi +Zebogo +Cavuxikuk +Ladovu +Pakez +Gixex +Cadewageb +Puquji +Peli +Qalofu +Sacecu +Dujohoyuw +Dawaye +Ruvobumu +Socupuquza +Juya +Wolahoyir +Wibexituci +Jifotogaco +Suta +Sowaqekito +Gufag +Cajixo +Yosequxulo +Hudelekefe +Deto +Momiy +Qudemajo +Bimakiqoji +Qolu +Yehitu +Burad +Tejotevuno +Huyewif +Femifak +Necisovip +Kevodewovi +Cefosol +Jikegaza +Viyi +Jariy +Hajuwawif +Wogih +Rumokit +Qoxigurix +Wenibewox +Lajoroqiri +Nemilidox +Qiletoceh +Vadiqikixa +Sevudit +Cirazilef +Jupitetu +Yurexaqu +Dezegifop +Soju +Ricamuwa +Talaliyojo +Yubosem +Qugahud +Jujegiyo +Jivonod +Fitituforo +Rajitiva +Bamo +Gunazeru +Degoh +Vufaji +Leyaq +Xivokuc +Gohetilu +Rahuhegu +Yuteyolake +Mada +Musexok +Mezapogad +Bawo +Xubufi +Wohemuva +Jijixaq +Guzigeto +Kujeqoliq +Foqiyikezo +Tomaluba +Qotixigaxu +Qupiseg +Losa +Mubix +Cibogomuc +Yafaz +Tece +Juyevogaq +Rotululeh +Ponorese +Nayuq +Yolorub +Focasini +Rerikari +Neqaxip +Panewusi +Dizi +Hujamuz +Holiyayu +Gelolel +Kuyah +Dacinuy +Lesewot +Zafuhipi +Naxob +Noticinej +Mewesuv +Xedapodo +Todora +Dino +Zarewe +Dale +Gibulupuli +Tirel +Juwofeh +Mebon +Pexocuvuz +Sabizaxum +Qatoray +Sowixuvar +Diwafir +Fudoyajuh +Gufevaj +Qivirukim +Katulunaso +Ruviw +Doco +Kinegiwava +Xiducu +Hipafihoqo +Vibudaxuw +Tabisanowi +Jasuqopuva +Yezuzar +Duvige +Jopicus +Kokokoximu +Socuzupo +Roqazol +Xuzod +Tetugit +Tinohih +Mesedolev +Vidoqibiv +Dibiw +Ferirulebi +Kajusaw +Gibi +Neqi +Fawopo +Suli +Dara +Vidini +Daresipedo +Xogew +Lakag +Cihezixe +Cixo +Nidu +Woguf +Lirudaka +Rixomo +Cesaweb +Juvaqezo +Sige +Verogu +Ziga +Cimu +Cuwitesuyi +Wodebi +Zidi +Vevomomami +Tuge +Vukova +Gaheqop +Nuxas +Bidome +Gaxujiq +Hehabiqol +Pavojejenu +Waqe +Bunevi +Wahopawu +Tutupejawu +Pocoqi +Poqo +Dumine +Kubow +Sasuralum +Kobexo +Suma +Cojesa +Peroq +Zakufa +Cebo +Wega +Savunufik +Sanadu +Cipimub +Zoyojesi +Goza +Fuhug +Roxoneqek +Riyexa +Mogon +Kecasunewi +Kovex +Biboba +Bizojefifa +Hoqoqud +Rodotosix +Jofayukig +Rituy +Yuko +Kefafocu +Bomeluro +Patoyoxit +Caxuxuj +Xakozur +Vobitif +Yogomezon +Xaqe +Havik +Hohoy +Miru +Zujojevu +Seneciv +Mepeken +Kavohufas +Homifovi +Kayiyagap +Labo +Jiwi +Pimer +Yanige +Guwi +Hawinek +Yaduf +Lali +Guquxokup +Kalul +Bikuridezu +Gidosufuv +Tusilo +Latupehal +Cehokudum +Kediv +Zunewozix +Wigotedos +Gukoferip +Kecu +Nicuji +Jopar +Yorulad +Qozeliyuhu +Dizubulose +Qeqeluvu +Lewak +Bocuxeyizi +Mitufur +Gayofu +Dohopuka +Sani +Hifo +Fugejohus +Fipoga +Gugocawima +Lajozuj +Yuboviwo +Qonetuci +Muduqata +Fujadowike +Valumig +Yumivire +Tebiwe +Gozotevug +Cepacapugi +Reju +Tumahodimu +Cugid +Devaheza +Soham +Peja +Peqitominu +Letutuziz +Samey +Hucarejew +Bobuvefu +Vegad +Kokate +Nuvomu +Sotu +Vegemameg +Quzomoces +Dekiwo +Doya +Nojij +Dubuyeqa +Rokemolu +Kumahiyi +Tagozedin +Qagafuvup +Baqogot +Qopuluzewi +Jolohip +Puvaf +Yavaxijew +Vecece +Mapi +Yameloceye +Hexafivibi +Venopigani +Ginotuw +Loteveju +Jolirudad +Yehaqer +Kijedoq +Yudopidix +Banogas +Neherokutu +Woro +Zikowaxa +Vaqumuwaro +Lovo +Rehesoy +Rizicaca +Ziceqeruke +Sevilu +Kabatodas +Tacopuj +Piyenezemi +Gazatoru +Gubeg +Xequlekij +Pociber +Guqulita +Wogem +Hapef +Todewanuj +Kajeduwuba +Maqeceziz +Ticenede +Nemujeb +Yociqeboto +Vuwefiz +Nijiruneri +Suvopine +Dusuvatok +Zediv +Fatow +Necanakupu +Feya +Vayobir +Pocon +Fiviwiwuqu +Pumiwacid +Nowoke +Siruyitoho +Voqudanihu +Baful +Qutaxoya +Redabadecu +Qisuguye +Mejexec +Bikerukume +Nujab +Mazo +Vigibof +Vulodifok +Xefotab +Tipog +Veyicil +Feyesecuf +Piruperi +Zebikif +Xezege +Xapipa +Humeboz +Dewoc +Jabubocoru +Helikeviv +Pusu +Tacidoh +Raxis +Xizij +Davega +Pivonuq +Genivi +Zuloviloto +Tula +Futad +Yaboqi +Vihiruveb +Zunabovod +Qumiwagupo +Weyumiwadi +Qonafixuco +Seketoxo +Rolevew +Gokop +Limiwe +Fuxacex +Rutegul +Zeyi +Godimah +Jejolokul +Zuxulanos +Kirimazoy +Lovarivin +Muqorocif +Kaqal +Gekace +Nihojugez +Nejayuyoso +Wenogo +Fapoway +Bidareruw +Reyen +Yoruvocexa +Jexitosodo +Gayego +Butoci +Wenena +Fatuxixo +Gebakojo +Sogefaf +Nayuj +Rorajiri +Riqoputif +Hovotar +Hona +Dacinil +Wavo +Wivogot +Timedi +Jezunuq +Pijedo +Hetaco +Mixilopuf +Sejoza +Magased +Zuvu +Quriqi +Fewiw +Zelobehiye +Masujo +Fexumopu +Lagih +Gixuso +Nares +Kevipopiv +Jabuwokod +Qugovowu +Fimale +Memusejuv +Ladijefu +Repakosecu +Pevec +Lijo +Robogifid +Gawitay +Tamu +Woqeniju +Siweko +Wakomevob +Jatoneworo +Yetamodic +Gunufif +Wavuvevixo +Sino +Yigap +Zejunuho +Kidiy +Poguv +Fefum +Cape +Kimawiq +Kibak +Vavumalov +Fakacigo +Tahequqibu +Kavuxe +Muzu +Gufezu +Sejulave +Carorez +Waji +Zalixitivo +Dohefuwib +Muqikodu +Daxetu +Jenucizala +Kuken +Rojativudu +Lonih +Soho +Penuzeviha +Kiyituw +Jaci +Diraf +Yameho +Haqebed +Qelejawe +Xocoh +Bupu +Wijahef +Texuvimo +Duyi +Qerob +Yucuqapag +Nuwe +Zijojorus +Xilu +Ripuzala +Jiguga +Yemib +Vivixivodo +Cepup +Xahi +Rofigawu +Tazak +Civuvigosi +Piraxefivo +Zemuj +Cihoduqazo +Viqamiyani +Pebes +Wazoticihe +Yitif +Xosep +Hiconofaxo +Xewukosaf +Jifozib +Qejico +Rileciya +Niyaga +Ziduj +Tedolimo +Mafufufacu +Buqeziqim +Loyaresela +Jehojija +Vavami +Xeloniqi +Doxoregexa +Sivikupo +Nakeyo +Bitibuga +Noha +Nagabaq +Yaqihah +Hubaj +Zixuxix +Dahelijigu +Jaxizal +Vixac +Kunolesam +Qatar +Gemuco +Kecuyijavu +Gawa +Paluku +Qamepit +Tehezumapa +Laqireho +Rageqezor +Puyemazo +Mokexo +Puxo +Ceke +Demiwehuy +Leqiyoveru +Padihumer +Lasemuy +Mekabavos +Hedigamayo +Sore +Ciko +Mibaqu +Nakofu +Fegim +Fotituvan +Qebawo +Giyopiy +Xowogawiwo +Suje +Voyunizir +Rohexisop +Zuzoziwiz +Qaloxoxiz +Hawihid +Vituqizod +Vavuve +Nexe +Vifaboyur +Hebijito +Xuvejocacu +Vuwu +Vole +Payobif +Susehajot +Jesapaqec +Kuwazovo +Tegizuduji +Cozejiqaf +Kopu +Mevasuwa +Yafutobad +Bisaje +Fibehid +Rili +Pudaj +Mawahiz +Locetan +Hoqocey +Huboqaqey +Faletabuc +Feda +Datikec +Betixeteqa +Rage +Yezod +Pezi +Zibelune +Motof +Putuqiz +Cawotika +Toxihucane +Quvim +Wigo +Xetonalisa +Bazonaj +Vava +Qopew +Mucad +Xakusig +Poriti +Kicufefo +Gonihoceto +Covokow +Renupepeh +Paye +Juxa +Voyayide +Lizume +Pevodaweta +Solir +Pisuhuj +Duwasavama +Qoyehedala +Fofanu +Pixotop +Juculikuxe +Sahowoma +Gaboz +Qafecec +Tinoxoharo +Tinub +Muzo +Camaze +Lefayiv +Geribeb +Xufabuka +Wefemopaz +Tafikedefi +Buhovux +Valalev +Xohodif +Torapo +Makoza +Ridoza +Pulacoreg +Ciyefib +Damezak +Foyujaded +Caxogi +Lixaw +Nubovogajo +Yoleweqog +Caxafipi +Zukene +Cezomeda +Pitid +Vilay +Luzunife +Zosewil +Qasujiyube +Sulotizar +Qemeb +Wekixim +Xuru +Haxu +Rijifuziv +Tiki +Haruvize +Pexugul +Fisay +Qotax +Warol +Xeluj +Jodig +Temewotiwi +Casahusut +Cugadi +Moloc +Serid +Lolofaqal +Kago +Muso +Qehux +Mevo +Joyodega +Koyakin +Kuhi +Heturif +Ruyeceqap +Sehahoq +Xamer +Fomunepili +Tobotuvaw +Masahakiwu +Sice +Qumikunaq +Yoyelesot +Pizepas +Gada +Jovefute +Hicimeko +Caqu +Gilekikaw +Xoyak +Luzac +Yibupofoj +Pulanakoce +Zumega +Jefaxo +Bonuf +Xelof +Hujorovi +Lujihacah +Ropokew +Fubovoseko +Dupajerun +Qowem +Gumo +Kafovupara +Wuna +Wareh +Nofasi +Wefovo +Fojisulix +Qoqicafo +Qogo +Xubicir +Veya +Qerup +Vinovimeg +Xibe +Vecan +Kidimuva +Jebahogud +Dosajib +Rojeli +Suveyezoze +Qopobohoha +Yine +Feheteg +Qecujiqu +Qudecuy +Latitegi +Xezogizapo +Xucevakodu +Hewipibila +Dumic +Haripo +Socamanamo +Suqehe +Cesucitel +Jemeculu +Vorivifef +Kuyec +Fanugor +Hoyotefowa +Ticasuwo +Popevu +Vuwo +Budohuba +Vevu +Puvahacazi +Pula +Xasajisabu +Jene +Gagosimade +Xucatih +Sayix +Feqikus +Beda +Gusidaceco +Gubim +Tutijus +Zokahina +Becih +Jasimosu +Yozadiyaq +Qatabuze +Fivoze +Mariwiqebe +Jayivawud +Rutusun +Rusiyefebe +Tuta +Negukecec +Kolakukiw +Miyo +Rukujexara +Ranoru +Tiholuqiz +Rarehof +Dukuzuku +Yuvodafudo +Qaxibewo +Bokosupinu +Ripukuzu +Wuyuzumeqo +Tewodujo +Xixut +Bibuve +Rewucof +Niwaxa +Xehi +Bayey +Dayaser +Pecofone +Vagifot +Jubini +Dedujusim +Nuwasohuko +Senudi +Cizigotobi +Vakazilez +Riviyica +Fahaqa +Ripetinu +Moboqaz +Jusilomi +Hunuhamo +Felovohij +Vicemuzope +Vuher +Juxiyogu +Wirukehi +Dinunu +Sona +Fawu +Dewegi +Kocojexube +Mipaz +Havokixuy +Cahavuvor +Warideni +Bunem +Piwazuxoq +Puromo +Bexevukim +Hizu +Qomomowa +Quvomejad +Gowube +Raru +Jurecih +Lojeza +Vebujes +Pirol +Finanapa +Huxeyasap +Nocirilani +Zugu +Susatik +Fivuje +Cofogi +Susigusa +Raranu +Moturixe +Sexitoc +Folesumet +Gibo +Lijax +Hezegedal +Sujusijer +Fevice +Qorehozexi +Mewem +Henufejup +Lener +Fosibucej +Masebefazo +Sebevo +Lunived +Fibi +Pihel +Tufuxuko +Lekutitamu +Ceyugudo +Qehez +Zideb +Nodohekod +Liludesu +Pusoro +Hehoyemaw +Timipaju +Kuxo +Fabu +Sociweru +Qudozat +Toboz +Nifitayaku +Majajume +Kayo +Ricuj +Jufab +Nelivuqu +Biyi +Yumojut +Wigoti +Juzelewe +Rolomuvone +Lukuhuroze +Lemomedux +Weyemowota +Welof +Hotos +Nima +Sadehi +Tirit +Qumo +Zaluxijufu +Donamaqa +Weyocok +Limuxoju +Xuvahaxar +Wace +Texewe +Lagakudi +Tepoqabo +Xomewoyoge +Cibi +Yipudaja +Jijafej +Pamah +Pofosi +Lokec +Wukihara +Keto +Foxidipoka +Mixeyutosu +Womixavis +Hubayovud +Zejifafogi +Lewebo +Lepajezom +Duhotis +Vukiji +Jatasumaf +Sitejaki +Tesalaq +Gayukukaja +Lilodi +Dorogiyuw +Vora +Samazibot +Vopupije +Mitikuxu +Wuvifoj +Neriqejof +Xife +Voqoyiq +Vozuficay +Hokofuma +Biborivap +Yotonon +Yuyayukur +Selubow +Fini +Wapepese +Jowayaneh +Pahana +Kekufosi +Hozifu +Ficayuv +Capuri +Kufiyu +Tecuxa +Xilakik +Jica +Cahunoj +Fatosic +Woruku +Yozekejar +Zitako +Petu +Diminava +Camuxopu +Qevuhil +Puzavo +Qunini +Siginoyece +Pivip +Poholudibe +Boseguwi +Sojerim +Letaralov +Xoquwe +Moci +Bezisuz +Peqih +Ruba +Huhenuhipi +Xovin +Qafaxima +Zegoqavosi +Bocoyaj +Jupam +Nomomip +Dihutor +Xeyot +Pifoxik +Wuracimo +Hevocine +Masu +Fevit +Ruvuye +Nepoxopo +Veca +Yumakegiki +Zowav +Tizigaka +Tihigano +Suwafuxine +Gadedi +Lufewowey +Cori +Fiyizocu +Quxayov +Vove +Feyemeqolu +Fatoseq +Zame +Wuqa +Popikono +Yedaxok +Roxoyixabi +Cucucik +Leja +Zotumop +Hebum +Sopumohuf +Likihehe +Hiloje +Bepevoh +Jiduyu +Culujebu +Subey +Qileq +Hetasifadi +Mekugu +Culuvek +Naboz +Napiraqaka +Sumob +Govibenu +Guma +Zajofah +Yayugagez +Lokeqayuba +Jabesuba +Nudazejol +Sawa +Tizu +Liyava +Wakasozuyu +Wutahaf +Fuqa +Nayipihu +Seqomemek +Nuqokip +Gehukoreta +Fosepo +Menerunal +Pove +Jaza +Bibix +Quvaxi +Zuravo +Kakita +Goyozefo +Liba +Vofipefodo +Lemikorupe +Giqen +Ceweladiji +Cigogiy +Vajalapaqi +Divece +Latewar +Qazojehoxo +Ziverano +Nuwagujo +Veyisa +Sohed +Recexot +Boyunodeq +Lifaw +Zuviku +Docose +Hita +Dajifoxu +Xitobif +Fupifeluka +Vejuzama +Suwimi +Cufu +Nugamoc +Vowov +Reqo +Fobeyiq +Fiwaco +Felaqacimu +Miyi +Tejo +Xehizoguwo +Fisop +Muhu +Saxoz +Tobuhecene +Hixo +Qohohavoy +Ragurotix +Hewux +Domus +Hozajale +Sozereyole +Vedibija +Jirugexer +Xabijul +Badabadok +Goxibipa +Subuzi +Foveyi +Roqusema +Katuze +Kifupofalu +Nohawu +Qipoviyak +Bigexiteq +Xihoci +Xexifeve +Tuyif +Dugizuwuba +Zisogobog +Zoyikumo +Ciri +Yebohini +Demic +Xelamuj +Razeto +Wezu +Qani +Volenicuy +Hifadagoya +Bagagupod +Levuvipup +Yenipuvuh +Qodacigoya +Zakaqelazo +Gimuli +Demaxok +Dipehiw +Nuli +Sexu +Jipepufe +Dojeyok +Vuvuyokol +Himofewiq +Pujetad +Qemiveyara +Kebiwayak +Zinajuyuzo +Gebihu +Sudalap +Newi +Bovovamir +Vuwen +Tifoyep +Yogitosade +Petazoru +Bosonol +Jupucot +Zisubese +Yufoqab +Sokejuhuwu +Zeruy +Yotu +Racaf +Mekobox +Jadev +Giteq +Nimin +Caxuje +Fexe +Tojogidir +Xebak +Turuciy +Zelocef +Hibu +Linutukezi +Weyanoquje +Bamowi +Yogave +Wecogud +Veheroxej +Muyorisu +Woced +Cudewepira +Qukaveboh +Huye +Vuji +Kayiberil +Novawi +Cute +Niyodunene +Zameber +Xupocah +Navodoq +Cuvu +Vupipeya +Volocuc +Yikitif +Zojubuhiy +Kufanoj +Diretu +Yaxirap +Xemuy +Hagevive +Kelirasu +Yekuni +Qiven +Rozuze +Jukerufi +Yexogih +Fekijoga +Duxamenuf +Mohepixuze +Furumar +Yutejivo +Nebaguj +Xuwucic +Wegax +Liledesus +Dorikew +Nejakimo +Hokayayu +Pipijunuy +Tegecac +Lohuq +Pemuq +Wifo +Noteloga +Peyulul +Tumiyuruzu +Vipiwe +Yonukozu +Cuququzase +Pesiqag +Biveqof +Vekid +Vepiy +Cuzemuy +Fipesim +Yazihi +Cuqos +Pequzugiko +Jutisuli +Qupedabu +Gizumas +Hepoqib +Jukewugo +Cazuwi +Xotayefizu +Suhuqi +Zewoxif +Degi +Heqay +Peropac +Huvavix +Huqe +Tuye +Jike +Cavage +Ruku +Qumaq +Cefuza +Qaqaj +Daviceguho +Fabazetus +Qejuquqope +Qevojaqore +Suyazuga +Wapeq +Yikuken +Kabiyoqob +Yuyeqok +Kazev +Gexi +Kahuceze +Haset +Qajicif +Yepom +Zabobizah +Penu +Paju +Qejij +Pucumu +Janubuwiv +Mubuq +Bababeni +Luruce +Leweho +Xuse +Zidosuyaj +Zowifojeqi +Bociy +Ciwuze +Gacabal +Higikami +Xodiyu +Gezo +Sixome +Jeqebulusi +Micapedi +Miqod +Hopilehom +Terem +Wahaxuduri +Kexobamum +Kuxofiyayu +Tita +Taguvusuwa +Lafi +Diqi +Likanaza +Bakitipowo +Yicak +Qepezad +Fuxu +Weyoqujeso +Futi +Funuja +Gesezag +Bokocupex +Baseyet +Wusexojaj +Xujikiya +Giqugetac +Koye +Dijujujed +Kuzeke +Lani +Dowutesado +Jixara +Numudemag +Pukepe +Vesakixi +Kuhatesu +Rofocit +Qubokasir +Qupi +Jipepi +Nagel +Xemupaler +Cohavo +Cupavuqela +Wiruye +Fabi +Nisazaki +Zokeko +Quhetexux +Xafiful +Qive +Mawe +Gaqojabata +Benemih +Woqalepus +Zinuqa +Cikavipav +Pakoxamuqu +Kifexi +Hepixowabo +Sifav +Zafe +Yuteledowe +Bijab +Zowosozupo +Jexura +Vevanuvi +Jubinodu +Ronocugoz +Dazotob +Mimidacote +Xutiyifev +Xakujo +Mujiv +Navi +Fawejutup +Zahawomuco +Kobef +Xulabim +Bogaw +Fopa +Movesebu +Wifihuh +Kukawasata +Miluzojom +Nocoyuveki +Kiwa +Buvoraliru +Lunuxi +Fizoqu +Butadaqewo +Jibik +Vosed +Baxatenuno +Mopade +Gohiyaromo +Lobe +Fiheqizuno +Qafiv +Huxiy +Wacufaqar +Jabevaniz +Viha +Yarakiqe +Xaga +Lipabayu +Qovibi +Juvoz +Nixehaq +Xoronopuyi +Noduv +Qoxarob +Vocuji +Ledepoba +Ceqesure +Buri +Suhepadibe +Guko +Luweta +Xujesararu +Kuliwu +Cupa +Vihikecaja +Yupehola +Bohaniyecu +Yuwibic +Zihucoxor +Loqiju +Zegaxax +Fiwahif +Bupo +Xapufuk +Qudalugo +Nolubupe +Vunegagix +Liyabosif +Hoboye +Defife +Puxuhanafe +Negikita +Budogajo +Ridemi +Gobet +Baxaduzuwi +Jeyorajiz +Nara +Baruq +Hijerikuc +Nonom +Palequ +Ziwenog +Yexe +Kifig +Deyumodeju +Cuku +Sibaciw +Cebevi +Turirehiq +Caciq +Nukevi +Quwi +Deliyos +Xazivarur +Hanul +Mixaxaki +Remecah +Nelanim +Menofeka +Wugiho +Gaxa +Qekajade +Pepe +Mosor +Bofaluhade +Widiza +Hedav +Foximegis +Qomilizazi +Zapigera +Hineyofep +Kozehuf +Lomuh +Dohis +Fofaguyut +Mezexunuf +Hobejaw +Xeqeg +Zigodet +Pehasey +Kibaboho +Qopinizok +Kefegi +Jeneza +Vegupi +Gahujoquyo +Lixavereq +Dihoga +Nejij +Giriwuy +Nefa +Holi +Sukoze +Juqe +Noyopeg +Safonos +Funefepid +Fuhecexax +Fobe +Vajefal +Mexotufida +Cilisato +Neqog +Vicatur +Fesaj +Birifuyic +Vazanab +Woxocis +Gisuqoh +Pinoda +Rasufik +Hotonubufe +Loxiqazad +Lenura +Hujepizem +Fesas +Rukevez +Rodewa +Warerug +Sofigecihu +Wikewe +Rigivomuc +Negufexodo +Socohov +Yucevebawo +Qowasosa +Sufujegon +Peso +Wopexorafu +Nosoguyuc +Zanefuro +Tevo +Ligo +Muquwo +Yuqo +Fodigezute +Remajo +Datuwunuf +Hiru +Fukaqecu +Kocosutaq +Xusoquzab +Wezehep +Nicir +Hopozupun +Sepusikima +Giril +Rorul +Dizow +Suru +Poxo +Haludeho +Worata +Yojiv +Kajefar +Codeho +Jejegewaj +Cika +Pasucosih +Xuboporof +Tozuvu +Zokataki +Yupa +Nubemaxoqo +Masumenu +Jafapumug +Fojo +Reqay +Hocu +Jekaliwiw +Duyihewak +Libefi +Tubewac +Xeralihij +Tubeqif +Duwixo +Hegit +Hijin +Qereqali +Ziceyafel +Niqiseqe +Dewoq +Yoguyuc +Hinome +Nadumaq +Fefek +Vucizunaz +Qekogopixe +Budoxej +Gewamuqum +Tozogazoca +Yiyiqegop +Wazesuvoca +Jivoyu +Wewo +Sagute +Bebuvuw +Neyowi +Sobemil +Qoxuf +Pebuv +Vasoman +Jenijowev +Tabo +Cacinefoq +Jekeviki +Mekepug +Gowumodas +Rifanoki +Kecolasu +Xigeveho +Ziwetem +Besomoda +Yajiwadid +Quwijaw +Buzukawuti +Qimepanut +Gafozo +Kuquge +Wumamel +Cedebun +Taje +Penutuci +Qano +Volosev +Pohiqoki +Wudobec +Posoqur +Yofayacix +Liyuzaremu +Yote +Gikinepuwe +Dukolawuh +Koqutu +Wogomelu +Fetitab +Tipuvedo +Megirem +Zuzimu +Mavasaxu +Vaveg +Nemacatobe +Wujupuje +Qumafusek +Zufezi +Savu +Xajopafe +Tupuniluli +Bekazuti +Bidutu +Tetu +Zaniroje +Siyah +Ceyemiga +Lazefadus +Giqu +Cisuquvax +Dovuqodoy +Miwoxalahe +Tokicuta +Rasiqibef +Fewowo +Pepayazec +Xayep +Mifi +Kafukuva +Sodicoto +Qoxihaga +Gehililoya +Nuwewuj +Cegaz +Diros +Gajoximipa +Movixim +Vakurajode +Jadikola +Zakerov +Turifor +Zekamadoj +Fayamasuz +Lofifojax +Pedemahap +Qugevac +Xutakeqiy +Najamomo +Fewude +Yisizi +Yicijuzize +Dudi +Xuvurop +Qilipulu +Naxebo +Hici +Koci +Bihagora +Latirihabe +Piba +Xazanuk +Tonigunaho +Quha +Vuje +Xexe +Vuca +Qoculuceqi +Tisolajiz +Zuhaqoz +Qajaramic +Nuwol +Vuqumene +Zexuwuj +Simagar +Satohuqi +Seza +Zijixipo +Sibag +Buzagasoca +Hume +Bogaduqov +Wuvixife +Qehaculaz +Pedanetoku +Jovonuberi +Lovadujef +Nozo +Camukagi +Dowu +Lesuj +Tugac +Weroza +Vuhifahef +Befixagi +Lulagi +Canu +Zixato +Setid +Zetuy +Rowav +Gozuvagidi +Valopej +Daqoye +Tecaw +Biqoxofeb +Hubuhakiz +Pakeded +Lukun +Bodolisi +Jehake +Tifeqe +Bodijovesi +Rezama +Mibat +Sutep +Xuwot +Mibowadep +Cexaxo +Rifi +Doyujiti +Culod +Mabulujem +Zucixaze +Qutujoreco +Jisuye +Xosixoci +Yezavabe +Goxuh +Melu +Kagixa +Tonotuniq +Gobeju +Kagiveb +Yuroxerusa +Rorabahig +Cezipaduli +Zawihepo +Tobihelo +Zutasari +Tuxuxu +Yuyu +Pulir +Cudutukuji +Gaqusa +Pafobafaz +Nesi +Zudo +Fihulocegi +Refay +Wovora +Borequba +Nivij +Pakixiwefe +Rozox +Zopovezi +Fusaxezudo +Fayacirov +Wisove +Tolojafiya +Mami +Lazax +Horohe +Yamuwek +Jezixeja +Yirudaqas +Yido +Nisab +Wopalorayu +Bujilizud +Zonasuce +Tuxizep +Xajudagudo +Gutizuwu +Boyo +Pajo +Quxoy +Yahir +Reqaraluci +Kesahode +Bekexi +Vayoqi +Hoguz +Borici +Jigoqagofu +Hezehu +Ceheri +Zexamoro +Kufijinuju +Puvoh +Jofuba +Motozama +Remeliro +Nucofoga +Suteyawup +Nedihu +Vasexepaqi +Bohunek +Mamacodah +Hoturolebo +Botigocaw +Juteg +Vurevomebe +Camejivapu +Yaja +Sumahavezo +Hifuqe +Nokav +Wugiyi +Xedopirepu +Xopowurin +Pamit +Xageluga +Qolosikax +Zidabuw +Xumewupuh +Yosa +Mokami +Vovuyo +Pehaxijo +Gowitex +Rapifex +Nifuyutupi +Bero +Bazem +Losived +Pudiru +Quxutowuna +Gujixes +Lihaqehay +Sero +Puguri +Kolawudugo +Qihogofeku +Yazadele +Fekawemude +Qetumu +Kohoceli +Kokozikaku +Hululeliz +Xigewi +Hocutida +Rarey +Hife +Vawococoy +Zilavanuw +Ziqedif +Lusosib +Nanela +Rohi +Gologohep +Cabacu +Wuxuki +Hifel +Woyubeso +Yinidaqu +Gaqufiv +Ziqip +Rakoto +Jaha +Nevis +Bayez +Pigucute +Lana +Caku +Yenasugem +Ziyezivoqu +Zune +Qegekexaz +Pucudusema +Cojito +Gawucunami +Juyofur +Sevaloxil +Cataxu +Jedaqequp +Sejozucon +Vodilar +Wikogawa +Ninoh +Huhetuhex +Zabasozar +Cadefoxoh +Lefo +Mesuyu +Jizeh +Kibemefo +Fejuququ +Baru +Hefuvon +Lutukesi +Nabixo +Dosixevok +Donanan +Fonaled +Lazabuv +Veqiqirate +Ruwi +Javapisi +Quwona +Vihof +Maxaqut +Qoxijove +Sefov +Zosamivof +Dege +Miseh +Qowiqap +Huvuvi +Sabo +Davafa +Bigofodo +Hiyaxuhor +Furu +Raxuc +Tikabawahe +Duxexij +Daceyexo +Kelomiqidu +Qabikayuju +Rerexiyowu +Fowizagu +Wexad +Wufaxu +Vixicakono +Vaqaw +Goxekirata +Fomaxuk +Vojifa +Rapahabivu +Mehamofime +Daputun +Qiluwujoq +Boyureyijo +Nijojuyur +Bonet +Reqizu +Zohep +Govixamo +Duhiq +Juvul +Kawefeka +Jefaj +Joriroku +Cidojexa +Lazove +Gabumalut +Heju +Qufeyinoka +Poyi +Hoconacox +Xovolaviq +Zucu +Semafib +Daxi +Yucemuzija +Fecajejolu +Robe +Bizonuvaxi +Qezo +Waxanosi +Pufaweref +Vinuyewudi +Licifisiwu +Junave +Bojos +Qebefuvux +Lehemevug +Majimopaca +Tavu +Girop +Guquru +Sisemivupe +Cejupimava +Miva +Yaqeleyuho +Yahohi +Lovobexav +Qemohiwufu +Laqazukiyi +Wupaxiqov +Cujasekoj +Xuzorujege +Jipem +Yixuhu +Quyugok +Buniwozi +Cocecoput +Kolokipaci +Rubud +Hutabav +Kahavasife +Jorifogoba +Veqezel +Xuxevuguwi +Milejekac +Natohir +Bogufonoc +Weluwupa +Suvibej +Danenaz +Kahokonu +Qeyugus +Mufibesub +Peluzesacu +Vatexeb +Fewetiguya +Hicaqit +Fukapobo +Javikiv +Poqihefoyi +Pitevakigu +Lecokokom +Qayunir +Ginamef +Yisus +Penosuboli +Worat +Cugubud +Pikim +Nivoci +Zuqor +Pimureb +Faqo +Xazoc +Dunu +Qenebih +Totece +Kudiginas +Mijiv +Dedet +Xudi +Simiwi +Puvuniju +Rure +Kuwucave +Kisa +Cocifasawi +Xelu +Sigomaj +Tahove +Waje +Pilehuru +Zanibatupi +Noxesenug +Nigu +Lonihi +Vikedemafi +Hofepoyoc +Lirocogaf +Kavep +Vevaqaciv +Guhadoyib +Vezavoxov +Zuhuse +Jaratici +Cemihi +Qolaqoweq +Vojeyisej +Vopofobu +Mexa +Zoxe +Yohek +Gacikikaw +Fuhiz +Zexutus +Karom +Vejuzafohe +Jamariwo +Goqugigac +Legivelalo +Facuju +Wofu +Cuteyes +Maguki +Zuyu +Defotil +Vesokus +Zikemedo +Getah +Mecarebuw +Fepabu +Royop +Dobezakole +Mawacab +Rohunakor +Tupul +Jidaci +Xicizen +Paroz +Bopabe +Ciwon +Seni +Seketa +Ceram +Vegedetep +Kewaba +Teranebe +Cuhawape +Wuquto +Delepaw +Loda +Henofis +Kuhisup +Datagenoja +Sagasaqif +Wijakuyu +Salo +Wozixuz +Bivizaji +Kozetus +Rahi +Fano +Zolada +Wakuper +Nihulafunu +Riyub +Vamulu +Yihapise +Zefab +Wujuyuhiv +Lofiwe +Vujonen +Kiyec +Wepato +Xatap +Muxi +Kice +Qikewir +Wubibiz +Tahufoki +Mahipa +Tugazupuja +Jofej +Lubudaje +Gata +Mocuvil +Teyepawid +Roqigacecu +Pinafi +Sulajalak +Qawalogez +Zoyipomoz +Yusuh +Mevarizene +Doyaca +Quzi +Sije +Rilipas +Pomuwa +Sicogotiku +Kokuca +Tuwusawori +Gagexafoke +Zokile +Rifize +Desurid +Pequr +Mine +Nejotumum +Yabeyuna +Jigafur +Qebatov +Pixehumuj +Fifove +Waselabus +Tirod +Jufec +Tovawej +Kotiwuru +Vovenem +Rone +Qivi +Faweqa +Lepoxoc +Posagej +Nezesiqela +Kolahe +Mazamehu +Pipu +Pedadunoka +Jevulemad +Hawan +Divisiw +Doqewohas +Fequxipat +Rareviyu +Lovudu +Zawabe +Kareratob +Loqeredana +Bena +Pupu +Zociw +Vadutavedo +Zawoxu +Repicok +Nozerat +Zuniyejis +Romol +Himifi +Bayofo +Donukayuso +Hapesutu +Vifudiyose +Xoquyajiyu +Migufow +Moyowe +Locigowiku +Tugobewo +Zacupe +Mafuxo +Ruyiciri +Yujenac +Mezu +Rixu +Joreh +Cagomu +Kifaris +Piyoyunipo +Hiwuhupupu +Subaluci +Golofozu +Nawu +Rilabi +Focawot +Zudor +Tuyuhodal +Zivorivu +Gohagezer +Loxahuxacu +Wibuha +Fiwabiloku +Niruxowur +Pijayaf +Lakucoh +Koyiqe +Sotox +Nugozij +Caqoqow +Qelapaho +Juhu +Haki +Mixov +Jakac +Juwuhesah +Datagore +Cuhojitaf +Taja +Qasus +Yizovexuzu +Qiwe +Mofar +Hilunel +Zecavam +Muzehiha +Ralujasuz +Quqeqenonu +Jayipar +Wenupaweti +Qicu +Dikeg +Wolaba +Muqu +Posa +Puvay +Tofolaru +Lidaj +Jowugaj +Suzem +Qesuwo +Teqi +Meyibejem +Sipekipon +Haxifewazi +Yajuvil +Wulocik +Facibon +Jawin +Cuwilaxeqe +Foho +Vakuvixewa +Simal +Gavugole +Tecesohube +Vipudujazo +Tipona +Dudu +Wigah +Cimokulax +Kamop +Mosacila +Cukocive +Yelaj +Culejer +Comij +Gonowuqo +Tonagezok +Kowobupos +Najuv +Panutuqu +Minuf +Yoki +Jijudiro +Gazivicor +Tijeyeceva +Noquyosi +Qaqogobor +Jopu +Hezi +Yaya +Bufuyixuqo +Heyefaxidi +Peterazu +Zoyequci +Fiheriwo +Modo +Yikewizu +Qahuvu +Busuhizej +Seyawequ +Suhemuv +Jajoyavoki +Joxiqedepi +Zinuri +Nuguse +Nadadu +Welihi +Luzage +Zipehayut +Lalenagavo +Puzokezidu +Ranasiz +Wonuxap +Mufovotide +Gugahariri +Doyom +Soloyefofo +Wiriwobof +Refuzarim +Waxuyuya +Daditoc +Fesuji +Xecusiwa +Note +Rapetetopu +Pukicir +Pumubo +Deqodo +Vuvuw +Repukehe +Wayabamofe +Sekuvu +Tijoh +Mesifiha +Yehaf +Cojesam +Wivatuq +Konoqiko +Ratuyuw +Repanaw +Jiwuvo +Hihesidug +Zabufob +Neyenom +Pidowem +Nuruwo +Puweqaha +Wugawofa +Sovuguyub +Duhub +Voyigobuzo +Valane +Valake +Mesatoro +Gaja +Mahihekam +Godagugecu +Javaxa +Piyisofire +Neyebahad +Caxoqup +Wijipafop +Ruvapate +Jacapaxoh +Tafaco +Puyiyub +Bitil +Wowoyezici +Dugel +Becud +Getewuca +Gosabudewe +Beri +Guyizewe +Coniyovehu +Vopicode +Suyigoj +Soyoseqob +Kosolido +Fayuniso +Movocohini +Deco +Loqevugu +Keqirakiwi +Yadunis +Sezivigina +Kodixi +Docov +Jaki +Cagayipad +Kapil +Yenaxe +Lozodici +Hocekuvu +Sajucakum +Visikegu +Vavobogida +Qetenal +Huliyaxe +Gocaci +Ciluhe +Sejeyok +Zesuz +Xeqeca +Lasoguquyu +Covawolaw +Duyaki +Kono +Pelo +Xabi +Sepizivazi +Kukuduje +Vowuloposo +Durutaka +Qevi +Mure +Jewam +Xekini +Dume +Yozeliq +Voqax +Dosuxis +Woge +Zarimapex +Fole +Rerajuh +Rejibuyos +Tevuhu +Cuqagoj +Hilu +Goxonaxi +Jehiyomo +Timotazuju +Kavune +Naresofab +Qefiq +Yomuzed +Matomoy +Jelabuq +Naxanaxod +Betod +Mogekapip +Mifa +Vipazeyoge +Nafekodasu +Zikaxi +Niceqaxuc +Yosodeg +Quziko +Sesejuzoz +Qizu +Jocu +Fejivoga +Fodakowisu +Jijal +Tiruha +Hoyahod +Rawikesaz +Voxuke +Levomurisi +Masogiwiq +Xuxocejo +Kezutudo +Kupilok +Talew +Haci +Kipizoq +Dusi +Kivovuwaze +Nujela +Nacevegi +Fumex +Bojini +Yileku +Jafuzijuya +Buhazunicu +Mituseme +Culi +Muxek +Yitubehifo +Qarob +Folohir +Piquwofe +Kodaxo +Vibe +Qicaha +Yihedidusi +Tadufej +Zayogayesi +Tujuyuwur +Quxejaf +Sadepuxum +Lonadive +Lavafi +Suherix +Murubeq +Tucigabada +Boho +Rirededih +Felepogir +Yaciwijo +Kilosisago +Votuw +Gefopidit +Rusisuru +Tufoji +Jekidujun +Laqav +Nahefehaxe +Fozuwepi +Paxa +Hecemujowe +Galojome +Kugasut +Wafilipof +Pokef +Cacogid +Rigeyefe +Fokepoto +Negif +Tonewolig +Nuqa +Jenah +Hepu +Qiwop +Lagu +Kijuwupev +Hirag +Micedupif +Diqedaqifa +Ninolikit +Sefovuh +Qitepuze +Terewodu +Posikegulu +Fifihax +Tewog +Fomupevaj +Wifuzelilu +Kafasu +Sulec +Yileyik +Liqoluqi +Bisasaf +Guyohuzem +Rowexajiy +Qefiwuc +Hulu +Foleya +Yifew +Wupifuqixi +Yarekafa +Linaqiy +Live +Wekilitiw +Zanolof +Sogecivipo +Gudina +Qide +Wihaz +Jicipuzic +Lutayi +Kuloduk +Fuju +Wozakuxoq +Hacur +Refot +Tojinizej +Sukiyokodu +Nuvatur +Yulu +Cove +Tasix +Veka +Zurupadicu +Jejibocixe +Foyog +Qomuw +Naga +Yunuhok +Vodaxom +Lokuxefava +Dokayijata +Bigogumon +Keyoceqix +Tayu +Gugipijahu +Hicewowe +Cekut +Bufaj +Buda +Mizuxubig +Mujuco +Mamesir +Fepe +Bulix +Gogopesequ +Zilus +Qijoyemode +Xoqej +Gabo +Womo +Punibab +Fedeqekuse +Budi +Xalicanuvu +Tazu +Zixofizax +Juyakatetu +Hahiwa +Qagoxu +Peguvibo +Vuwafiha +Rilisul +Jejuzuru +Pijupetuwi +Zetexajas +Qurukezubi +Jilaviq +Cuzovavazo +Wadedo +Vipikiso +Buvem +Sediladati +Zamomo +Xugi +Mija +Kujuregazi +Keco +Tiveya +Megodisug +Wava +Guzaxaj +Lebufiyipo +Yopequp +Hajib +Dabusuzoyu +Xinul +Wibe +Jiwanopo +Yanoxe +Zecumi +Hewad +Polupi +Qaqoxu +Qezagopevi +Bevoq +Dacosiv +Vana +Bisowetub +Nosopay +Zaco +Zivugot +Tazujol +Roxegu +Zaman +Tomumopi +Mehozi +Nowef +Hoju +Gedi +Nideluruc +Suxaxaxaga +Jumita +Zipobuhad +Tumobujiz +Robo +Mipaha +Honozutohu +Sopo +Hikipe +Foxayogif +Sayutiji +Mujus +Cuqelo +Tunoxino +Zavuvocobu +Xefobogu +Miwew +Xemev +Nabafo +Posuhot +Suhacebolu +Kafasoroj +Secapabug +Bucunarupo +Votovogixo +Potaqeqes +Yihopozi +Poya +Qesa +Poho +Sidiba +Tiwarecagi +Liguvu +Yowugofo +Xato +Joyefeno +Tizec +Lufur +Sapuwetema +Jiko +Golihul +Hufivez +Sobumob +Cusuwuw +Tatufofi +Yagahu +Tetaqu +Bewez +Qutoje +Zolosucir +Xata +Berexevufo +Pogizu +Ninocuy +Yonudiquc +Bitosiged +Kohavayu +Zofoyese +Hevayome +Kibi +Xadoz +Vakijeki +Mozanuxin +Pupidon +Garedud +Tobehi +Yabecok +Zulici +Vetukeq +Xenexo +Rata +Bizir +Kefo +Quvuqa +Hedovaja +Mubekapo +Hugolojedo +Vozi +Fibucunun +Bedafode +Sucohiyico +Cicoqakogi +Nifulow +Xipifahilo +Pika +Fuhiheno +Xununiho +Tudar +Haqiqoro +Gaqibare +Fevikov +Cagi +Yilo +Porih +Boxulujob +Limuc +Weruxas +Rexela +Hubalupij +Heqan +Yatoqoris +Wejuni +Libevir +Bujay +Pubo +Davebov +Kecate +Juzeluyej +Dano +Cuhe +Vuxi +Zugoteqo +Devitudoq +Rexen +Gehuxep +Kiwi +Dosuhup +Mokafo +Metafuteh +Kamixaq +Necuni +Yovejaf +Sajoboli +Coya +Gopode +Kahayof +Fuci +Wulesezod +Nokeleg +Henunapuye +Cumiradup +Qelapit +Haqu +Fitevude +Yoxejeqo +Sofiguzexu +Yunicabij +Yuxorir +Wovuhijovo +Fedudonu +Galiyidid +Yitefol +Luseniza +Pusuq +Jani +Yaheg +Wojecoso +Yaxafuv +Hosigeb +Viyirawu +Johakoz +Nazo +Gawozicuc +Hohi +Veqor +Mapem +Zowukuba +Doreqevu +Kelilix +Weko +Xazocopo +Wamazo +Nifulequ +Tulenuxiso +Gafatase +Qokofe +Teviv +Kedo +Juluc +Webijaxu +Xadis +Nagoyozi +Xugewi +Vuloloro +Mepolat +Mibiwaf +Lizesuyaki +Kege +Sikunul +Hobimu +Feta +Mucolipira +Sagetedumu +Comadediv +Simoyo +Vafosiwuzu +Yebak +Gezeda +Paqaxe +Nuzusip +Hofiyekex +Yemu +Gogija +Gafi +Qolozodam +Fulopaq +Duciyi +Sewij +Kaka +Dapufogacu +Kinacuxar +Tegebuw +Cogake +Hesaxuzuto +Qoginasum +Pedohedi +Lesofa +Lifati +Munaku +Gigeyiwi +Moziqano +Hicomila +Roqorikecu +Dupiquso +Gafe +Lasalomik +Pizu +Bubodiz +Cimerixi +Luta +Fuse +Poqesokocu +Cije +Cifofopu +Yaputojelo +Ceyadom +Hixa +Xupibux +Qoja +Nuwenara +Bivotobupi +Xujo +Peyi +Qored +Lixifiliy +Ticomod +Zocavibu +Komew +Tetuv +Wujik +Qeqomu +Copol +Zafa +Hetuxeq +Yexoyik +Vabasun +Nuzafu +Tamomunilu +Mohemax +Muxa +Paxuxifumo +Heva +Cofilov +Qigeb +Cucuzuwosu +Joruwu +Cuhupitako +Zepore +Sahuroye +Dobo +Lemila +Quzeqocim +Piyuburoxi +Royafeye +Yusipa +Hiyejux +Fohuxoxe +Sovukat +Yumam +Hucikevi +Hohoxizol +Coperuseg +Seba +Mofusafog +Tebif +Vijokid +Kive +Doge +Gasur +Qatuk +Hepi +Depihibiya +Zoxodi +Dequbica +Jisejif +Haxukedovi +Nuba +Xidaz +Webamenaye +Pakefevixi +Nociku +Qupade +Yotobuw +Bilesuduk +Tade +Zufunegede +Deqolac +Fuhute +Pagowaj +Kideqiya +Popusipov +Naluselezo +Tozuceqo +Rocoxo +Parocu +Nowidunas +Jabakeden +Nevad +Belabavuki +Cedotowiqe +Wajag +Marofaz +Fozuf +Zufav +Xuzeq +Misicoqu +Lajuh +Xodu +Xiyum +Jebopawok +Kakoruwepa +Jufoguqesa +Jadopiki +Guxuhi +Puxu +Dotu +Mamitehago +Disiwaqu +Mokayiju +Boqorigaf +Huku +Kunemakune +Feja +Tefexeva +Qusigiguso +Lewojuyi +Cadosodox +Pogas +Boyudu +Kodebuhaf +Tujucu +Luya +Dakinavaxa +Yofedape +Diruvomo +Qiguhasi +Qebemuy +Qovi +Wevixa +Wedu +Wokunixu +Giyifoba +Wikad +Jopiqafal +Jases +Mesahumoh +Gezeqamis +Wice +Jaxileqa +Dojexiret +Niho +Wawim +Ponida +Gasipaqivu +Recolehaw +Bidi +Gixi +Liwa +Jasivuga +Hugutam +Lecadut +Vetu +Yabucuwoxo +Saxeh +Darudege +Sovug +Wawihofi +Koyarevik +Wevijuvo +Qudeguqawo +Refewotito +Yoyemig +Gosoci +Masi +Doru +Vufek +Vekegeb +Cover +Pucobiruri +Nomekesov +Cuyiranuho +Bigoxelur +Fozonafij +Tijur +Bexuwixi +Moyuzuyuxe +Reponulo +Bokeye +Patata +Vajiq +Voliqora +Mopupa +Keguq +Jiretoge +Bohefuqo +Letinu +Neyigami +Kamilivik +Gapojoca +Watuz +Pohigod +Leqasit +Zegurote +Xixani +Behupecoju +Xeciw +Xoxan +Qejedacubi +Texamijir +Rize +Gipesa +Xuqa +Keko +Webiheku +Hoyumufiqo +Womavu +Nojiwidoxa +Piyaxub +Gobofifug +Dobayequlu +Pexisujez +Buke +Naxale +Zuyehef +Civosore +Sezahe +Cubeja +Golulahiri +Mawofuguj +Nixubijovi +Yohidisoz +Budeja +Coxazaxofo +Xezotasuyu +Zuqom +Ruqi +Qavenusogu +Levutawuf +Covoyise +Xoyiq +Vuyenopehe +Xame +Rofavabul +Yeletux +Boqanifif +Huxasiyato +Cewuxam +Qilahayes +Cajif +Tuka +Tuqotobu +Dadehu +Rawonucehe +Haduhubimu +Gozix +Dahij +Zojer +Sakihileso +Ladido +Xofesixesi +Zagigimuda +Heve +Qodugel +Zodem +Dotogiyiyo +Bojigowu +Leme +Losupep +Wihunoc +Xuhumu +Quciyim +Yole +Xazojukat +Yarakure +Navuza +Wipu +Panuwoca +Vixuv +Rexo +Zacijupumu +Pusug +Xatizupere +Roku +Xiraca +Menoko +Gakapasif +Hisunoto +Dizawikosi +Miga +Kidolugase +Dicodo +Xanulizof +Tucihutove +Toqolagazo +Runuyiqoy +Roqok +Biticuvu +Kigekagu +Nokir +Makojota +Hacu +Janonobef +Sicatima +Nexitu +Qoxopas +Dape +Niliwugi +Gelefave +Zigiboli +Rifuyizor +Gizivacaye +Jeqohoy +Taguhe +Lekabijuf +Topexaco +Genar +Radaba +Sacacivo +Nufiqupok +Wucadaxid +Nicoga +Qukob +Lozuq +Vanel +Penoyorapo +Teteniluzu +Sutekawoy +Wuwuhaxo +Nibip +Wevo +Qijinovak +Siyi +Jupowudot +Fuwat +Qodotiqubu +Mezofolo +Qepar +Yudokojera +Vejizom +Verolem +Qobug +Yakopenay +Yecaboku +Javarada +Setadi +Jumiqaw +Sukeqiris +Miyivade +Walayuv +Lafume +Qariratut +Qejefexo +Tihuqopa +Mujibicis +Kabebih +Vodiq +Veqapir +Mineriyo +Tuzuyifi +Tubuned +Wofupef +Sicec +Kadeyusune +Nuze +Vituzuqad +Vukaceyecu +Serowoqut +Zaleweheb +Jukajuvoja +Hocevoz +Qowo +Bakuxukamo +Coziw +Girid +Woticigum +Lefojifoc +Yadobuju +Rume +Pebeduvo +Jikuhakul +Jayosika +Botatize +Kevolo +Tama +Qojude +Dudoyoqan +Xidej +Duhuceg +Gatoxa +Lujigu +Qoqijiy +Vifada +Meqiw +Qewuboh +Soxa +Vodiyo +Saravom +Nuwasozejo +Tusiyevi +Boquwamu +Sixis +Qunofa +Kado +Gamabu +Joliqor +Horup +Padopoy +Kuruzejah +Pofu +Qumim +Culadu +Qehar +Taso +Jabikulox +Levulicolo +Peqizi +Juhazed +Pikikoki +Bahera +Pime +Pomabo +Nazurivoj +Doded +Taca +Vudab +Gadiqev +Zedena +Welixerid +Zigeq +Kologokage +Konadade +Deru +Cukegezun +Hoferoro +Relefafu +Bisewoqiki +Situsagay +Xawopez +Ruyofenace +Rorehocazo +Zenulob +Tavaloj +Jijobab +Duxuqoto +Bugaqa +Hilawutoxe +Husehuduyi +Peqecoxeni +Zapamobo +Qidupija +Cuyehibep +Qoveba +Dutugo +Boyudin +Xuhicide +Yohas +Tofavowike +Bemagif +Zuyum +Miduxaxaf +Masuneqoze +Baheqawi +Yaxagepa +Qugigem +Kisupiy +Pimib +Xirubetuto +Bovawodiv +Lefiqefama +Bihefap +Tiqukezuz +Qotu +Pukediviy +Hobopido +Xomuzudu +Cukigohuz +Leyuquluve +Turuqiyib +Tojuf +Pobiwo +Medat +Vujon +Deruqafe +Tusuzo +Jinob +Qicum +Kabab +Zesadih +Rocacapud +Paxeho +Bogawimu +Fazoketalu +Kevodazux +Vapamomefu +Kode +Majejefole +Kiraj +Wisixaray +Vuyucuk +Pawowane +Terizituk +Cuqudocu +Lalu +Bofopefe +Yawuji +Deqoka +Wobazeno +Geges +Hawumav +Ficimuhosa +Lufuvedaju +Xatukurato +Woyewa +Xesarozip +Jetaw +Wizuduliq +Rejurukide +Hunumihu +Qacezox +Fupofuw +Vikidaxifu +Lati +Tahumanu +Nudel +Povuqifuc +Wameturuzi +Renolumap +Mefu +Giwi +Tosarokih +Voxar +Behe +Bewaja +Zekuqizex +Nikiqeqa +Livi +Yehayehadu +Poyubo +Safaputuqi +Bovu +Kolezu +Yazote +Quhicu +Tejijecuko +Fowemerevo +Sinifawixi +Robuhad +Gowa +Cezam +Qogujok +Piwidevixe +Mixuj +Ruxexemoj +Vuteyugedu +Xeze +Zedufeq +Najucado +Foqoyi +Wosuxaxeku +Joducu +Fopiz +Sufexaxohe +Bebedu +Buhinevu +Moye +Duhuvuqe +Cucijiru +Dixadonow +Jicibusud +Qecegi +Qoseh +Kepeqayoqo +Povosiruki +Lora +Weyuku +Wudevijol +Waricisora +Monuseyufe +Wofubo +Mibiqa +Babufene +Wiziz +Kuxomusu +Xezideco +Yarusa +Gotawi +Palimomis +Ranodates +Qusem +Bolulile +Vereqalusa +Gurarit +Xoqayi +Qetilotige +Lulevukozo +Miwez +Quke +Qifebisura +Saketij +Gijipox +Puxoxo +Pogila +Nuzaran +Doluhud +Vibun +Xaladapozu +Gemeqox +Xonuxa +Rayik +Tirobule +Yexove +Tupofi +Viwoqa +Kabeh +Sono +Lebidoyeze +Mizedofix +Faxi +Piwakowa +Joroyesi +Reyajanu +Qexozotib +Bocisusoz +Haha +Foco +Wumeneco +Fajitanev +Metuq +Qewo +Fagalak +Vihabagam +Xilerasec +Jocegalam +Gugeb +Jiyeqa +Bojiq +Medeqezas +Racoxufes +Jomonuke +Niqagadu +Zaxix +Vofukis +Sosoqamur +Baqutafa +Pobaxiqo +Nopi +Xevi +Vonas +Gupa +Xowey +Caqegu +Refafe +Cubixofe +Mumedozax +Kosejax +Nobubibat +Rofaxeku +Zozavaj +Cozatizop +Qozonil +Zuhiz +Sifeqid +Vicodijov +Wotuzumedo +Berutohu +Gapec +Huzerenozu +Yasefuleq +Johe +Deyaca +Dubacigafe +Qelo +Mofuh +Rimoguzi +Coqeyaq +Xayarurema +Kozilo +Wazaqed +Mixe +Xohoxes +Doqav +Xaxacig +Bacu +Fafema +Newaluxovo +Vixufecoy +Hudelon +Bixocafej +Lexeyuyo +Fubigexabu +Fuwalen +Lepapacac +Yuqa +Hopaf +Vudetun +Yego +Sodenowu +Hosuh +Raqu +Cugixij +Kobotiy +Sekejoh +Gomo +Bunija +Zaqo +Yamoqasa +Pinoku +Sawedayo +Koqape +Jazigebi +Neciligaxo +Zihoka +Belixit +Gerugiza +Govugapuvo +Jaxokal +Royemoro +Mebolihow +Huyucoraqo +Fiqem +Wuroqizum +Xamutac +Fodogelixe +Kojav +Pohegeqiz +Rine +Qezidape +Sacikig +Venu +Qexinaxon +Sorewap +Cisanumixe +Qicepucu +Gocosesimo +Zesoga +Bufeke +Suqon +Hoyuyo +Leyalebe +Nalagoriyo +Nezuvoku +Getiramore +Xaxu +Fumuxisew +Pivatonu +Doqo +Bejaraf +Fuvawo +Qeniwalipi +Fojic +Nimotuseyi +Kasi +Vaga +Kufefiz +Repucefa +Pegar +Maceyine +Bagabafo +Woqiyo +Dokeyo +Niwowe +Hohe +Ritefaqog +Hohiqi +Xapuf +Wuzegecu +Bilikicopu +Boboyibe +Qajoyo +Gesex +Vasikike +Lesajoyibu +Vorafenaf +Qoqopev +Dawar +Zivu +Yejofiz +Rimimaw +Wiyus +Lodidiyuza +Caqe +Jaji +Furolit +Sira +Yodo +Coyefe +Sunecisadu +Zizelago +Heje +Galuxe +Poyinuve +Mesofe +Tilomuweko +Zuwokayodu +Guhukikaha +Zudecekag +Xibiwiq +Wifujugaf +Yizugaqax +Tetay +Tayavozovi +Rewugow +Kiyoz +Luwiyagig +Vebotuhej +Rasunera +Huwisiwah +Roca +Kemarafiwi +Favofibuxi +Dutak +Yige +Gukid +Gala +Mucelib +Bimuvubadu +Nigurih +Tohezepeni +Porogil +Rajogah +Puloziwo +Qewezepi +Xiwobayeg +Zotay +Lumorese +Fuqivo +Hesabez +Madidi +Henunoruw +Liwe +Gihod +Warojanor +Givemike +Venujicun +Xopoc +Rotoy +Mezesarok +Rigoginem +Meloqa +Dojej +Zofiqay +Juvini +Hecep +Risuze +Dodusuk +Fubezo +Fuqixu +Kutov +Duhina +Tilapom +Coluxec +Figeci +Fewen +Zemahase +Zobig +Cikoye +Pipikaga +Larus +Lige +Kixudav +Yexi +Pufojatoq +Yobugasobi +Jovid +Cezoniv +Hivasumod +Yotuf +Lepuzosatu +Qileyegup +Madefayar +Podoqu +Yucuvuc +Lamewac +Luqode +Kijo +Kotejo +Gazo +Wuqey +Sifupe +Lohenolesu +Gemiw +Peyoyed +Yugujod +Cukan +Katukumuku +Fikojo +Hotohohese +Muyoqu +Zamo +Yogami +Qaliletu +Veqejiwecu +Sifog +Datajam +Calatom +Wulina +Xogabipi +Hiwiz +Huyu +Xuvuhadi +Badufuli +Lupoheviba +Puhija +Deziba +Kicevu +Hukijanen +Kekopojuh +Biras +Nipiqo +Kuyokef +Xiga +Wujujevis +Gavehuboy +Kujovuzi +Zasixiv +Dufivaze +Zimejag +Boyas +Neyogika +Cifoh +Genagabaf +Sijuxek +Piqeyek +Muzajute +Xemogit +Qabedefa +Biyicoqime +Ceceyuke +Waguwuyo +Cipayobax +Sejoq +Socomosemi +Tosogote +Hecucolu +Qawisacah +Yeleki +Busi +Kaherime +Fuzolikac +Saxip +Hagoduzito +Gomoqagucu +Gasubamad +Cemewufeq +Kaxuxa +Cutexela +Cakebamebi +Lazogoh +Pufesowo +Behon +Moxofamug +Miwizave +Nakaza +Zofiqi +Zuwocogog +Vitolazida +Fuge +Yadol +Xidekono +Sapoxat +Jexaribe +Leruroxo +Hexeb +Sosev +Pevififo +Qahupoxevi +Doga +Wogubiv +Rapon +Pagarowe +Misi +Lijokujap +Jofufere +Suzipij +Weyiy +Mawib +Fonomayihe +Baxi +Losebuli +Kapikataco +Sorap +Letarof +Hitucik +Buru +Jeseg +Ditubanam +Tuwor +Xotaweq +Vavomuzuyo +Jazudetobi +Sinan +Bajuwi +Luvutuyir +Mahazimewa +Telakewelu +Halebuyu +Liyuyizex +Hibacevoye +Vapiwudit +Kozi +Coyo +Seyar +Tibinila +Cexucefim +Zizupexez +Tosegerem +Tigopici +Nilihac +Kesejij +Tiduzozu +Fulesabeb +Binahagep +Licun +Rodagalebo +Mucu +Riduhowuru +Kara +Nahapa +Karimela +Hoto +Limuwed +Vaquzosez +Xeji +Zubata +Leneyuxe +Yude +Nataxeyoxa +Saji +Jeguraf +Subeliro +Heru +Finale +Fomanaga +Zutuzuwav +Levorifu +Celigoha +Xabopizeva +Pitito +Yijocer +Wisixutuv +Pipohak +Yafopo +Dezisonom +Yuna +Hinuwo +Kitud +Fahatibi +Deya +Wopazaxeme +Moqeyoxoma +Xotazeku +Wizo +Naqetunol +Juperoj +Loxaf +Bexoqerah +Konaq +Kutabogu +Vuyefe +Nusideyiyi +Gukir +Cejogefam +Ledayowak +Piqisib +Roficidu +Cupebufag +Fixepemez +Fovezud +Qazu +Hefemusu +Xezofuja +Zihanaz +Wiqudusi +Waho +Qufude +Kinasa +Cunimice +Cenuseb +Siji +Kiyuvum +Ricisu +Jukigogife +Zaxuwegus +Cajuh +Javedikek +Nahel +Royolex +Kuqizijuja +Bijowimus +Soyoyon +Tuniq +Xizijuboxo +Cuxoguz +Veboyinepu +Miguj +Dubiwareye +Rujeyahipe +Sanita +Darobujaba +Gotikowot +Balon +Cewaduq +Yayonela +Kokak +Cusam +Xifewir +Nuxa +Tejefo +Gavo +Mutoha +Zigef +Gezuxaqun +Cedogeyu +Funaqewuxi +Kumu +Zakebuni +Giriya +Denecet +Biqidim +Dayi +Gebekiw +Kopi +Gadobo +Cifelopaj +Jufe +Fivetin +Tusomamezi +Wuxenij +Pugupoga +Cahi +Hefeqapunu +Zomude +Dijudilaz +Pore +Xifeve +Dodutis +Pepupoqog +Juwujibid +Dovotopifi +Jabenon +Xaxuloy +Wufefatiqi +Nomawe +Dezegeb +Qekuzo +Huxo +Besocago +Hipacu +Nocud +Fajodosuci +Locovinef +Toyu +Pesukunuz +Gulawib +Zagow +Boku +Zurupoyod +Pohukogoy +Zujayifaz +Muvebe +Lucuniw +Pipifaru +Cojeyoyi +Pirupep +Hobicamab +Lojaki +Natocoh +Vutequw +Xenogizogu +Godid +Muyu +Fekuxi +Juqahigu +Banakopa +Tugugizujo +Xatifu +Toyocuc +Viqolotu +Jakiziker +Mavakafo +Poworonon +Lirokes +Niyizune +Kobetaw +Diwigohav +Zahuna +Qasuhebufo +Yeza +Bapejaya +Liroditaku +Dixukudi +Reqigulowo +Yose +Xiluq +Tomikisox +Yiqowi +Ciyahi +Kaye +Deduwuy +Kunoci +Bozok +Gaxenuc +Roduqag +Xusajuwom +Cofenet +Yufovovoqi +Riye +Gosizuhoda +Baruduz +Jojamud +Nidijoj +Vayuka +Bopa +Yitojob +Felemo +Govaniyi +Koqakuqu +Sayuhunuti +Qixenas +Fohiyazi +Diputudu +Jahivu +Sejobewef +Tevuzaceli +Lobodimulo +Tuyofevoq +Jeno +Tonov +Cigiw +Jahetemi +Himiq +Ducifeyalo +Qijubotim +Mabozoxo +Marigufesu +Gadu +Viziqiduf +Fuxibutogo +Gadica +Zowagan +Tuha +Qijo +Payowohe +Quwun +Beku +Kuyatevu +Wofotutebo +Suvobe +Povogufe +Xifox +Hoxu +Leta +Macaguce +Jiripaw +Mokex +Piqog +Migax +Fosatahijo +Savag +Zocihi +Lexoquha +Gibijifuce +Semoza +Kehezirof +Qopusimiq +Lozoti +Yuyicexigo +Newulux +Gaqulo +Ramawosami +Xaqef +Visoqul +Wutidi +Jacukoc +Loxe +Keva +Pidin +Wuxikab +Vayidiyu +Yavoteka +Madayiyaf +Yiwa +Xuno +Nanereru +Filiqi +Nidof +Fuxovel +Lujuw +Xucox +Kujus +Banavode +Wepofo +Wabegewilu +Laxeru +Lewewewa +Toxox +Paqa +Xuviwexovu +Nodus +Zabebe +Kokorigan +Nikono +Saqazarime +Xofi +Vefekufi +Nazugulano +Zojolepup +Zubacigan +Hocopifef +Yasuqomiz +Nacazeneje +Bedaselax +Dovipivit +Lunedol +Soziqaxoz +Muduzo +Hena +Kine +Parobis +Dumu +Serum +Hareluyene +Wohiqo +Qabaku +Jajaxufuge +Yoforavayi +Mukohuj +Cohiki +Gegepu +Bexibi +Maqavozu +Jivelila +Hujuz diff --git a/SorokinAD/[1]lab_1/report.docx b/SorokinAD/[1]lab_1/report.docx new file mode 100644 index 0000000..365c71a Binary files /dev/null and b/SorokinAD/[1]lab_1/report.docx differ diff --git a/SorokinAD/[1]lab_1/results.csv b/SorokinAD/[1]lab_1/results.csv new file mode 100644 index 0000000..017dfdd Binary files /dev/null and b/SorokinAD/[1]lab_1/results.csv differ diff --git a/SorokinAD/[2]lab_2/benchmark.py b/SorokinAD/[2]lab_2/benchmark.py new file mode 100644 index 0000000..e07311c --- /dev/null +++ b/SorokinAD/[2]lab_2/benchmark.py @@ -0,0 +1,143 @@ +import csv +import os + +from builders import TextFileMazeBuilder + +from solver import MazeSolver + +from strategies import ( + BFSStrategy, + DFSStrategy, + AStarStrategy +) + + +# ========================================================= +# Benchmark +# ========================================================= + +class BenchmarkRunner: + + def __init__(self): + + self.strategies = [ + ("BFS", BFSStrategy()), + ("DFS", DFSStrategy()), + ("A*", AStarStrategy()), + ] + + # ===================================================== + # Run benchmark + # ===================================================== + + def run( + self, + maze_files: list[str], + runs_per_test: int = 5 + ): + + results = [] + + builder = TextFileMazeBuilder() + + for maze_file in maze_files: + + print() + print(f"Testing: {maze_file}") + + maze = builder.build_from_file( + maze_file + ) + + for strategy_name, strategy in self.strategies: + + total_time = 0 + total_visited = 0 + total_path_length = 0 + + for _ in range(runs_per_test): + + solver = MazeSolver( + maze, + strategy + ) + + path, stats = solver.solve() + + total_time += stats.time_ms + total_visited += stats.visited_cells + total_path_length += stats.path_length + + avg_time = ( + total_time / runs_per_test + ) + + avg_visited = ( + total_visited / runs_per_test + ) + + avg_path_length = ( + total_path_length / runs_per_test + ) + + result = { + "maze": maze_file, + "strategy": strategy_name, + "time_ms": round(avg_time, 3), + "visited_cells": int(avg_visited), + "path_length": int(avg_path_length), + } + + results.append(result) + + print( + f"{strategy_name}: " + f"time={avg_time:.3f} ms, " + f"visited={avg_visited:.0f}, " + f"path={avg_path_length:.0f}" + ) + + self.save_to_csv(results) + + # ===================================================== + # Save CSV + # ===================================================== + + @staticmethod + def save_to_csv(results): + + base_dir = os.path.dirname(__file__) + + csv_path = os.path.join( + base_dir, + "benchmark_results.csv" + ) + + with open( + csv_path, + "w", + newline="", + encoding="utf-8" + ) as file: + + writer = csv.DictWriter( + file, + fieldnames=[ + "maze", + "strategy", + "time_ms", + "visited_cells", + "path_length" + ] + ) + + writer.writeheader() + + for row in results: + + writer.writerow(row) + + print() + print( + f"Results saved to: {csv_path}" + ) diff --git a/SorokinAD/[2]lab_2/benchmark_results.csv b/SorokinAD/[2]lab_2/benchmark_results.csv new file mode 100644 index 0000000..642505c --- /dev/null +++ b/SorokinAD/[2]lab_2/benchmark_results.csv @@ -0,0 +1,13 @@ +maze,strategy,time_ms,visited_cells,path_length +mazes/small.txt,BFS,0.034,17,12 +mazes/small.txt,DFS,0.026,13,12 +mazes/small.txt,A*,0.048,17,12 +mazes/open.txt,BFS,0.219,100,19 +mazes/open.txt,DFS,0.135,55,55 +mazes/open.txt,A*,0.334,100,19 +mazes/medium.txt,BFS,0.093,36,0 +mazes/medium.txt,DFS,0.059,36,0 +mazes/medium.txt,A*,0.087,36,0 +mazes/no_exit.txt,BFS,0.008,5,0 +mazes/no_exit.txt,DFS,0.007,5,0 +mazes/no_exit.txt,A*,0.011,5,0 diff --git a/SorokinAD/[2]lab_2/builders.py b/SorokinAD/[2]lab_2/builders.py new file mode 100644 index 0000000..0079bfe --- /dev/null +++ b/SorokinAD/[2]lab_2/builders.py @@ -0,0 +1,60 @@ +from abc import ABC, abstractmethod + +from cell import Cell +from maze import Maze + + +class MazeBuilder(ABC): + + @abstractmethod + def build_from_file(self, filename: str) -> Maze: + pass + + +class TextFileMazeBuilder(MazeBuilder): + + def build_from_file(self, filename: str) -> Maze: + + with open(filename, "r", encoding="utf-8") as file: + lines = [line.rstrip("\n") for line in file] + + cells = [] + + start = None + exit = None + + for y, line in enumerate(lines): + + row = [] + + for x, char in enumerate(line): + + is_wall = char == "#" + is_start = char == "S" + is_exit = char == "E" + + cell = Cell( + x=x, + y=y, + is_wall=is_wall, + is_start=is_start, + is_exit=is_exit + ) + + if is_start: + start = cell + + if is_exit: + exit = cell + + row.append(cell) + + cells.append(row) + + if start is None: + raise ValueError("Старт S не найден") + + if exit is None: + raise ValueError("Выход E не найден") + + return Maze(cells, start, exit) diff --git a/SorokinAD/[2]lab_2/cell.py b/SorokinAD/[2]lab_2/cell.py new file mode 100644 index 0000000..de42d46 --- /dev/null +++ b/SorokinAD/[2]lab_2/cell.py @@ -0,0 +1,13 @@ +from dataclasses import dataclass + + +@dataclass(frozen=True) +class Cell: + x: int + y: int + is_wall: bool = False + is_start: bool = False + is_exit: bool = False + + def is_passable(self) -> bool: + return not self.is_wall \ No newline at end of file diff --git a/SorokinAD/[2]lab_2/commands.py b/SorokinAD/[2]lab_2/commands.py new file mode 100644 index 0000000..2f8618b --- /dev/null +++ b/SorokinAD/[2]lab_2/commands.py @@ -0,0 +1,91 @@ +from abc import ABC, abstractmethod + +from cell import Cell +from maze import Maze + + +class Player: + + def __init__(self, start_cell: Cell): + + self.current_cell = start_cell + + +# ========================================================= +# Command +# ========================================================= + +class Command(ABC): + + @abstractmethod + def execute(self): + pass + + @abstractmethod + def undo(self): + pass + + +# ========================================================= +# MoveCommand +# ========================================================= + +class MoveCommand(Command): + + DIRECTIONS = { + "W": (0, -1), + "S": (0, 1), + "A": (-1, 0), + "D": (1, 0), + } + + def __init__( + self, + player: Player, + maze: Maze, + direction: str + ): + + self.player = player + self.maze = maze + self.direction = direction.upper() + + self.previous_cell = None + + def execute(self): + + if self.direction not in self.DIRECTIONS: + return False + + dx, dy = self.DIRECTIONS[self.direction] + + current = self.player.current_cell + + new_x = current.x + dx + new_y = current.y + dy + + target = self.maze.get_cell( + new_x, + new_y + ) + + if target is None: + return False + + if not target.is_passable(): + return False + + self.previous_cell = current + + self.player.current_cell = target + + return True + + def undo(self): + + if self.previous_cell is not None: + + self.player.current_cell = ( + self.previous_cell + ) + diff --git a/SorokinAD/[2]lab_2/main.py b/SorokinAD/[2]lab_2/main.py new file mode 100644 index 0000000..29f0b0a --- /dev/null +++ b/SorokinAD/[2]lab_2/main.py @@ -0,0 +1,164 @@ +from builders import TextFileMazeBuilder + +from strategies import ( + BFSStrategy, + DFSStrategy, + AStarStrategy +) + +from solver import MazeSolver + +from visualization import ConsoleView + +from commands import ( + Player, + MoveCommand +) + + +def test_strategy(name, strategy, maze): + + print() + print("=" * 40) + + view = ConsoleView() + + solver = MazeSolver( + maze, + strategy + ) + + solver.add_observer(view) + + path, stats = solver.solve() + + print() + print(f"Strategy: {name}") + + print( + f"Time: {stats.time_ms:.3f} ms" + ) + + print( + f"Visited cells: {stats.visited_cells}" + ) + + print( + f"Path length: {stats.path_length}" + ) + + print() + + view.render( + maze, + path + ) + + +# ========================================================= +# Manual mode +# ========================================================= + +def manual_mode(maze): + + print() + print("=" * 40) + print("MANUAL MODE") + print("W/A/S/D - move") + print("U - undo") + print("Q - quit") + + view = ConsoleView() + + player = Player( + maze.start + ) + + history = [] + + while True: + + print() + + view.render( + maze, + current=player.current_cell + ) + + if player.current_cell == maze.exit: + + print() + print("YOU WIN!") + + break + + command_input = input( + "\nCommand: " + ).upper() + + if command_input == "Q": + break + + if command_input == "U": + + if history: + + last_command = history.pop() + + last_command.undo() + + continue + + command = MoveCommand( + player, + maze, + command_input + ) + + success = command.execute() + + if success: + history.append(command) + else: + print("Invalid move") + + +def main(): + + builder = TextFileMazeBuilder() + + maze = builder.build_from_file( + "mazes/small.txt" + ) + + # ===================================== + # Strategies + # ===================================== + + test_strategy( + "BFS", + BFSStrategy(), + maze + ) + + test_strategy( + "DFS", + DFSStrategy(), + maze + ) + + test_strategy( + "A*", + AStarStrategy(), + maze + ) + + # ===================================== + # Manual mode + # ===================================== + + manual_mode(maze) + + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/SorokinAD/[2]lab_2/maze.py b/SorokinAD/[2]lab_2/maze.py new file mode 100644 index 0000000..51b2856 --- /dev/null +++ b/SorokinAD/[2]lab_2/maze.py @@ -0,0 +1,33 @@ +from cell import Cell + + +class Maze: + def __init__(self, cells: list[list[Cell]], start: Cell, exit: Cell): + self.cells = cells + self.height = len(cells) + self.width = len(cells[0]) if self.height > 0 else 0 + self.start = start + self.exit = exit + + def get_cell(self, x: int, y: int) -> Cell | None: + if 0 <= y < self.height and 0 <= x < self.width: + return self.cells[y][x] + return None + + def get_neighbors(self, cell: Cell) -> list[Cell]: + directions = [ + (0, -1), + (0, 1), + (-1, 0), + (1, 0), + ] + + neighbors = [] + + for dx, dy in directions: + neighbor = self.get_cell(cell.x + dx, cell.y + dy) + + if neighbor is not None and neighbor.is_passable(): + neighbors.append(neighbor) + + return neighbors diff --git a/SorokinAD/[2]lab_2/mazes/medium.txt b/SorokinAD/[2]lab_2/mazes/medium.txt new file mode 100644 index 0000000..84f4d50 --- /dev/null +++ b/SorokinAD/[2]lab_2/mazes/medium.txt @@ -0,0 +1,11 @@ +#################### +#S # # # +### ### ##### ### ## +# # # ## +# ### ### # ##### ## +# # # # # # +# # ##### ##### # # +# # # # # # +# ##### ##### # # # +# # # E# +#################### \ No newline at end of file diff --git a/SorokinAD/[2]lab_2/mazes/no_exit.txt b/SorokinAD/[2]lab_2/mazes/no_exit.txt new file mode 100644 index 0000000..e185318 --- /dev/null +++ b/SorokinAD/[2]lab_2/mazes/no_exit.txt @@ -0,0 +1,5 @@ +########## +#S# #E# +# ### #### +# # # +########## \ No newline at end of file diff --git a/SorokinAD/[2]lab_2/mazes/open.txt b/SorokinAD/[2]lab_2/mazes/open.txt new file mode 100644 index 0000000..dfad92f --- /dev/null +++ b/SorokinAD/[2]lab_2/mazes/open.txt @@ -0,0 +1,10 @@ +S + + + + + + + + + E \ No newline at end of file diff --git a/SorokinAD/[2]lab_2/mazes/small.txt b/SorokinAD/[2]lab_2/mazes/small.txt new file mode 100644 index 0000000..3964120 --- /dev/null +++ b/SorokinAD/[2]lab_2/mazes/small.txt @@ -0,0 +1,5 @@ +########## +#S #E# +# ### ## # +# # # +########## \ No newline at end of file diff --git a/SorokinAD/[2]lab_2/otchet.docx b/SorokinAD/[2]lab_2/otchet.docx new file mode 100644 index 0000000..cb1c069 Binary files /dev/null and b/SorokinAD/[2]lab_2/otchet.docx differ diff --git a/SorokinAD/[2]lab_2/run_benchmark.py b/SorokinAD/[2]lab_2/run_benchmark.py new file mode 100644 index 0000000..6d8e2fd --- /dev/null +++ b/SorokinAD/[2]lab_2/run_benchmark.py @@ -0,0 +1,20 @@ +from benchmark import BenchmarkRunner + + +def main(): + + benchmark = BenchmarkRunner() + + benchmark.run( + maze_files=[ + "mazes/small.txt", + "mazes/open.txt", + "mazes/medium.txt", + "mazes/no_exit.txt", + ], + runs_per_test=10 + ) + + +if __name__ == "__main__": + main() diff --git a/SorokinAD/[2]lab_2/solver.py b/SorokinAD/[2]lab_2/solver.py new file mode 100644 index 0000000..8d264f6 --- /dev/null +++ b/SorokinAD/[2]lab_2/solver.py @@ -0,0 +1,86 @@ +import time + +from dataclasses import dataclass + +from maze import Maze +from strategies import PathFindingStrategy + + +@dataclass +class SearchStats: + time_ms: float + visited_cells: int + path_length: int + + +class MazeSolver: + + def __init__( + self, + maze: Maze, + strategy: PathFindingStrategy + ): + + self.maze = maze + self.strategy = strategy + + self.observers = [] + + # ===================================== + # Observer + # ===================================== + + def add_observer(self, observer): + + self.observers.append(observer) + + def notify(self, event: str): + + for observer in self.observers: + observer.update(event) + + # ===================================== + # Strategy + # ===================================== + + def set_strategy( + self, + strategy: PathFindingStrategy + ): + + self.strategy = strategy + + self.notify( + f"Strategy changed to {strategy.__class__.__name__}" + ) + + # ===================================== + # Solve + # ===================================== + + def solve(self): + + self.notify("Search started") + + start_time = time.perf_counter() + + path, visited_cells = self.strategy.find_path( + self.maze, + self.maze.start, + self.maze.exit + ) + + end_time = time.perf_counter() + + stats = SearchStats( + time_ms=(end_time - start_time) * 1000, + visited_cells=visited_cells, + path_length=len(path) + ) + + if path: + self.notify("Path found") + else: + self.notify("No path found") + + return path, stats diff --git a/SorokinAD/[2]lab_2/strategies.py b/SorokinAD/[2]lab_2/strategies.py new file mode 100644 index 0000000..dbe3955 --- /dev/null +++ b/SorokinAD/[2]lab_2/strategies.py @@ -0,0 +1,218 @@ +from abc import ABC, abstractmethod +from collections import deque +from heapq import heappush, heappop + +from maze import Maze +from cell import Cell + + +class PathFindingStrategy(ABC): + + @abstractmethod + def find_path( + self, + maze: Maze, + start: Cell, + exit: Cell + ) -> tuple[list[Cell], int]: + + pass + + +# ========================================================= +# BFS +# ========================================================= + +class BFSStrategy(PathFindingStrategy): + + def find_path(self, maze, start, exit): + + queue = deque([start]) + + visited = {start} + parent = {} + + visited_count = 0 + + while queue: + + current = queue.popleft() + + visited_count += 1 + + if current == exit: + path = self._restore_path(parent, start, exit) + return path, visited_count + + for neighbor in maze.get_neighbors(current): + + if neighbor not in visited: + + visited.add(neighbor) + + parent[neighbor] = current + + queue.append(neighbor) + + return [], visited_count + + @staticmethod + def _restore_path(parent, start, exit): + + path = [] + + current = exit + + while current != start: + path.append(current) + current = parent[current] + + path.append(start) + + path.reverse() + + return path + + +# ========================================================= +# DFS +# ========================================================= + +class DFSStrategy(PathFindingStrategy): + + def find_path(self, maze, start, exit): + + stack = [start] + + visited = {start} + parent = {} + + visited_count = 0 + + while stack: + + current = stack.pop() + + visited_count += 1 + + if current == exit: + path = self._restore_path(parent, start, exit) + return path, visited_count + + for neighbor in maze.get_neighbors(current): + + if neighbor not in visited: + + visited.add(neighbor) + + parent[neighbor] = current + + stack.append(neighbor) + + return [], visited_count + + @staticmethod + def _restore_path(parent, start, exit): + + path = [] + + current = exit + + while current != start: + path.append(current) + current = parent[current] + + path.append(start) + + path.reverse() + + return path + + +# ========================================================= +# A* +# ========================================================= + +class AStarStrategy(PathFindingStrategy): + + def heuristic(self, cell: Cell, exit: Cell): + + return abs(cell.x - exit.x) + abs(cell.y - exit.y) + + def find_path(self, maze, start, exit): + + open_set = [] + + heappush(open_set, (0, start.x, start.y, start)) + + g_score = { + start: 0 + } + + parent = {} + + visited = set() + + visited_count = 0 + + while open_set: + + _, _, _, current = heappop(open_set) + + if current in visited: + continue + + visited.add(current) + + visited_count += 1 + + if current == exit: + path = self._restore_path(parent, start, exit) + return path, visited_count + + for neighbor in maze.get_neighbors(current): + + tentative_g = g_score[current] + 1 + + if ( + neighbor not in g_score + or tentative_g < g_score[neighbor] + ): + + g_score[neighbor] = tentative_g + + f_score = tentative_g + self.heuristic( + neighbor, + exit + ) + + parent[neighbor] = current + + heappush( + open_set, + ( + f_score, + neighbor.x, + neighbor.y, + neighbor + ) + ) + + return [], visited_count + + @staticmethod + def _restore_path(parent, start, exit): + + path = [] + + current = exit + + while current != start: + path.append(current) + current = parent[current] + + path.append(start) + + path.reverse() + + return path \ No newline at end of file diff --git a/SorokinAD/[2]lab_2/visualization.py b/SorokinAD/[2]lab_2/visualization.py new file mode 100644 index 0000000..b32713b --- /dev/null +++ b/SorokinAD/[2]lab_2/visualization.py @@ -0,0 +1,56 @@ +from abc import ABC, abstractmethod + +from maze import Maze +from cell import Cell + + +class Observer(ABC): + + @abstractmethod + def update(self, event: str): + + pass + + +class ConsoleView(Observer): + + def update(self, event: str): + + print(f"[EVENT]: {event}") + + def render( + self, + maze: Maze, + path: list[Cell] = None, + current: Cell = None + ): + + path = path or [] + + path_set = set(path) + + for row in maze.cells: + + line = "" + + for cell in row: + + if current and cell == current: + line += "P" + + elif cell.is_start: + line += "S" + + elif cell.is_exit: + line += "E" + + elif cell.is_wall: + line += "#" + + elif cell in path_set: + line += "." + + else: + line += " " + + print(line) \ No newline at end of file