From bdd62608664427ab5c3fb7f18bd23c54dfba6d64 Mon Sep 17 00:00:00 2001 From: Dnomd343 Date: Thu, 24 Nov 2022 15:47:35 +0800 Subject: [PATCH] feat: new all_cases build --- CMakeLists.txt | 3 +- all_cases/CMakeLists.txt | 4 + all_cases/all | Bin 0 -> 22624 bytes all_cases/main.cc | 268 +++++++++++++++++++++++++++++++++++++++ src/main.cc | 9 ++ 5 files changed, 283 insertions(+), 1 deletion(-) create mode 100644 all_cases/CMakeLists.txt create mode 100755 all_cases/all create mode 100644 all_cases/main.cc diff --git a/CMakeLists.txt b/CMakeLists.txt index 8c3ec34..1f1d669 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2,4 +2,5 @@ cmake_minimum_required(VERSION 3.0) set(CMAKE_CXX_STANDARD 14) project(klotski) -add_subdirectory(src) +#add_subdirectory(src) +add_subdirectory(all_cases) diff --git a/all_cases/CMakeLists.txt b/all_cases/CMakeLists.txt new file mode 100644 index 0000000..bb5c16d --- /dev/null +++ b/all_cases/CMakeLists.txt @@ -0,0 +1,4 @@ +cmake_minimum_required(VERSION 3.0) +set(CMAKE_CXX_STANDARD 14) + +add_executable(klotski main.cc) diff --git a/all_cases/all b/all_cases/all new file mode 100755 index 0000000000000000000000000000000000000000..549505ef7581120c54559f7607137556d09fec0a GIT binary patch literal 22624 zcmeHPe{@vUoqv-V$ne9NfT$6FFluaxO3d&}rikRh47{-uh$K}NYY&&rWPVS9A(T@~m(@xyec|w) z@vc|Sls@~w%eTFApzrICzOga1w*e0?7L_w(RS<-u>tgD3x8_+*!#1Ch($;XHVXy9=M}auX1)Y$WQ< z_~g?64)E9J;FnZ&ZA-XSZP$VkO;sh;UsI{pha#c1P3>AJQd7COIoukm39e}l8MNG# zFIHK>e`}NG zb^AKVgw9U2Efi@Fw+5S=wDoF7Ihb4T%PF#$iPW~<*VJ0Ct_Zb9TS8J>q^VVFfTFt2 zpc>RdolTn55^AYyThDO~O{Dq$5Mf)w9q>iPz^LPHw*;G7CDhxs`nnr$q`@(ls%z`O zKs7hj>J0qS#f#NhW#!W1l`G{%e$`zz%XC@hk(LJhi$DX_(OoLM#py-{#f&;u@^IYx zfv3SgM)LByR{AKWJgam^TE0N~ET@sa$G-ke3}2hHisPbFo5qoyjhtW1!(!g-=SkMX z=UIX8;rG8?S@>?w-&jShNs{0f_5S4sp5_qpS(N=I{CI%`JZQpCG~tsb{6!}GDHGmd z!VjD9P7}V3+ez*t5b09P@rA(f&@h_Igcoxo5vH5)G;fMhZo-Ru1JUN0@cb6ZL@G>p zijgRa2~ReOQf0!6SQBlf36BIBEu#?_jlgIGMk6p9fzb&34G~ac$L&gd%-ahkN$Kj* z3R3+_Y`eWLtsyn%5J;)(598Z8tpZn6ZzTHQ!4%5%Z&00<5QF`!zL)B>bQtVm^*vOl zCBxt|tiFxvv{V?}%IYsrot6lL-K_pos?*Y7a3iZfL3LUZ47RcQ52#K{fx*?RJ|6Xk zZq!*(;$JSQQsP?4YNhlOr7NY4Nqz@xgf1s^MH>B8LhJ7(pWx&QB3Gr!bsX&?ba@&b z;8GeR-&#V{qBOOPQ||<9a8C0|Qf-6ty&eSFrRYbUrM42~H{OyWvNSmp%NCNhD>u$A zQ4$Nfua+ctkJ9^zHTkVi$YLmm{TGQAk^_W|ZFjkQR`n_Rj=`^>k#5$1i3LyH28}&T zY{50SrcP86mu#lX#GGz`!3d}g-R={9ec&ENKcvJCpQ@?}B*xr;m9CPws1H`b3i2;? z$xiG(e8B7n>JFx4%L&^c`*xzooX_*wgjIa7%reW0IGdQUD? zdWWrwWv4Rmi8ciaqFjMJbXubPPQbx`1hJvaIgK7@C8=9UEK13>e*O1;{ghlI>%0B>t8(m!r4|uXdQU8@ zRxCS|fsYl>$uAcVJ`D-(hgZMy=Za^?0}B*=r;@nSq9kmSmBf@kCX?CEqQR z=g2RRevVe6$$;KNGm(W<^@ zkWxIL?=@>gv`;Ce!%A$p!nx%MjB5E#zy2Bp@MF2guYXWmt#s{mZkhlJ0;(j!Hnc0p zD{XST?VLY$(h?|5lKtdN??(l2NRHP^aLS+fa+ee@^z=Gok0HvQQ_ipcjNoZ!Y&tcg zNAamT2URd(h&i(nbSXZ|ufOFvecugAENS!X>6pyp8?QRYFawbf70>>TV*O%Z^l~O2 z>$460hVupV_XFrb{Xp_s3W2_#3}oIt4(*j)XS79regEKG5Iv{cuV`?#?!l+G!MUcl zL3Y08lVs=}Y$7sDt_75JpQK+#4KdO(QrkORpd=cR>wUW5;dIX^{0v0sT*Md}4|FOrR7Vzef~V_m4hPs6{aNq%UYF9X6tl^Xl6e^;vh17~k?;G@;6O%D*Dba;;obTb;P_7EFVkdZ1*Y z{<^&HU1zBmGd3pL3b06Yv6?OjUFGXKd`w6{Nh9<^# zSiGJOotypz0{SsMIdJU3L$xTS{rWaUj>YW3Llim7HpDq;v-Dq2Q3myx-9k*qiY)!H zgA2W$Wb~(Knl`wkt~Z@qj-gR~(B0#PuNBk_`pySm2Cd=@Lh0KX+h!RU^z4hi3rlXI zIe(rqAGa&#rtgv5SlFe+b|N)EAOpKp$Uu4-x0mJq^RqJbJG^#m(P8IJSrY? z%H+^|(4Cv+AYxuU>D7-7B(G;akq5{ACZC3*Pbu-{lJWo<==Yq|z8{ZDBVInx?loK- zx`dBExJBC+8_75AYIqHAqsR0=1K;~@!GlLZ>lqjvHw@1Y3C~xO=c~0_^|8X`l}c=f z4b3?>-2}HYn%t0}V6DWRlZ2wb74vVrrleR&U@?$fkHx~!uZRn4f|D48nw{?ZU;Q&i z7h4vHyDY5@lJ^oiw!KpfIa%$CdrKzz^!Lc|D!tdzC+|DzgUnA@3h_`E4LR6+O!4-4 z-qX7OzDUnUlhL11lvh%ee~dwA+|V+7cW(I#;wM6msj))h@kUH9EZ%-JVfQ0+MOujw zZ$DDZ&f^{JW=;=&22nT0y@I$F1@xoI>#!sn+TZQ&8G4c7DAwi4i+~+`?p!M6?isv= zrZ0+_2>swjTA*O%a@UzuiuaRzmtRj|IJ1F_QCzIV3zhjx?HW>jsU4X`D?Lg6CGBa+ zFVf1%umgQ!_qor+dMwDAi6b)@+Oxag^p<|e^?UWB`s*ogu;cDx|^gUWc=?vLLb@L*8Ai#99u7=`ltBO|tkyO1VCp7dJt_=Pm6PZ+w<_epHIQ60bg|Bo?2OJ+C=q??Z)N zg|PJUdmpfolZKodV$t1|o+H|Px}(VGq;q~uaOXS&&e(S$n9d)jVdu!*6L+2MHr)Zy z=nkZPu_^84Uy;>*L~7>HVUd3(7v`8;sQrLuqY&1eeHf>2YtMS)*LmlMMqKcE4t11e zng43!q*uRY=(hp=-Lw_XuKCEd!GFM)qQ5?L0AGW}sEGE({O{L4N#{%><(`YCcNb0e z<*=H~`c-s6=!)bwcrH#?;&+$00*QJ|4xXXtRYUjjJfYn0!;RaRVij`p?)b%&xk{cJ zYM$FE(y^GPqN?bVWL8B$Ka{)-GcQw*SUzFouRlK4KYt0*+^;XeN}YsYSp}a>?CJi( zG~&~b#|~O!!&YrI4JV}%8Q6Q&1rwu_hbqNo4IT?rVgZHrR+%fnVxJSk+%~$eW>B0XCFj1LC z(?B48pFMyPsGp(*8?CQA`<RgZvuh(R z8vM@IR~i(o0~LK$QG>I&*Ez{Y&s65&Ve})+Qk+Zs@I1g4R}?ILN=fpP(-f^KB^a%W zrO$XMG2)`Xf=MKREJ1W8mL#tPV}K^J0LCr2Va$dr0{R)O2Nlo*r6-fGpCVloO9n#- zPC(y=;S$haA!>4qAju#Z`hS7Rm&ykAxQxfKt1)RNYr)9qIpXci6>sa`6K{Vy-f)Y> zTQLQ^nFaiZBH$Y?G~kAR>3Hve95TR&_rJb(f$@G4jGq$kCZ-GVZa^3_<9)RtEdq(h z8>5U$I^Iv=XPM-YllkNQe<8o;z`qO1?_0t6De*pgB5!^_B}jiIzi-3(G8qLU&+kBD z!GRmFSP&1cAJSw0xmqPLV?WTAiRTmcoQT`eQ8_i`047HZ zO^U}b&Sa1V$q;8iCOWj7DHI0;3TajlgIG{E7eFS*xVehQ=3}bLlI4C$6rldGj4NT-&~JBEn2Ry&Zl3^=)cw<97v@; z0DSCVDs?6HVtxeJhTn?b09=WE!=iUmsTTof1GWJ^2KXxAcEIhBd-hN&H5+n=|CCB~ zlKhcWs)y=;uL5p*HYqG70*2Jc-W+eKz(_HUj<#J4?r* z-}axt!esh4yYsVG-f!oq}Q5c_T6KlAB+WNNL)=ie}^ieq|gOu@6`9WL2XyvR|s$YEbHpRMvxdK|i*L=Ie_uDo_ppHi{hUlm{(QuxoIt0d_P zBTw*N1ZdRv-H6q0r_ETVHo2Ow1Zxhn7 z!p&nJ9+R+bu|9&0folEQb)zQTmfd| z>u%`T1wC*jT~I6hsqJ(@Z=r-sn;TOW;MlpTf)}i2jO}vQU95gNI7Z881V$q;8iCOW zj7DHI0{^cgkbZBCzo#bNOA~7hdZ&(xsM9-m<~qGIM`fY`j0XW+i+9atUuO_5=XCMj z9M)B=&~pQosRoe5dvao3EuMis{3I177CY8hRKzM~7uG~n#5-W+oG#vt)3|-Ko}^N2 z0O=AA1>j=Ff*nX&4pZ500JgrPOZ+d1mCHCB<_Lj5#SIa5+j;xqojK7y{yW6{ff~k& ze>AcBYA%mof>~YIh2Py-{Z>vt%j?{IZq5H3NWWK}Wx`zE!Am&2lfwoMJ2>3T;Ws(_ zHxB=UL!nl@A1Ug1{q%FL>E6(qreLefU0#NlOJ~e2SrM?=tb@ zC6S+*c#MXuxDwrpQS8czzewuIiFZi-Iq^}7}r*5Qu^EgGu4VWxA*7d zzgX&|*M_r-6{A$lFJ_Vzqg~7^nfObkTzPAiE|bLjx0(DHy;Ww6acz|@msaP*Pn9}z z;>GMYqKl>pn{+xgf-$aW-YAe9(n0>dFx&e9?rR*+HllFN_HzJjP(=KqU+8(C%3O{g z%jbE4U(NBiay&iLQd!6G;{9dzObh%L;4PS~*K@y6W#zlL$Yno0cauFXZa-(2=$!z< zS7qUU$?@VoB>49MPwk3$qRPqvhCjc5$6|c4IArOc47?>rp5(LN&G;uvT8@0nB^DMPlNwj^w&n7AZ*_ZLgR3QnnX^O8ydv@s2KQbg;Eoo#qbX4)HDMr^dx|v z4E?Kl9@0Jyl}8!gxHf;k2>hgi%cbo5!FuEa>FMV;c(Ff8dv9d_>T3)wqTLc0O#B=9 z0)*{@fh7R^HPA2Kdl&cfqlnMsg7fD$dJ~QGJi`|*v>gCY(DG#1AX}s&&=cT;oR;|GMg+f1MAddEK(=a&?ZXhTGcRb5uW=ao|XM zI}`KyI%?FKaci^V=I|QyNsk7naGD{>7kW2qS7{1Ut}1Qh898FIiIULu$y20zQ==7gNEGYQga=bS8@$st;;G z1PDjeWaS)EGy4ZV|Lv5E9iN`RZq?`Wwk@xrgLRhUw3+&*RyEolB3tRG8gVR5rYU9{ zcxUId0ZH)bHndca*uc)Yp`noXtRBM_*j23zat@E@~Pd^F~?YQ^6knlHL< zX$}W7hleTQd25pQuChp|p)AjFL7zTi_>n;AVB=UGjFR%Y#!%h8Y?Q5|5pv;Um3N|X z-cVXA%O*O!C^MGE8Auf)#|Gi7AXUZrO6g3e1T+pL0$~kiG@ioepPEERAZ2PdPBW@& zkFp^kPC3f7DaR>GCUgG!$xj)_Emep!koX}=)GQ5om`&#-nGRLTHsHLIrt+L7mGhja z43DL<_Vq1Va1EdqF<_&(!XzJxv`J;HVJ%dK`%4*{d}lP(a}>^PnxO^PN{rSRY;Tmx z>eshIp8>UqL7_>rDcqV-Q9+A@nu8?3uiBb5sf=bKsSKB8Ys0v}2~_xIF)53L+00TF zYUC4NV?C6J8nok-sZeKKs7+Jh2SyrGX3U9(4sne(gDp*U5D9D47R;qNs|>j!;cn2< zg2~pj6!^O?>4}Zj2w3*8BK8Xe6#G@2%y`8$L0V?e9+8k2`w9Y<5R<83`Ib@WdCe@J z9H*N9?l@3uve%NbpgMdB`@|T1Po>^mPPwQ z-w(6o#r~3jVt-ZeQ(u|Ok5M82MgNKCRRP6wlaR@l|Mx8UeCJ!{lmB&=yx7+gaBEhB zB5p$8?kst+|0Q7d_C)shc@y#ud?>f6i2Va`er9&OMf(CCg^Uv)AusmRb}b-nBl&97 zM(RTTKS2;e3Tbd1PvAt&tmHe|>r(Z1N9>t9IP(%TP41>Ztmz;nQv<Y?c?#!>cO{5i!n%0wE{r6Cg}DVZV6J?yN94viYekbD{rH5w6^f z#I=zBY!+U~n_)WlO}twxjLJjYfU8iYToU#Ozi503+YJfhd%E9%D@Dg~qG(s}(zZ@6 Q`HjmB4)ME^;Ln!-FO8?DtpET3 literal 0 HcmV?d00001 diff --git a/all_cases/main.cc b/all_cases/main.cc new file mode 100644 index 0000000..1841c67 --- /dev/null +++ b/all_cases/main.cc @@ -0,0 +1,268 @@ +#include +#include +#include + +void load_basic_ranges(std::vector &basic_ranges); +void build_basic_ranges(int n1, int n2, int n3, int n4, std::vector &ranges); + +inline uint32_t binary_count(uint32_t bin) { // get number of non-zero bits + bin -= (bin >> 1) & 0x55555555; + bin = (bin & 0x33333333) + ((bin >> 2) & 0x33333333); + bin = ((bin >> 4) + bin) & 0x0F0F0F0F; +// return (bin * 0x01010101) >> 24; // AMD CPU + bin += bin >> 8; + bin += bin >> 16; + return bin & 0b111111; +} + +uint32_t binary_reverse(uint32_t &bin) { // reverse binary every 2-bits + bin = ((bin << 16) & 0xFFFF0000) | ((bin >> 16) & 0x0000FFFF); + bin = ((bin << 8) & 0xFF00FF00) | ((bin >> 8) & 0x00FF00FF); + bin = ((bin << 4) & 0xF0F0F0F0) | ((bin >> 4) & 0x0F0F0F0F); + return ((bin << 2) & 0xCCCCCCCC) | ((bin >> 2) & 0x33333333); +} + +bool check_case(uint32_t head, uint32_t range) { // check whether the case is valid + uint32_t status = 0b110011 << head; // fill 2x2 block + for (int addr = 0; range; range >>= 2) { // traverse every 2-bits + while (status >> addr & 0b1) { + ++addr; // search next not filled block + } + switch (range & 0b11) { + case 0b00: // space block + case 0b11: // 1x1 block + if (addr > 19) { // invalid address + return false; + } + status |= 0b1 << addr; // fill 1x1 block + break; + case 0b10: // 2x1 block + if (addr > 15 || status >> (addr + 4) & 0b1) { // invalid address + return false; + } + status |= 0b10001 << addr; // fill 2x1 block + break; + case 0b01: // 1x2 block + if (addr > 18 || (addr & 0b11) == 0b11 || status >> (addr + 1) & 0b1) { // invalid address + return false; + } + status |= 0b11 << addr; // fill 1x2 block + break; + } + } + return true; +} + +void find_all_cases(std::vector &all_cases) { + std::vector basic_ranges, basic_rev_ranges; + load_basic_ranges(basic_ranges); + for (uint32_t range : basic_ranges) { + basic_rev_ranges.emplace_back(binary_reverse(range)); + } + + all_cases.clear(); + for (uint32_t head = 0; head < 16; ++head) { // address for 2x2 block + if ((head & 0b11) == 0b11) { // aka (head % 4 == 3) + continue; + } + uint64_t prefix = int64_t(head) << 32; + for (uint32_t range : basic_rev_ranges) { // combine 2x2 address and range + if (check_case(head, range)) { + // TODO: emplace with range_rev + all_cases.emplace_back(prefix | range); + } + } + } + +} + +void load_basic_ranges(std::vector &basic_ranges) { // load basic ranges + basic_ranges.clear(); + for (int n = 0; n <= 7; ++n) { // number of 1x2 and 2x1 block -> 0 ~ 7 + for (int n_2x1 = 0; n_2x1 <= n; ++n_2x1) { // number of 2x1 block -> 0 ~ n + for (int n_1x1 = 0; n_1x1 <= (14 - n * 2); ++n_1x1) { // number of 1x1 block -> 0 ~ (14 - 2n) + int n_1x2 = n - n_2x1; + int n_space = 16 - n * 2 - n_1x1; + // 0x0 -> 00 / 1x2 -> 01 / 2x1 -> 10 / 1x1 -> 11 + build_basic_ranges(n_space, n_1x2, n_2x1, n_1x1, basic_ranges); + } + } + } + std::sort(basic_ranges.begin(), basic_ranges.end()); // sort basic ranges +} + +void build_basic_ranges(int n1, int n2, int n3, int n4, std::vector &ranges) { +// printf("generate n1 = %d | n2 = %d | n3 = %d | n4 = %d\n", n1, n2, n3, n4); + + constexpr uint32_t M_01 = 0b01 << 30; + constexpr uint32_t M_10 = 0b10 << 30; + constexpr uint32_t M_11 = 0b11 << 30; + + std::vector cache_1; + std::vector cache_2; + + int len, limit; + + len = n1 + n2; + limit = 0b1 << len; + + for (uint32_t bin = 0; bin < limit; ++bin) { + if (binary_count(bin) != n2) { // skip binary without `n2` non-zero bits + continue; + } + uint32_t range = 0; + uint32_t mask = bin; + + for (int i = 0; i < len; ++i) { // generate range base on binary value + range >>= 2; + if (mask & 0b1) { // non-zero bit + range |= M_01; + } + mask >>= 1; + } + cache_1.emplace_back(range); // insert into cache level 1 + } + + len += n3; + limit <<= n3; + + for (uint32_t bin = 0; bin < limit; ++bin) { + if (binary_count(bin) != n3) { // skip binary without `n3` non-zero bits + continue; + } + + for (uint32_t base : cache_1) { // traverse cache level 1 + + uint32_t range = 0; + uint32_t mask = bin; + + for (int i = 0; i < len; ++i) { // generate range base on binary value + range >>= 2; + if (mask & 0b1) { // non-zero bit + range |= M_10; + } else { // zero bit + range |= base & M_11; + base <<= 2; + } + mask >>= 1; + } + cache_2.emplace_back(range); // insert into cache level 2 + + } + + } + + + len += n4; + limit <<= n4; + + for (uint32_t bin = 0; bin < limit; ++bin) { + if (binary_count(bin) != n4) { // skip binary without `n4` non-zero bits + continue; + } + for (uint32_t base : cache_2) { // traverse cache level 2 + uint32_t range = 0; + uint32_t mask = bin; + + for (int i = 0; i < len; ++i) { // generate range base on binary value + range >>= 2; + if (mask & 0b1) { // non-zero bit + range |= M_11; + } else { // zero bit + range |= base & M_11; + base <<= 2; + } + mask >>= 1; + } + ranges.emplace_back(range); // insert into release ranges + + } + } + +} + +//bool check_case(uint32_t head, uint32_t range) { // whether case is valid +// +// constexpr uint32_t M_00 = 0B00 << 30; +// constexpr uint32_t M_01 = 0b01 << 30; +// constexpr uint32_t M_10 = 0b10 << 30; +// constexpr uint32_t M_11 = 0b11 << 30; +// +// uint32_t status = 0b110011 << head; +// +// for (int addr = 0; range; range <<= 2) { +// while (status >> addr & 0x1) { +// ++addr; +// } +// +// switch (range & M_11) { +// case M_00: // space +// case M_11: // 1x1 +// if (addr > 19) { +// return false; +// } +// status |= 0b1 << addr; +// break; +// case M_01: // 1x2 +// if (addr > 18 || (addr & 0b11) == 0b11 || status >> (addr + 1) & 0b1) { +// return false; +// } +// status |= 0b11 << addr; +// break; +// case M_10: // 2x1 +// if (addr > 15 || status >> (addr + 4) & 0b1) { +// return false; +// } +// status |= 0b10001 << addr; +// break; +// } +// } +// +// return true; + +// uint32_t status = 0x110011 << head; +// for (int addr = 0; range; range >>= 2) { +// while (status >> addr & 0x1) { +// ++addr; +// } +// switch (range & 0x3) { +// case 0b00: // space +// case 0b11: // 1x1 +// if (addr > 19) { +// return false; +// } +// status |= 0b1 << addr; +// break; +// case 0b01: // 1x2 +// if (addr > 18 || addr % 4 == 3 || status >> (addr + 1) & 0x1) { +// return false; +// } +// status |= 0b11 << addr; +// break; +// case 0b10: // 2x1 +// if (addr > 15 || status >> (addr + 4) & 0x1) { +// return false; +// } +// status |= 0b10001 << addr; +// break; +// } +// } +// return true; + + +//} + +int main() { + +// std::vector temp; +// load_basic_ranges(temp); + // n1 = 2 | n2 = 1 | n3 = 3 | n4 = 6 +// build_basic_ranges(2, 1, 3, 6, temp); + + std::vector temp; + find_all_cases(temp); + + printf("size -> %ld\n", temp.size()); + + return 0; +} diff --git a/src/main.cc b/src/main.cc index 3e8017d..d81e1aa 100644 --- a/src/main.cc +++ b/src/main.cc @@ -260,6 +260,15 @@ void cal_klotski(uint64_t code) { int main() { printf("Klotski engine\n"); + std::vector all_cases; + find_all_case(&all_cases); + +// std::cout << "klotski cases -> " << all_cases.size() << std::endl; + + printf("klotski cases -> %zu\n", all_cases.size()); + + return 0; + // printf("%lx\n", compact_code(0x0E58FC85FFEBC4DB)); // printf("%lx\n", compact_code(0x0603EDF5CAFFF5E2));