From 31b6f1a3e8e73111e95feb46cb1e0ff6ab42993b Mon Sep 17 00:00:00 2001 From: Simon Rozman Date: Mon, 8 May 2017 14:52:30 +0200 Subject: [PATCH] Recursively inverse translated translations ranks updated --- ZRColaCompile/main.cpp | 93 +++++++++++++++++++++------------------ output/data/ZRCola.zrcdb | Bin 3640876 -> 3640876 bytes 2 files changed, 51 insertions(+), 42 deletions(-) diff --git a/ZRColaCompile/main.cpp b/ZRColaCompile/main.cpp index 31bbdf8..5524031 100644 --- a/ZRColaCompile/main.cpp +++ b/ZRColaCompile/main.cpp @@ -135,47 +135,55 @@ public: typedef map > translation_db; -static set translate_inv(_In_ const translation_db &db, _In_z_ const wchar_t *str, _Inout_ set &path) +static set translate_inv(_In_ const translation_db &db_trans, _In_z_ const wchar_t *str, _Inout_ set &path) { - set res; + set res; - if (*str) { - // Inverse translate remainder first. - auto rem = translate_inv(db, str + 1, path); - if (rem.empty()) - return res; - - translation_db::key_type _str(1, *str); - auto const t = db.find(_str); - if (t != db.end()) { - // Current characted inverse translated. Iterate all possible inverse translations and combine them with the remainder. - auto p = path.insert(_str); - if (!p.second) { - // Path already contains this character: Cycle detected! - return res; - } - for (auto d = t->second.cbegin(), d_end = t->second.cend(); d != d_end; ++d) { - auto src = translate_inv(db, d->first.c_str(), path); - if (!src.empty()) { - for (auto dd = src.cbegin(), dd_end = src.cend(); dd != dd_end; ++dd) { - for (auto r = rem.cbegin(), r_end = rem.cend(); r != r_end; ++r) - res.insert(*dd + *r); - } - } else { - // Cycle detected. Do not continue inverse translation. - for (auto r = rem.cbegin(), r_end = rem.cend(); r != r_end; ++r) - res.insert(_str + *r); - } - } - path.erase(p.first); - } else { - // Current character is non-inverse translatable. Combine it with the remainder(s). - for (auto r = rem.cbegin(), r_end = rem.cend(); r != r_end; ++r) - res.insert(_str + *r); - } - } else { + if (!*str) { // Empty string results in empty inverse translation. - res.insert(L""); + res.insert(ZRCola::DBSource::charseq(0, L"")); + return res; + } + + // Prepare inverse translate of the remainder string (without the first character). + auto res_rem = translate_inv(db_trans, str + 1, path); + if (res_rem.empty()) + return res; + + // See if first character is inverse translatable. + translation_db::key_type chr(1, *str); + auto const hit_trans = db_trans.find(chr); + if (hit_trans != db_trans.end()) { + // Current character is inverse translatable. + + // Add the current character to the path before recursing. + auto hit_path = path.insert(chr); + if (!hit_path.second) { + // Path already contains this character: Cycle detected! + return res; + } + + // Iterate all possible character inverse translations and combine them with the remainder string inverse translations. + for (auto d = hit_trans->second.cbegin(), d_end = hit_trans->second.cend(); d != d_end; ++d) { + auto res_chr = translate_inv(db_trans, d->first.c_str(), path); + if (!res_chr.empty()) { + for (auto r_chr = res_chr.cbegin(), r_chr_end = res_chr.cend(); r_chr != r_chr_end; ++r_chr) { + for (auto r_rem = res_rem.cbegin(), r_rem_end = res_rem.cend(); r_rem != r_rem_end; ++r_rem) + res.insert(ZRCola::DBSource::charseq(d->second.rank_src + r_chr->rank + r_rem->rank, r_chr->str + r_rem->str)); + } + } else { + // Cycle detected. Do not continue inverse translation. + for (auto r_rem = res_rem.cbegin(), r_end = res_rem.cend(); r_rem != r_end; ++r_rem) + res.insert(ZRCola::DBSource::charseq(r_rem->rank, chr + r_rem->str)); + } + } + + // Remove the current character from the path. + path.erase(hit_path.first); + } else { + // First character is non-inverse translatable. Combine it with the remainder(s). + for (auto r_rem = res_rem.cbegin(), r_end = res_rem.cend(); r_rem != r_end; ++r_rem) + res.insert(ZRCola::DBSource::charseq(r_rem->rank, chr + r_rem->str)); } return res; @@ -301,12 +309,13 @@ int _tmain(int argc, _TCHAR *argv[]) // Add translation to temporary database. for (auto r = res.begin(), r_end = res.end(); r != r_end; ++r) { - auto hit = t2->second.find(*r); + translation_db::mapped_type::mapped_type ct(d1->second.rank_src + r->rank, d1->second.rank_dst); + auto hit = t2->second.find(r->str); if (hit != t2->second.end()) { - hit->second.rank_src = std::min(hit->second.rank_src, d1->second.rank_src); - hit->second.rank_dst = std::max(hit->second.rank_dst, d1->second.rank_dst); + hit->second.rank_src = std::min(hit->second.rank_src, ct.rank_src); + hit->second.rank_dst = std::max(hit->second.rank_dst, ct.rank_dst); } else - t2->second.insert(pair(*r, translation_db::mapped_type::mapped_type(d1->second.rank_src, d1->second.rank_dst))); + t2->second.insert(pair(r->str, ct)); } } } diff --git a/output/data/ZRCola.zrcdb b/output/data/ZRCola.zrcdb index 03683735e075b5343bf0ebd3ab18544f6c64a538..8bf33da1d1a24f92e746ce9440aa86e8aebbaf8e 100644 GIT binary patch delta 19899 zcmZvk3wTw?=7Zeex9+9FVf_l+QskhhbwdhF@6@x|IphfS0)~vnv99q9`oG-t%X3d&4 z&pmq|p8f5|@>!(kJD!wkRo=-0{D0udky34a{N&v+WbMu_mdMtgE5u)`-ug#A{@?VE zT|k@9pD~iBzh9zql#s#~56iQuuT#fU)k27gLM6+U?A<~ty{MHe%{D5Yn4r$3>SSq3 z;4hWj)k>~{4Lv$j79(4hDN75CUQE=hZ&E*KPiDxp`TK0@T^)LIrIYn4q| zX*R*J_$xPtVsY_Db)@lJYPLAiSVnD#=|{6=x3(UH3GpHeJEa1#(g(6-ZjmYLi0w5}RB080$V3YDZDd!p;+Zza z{p9{Oa-PgJ&5nx{d^matDza4w+13ob;w;r=3AnN|4`;3p!0qx%aJ92C{LL1c96@F zm35TMknQX!yVBtGgz!$J1_+Ug8Z3!qSfVrYWHGC@grHJLN3|75MNn8*=gB7#;AWlV z(-`2%E%`D>a?znsL{Ocg!-xd6G+h?fG7f@iX|;?8LHyaF@&Z}R-S;a91`3{_6wy^6 zlZga#=Mj)wM9b74P&{B7Y+)Mn#IH#&((=Tkq~(&wKq>`D9h>sRZ-Ay56pokQlG4i# zd7N}y@;lOT9bZd2hFB*(u^!|`vK){nLGB__XOCHfj0=`NMT&+_1`Ue; z0d%O~HH4z|G|0>}vJqr>TBXl`%t>qDv)+koQzO!pHbH4_8hHU^P#W0^GKCGrbk9PW zGu(RnA{92?n&}es(MzD$rS*|7l3){=+3D$vmsyX)t979)q2b|+oe-I>k0Yvq`Ws-T z>kSJ6vkR;;EevmhOiLrXL2gKE&mNFF)5u#OH=0t>@OT^OE;1A>Cw~Sh7m-Vz*bh>b zM*c!NJU8IFC*CI=OKjBsn{-UnFngh6>0e2&y}_7nz;+G$AK(E&75Y#YoLK!ymHd=4@r zjeJ2m?hHCiIuY^3m#h<6@r>Tkw7w57)EPr2*TKcF`#ZElfFme_{dXM!A z;qygl`y-7N;qfM>NB1I&btnaYp0e3qn;o-RZn5kQ*|1_#skPbTHrr*h!#2yjf>cVc zfK42Bu8`f3ExSVYM7GWRg)^U3X;DI&#U)hxm=f6+GF>8vAv;`x`eHi&N|IGxNt(0p zS2r_id@+ogHLf9QRvhd|qgkhdV_8h^vc;ROBJY)2`%d#F_QLG5{0 zk>+M16XPrD`DBAXHN8~t3`N7mu57yHooXy`*tO2*V7c9E$#E;>b`(9^icXA1ARqJ|+dXN)aU5DFvD;-YhCh#esF5$zwg zA}$I;3#^+QGE^>7RW_7^ARUqx$_gTGD6bE6LZ^LE8E84|2G--a>Tbj3nSM6pw?Q-` z3JToyMHRECs<^m4(&JcEjR<2gDHKLM7Z=r`88P>6lyg}0GqxItmX4Ai@Ime85ScMKzzN7QVr?827Z0+YNTbVHGoAi|b!D3F z3f8rBqQZRpWVFoTG4@L?)1S)Np&SuqYYZQSD7Q&*JLnvd5RZffLSHdjT<*3kA#_-AsIOa$ksoo} zo`Bd6JhyG@n5MUFeW;t>h9^VqbpHELKfP^F8UC-@_J^=Q=qt4?;^}RBI;=RK13K1T#sLd1Gi3F3hcAU(sv1`p65ZHkq#mX1Em_{rv-el%> zoiFwcLg83%L(|pTC7MzNXpx8}SX19pxb+_SOP3h7q+Ofvk ztlnl%+w47?ov>Nk+ex#Z&8ls-+-6&B_JPgL+bn+~6{xV;44bX7*>;;X*eo&0Zksk6 zZnFh8TWho3Hfyq3Ry7qUv)Oo?Ew?Js2e~q3uJY{4L|7 ziwY*TI8KLCz;^K*d`C_J+4om6fEM3Rtif7649P9GBf*CM5Q=Dhf(pfSu z6q&lF!=|lm2SnVOJ>=|va!igvkZbGT6V`8qG2L~xEMbFhaa|8IT7$D@%VHMoWzojY zR+O9_y0I4~jT`&ejjtlnK90vTTq=J~SZW_TvX@JZnIp?N(&r0IeBN*(ZHXH(Lrh?T zNWTxuMYf6O;p%imEHH5)WivW&E>4b^a&u)~UmNT1U^FV1&fLna-u$pnR=Fl@?^^Ez z6aU=f-yt%l1wr2(g9#4x#?H2BLC^~4IU?J%AZX(w(K9Gz24B!Yt6Y(-E9jti=Hbpg zrn}9T9gtPdmy>za+}8aD%(mcxb@zO^A9Fz0%AMvSbIbxcO=g%DH5aQ>`rcaArn#M0 z8RqY6mdZ<$YLRSh4&^yN!?=$n%YG(5G=FB@Ly<1H2hXW7J>(vl3pn{6S&i(yduZ)A zaZmWdVQhmr?VI~xGoSn5-2>ES)zLHVZ|cnDs_u6$tsj%`CAiXN+wY}EuQT`3BS3yV zWkc#^5enRG|JqPb1>U#Wd7Bm9N1DU$Bh7l7ZMN_un8L`|)nV?w9vB9BHf(aem;$zM(rTk)!!M_^XC~9TV6jqMg?l ztC;cLON-iSFm-|68fLEEBVa9|=Q0f@FDU!#ivR_n!VEM%#U7CP?9*=`YJP$KZ<)Dv zf5#>g)&%*v7R=P;vM0c@!J@JWu`Xl|ufqXuJp?8oCN)n5&yEo{jwM3wlYYj((6xI1 ztZTTv$udhu3-KiC%NJ#2RsXzJU4*5)WT`CT2cL})pT-4g;D{%lAu=ZcG8_1%mhE~cP_iKO{|P?s-i$Z{EPyPn?p3)v6tlqKprtms93uJU9j{X|(G+Z-F#AEt@Zby>Igh zvxMpWaAmM*f-jad+GTW4LEwtV>@9~p0NeS(wQPvls+RDsTKvm!b6DRIkI9^VwtWj&=%wpq7A(PY9+M?}aaqTrD6nyHZ)hUMweEk+Y^%vL zkI8-tj+Q+x-$5pSCkG%K_&d3k7IZwyQJ&NwOTXR3)adObmQQY>V*rnQM+KF)?3!nIb!!(Ix;k^mH9kLcGJKzE0mc< zc~8jK(8`7Fk{@fT)6*o)VN_jUixqAadt%sM#{mF!q2%lO{p z0Cht8EQpJbxocuUpXKSG2%gKuLWU{PjR zgD)OnBQ9IYdO;T+g9(o6&so&PnnWxK%Evbs!<$V0F_YYz;*Wx7~dq-xcb+9wo%CP~YXa?+NuI>xLfdNTVs{ zRO*S{G>~~w(zE_3^LdKB%~rfr_pq zWf80Et}n`b?$Y;I#7{`csuyKDtggwsld`QGZM*MV(m9(pL*n9F@* z>Dy0(FS6|Dk0rl)S?0xLOlSTn+_}0Os<~h%?)xYCA+IK-hs^6bcPGAzNU&n`*&z>M z<;r_i&Oo;ERawE!yOFF0?x^I^SLM-QG*5%fIc?|@ugkH#_|Af;ONwWXuG%T5BP9EF z$`516H|&-Laa6N!uQ{yhV|!@@_urNIZSA5}`PqyM7cE`>uFPp>!wIpL&&cfL?0047 z81L%~KQl|#S=_C8sbB_f*+X zvc!X*TR$)dZ=Lwx@Y(q9pACuD=w$u>O6l=6QK%;~cM&nFkO{xN-N#vYOj8kd%0d$_Sax`4fjdFaJ>5`bJ`~2V9_vCo_ z2jzL=VeF9HfNawtSyN`TJn`k{Bcpf`X(GbiLF5P#_A5E~Gig3t)cZfjg@e+ozMxyd z-CyAADL$;s{KCA~cSrUtA{=M3Ih#nd>Um-gk$meh>C7dx6R<@7`7fY^al7$#N$rq2}RS;UR{cHIZvJJ;5g7P?>$O@0km6#ZM+bQ}E^1vxs z7F>2dd-xbWZHS(1J+X<1+nDEw1j|*oc8{B+H2!t z+n466feRb9?aQ;NaY4h9?cz9o!^qZzT8ykLLzz48nhZ5T^1;4!(` zUlfu+ILf~0LQFc$6J5bhr=kfS7nh@U`zfsT(sZK-N?!^)Bgqi{Ryd@-xLogSp(Y|q z1uYRQ1Z{LHHGr3b8=8*egS@EizOV%2*J;vV(u(5Y3rkuCOEdX%BWdA;gTGAJePKz< zl*@)#tt*@g;=)2wbczpUgIsZP@I~qaO)?wYn$eZTY2W7)?{`T1{HVBFPi43 zZ77~tL4+f#*R@t7VeL$7GdPp&vXvj~cpIBWMJ07f8?}W^zSMLsRV$*SmnV`^_-2i~ zN`BN%y>AR{Zm-M&u)Do#GJkIApvsUP?x4&EN%%RRfOO0zgEx}1a?E+_9kx}2^o7PQjM^@Nf ztwOfFJH;nfqy zzwe>S;Y)c>)y?c~(@WG~vyN^rQ#+6?xSIN_d6W@l`<=~-2j8h((&jwsnsg5KlpkI z@XG5ksPSps^)yNjT(1gvK$IPwL#uvhL$|G@>iU{2rmHGdu#^AjXq{Z2GJ9>XPW3_I zH?a;zo1ZT%TNp6CrBY>+zrMJJ)EA0`W1=sc2sZw&DwX*}e!&f@0omBWYAYWwZaZpr zn_!>LyHV|B!88)|ur~GgH&SN}7($!m<{|0;ACvDpdM<^lQK#y~M7&g-i*6lCqvh~W zRWjBd0ahP18*8)*dtx;z8`t2HHKdaW?RsJj>A2(((#ha@YKN(-D4N z9AyjRUDZuy>Cn|TsSYi{B)1nt_EfS9)!D-nUmLNWIhDBNO)6PP~P4tJWT^!v;lrkfPI$aMLp{C)`zI}u`!5g7CX1<$tH$6!t+Vni3h`7GQh`7VX zBa#t3Pf;6uV)?di5MRW(9Jy$1YrLuYB$Y2X@&CQ6h_hg|tTZpuL(SlfWr*2=g zWESapq7|{|O2-oy8B!|tlZd%397!b7@x>@28ENOa(Zr%b=ZTw-o#+M6+!l@@CAWKT zAtIuC+A%7)VH`&y<<#Pf@x;Q_i$=q(%(x;wD>88#iLwIgq+Ue~%Tm~AU);_nxU2O} zm>6%Do=GH%`qvZHY&06#cMx$qWipYd<9soNNI2DX@hxFPr;;e1=H)bE;r%svekZZ4 zRB!9Ku8&OIMWQawc=p8%W>H`IVkR?gkKPXx^yKG@*(AcK3FG34C%^^>cLJ;<;+kAf zB#fsn9vjZP-;>CV-BU!|Y48Uk?jU)Zh#R~AAQHxo2KfeJQOtd@k+s0|uCXegx4`Ft zYn(RtVhfRYs)*y*YMiR(gUZV!@`5p^myT0;Wp*HJClQw+7yd-VZQc$d+&ulsI670r z#;aiytc~3yw|j!wjqsrzk@TCaw}_=T_ibV^r*FOnsR-Jow~klAZ%0p(An4(5$E!SS zZtZX7XAMuBBY6}#Pl)5@H!g0+OCoN^DsyQ&o-H=q|0apRIn#JoEXj+qw| zamQvB+lgHFMQdU*n5g7d_VE*S2(p(3+mNE$)4s?d=B2F$mk>)|A##azaSm#}xRhBG zHD9zPX4b&Es2x8b=&sh+f(%I;1LZ`b-o?vhBGKf>?nlIp>raS8o#crDL=c~-|Notk z8`yzFqQH7$5Rs@Qo~R(=cF<4|Ja{@CG>k~(v@dQVVm7NjQTvAzbSLu&BCbm#iSUTm zbE;JEJ8Fr-2QtQ zWMmKu-S_rzy00RE>&I#$t{-cNM1El92e}=iH451}BHbObo`@U7Cy8+MO?P|Z_k$&aSfFa zaYx*>AT!f~TTaC7r2a(Q>W6~N#!}(z2g3-tN;eU44GkyaPJt0bT!%&yahoxUNYo5p zj3$Ck(j6u%pU3gd1ceiBUyLD^nZ|A*mK88vH8~u|<46<>M6~*hC+1G%TZy!CLO+3s zyF%Rtl77cuMZ}HI?L;U(_P4b7Cmjg60h&a_4Nx@^H$XE%=A`xEEFx~`XA^O&zZYaK zmzrS@m-U3)V)qeoi!CPNw)J6_o&R7+7rBS!xDZ?qqonemnFHic!%KW+FE74ebBYIO;yR*Pt~J}e|z%hQ|1FccO&1= z#Es8ih%wQBU8t7w4E;X@(-;Uuvlgk~SJnqm#+)^Ir0UleskYQn8RFwp_ESmwy<^ll z_<9f$`(U65aVNHfL2V})$_C4w?jM^lAYC6%p=IeK#dBc>fMy3YXs9bwGc!M4sCC#eoi)&At zcjzul5VLR5L$3GTuL>wi3DG|^6`XCXss3atWIAt2xNR8G+0^w7fl%oo_@~3VnsRvH zW*1DO4T%#893Yxpu>|kC(4^fDsOwA%n=Ml_c&+{IX}b_-1lQ!rhnC?To>WT@K4?-5 z$wTsy;z$Xk45VgA&5>FlwM1%#bP-Y}(#1$wNUf2wk=h{TAYFo#i*zYcTcjT#wL|(h zr1nTZMCyRl5h)L;6H-3XWk>}`oskNWx*&B$x*Vw+Qg@^xq#j5;k$NE&BVB=1f^;QP ODbiKRgAbNf#Qq=AECU_@ delta 19902 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