From 103c893c85c704068df684ddd9ea5eca656a09be Mon Sep 17 00:00:00 2001 From: po4k Date: Sun, 28 Sep 2025 18:51:46 +0300 Subject: [PATCH 01/26] =?UTF-8?q?=D0=97=D0=B0=D0=B4=D0=B0=D0=BD=D0=B8?= =?UTF-8?q?=D0=B5=201?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- labs/lab_01/example/Untitled.md | 156 ++++++++++++++++++++++++++++++++ 1 file changed, 156 insertions(+) create mode 100644 labs/lab_01/example/Untitled.md diff --git a/labs/lab_01/example/Untitled.md b/labs/lab_01/example/Untitled.md new file mode 100644 index 0000000..f9b9360 --- /dev/null +++ b/labs/lab_01/example/Untitled.md @@ -0,0 +1,156 @@ +--- +jupyter: + jupytext: + text_representation: + extension: .md + format_name: markdown + format_version: '1.3' + jupytext_version: 1.17.3 + kernelspec: + display_name: Python 3 (ipykernel) + language: python + name: python3 +--- + +1.2 сумма + +```python +import random +import usage_time +import matplotlib.pyplot as plt + +def sum_nums(v: list): + total = 0 + for num in v: + total += num + return total + +items = range(1, 10**5 * (20 - 6), 50000) +func = usage_time.get_usage_time()(sum_nums) +times = [ + func([ + random.randint(1, 3) + for _ in range(n) + ]) + for n in items +] + +plt.plot(items, times, 'bo-') +ax = plt.gca() + +plt.title('The execution time of the sum of list numbers algorithm') +ax.set_xlabel('Number of elements') +ax.set_ylabel('Time, sec') +plt.show() + +``` + +1.3 произведение эллементов + +```python +import random, usage_time +import matplotlib.pyplot as plt + + +def multiplication_nums(v: list): + mult = 1 + for num in v: + mult *= num + return mult + + +items = range(1, 10**5 * (20 - 6), 50000) +func = usage_time.get_usage_time()(multiplication_nums) +times = [ + func([ + random.randint(1, 3) + for _ in range(n) + ]) + for n in items +] + +fig = plt.plot(items, times, 'bo-') +ax = plt.gca() + +plt.title('The execution time of the get multiplication of list numbers algorithm') +ax.set_xlabel('Number of elements') +ax.set_ylabel('Time, sec') +``` + +1.6. поиск минимума простым перебором + +```python +import random +import usage_time +import matplotlib.pyplot as plt + + +def get_min(v: list) -> int: + min_num = v[0] + for num in v: + if num < min_num: + min_num = num + return min_num + + +items = range(1, 10**5 * (20 - 6), 50000) +func = usage_time.get_usage_time()(get_min) +times = [ + sum([ + func([ + random.randint(1, 10) + for _ in range(n) + ]) + for _ in range(20) + ]) / 20 + for n in items +] + +plt.plot(items, times, 'bo-') +ax = plt.gca() + +plt.title('The execution time of the getting min of list numbers algorithm') +ax.set_xlabel('Number of elements') +ax.set_ylabel('Time, sec') +plt.grid(True) +plt.show() +``` + +1.4. вычисление полинома методом Горнера + +```python +import random +import usage_time +import matplotlib.pyplot as plt + + +def horner(coeffs: list, x: float) -> float: + result = 0 + for coef in reversed(coeffs): + result = result * x + coef + return result + + +items = range(1, 10**5 * (20 - 6), 50000) +func = usage_time.get_usage_time()(horner) + +times = [ + sum([ + func( + [random.random() for _ in range(n)], + random.random() + ) + for _ in range(20) + ]) / 20 + for n in items +] + +plt.plot(items, times, 'bo-') +ax = plt.gca() + +plt.title('Execution time of polynomial evaluation by Horner\'s method') +ax.set_xlabel('Number of polynomial coefficients') +ax.set_ylabel('Time, sec') +plt.grid(True) +plt.show() +``` From be9052f109aa6d750d43cecd60991dd1a335f64a Mon Sep 17 00:00:00 2001 From: po4k Date: Sun, 28 Sep 2025 19:27:36 +0300 Subject: [PATCH 02/26] =?UTF-8?q?=D0=B7=D0=B0=D0=B4=D0=B0=D0=BD=D0=B8?= =?UTF-8?q?=D0=B5=201=20=D0=BE=D1=82=D0=B4=D0=B5=D0=BB=D1=8C=D0=BD=D0=BE?= =?UTF-8?q?=20=D0=B3=D1=80=D0=B0=D1=84=D0=B8=D0=BA=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- labs/lab_01/example/Untitled.md | 16 ++++++++++++++++ labs/lab_01/example/images/horn.png | Bin 0 -> 2397 bytes labs/lab_01/example/images/min.png | Bin 0 -> 2397 bytes labs/lab_01/example/images/mult.png | Bin 0 -> 26772 bytes labs/lab_01/example/images/sum.png | Bin 0 -> 2397 bytes 5 files changed, 16 insertions(+) create mode 100644 labs/lab_01/example/images/horn.png create mode 100644 labs/lab_01/example/images/min.png create mode 100644 labs/lab_01/example/images/mult.png create mode 100644 labs/lab_01/example/images/sum.png diff --git a/labs/lab_01/example/Untitled.md b/labs/lab_01/example/Untitled.md index f9b9360..5a3eca4 100644 --- a/labs/lab_01/example/Untitled.md +++ b/labs/lab_01/example/Untitled.md @@ -42,6 +42,7 @@ plt.title('The execution time of the sum of list numbers algorithm') ax.set_xlabel('Number of elements') ax.set_ylabel('Time, sec') plt.show() +plt.savefig('sum.png') ``` @@ -75,6 +76,11 @@ ax = plt.gca() plt.title('The execution time of the get multiplication of list numbers algorithm') ax.set_xlabel('Number of elements') ax.set_ylabel('Time, sec') +plt.savefig('mult.png') +``` + +```python + ``` 1.6. поиск минимума простым перебором @@ -114,6 +120,11 @@ ax.set_xlabel('Number of elements') ax.set_ylabel('Time, sec') plt.grid(True) plt.show() +plt.savefig('min.png') +``` + +```python + ``` 1.4. вычисление полинома методом Горнера @@ -153,4 +164,9 @@ ax.set_xlabel('Number of polynomial coefficients') ax.set_ylabel('Time, sec') plt.grid(True) plt.show() +plt.savefig('horn.png') +``` + +```python + ``` diff --git a/labs/lab_01/example/images/horn.png b/labs/lab_01/example/images/horn.png new file mode 100644 index 0000000000000000000000000000000000000000..458ee0d9a4ebc2a1f34ed3e4c955f3a225e98219 GIT binary patch literal 2397 zcmeAS@N?(olHy`uVBq!ia0y~yU}|7sV0^&A1{5*9c;^X_vMOsbDlCjFttX k#o=g;Fj^_nwOyd6R>{6+`SMLk!1fA*r>mdKI;Vst03@iNd;kCd literal 0 HcmV?d00001 diff --git a/labs/lab_01/example/images/min.png b/labs/lab_01/example/images/min.png new file mode 100644 index 0000000000000000000000000000000000000000..458ee0d9a4ebc2a1f34ed3e4c955f3a225e98219 GIT binary patch literal 2397 zcmeAS@N?(olHy`uVBq!ia0y~yU}|7sV0^&A1{5*9c;^X_vMOsbDlCjFttX k#o=g;Fj^_nwOyd6R>{6+`SMLk!1fA*r>mdKI;Vst03@iNd;kCd literal 0 HcmV?d00001 diff --git a/labs/lab_01/example/images/mult.png b/labs/lab_01/example/images/mult.png new file mode 100644 index 0000000000000000000000000000000000000000..9056467af52e7ac2cb522f0d431d09ae562329ae GIT binary patch literal 26772 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 K>jB$3@P7cMBz7+V literal 0 HcmV?d00001 diff --git a/labs/lab_01/example/images/sum.png b/labs/lab_01/example/images/sum.png new file mode 100644 index 0000000000000000000000000000000000000000..458ee0d9a4ebc2a1f34ed3e4c955f3a225e98219 GIT binary patch literal 2397 zcmeAS@N?(olHy`uVBq!ia0y~yU}|7sV0^&A1{5*9c;^X_vMOsbDlCjFttX k#o=g;Fj^_nwOyd6R>{6+`SMLk!1fA*r>mdKI;Vst03@iNd;kCd literal 0 HcmV?d00001 From 587e2fd6bca10964b36a9bf0cd15380e91db88ed Mon Sep 17 00:00:00 2001 From: po4k Date: Sun, 28 Sep 2025 19:59:07 +0300 Subject: [PATCH 03/26] =?UTF-8?q?=D0=B7=D0=B0=D0=B4=D0=B0=D0=BD=D0=B8?= =?UTF-8?q?=D0=B5=201=20=D0=BE=D1=82=D0=B4=D0=B5=D0=BB=D1=8C=D0=BD=D0=BE?= =?UTF-8?q?=20=D0=B3=D1=80=D0=B0=D1=84=D0=B8=D0=BA=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- labs/lab_01/example/Untitled.md | 15 ++++++++++++--- labs/lab_01/example/images/horn.png | Bin 2397 -> 32869 bytes labs/lab_01/example/images/min.png | Bin 2397 -> 29967 bytes labs/lab_01/example/images/mult.png | Bin 26772 -> 26554 bytes labs/lab_01/example/images/sum.png | Bin 2397 -> 31068 bytes 5 files changed, 12 insertions(+), 3 deletions(-) diff --git a/labs/lab_01/example/Untitled.md b/labs/lab_01/example/Untitled.md index 5a3eca4..13bf6f3 100644 --- a/labs/lab_01/example/Untitled.md +++ b/labs/lab_01/example/Untitled.md @@ -41,13 +41,21 @@ ax = plt.gca() plt.title('The execution time of the sum of list numbers algorithm') ax.set_xlabel('Number of elements') ax.set_ylabel('Time, sec') -plt.show() plt.savefig('sum.png') +plt.show() + +``` + +```python ``` 1.3 произведение эллементов +```python + +``` + ```python import random, usage_time import matplotlib.pyplot as plt @@ -77,6 +85,7 @@ plt.title('The execution time of the get multiplication of list numbers algorith ax.set_xlabel('Number of elements') ax.set_ylabel('Time, sec') plt.savefig('mult.png') +plt.show() ``` ```python @@ -119,8 +128,8 @@ plt.title('The execution time of the getting min of list numbers algorithm') ax.set_xlabel('Number of elements') ax.set_ylabel('Time, sec') plt.grid(True) -plt.show() plt.savefig('min.png') +plt.show() ``` ```python @@ -163,8 +172,8 @@ plt.title('Execution time of polynomial evaluation by Horner\'s method') ax.set_xlabel('Number of polynomial coefficients') ax.set_ylabel('Time, sec') plt.grid(True) -plt.show() plt.savefig('horn.png') +plt.show() ``` ```python diff --git a/labs/lab_01/example/images/horn.png b/labs/lab_01/example/images/horn.png index 458ee0d9a4ebc2a1f34ed3e4c955f3a225e98219..3dec0dbaf9b52af675cc61dd3abe696d15061769 100644 GIT binary patch literal 32869 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 P;6Da>Cc4+PUH1PM&Faca literal 2397 zcmeAS@N?(olHy`uVBq!ia0y~yU}|7sV0^&A1{5*9c;^X_vMOsbDlCjFttX k#o=g;Fj^_nwOyd6R>{6+`SMLk!1fA*r>mdKI;Vst03@iNd;kCd diff --git a/labs/lab_01/example/images/min.png b/labs/lab_01/example/images/min.png index 458ee0d9a4ebc2a1f34ed3e4c955f3a225e98219..ac264b3ae0bc97e7d5f9e5da2dc8df7b816a526b 100644 GIT binary patch literal 29967 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 NS7)>KEiJpF{{?s8k~IJT literal 2397 zcmeAS@N?(olHy`uVBq!ia0y~yU}|7sV0^&A1{5*9c;^X_vMOsbDlCjFttX k#o=g;Fj^_nwOyd6R>{6+`SMLk!1fA*r>mdKI;Vst03@iNd;kCd diff --git a/labs/lab_01/example/images/mult.png b/labs/lab_01/example/images/mult.png index 9056467af52e7ac2cb522f0d431d09ae562329ae..2b1ef3fd6be0d59d960a0f3168c6aebf8ce471aa 100644 GIT binary patch literal 26554 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 literal 26772 zcmdSBgK~khdx)cNiR6qo2ln^API~1i;L=cch5CH+{RHRWrR76sx zyF1>w@%hDdeee4ReD`(V&!e!<-fOS5=9puSIo1i&yrDu$#6W~Xp-8W(DruuoSb-=M zdV&BCesZaQWD@>Q%Ju3U*ISNOt{!)tEm7C+x;oi8y4u;?V{^B3cCm4ExF{ejByfqJ z&Dzz~$wf*~(Eh)#5O8$9FQ|WDEe&@ebW+uKL7~X+BLAWDY7D;c)8&Z?5`_|Up0L6 z>%r@a6~oX=jAxQl$60s8Th3kVJeQm-oqXUg+bh$VD(NzFQQTwM*ZGU=Onxv0mJ<6uYmmNM=MTjXlSVF-6Yf*N=iyz5-J4@{PW~4mMU_ckOnFYeog(9kPUtt_fZIa z4t}dm&lQM#n5gCd-ydGYpd+KAo~Y$sadmw^l1Xh{s9W?%E%)R1LcJ-ntL?PrBDcN0 zrQ~)euyJs3nm>F%r%AbWZHc{KIa&SPGEJ`eL5Ghf?|O=r_Gm^1+vd`+_{|ckGiM&f z#!`$P73!5-$<@C5{mpH!Unc$*(XF(j4L)?nwXT;-@3m%V7f_r%YxCY=y6Ns^Ilak{ z?WC9T0gWS>Nl&&9WW>aD69;=g-+!O6;*)Y6b(`<`HSrp<_(yizi$g!_y~;=K&X%?& ztuLfFHhy@W?jJ5-Tx+&9|D9gi{cV431f5_aC-1wQ3x<_RsTQ5~HFLVnxkdm(AOwTPy8{g}l}+-s+d*+5dW9I=dk2wT?58cm3}Ufn_0ETDNn{ zwPjSKez{fD*pXw?5pBTXno8oj+H=0&J;@h;kQ6ni$oh!Yy3WPtUVWoiVlq3{ApPyZ zC3BI-%+l@|ItAKy-kDvFcB2zCiTu+VF;kPAq5Pl}J{3Ihd{Pnm?V-xRd1kq)#PkT4@zLQ3jmf4|nU(B{v38hPO{F}?8`njg%+1jxan8W|gZu51`_diXGI z%FTsCK0W!7Z!r&nwzl@f^0I&jJ?*nsuc9L(Nvf->JGReOh@~uHeTjg-_q@DBe0+TD zvsP4 z2e88?9+S%{Jb3V?_(r;%-^BdEUu+qd|;d?;>j-B?ALo6%>td;1HR`( zyu7@38oVot8I6bMEfyJGwnorp!+L5KeqY_#Xn}2A?)v;maB#+h?{6gh_C;TcJ4Wl7 zc;V)%J^xtmwc-3Lw3DO{PJ`gIb5wq$GNsLS540;^O>U zugPF}tegVe=f2{an3y0lGFt1lw$Up;Lw}wvjbJ?B#1CFsp-4CTUTb)ge1Kdq1$?*Yso%_<)@1I8);$FTCfB3g86M0P!50#lOX%AP%8u*7r zwmd~9Cp({6|9E?LWMpJwWhEy0;{AJ5UC;4i!ct9MJB~MohKFNi1W2m5uOE0^a*s+W z?S1;=z0H8o-H$jZg=7&+*U|^$F4MNCiuTFn(K=zzRWs`Ix+E+tEVH9^;w-Y>2}?er z?tWS~(pPK;i|_t?cQ^k|DF&XU`Sy;m>(Z~=D=TFWzVpGKXi$AHP5kX?nMYKttTAY8 zyyo_Hd}Kznvhj3FOzefG_cmtChsrE@^op4vR_4DKhA4)RSswUT2$(iT78}=n?CvH; zHi}8Wk=x<+u%rHV0R3>ULt@>wZ8COKdF%*;$4lX?kc0C^f`H&@0@cN*0ac+e== z{e zc+Z32+-MC~IW93Rn~)HNgM$MyqsK=(9!0HGZqMArOGiP0FZg*iPO=(Tm9A#Lmr)c3fPgk!`lV7UiW2PC5HXZ0po$0zhu)i z8S=RjHQfqXZDL{~aP4n92Rl1@WBRjV?1B7A)Ow?;K* zE*QLTekJRJ3?zHFx1&QLgp7F=_L+HK#^rpSf-^VLq@KWwPaN)T)Y|@}6)*}#?sGF; z?q^egJQFkX+IKzEy9e7#cgn3u4-XGfs-q)*`E53wV_0Obq=?y5(9%9#U3F4YQ8EAX zDJ);Nh~ZbIy=`R@Y64)^b0*D02zGG&!EzlESHG$pV{+AB{0TTYU`19B1^HaT)3e${ zd@SJPD5NclF&mINNz~@d$mnS4!@tU|^WO;Nk9RqwJeKV?-JVduNU+_PN5Wt;XIOoH z`LoiVkxL^f(6Gwk?uSRXJX%>eKi=v;hWBEZlspS80hQBDLlPDl`Kcq0Ln~jCee^|R zOiYYPS{#Q;7Hl;H^NLLx!aF)tBk6^)7{%=RhGX)WZay8UbyI&Ks_{zZ?DF#R?*2jv zX{CSix)f~Iwx!`JQj^NKw8KN=4L*K;l9}H0_FA`vcV-{3s0B@!P_CUp!W_zx3Xn&H z?0<=l&isMBS{w26x@FhQL0_ig&nidOT8|a7fPes_25%bmME=XFsssSDQ3$wQPZ4W{ z=y+${k2zckI2mAeY>TdYeKQ?%?i>!}u1}$q97voUuC|cR4p#{xVFSB-;k#*_`voKh zV6yXd_9+6#fTpVRpf_oE*Ry`DjS-nuuIn#@F;~MU;B%p2VQ97^zZb9>G8IFz z;Nt|u#MmgE5);{W`;>LBo+4y&Ejr_o{71$l5op<+n5i0vLEc;Kg+SC$`F(RpNV}T@ zH?=AreCI!y9d>NGs;zzIDLHHO{oYr1e}8-eOM?qhkSm=&xjiCo_fsf=M+=KJ;7}N{ z9tx%Sl;pCjtEh4$eNfl)^M5})#@~h9^KiQ7?6+d$;n{BmhpUR4i$hc}xp!(^dA)a*qhKFrX(Wp%@2EG1VcpwZ{r&MyHP8oY zloBK=B_xIV!W&@)O1RA@P+SRx%&gVu>qW`Hz$YRi;=1)p#tYMxz{_D!<&b7iV*BGQ zB^epnJwOoeDfJfuG^kI2if)#}mG)GqPe629r@CJt2&MG;Mw)93Hz#KpEKBIln9of| zLyzSV%2%&mc~8M6qIp70M>|+-JWzPB?lU{^I);FRr02}Ww}M;ci{c(09{sSV_}%o1 zjd)R^=kl3V(0_}1pY*ck5Mp0DeJ9t3pP=sK8cU}W}k;)C8O9HkG2hs_2G?p z^viNQ50vgU2+Rg=21O)|Q1;PTS7i-itjgE|LZV%|0`f;K{)1*D-y9_Grc;DPE zWK@r7p=?uI_uh^H*DdG#q#exf8b0dHi`~k?QErYlY{CUx86WZzr;9tj zLb3Vp&v9o98`n5rMNz=ae0!d}zURL_c`dPedu2R*>f%ldxxB@YVB0-_6__87alhB+ z)z#IhNEyYbpAgZU2@4DJ7N$F|t0CjNtEsmGr1%W#6QFJURE3Ecq$sq)N_}!d!Z~Eo zA3b`s`Q-xY6T)>y$GY82j~T7x^z44UzlNfKq##lo<+HPFIdsEa<4A@f{ATyhwS+yN zg1aqGfzF4qD?Xj=`Z_T1q^YUtgL&8I&(}xly>99GL*_v%L^4b3>RHX#++@7D)ol-|pNu>S*0pw=5ojx(rrHw_<8&rk^dh9nX{ zs056dUwB#S88<@;8L0chDIq~0 z`0WUVYL8)UhkdyEMS5idqO>~TL~eP!DJCI-`n}!InL3Y^FY!lBiy^H33J@x*zidn9 zUiq9H`@OgB$3ndW@?|_KKIVyyfG&5s@1u9`gsN+6{}h%qew96LXAPKuj62((9Wqu4 zIk7+EGWKXC5T=mPI*;stlVcv^+V>_hHA|SzBKea;DjORc`ioYPCg;0-RvPfh$;lf8 zm{5@3W5+JNgk7I++SKT9l5z`Bq5s`o#nB_c1r*BQy>(_)`unM0^el3|ND^j~kzu-a z?ON^8@x%x0;HOXje0)M&?Y5BEKR8-uNesgfe(;T_VI6Wg>lK1SV8m8FF@lVu*0E#b z(l99uQFsuN*k=1{7Ck?T43Q^&d#is-Z+dF#2?WRd_wJR2$#W$EdXgjzqN*!R2LP}i zJ39#tEA52681wuaA+%hZWQna#SgG-rk{v#7jU{TWuMhVR<4=z=wsyLpLu*oI-b z)#p_p=15Tr1uhyUqYu`le&dVu9?Q>XgMM)-_EsK?jNWNI?Hnkbd`&c?xC2gXl}mc& za=X{YbS6BLfPg>&a^vcBienZ~1)#}xl`DcJ?eDfFdVB?(ot?X!_0=6>Y+T$*UV6(w z2wHWr%E-!+`g<@ONT)nA<_v684zwW`wO<$muzNH3b*=2m6QZ-D{>sXD0Q*mSqw0YB^A}PrHZjiCzAVCvqw`;3fdL@ zzc?nE=@FXUc#lmiBO}uXuPY;a@+pkU8mg-3(GsX|X9r7I`Sgk-m7^H$j@5h3j?`QP z67`xcqN>WHvef#dP(<|Qg5}i++Dj5)MVYj`x9Xy?v9Zyr8yO9US@4KhIr>BI&XzddSsrz1wa|5qywX{(}5C13`HTg5cP1mUpKZIxgRia4d4b-(6tfR^Y}~^eEHND{+*l95hdiKo<;o)y4_hN6CfElFmcxKY zTt%L+#OFb2F#{s$T~cwcmFV2La~Z~U?vf5II(cmgrekAcAP#*1_G7uK1hI-l)s^i2 z2_RG7&YMDn>hRsJN%@a?1{gyN zEbZ1kiHCoJuicWF;`{+rdT!}4r+OlrtgNhFdtgDjql!v9e-YZ$ckOE8kDQVE7~pGE zKm_|4YhJ<>3O4Ry0V%lxGpymyD%tP_a^Yim34QRB2X}AI!|?3d8PFr+Ja@e zjgSBPnY&9Jx73-kkr6;j-Rgq$VpU2zhp;u{mL1r66Ohkq{|YzFfJoHPGh)23v_vW| zFW*qmMqIcfZe*a`~gxM2C^q`a$G3JABTkCBZVtc+qf_NLS#XZCxR9ROa4}k z`z!u!i*mcxmUT6vFXtK+vKJxMT>%xwX>0yAqIlE_F2W2Tr7aS<5X8ADFS7yO^ab7( z!CpK*+_>p`yf*`al_GqK#3cI`=o(1f2uh&}l*dr;;X}-j!SIwDythbhbfxL#wONpX z9)VQo2tERNCx?Y?1>#Z~aN-Xnj*9z6s?h$(_R?@RMC&fpdJkbZ-}1GvK}Bo7DSs3! zY~D60;TI+BHvjEIJg2&l%d|#4cfBEvo8Wi11s`0$s+)Q|b+Bs`lkXNBr%mA67CVV)dcgN7N z;mIZ2ABf@zDBX5^bg%}|h|o^&;Wzr_TnK0KST=$vLgY7qLGM9UTT%v50#m;&n*Hsi z2o9BKHjpg(`}=>^c?e=SILeJ?Ug`m-{Rl;OU!}bv@(Q5pfs%L$pz;w^iT!qkZ!Idl zw;u4D)YC%+q6~sYY(hdX;6qDGi{hZ#!u0f0KoRqnr=FZ zLG1(mI|FtJA{-%mgGtI&wZyWQ;#SP>9wQ?oL=cE%l0+0BkUb<2>EU*vZl+O&| z^tI63u8YciV89|VB?$`~`zlb>GCOR%yx2Y#>~#PA0+T)1Zb~3AU4;t%34EC6_L~IH zg`z4YS6A2QQZA@?OU>Jf0Bk_e;s;tJD0j4ZtAUpZYC%yUqy%32RY3(+$B&d>3J1p* zZ(7EAy$OENeH}tV(tRZVP%%xL_iR=%B`-K+7F98%L}5s5_I`;(=ac?BaXssl(SrfzqIpcJGU ztx7w6sBH5+BI#dp%>eAwF4b07hl2cV8TR>SqgW*?X$|x@W}#SKKKfo_YI+F56kgT+ zVjHt)7Fj;;%~^I3ST1~fPyskV3$nOwV(&*-R3%_{!4VPa(JS2I=_*mm99%b2dBW)g z1x&oAXb>Snz@*-K)3dAo`clmS$PM08ASWXHyY@iv#82*E@ggM!1smKJnLB`{j&&B$ zV9!SIUb=K!BT48o0FxrMfYBWgM_G?<$wR1pELBt^tWbg#Lvr>8I85A%g%RmCWcUWaS0|9$7 zu07+@I1W`6LwJqz(FDML1SDGqqvJS@?0j2PSVuK*5kz2n&UgDGg2G5z=i*{WyBHbT z!GK6uu;a2o^F>k`%yc--d0nI_QM*;byMy#9Q8qZnAV@)$#Cxvx1mr$*hz(GW3Pv(1 z;~wGS;$I)^nY(-;s;GC0+DtYZ;XQC zVtC0Q2%4SS$^=0IX*EzA zm+Oirq8P;|e*b275rvOign#;^1Rakg`_BuHLJ7^}tn2(_Wn@mQlR)NmX z_cm0pYjVynK>AKiODhG^DdQ+EER5(~s;a6JqC)TqT%4w+rD|Lu>9c3g?k-i0Lx|x* zk^T|70gzFIeqKK;`}R!-R(5_A1{6xfaFr`?ZEa2U#*H@6@cZ(vGun+eG9wA&&K-K- z3YME*AR(`AZhjlBCSih>^PY{Uf*t=mhqTRG*>TdCgX|803CPHZW(`6F{*Pkg!oopF z_z(!@&|$)>dIoJGc;u+xlD3GN!xb(JM&xx8z1gPq#Pnx6%j4tbk53ftBzc)UHf|=e zM?<=jNKH-EtZ}w%KpLBt(nNQPbQco+{;oU1>rK;8VY|*{r5~c3iww2BG$Lgl4spOM zAo2xFHL#=Cdj7|UUO0GoUDPx%TxT0m?e6qU|7-R`Ny3X{VszX!*zXc1CoK?)?QsGb zP{RLE0?B^0t~LVZR6j%oLNmn-+RO-7N)#{-2ZTk^GsMd$=yrwzGw7fZ zfsx&7ZB4FXvAjw7Sb_fuT^w}#lU3~aSGDV+w4^t$B7#75HoGPdxzV>T=Fa6qe+S8yj!2ZtUP^Wq%eY zXB%2$qksV8qYp;mk>d#%#nyU}v*O)IPsH=x-B%lJwA;HV`0wL|H0N_H$C;RewieKi zj&sV1Edpln$@tF&x0*ZRzOIy8p`#c&8Dq5nIS=&Daby4f-CTZOAw{e?n9x}zhw0Rz zpi0Z3jJn^8-gYLHE zjK98#|5EI^I1A^!Q@exi#$=f5==d{kh3>@W$xgVt#_8QV9w^7)K__x`4c&P1YU7~u z$*CPezx7u|^Ps7^dY#`%Ljq3xzhI7QO_LWa+D4;p<*AM~ont+HPYbQySJwuQIJvPu zzeKYJ@OvnII*oGv2O|;_p9pQn*}`8m*#4 z=Pq`}oIW-Ax<;hv*PZF>N9$kGg8DSQ?q$9GiK_u0v!X;cYy71>?7+_{x$T`|r*oF& zJ7ArYD9;`_c=n?58fe~5!CM8WfB-g$pHdICwtt@9)vN42xn}m$ghNSb z>;@n8uvcoirZ;`$MdF_+3=^GBM8f&Gx#n*L3aX)^@BV(*3-UV%{9YI|Yn`FPd$fOi ztnGCtiT`&zdJzla7W2%w4sUajaB=kf=*j^8?jPa|r@M3hcj)^{|3*Al@b$}eFs(cs zqWw3+@llLHmmdcP<21Km->IdZ?dPzSRZ%H$i?yRWUG%SBUd*QU3!~-toAb4r#m80M zOahqi)Y0C`RZ>Y}+V)~q7C@&@=U&oAF@3Z6Z-f^78-`^iZb;PC7Ukmk95O_Bs7d<5j~9)OIdrO7)X#{WWS(C7H+IpOwh5>i;ibPWEH@Ca^zM{p!u z_VtwkW<<)(%`G7*`5O|n=gH9yB{j9hrq?s>o61n>FT4M3BVE9~4jcY*g>94Swn-a2 z@foHr&}VD@2{b|HonpvDY=%>-p^euHyIa^9j786ExTt`_-=FgK5m_Rl-bozZ;H(^pqD(jQxK z8kO4bI#lOoGA=`d>uqK%%_+oc=l^XF`gzADVI`E(Sw->3DMYAdzAp+eu2b7MigW(= z$qZ?aK(~b)82NK?+A_J*-B0x1f-p7_Pt=a!TZy2DsD=G0Zc$GUUF1dM{M>)7^Y8Cg zO9m5TvOtVxNA#DiRmuMSR4J71vAl9LPU@ojHG(d((`dmRD#ey?Q+v7LIH6FJ&0h2G z(XqJ1Iq7}}YJ~x@BL9XQx-kL}nLdQSZGMckM7TqYs};q4+pw$X24XKY4* zvg1qZCzQA&*4UUr3=7OnW#H*O(gtoE%DD1O%=6juSa6(%D2y9FCnX{x0d)p_I-13o zm0K%m9w=5;eMNT0kEeILVcbNfq@vywbCv@>X#Vem1^GM**>QP(1zL)*#)+qIT&CFB z*<5D%b;a%|yXW6!nT}1kEb@3=&z~jwb9g5|8$naR>v>s=g1-PrLi6H~_Rws9Aa;rm z57oa{V&hU)+jbc9)ymUGo0zP(Dpj6Ni58j;!D}pnOj7}zzCyZ*X}sVkom7lNTw+83 zwKQf7QQy{INbdOnlhBsMTsXZM?$1}U`=gD?gy@lK_U{~DPZO6;;Aw8>#YUDc3#(^v zuzpMR?CEf6%%G`KT-?U0R{%^Ez}j0lZmInLLM5$6&3n`3+d)UwDl)hPY^tTVmmDew zr1w5WoD>?$^Wy8*Ko;4+`@JOc#oE{8IXKWNDuqw3;s%a#1%l{`I9#%_vdUz(q36vc z>rH(tPvZkrUm)Q=hK4oN4`d=r5P1ncHZ}@X4$U{^(GM;OSrSdGl$f@UvxY`bQwt?L zR|{Rliyp=YN)LFLdF%BJTNQe$fotf<`}38OxPD z7v8<$_t(^p{r3q8Nc~FBs2ZiZel~RyGCU^vy(7;3=*Klx)j)t_=#oVKxOV;eRcNX% z`$MHpgW#t(yUTi&S9!uATDy$y4CcP8j^^z% zLLf~xSRr$Lj+ti1jMa{fjB+MRt~1tTXFXC~Bb?Zn>7`_0A!Ek@87$s@6a-!Hsa*D` zd-(V1^Q?cLGh$e!q-vRrS-;tD-27{D1rYKl*x8~7(ExJr@A<2MbLYH{nLKBhC)!za zCmjd4GVBeJCuo!sW{B<8IsL{$d>Mdmoy;%?TC~0C*s?xq*zJA{?yi%1*M06*TLr8W1E4zOi=ys(yO3%7@Q;#9Ny9q7TS?& z@~W+Mm~nT$kgn5IgJkuGp|grL>+X?#`-MPucJ>Z|s)~X77f=u6|A(4iKXQg-Jr&c* zn*0p*6M!!6RSlB9Tw=3)`zzUT#n|UWxLa>xE5ej;M=3wpyZA#mR~v2Krn(i{bIQiz zA`!B@bnqXttTcTZ>8i@7jK<<0`4Cy(y5uN}xpf-a@mfwov7-h!d^AvKf9DXPJAJB% z_xh(@bH3-B7e%yRl0EG(I*p=E>tCYKeQa*W=eezRA{-E4LsHT^`(LV4T*b<234*62 zC;r2rDfHk_Pl&D!?o#Sgoucpgh!}jX8wvjDk{1^$0+bR@OTvyWE)5hQ&x0R0Psv|M zGiYN@N38qag?n|W>MOON`U|WZ^$h72{}59R!WH4TAtY!9(O7X7ZGnH6iv-9yZSzko zk@md0;31l0aSD=eC)O>^+DPU=XT}ewj=RL9Epd7^Efend#VKD#v-_`0v*Sr3!Bm@@iFpA>#ABZQtM<)b9B=_kP%DC3z`Z212QG%;&Uzl<# z7|AtSET@$nMcYE;S&r`CqC?oGpJANUH(9MJQHqA5X*m@;c(jHj0gKF|6Mt9d$ zD!UyFQRR>)m{EaQXkp*pXN6VqHCI!a#I9XRg*;=q7&?s$Je&{+T8Jq%*% z1p%vz9t>|o81_I)jzDHdz~rwH(_wWdUK?##_<{aj*v(9-b^P=HRrK#d!yz_4{t=iAe}gpxX>U|I zj1mnlT5Up>Y28~ApEzl{vO4!#;b42cP0@nvRNo1G#P>fk&K7{J`|LMfn~Io83$ux4 zx}rdxcWVcRnS;oQfT_u4W1CNo&Sjzv>N?cVtNNkhe=b}EA?rtpX?m_NbfA#k zO@f?hXgCeltVf^n&NPGVWxi-ElLk!u@W(D7c9cWsZw;<*ZB^JYDLKC@xXcCy9@U#S zd$qys;3DIU+=y(gMrV zS=i4QpJ(w{uFE9+rpH@v^jC#VsaV^2&yJluVV z7!pA_4opd51ap2g#7DO8-nw&0A}-xCE)1W|n$;#ND+SG2|>rXI$g?*2!!R& z+RIBzQ3pFK-KWc3o0Rl6+jDdTwX|7EN!k1(>GFdooLIgC1st?}~HWDL*66g3n$tfJvn{(v+HLO@4HM>8nT!v2Szo6Dny z%d4$iW|BDN4`XA#7^0Ii)YDA0FjvtuU7V&L66 zUdiek9*fi=+gWMf4m5XYkMNr|GC}uE7_l$IEPi`)yPJzU2(%Ngv(@)_Ot(T4U|TB` z0rdyzSpjRvvetj#l*b`)nAadd=<)u_xF$pht*{g6lHC&YN#sCk7Qh z1ta5mM<=-S)}zNk@tjdW{?TYO6eM5o-y$>v3I4&id^Boz>V>J(-nu39R%nrvC15b) zadCxDsWUM}atHp>YKn_98hFt`0aLUBezf?L6Pq#cZ+&cO(E`aBJnXDsQi+$80s!O$ z;A@Y;zHvjJ>M{sSQVayd&p1UfDe%0Em>6=f?UF_*KL)dT7PMJWfndIFjyw5CN!fqm zv#Rj&FF6Xb0|RNj3->$sqRovi8m<7Pp;8E4Xk#cs2M|&%VpjoE0je1sa%ttev zNDp888|1SS*!4X3wj3yuu@t~~`6K{gQo)xE9k_64e`mnXfx{9g6u37uUW#6uo`n^q zJ=~&u_u#o}+W7iZv$}daRa}_P6$|kYDNFAE#@WD-kdTqz6qG{^uWtrD_#UYK0@zt# zK2Hrt)}zqzaWQvNgk-qq-Fy+>q@5cWN&rVYT&(pIXGssHMrx6ckV(nCHCE zgtiLRxZe)*mshg3tCCL*P}o>l)Uq)YlySK-z63gNa6YxG4>b86mX1IMnUDz-`-SVf z_UEcmtt%lEu1{d4f+-;Wt^A^p?a4mS6b~joKm(zDrV4{1!?fVgP=4D(Pu{&kqq7tD zG?k_;ZxK#F&glc=AY!e6qdMTWQvgeouvs$-tc29*e%r}ICWUZXBI%MXEh21zx;FtO z>c5j_GI)qRhwu8$A2ntDgBj|=xUj|+`XI%ceq8Ne|#n{bA9w%E? zV2c9(d>E{BCem~_susGDDiH+j+CS@4-T5XBQt{88O_6Dlm$0*8M4CWCHJJX~OD^GO z@bVz0BNa+O^9zVv;0>&qoKR|0w9H#fs}%g*!M)1f`u&SHTK=R3a@WCt0-GE**&1>fa5oPWtQs5F&Xfm zBK&9-I_tk73c$-yGV&WTellQpwhFemVja+WPwnmZlM`wXIpiu>52xSXk6D8|8lW9V zV&|U(-?_k#X?<6Ks2sJ zfw6tl0cJ0BQKj@=-uI1D#-e6<>p~#-3tOQ#Iq~-|hX)VbfSs4Ox!!ANu-^omp2;pP zDKw!i&j3~DI``=3&pW5ROk%G?de6V46D3WkrNd*s=l;w~M;)qUDE2by6b9Tw(07od zPMm593UHWUVsY{9&Mv4w7U4ZY(ZFv+jD2M&7>JnU$*6g;4v(ds4%~luLHy)Q3i4~@ zDReHc9SpafX@&-sSw}28axx5>zZu?h<5xiS>3$*DO>e9#6Brt*;j+Qi_lCx4nF)$j zNcWlzwVO%G98ud*5zmVEh{>$FS@mgwgz%&Jfttf!d;);-;lqbK@7JV%&>%FGN6>+Q z@#|87+e)uILNKGl6CzKc)(kv;U}e!|ix`vug)Gl}r7K2`i9dH7tY&vLv>g0WY zeUsJh=ex_xLI6J`WXxDEFJXg3^5*ulS}*k%2p_?+vtyu#Oax-cUC`oT?|Ua+W=jt^ zuF*gs(_wLpw0?^=HUUS}8f7}SQOhah{>E3hx8!x14V$>?Y)x2z8m&{ERC1vNA zK2)^*aA4Iq-YZ$`m*V)KWbqi?Sym03wG?}fS{|vnwM+qHQ4$u`f9=GpOX9gn(9wbV zRe|lli*|B(Ca8=N>49vI&^4&e1&jlGHdJLi*^cZ+=zqQ^>~Q5IryL>}qH2b1{T90V zaJ-G6`|gikIJS2l*@B1c`<6OaIks7Wa)8y3f8GYrKQq>UHw zSy65aSby8*$O+bVAgMBOxv^oAhcvL@T%&6=^q0ymhmc)6?=w=3uCBu_)V=0{!qU!q z;l)W&2_#i6(`AUGsu9MGpec7mHJ))hNS@Juv)@2K-LDc#_ zY^34%mqa8C&>nl0aOk#30IAb|T}27^#r5|nXKEpMXB*L{b&e3`wVo$?Dh%I*UATm7 z&ggBkm2t!ST3J|hFk?~1Wqtaj+FfJG(k$%6MnS_#y1%-P^`jW~isDqnGr$`zWP!_G zCD9i=5p*I+P+?D+zhq)RY;fMoGv(jz9qmT3^aPA!%Rt|5pIt@+?z>9PKP2u z0shSV+l91XOnkL;n%R?*@;x{(e5$A1Gn9y{l`HUtplKUa=9+L!$8NZi6wvYXNEW2< z>|PMq0$;y=y-Z6%Vb&TN7P>AdLBF~td|a)Di-QBIONW0!@D=XgE)O4GhHiQ(oGUgS z0z7h>?PFgYZyKNY-)tfjsPKP;<3GYwlv9HNC(vLX%n@oxFd*n` z?o{0~MEUvoX-N(wY$HAuP@$vbRN$;5INDZ}m2@;yrEsBn!5MJ*a$tJ;@!#WP0N{ix zrH>UD#2q4Gg65v5K}G>9jtIn;g(UY4RFMICX9c^$7CYb&?di>6LKqynn0}9{8F9M+ zqk?%B14_IGc26_N{dX$ulEKeHnf!h2FVd542~ilWZQfoAbZ;w+rI6&{z|79ihOTOs;geIT!Sr3w29aW}x-5JM{xYkae!3`aIbOiY39 zOM#OXHm)lrO<2pz&MMcGDv@@O7Mhw0JCcQTq<$|;BNr<;R{7|7op`nD{Cca3Qf1WX z6;w#K1jFegI55U45!=a1X&Hk^6f|uAL;)oT2LHWAYWpTg=Nvpa^x`H6O3|z z#7aqd7WuM*d{o$}G^fpl$eXxOui9++`dwhe2MWxDb45uh{E+X?vZGLPf=QRpH+=zs`!*P)a!MJBcY}qoJwS7V}~`h8}JA3#YoSn~{!kh|V1v`9q-z)EO$| z6E942C>u6ru+7^W=||O-ECi4@waDn7C7%Fc2NWI&UwS7u+{Obk&jb4!=y>=b>P<%% zJt-(z<*M#_we_Dgm1MnEc5(MQiWdXxSqZ`g09W0|+1KBr(q zX1DA@rTbzyy_2~;evHLLCgcUPW6I7U_oQ`NWz#IA1@+!FppOl_7-n76P;!FK-_+RD zq{BjMb#y08)k}h$jWX_RZtk@rUrI^^<)^N)^nciFT&LLNn#Q0uYj-V!f zD^9F56;Y8>YWefXAq^sBKnuhVi5yy5c7l!f@T@qdj63`$3T%7PV9d${)2!r=>(DoY zmf2WTXu^kYC*(DejFdDu;Vd|1{zu+O&ks33SKto^YQPEW@H-#!cd7(Bk~sz9NsWQD z$8sbzpH0(_7;(l4d2d?#f+YY5;H5dq|7{5%22^nF>Oj%*qvi+kzr4bQjzrh#qgQ6R1GJMPg(%oGLjgmltD`=BQi6gJ!_FSm$ri`F zx22a65CF~d=Fg6i9fG@sx6mo*Jxzs|fmgbKGpC`=OzzZx6i8IWc88 zT!DgNQBlvOaWG{Syjb9SnwwMTjBlR*-puIOL5rb`YefR2Rj4u%@cV18lpE5I zQA>E|Z4H5v`%|k~DThDr?Gz)cV9^XjHezsz!z7g@u0%0{c!Tjl`Z&}2-{CdE_gkW|3cRdya!O9+ISUiAw;tiC8< zj1zw_vMjWCu8SSW?T3&d8uwWTdTj*8$S3M<0s{YdD_n0S_}>q~4bOD*bsWX=-okQU zNt}0GBJ$m$(R`m@UkaIt4<=Q|jNYJqu$$O(o5XV+hewBCcU?WhW92QjY-s2#E^+}I zy!OfNyv;`i4Khn&bCcIHEY)rPOiO#9 zLhQciB5lTIH{Y;O4Fo~$x*B|%`!W@Z44S{B1sah0Zc;)I)HXonGE=F&B{K6Bsx z>-M1}1r4r73f{SMs+M2^DfF>c*{Q9uOvCRRH&r{XMjkhZ%-U`Gm!F2lS?^S9sx7uf z<9i$E-yp;(HtJ@deVXBiGzGS2lV5RFSh{A z>Z9b6fsPUm+d)`r1yGsRh}`9|8)-?0pdCtGQ}OUz6p34lOz7~OLUN*aQ2Ib+As+S@C~05}t%MZ>X+44diOvtiWXRFaUR zS+7>1tl&H%3bnev9xr(YGwgIwDf(xSI<+G?G=Dm zLy;sER$d~wy4DV-X#>m4-R^N<;<1~WXkMY-ME2;`IZvq}-`&(cvw^}GzV1g|zC6_X z_q8^<{62QJGPXw40+g;aE!$K3FLmn4(Q7mLU@+_E*6m-5t z*zSINFfrE&ha7G*#ir!vIFlRw zzWj#I)Bx;tJc^8(Fs{~Q@bfv5duJ7uunS)<6CpL#g$7RD6Ay)mPx^ z1_Z9`Gwv!*tlpiIl0!MUJ)bA1M~T`KNl2icpI5i!qnTL+|IP;D<)@7uB`~ocIzG}~ z*LxlP?JFG}cLm#D%iPdbB-PSbaw*T#(3%4H`mL zy(W9XaovjAXodXIC(3$waEb&`QU{D`&7=my>EzhJd40@xN8p_^XJ1*a&X?0m3L(K* z1Quj_W@iW8NQ;#J_tS_ZRJ`#;OH@cAMRU^$mi!5S#bolIxq;LLCmcaQC0M*)BF|_s>H;y^P!E=V}}0 z25QKVn{dNTJT%TWQ=Z++>KQgv+m&*SjhA1V?BP^%qW-T7%AH+~#=13_o7cWbgNa+= zXkYNhm|wCxbxEefWQS_>AMg}Bf{i?M?pE>mz!|J+C-lz-Lpb1HXH&BF!w^F2zG+Cd zC)kKsV7gPD4Q%-^ieu57$EtI0P~Bf1`+T&JBo+Ah^olXChD3C#(-rd$t~?33?`Kqm z#~_M&DTd1+j)zBv<1jvrA_GlQ5#I0WWFGO3Wx!$F#+J_&)oi!Nk8^`d^e<+Z$QEeW z_G8E<*g&3A<_yjhJM;fZ6T*e{WX-5ZkKYfTm4I2<biEZ0iY#uSx@;Gi**K#CT&n&QeAl)$zH(*Ee57XJ z{lfbCvkqu_`;`r@tc;k^y(8^%{CY3!hx8IEa@M-#n%M(BrzxU$Hn+YQR~Hm~{oF~I zuS1w`!VCw1YHt_u8FzauBzhJ9pU%!aoXU0muIx%hbs~}}bB4l_Xdsz~lFXGPv47v&*}rqHbAH!#uIqRH(B)cL?|R?o zect=IpZorPKdYsKuJdN1&~-*fTe}TSmQt81w%^j3={Ho$BGiJ*Q0JZDwFNI;I5ENc z+%p!hSbN>`J-=J`%dm#$SA(zbuk5Wa%sRZ&*?OM<>+=s}h~is!9$^haR#j-JicPXXW$jO7?oq9bR5Metsu7 zF&+=D?qdCt+=7R6s|_oqXkH=IAvaL6_ztrv7lYzHx}KOO5^_#2Z!fuisA}q}JI-Bc z7T5PYuy-AwJB2d2;oVN3=GpPHqA%Xz5xgBFqh|Tza%^mlDJLc-+ldqPs^FOK)P)OQ zj+NaLsH+|;J6AV=XH`;`%h-+OhEgxeLj)W6iMGQ8W{4eoo5XTSClX7OzFS$?$TL&D6=UzMy!-L1duvmUT? z;!8)JMRTFofPRw4JFT_yQTm^PpW{Y(&TQHl|CKX7?$Q606!Dy0E&|q;87 zfq}xWa~(gW+6xHl_0(lQ-m>eS8C-%jb7wNBM-BtEX5yPRqVy6f5S?7~jL41w( z_wl5`Ngs*$U(SyI5@dP!qUwo2gPah3?0G9Apc9C=m)6ptZ#m;U3|z}4CAkPuVIPiW zUWmKY>eYPEhPs~-6L`QKD~NfWSUY#W0N+Tlz|(K1XHNm?1P%bWMb{+<+X+~!DJv@%wzRa|Om1syi~BApTR1+r zu0M?Rzwc!ijSmLK`NzG6mBS$+kCZR`|MZW&Ta|8p9`=100Xa+0CT5BL;{)jk%Nqq{ z+^iNn(_A+Bwqjuv@%|I}GjfZuu@LAvAQPU&BixEcM|sACp!&}fWG5rW9m>oZF7>wY zdTV8r#%xDFzlV8I2X|`+%E-`$t$F6Z=eN#pS=HuX7C`?7cbR=Xle8*xtR32=1!{hi zt$CCCBnZeEjqUWb($di(A1qM~QEEmXGmMmNtIauY^L&*6HWP#;73eLO=3JF$U8GAz zp#t4`@8LIl9^&)Do;l5Y+{BWTlXGm!RwP0ma()Gux3kf$d1RO(939iac82X0MFjTq zD~fA{udlV6vg#D5LNrMUR7Uz(*ejPQCjo9G4b{5h3O9<{~%*IR2Qv)J0VreOkDDK^u4E*qXn>7MA>k2ONkOs&u#1vOG{Ho zJJ_@cJ_l{cDe%rSa7~lJ%_O|>r+bbJJZ@oVZP~zK4BW~LlSI>#IK@@~-L6MTC?)^X z;J4yUf%|)Y2#L=Cp+$rP;CE&a9D)^Uba12;?$(;@qs|C%+`8dQG$HY;$@lj~hqJOM z!rb!U$mv>~R}F$aNI@^z5%ZbA#0Ovm5ML{M40tM79}!A;PYt8~O&;Q}6^j%cmrWNG zaj8*G62rAW0(W3XmYWTA-nX81R6JJC>hA8Qx^_F10>b2Q1<)sreLFg)!Jjk=Uo7xXnX}D8n(fcA5q@2CEx3i24nlyt_00EJ|nxo3wx^;g)!$ zw(HwzF?5`SVf0@#14lS_^utw? z(0Y@%J;z>Avlixfnwrmh`~!7R z;*&1OI-XgNgK}mnZRlLa$uDyOAOW$0<9<`d@pG!o#KhR4MAL^;;C#ts2i0DR@jnbb z4rvKsiY|dq)(!fE8Q2Fv<}Xvdax}L$%&Ykr&&WWFE-d!Tf;51-4W6-ZXKT(056;_T z@=#`gP68#vRfCA~Ly)_ng{K2crPxTcDfL@#X+)!o3)teZb&YS`>PXw!Lx%V`BVJu;jbTe zl$4Z^Z@Bo}Lix^F=Ut$7bCyHvj>r^9J?Qutqk-Hnvj~~UKYvXbjvx8QM8yqQy#ZG! zfvb490#A1s`bvxZ4B`Iq*j;b~BUcU9t{McGrwCF7)^Dag?rDSn;qI4`#H@orw=T-T z-kxD#40Y>oREd<@Qh}M0G!x|j+N0DWBlbD zDulj%dLsZu_cVqiZcsWbP;i`0SE;PLs^iZ9yRK~rLZulKNmd0S__GoO(Cw|h+dhk9 z{XnhtDLO&2wk5pG%VWEExggshe=J09zp3c=?09;)Fc>718yGv%-W+kjDnq|igKBl^ zh11)VI7@%#d&dR!bG0(7Feeym;BQbIo(@sySv0)OC5*#3efi#C1h}CGy+l1=uUAiX z+^K^lc5pN(7AxJ)UBbeHH)$8xBFm5-0!{($^`lciXUG7XcTuwZ)rzNV&8-CuJ;&se zspEtQVS~0CInf&1%Fw)$;2iTnWB)D?so|pP;aDolmfk#CzL8fu0_sZ{c-kSgh(Z@O z4I}g0s-3q(vOK!Nf$2j|7>YR8{b`^nXAi2mp?CO^450Gq zVjx03esr9}V%^D+l$0zV7Oq4P5tsK}#2t&f37ja!A~}rZVcf(a3===PxpKgE{B;ll z(~*ZBLMKB!f@T%7;eZG1V;nKYQE0$8d@f~K zg+L)HK)eG;MyY_*WQPT59wKJV{Q@vKX-RBrZx;u)MI7`lB`IAOmB;lgbQY&*L^mMT zC5dKnV`=riyh-u|yEDM5w;|I=!LeEc;${l6a!^)9T)TGg{oS<^N@GNxvjr6RCLkC^ zZ{F<2DiwlY7OHze#7x~y{@r7bJ5OHZf6E&IyoW%59FGIFiK~e}fu3Y3Bxp$@nUc5* z^nVRMxXmoX!(vvea2fN(-B9DAB%+{QL)WiD!!Nu!od4%{0Q7lGP=nsU0_Tf6K zGxzUH;S?_4am6AJ4j*Zq_nkjq*4+2+g8JAVS6(sM;}d?w-8zuI2#~uX;H@h~UAU<3 zTAg{widdbPKFNMq03p#@r!AR`30Bn9v=m5TPHIBprqt5qv5`{$kl7nw%ao&L1<*MJ zRD~og46|V&ie^f7k=$3w0T$tkHbyDJ!6Z9)vWHSB4j2=B;>UdYLD#5$V4(_=_!X5k z;uTwve$;@Xa_hpKgoJjW4NLH74q{#yCz;QuwmR6POe@aOG}WFD{9P+TvoVAqbq=z$ zPT~G7gh3xUosEb#XU-g(v?`#CQ;(d{(a{lKwMx&c0KnsqukXzRIdG<^s3-w{Nu2>| zp&WR}+^ET~HF#Mmy($?6Dar8KT2NSJr$+_Jm| zL^gQ#h5!Xb?JQ-#?`{t=RUw@v^(dAk9he{}Me-U)X zLxXLbFH2;KtxMK6&{|J?;G0mpimzCqLqHekLjm zv)H^tFg5Q0>qrjFc0#YxDoGg~!2_C{m7Hr0gw`1A5gvp-2S2r~W8)aO(`bj8f^|xX z1S#T(52Jj1A{TKiD@%Dty#D+lXtu-fdqiZUy_+gxt`M4GlQ$Fc?u(|6-Q$r~Beyl- z9kPx4fjGe@7L?^ZbQ2(MmVmJIYyf##*i+7j9&9cYif>%yWo5Txs)b_epM@DN3~fjd z-UMp^d?3a!MdTVl^LAhn1?nuKrw>(&P@vKfE_mBoTW>VzlJt~WMnE4#_?03MGF?+Y z{tIgNrATZ`;b$uaaHJHa^AZ>XXY>n-Z)KK&aB@56c;7okf|bH19ls|TsfO+6&T=-d z7!p-!EIzb#e4FQ+`4&;`uGyo6=27-!3*{FsA$ACMvlhhD=8YJcCW}h|_sYTyU=eL( z>-_;BdeQ|$nKzG}tH*RzUcPnz3w!`=0|PR^KuZP9rdvrg*J|HBnhZ=kLIRt2HCG~v z^Wg(^FJ2e{5x+GV+FT!7V8pY>VC0#N)K4+{Ja#srpb=|RO0Hi=+#m=KsqK2`vhD#PHGW`WZoA+g!p*EbB@ zGF~yupEC(deg6wQY+M>K)pN_mJf=|Iz|SD;SqyyW>|Bn88|c?ufU$hKri%qByLW~# z)?Y<8$5UbT_I{|(2oMa3*Yz$}Y)!al&60T_i#?Gh0>{yjrAwC*Ckfido=wSEO0rx2 z08|6|A0&m-8MpQlzTU>i^AJ)hKKnp#iYItJ!+?fWzCHte*2aAQ#mG8pr4HfggqqZ* zU3D7xI3Y;HZ$RSh^By@C6hzTax?+_NPr<7t&>AO8&0{Zx>$9-!q1J$3D8?2?yW}S^_{QA?-MJ1M_j+Z9P3#$E(CrZ$Lqh zrMn&b1museeGPmA28V}FU%GUuKbO%MQOODz&+gCGkfd&>58>;otG81rh9HFAS-G6Jc8BEE@iG@vF#c^Z@y@)XL5Th}+i;drJuly@IW!G?hV9}w}DqBu8Lqbu45 z&WvJuBY|rs@{fPt<;V|&hu4W?(hzPL< zDTc?PCecjZVido4C~9j#GK&rlew?||-BXN4=$7cg}M z5HX4X?tXC2s_K2soW$ z=!H=OmDEDf6q8D+p$CD;20#|XN@=2F;~|VY{^ta90!Qn>4?$FNEK4M~~m$>i(r-NyG5BZ^4k0Qw9$~BJ>DcnDI|AWK>_+3!Odj>99r|v2fCg zb_W`!NnM1IJ=myB3RCiiF!vn5K5r)c0^tv+W&xST%XDwxaVM8Kd`(47n$xZ{=ek*> zasx8T!Ph7wcrE(D)dT@XvEgGBtOR_-`@^1(Y#W#2LXB4 z0af{Zl^UUQB~fiV2{kY++T=u;7%BL3VWL%@&(Yp@=>nnw-^Bt?oe~Qoa6UBinS1jd zNM`f^YJvJe8}g1PfEAyEh#U%DE<{!u_aQ_-fM2P~uwbLNTYkG_1uWru(VT6Tgzv>_ zLPS@c9+WxS@a{A%Z%<9h)P`cpWbM8Fj#&9G>xlpP+jM^ab1GI7?G}?RFML4|vqjrb K>jB$3@P7cMBz7+V diff --git a/labs/lab_01/example/images/sum.png b/labs/lab_01/example/images/sum.png index 458ee0d9a4ebc2a1f34ed3e4c955f3a225e98219..0fa7b537fca36ae62f09180eae58894743264cc4 100644 GIT binary patch literal 31068 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ͭ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 From 7c69c43926644f3213b0084689cf9cf60e60964b Mon Sep 17 00:00:00 2001 From: Evgenii-afk <69784610+Evgenii-afk@users.noreply.github.com> Date: Sun, 28 Sep 2025 20:04:54 +0300 Subject: [PATCH 04/26] add png --- labs/lab_01/example/Untitled.md | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) diff --git a/labs/lab_01/example/Untitled.md b/labs/lab_01/example/Untitled.md index 13bf6f3..d57b228 100644 --- a/labs/lab_01/example/Untitled.md +++ b/labs/lab_01/example/Untitled.md @@ -46,9 +46,7 @@ plt.show() ``` -```python - -``` +![](images\sum.png) 1.3 произведение эллементов @@ -88,9 +86,7 @@ plt.savefig('mult.png') plt.show() ``` -```python - -``` +![](images\mult.png) 1.6. поиск минимума простым перебором @@ -132,9 +128,7 @@ plt.savefig('min.png') plt.show() ``` -```python - -``` +![](images\min.png) 1.4. вычисление полинома методом Горнера @@ -176,6 +170,4 @@ plt.savefig('horn.png') plt.show() ``` -```python - -``` +![](images\horn.png) From d263b6e92b4a014bb0114933b43b7d1f3a2ac9a5 Mon Sep 17 00:00:00 2001 From: Evgenii-afk <69784610+Evgenii-afk@users.noreply.github.com> Date: Sun, 28 Sep 2025 20:06:28 +0300 Subject: [PATCH 05/26] same --- labs/lab_01/example/Untitled.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/labs/lab_01/example/Untitled.md b/labs/lab_01/example/Untitled.md index d57b228..9c00bd6 100644 --- a/labs/lab_01/example/Untitled.md +++ b/labs/lab_01/example/Untitled.md @@ -46,7 +46,7 @@ plt.show() ``` -![](images\sum.png) +![](images/sum.png) 1.3 произведение эллементов @@ -86,7 +86,7 @@ plt.savefig('mult.png') plt.show() ``` -![](images\mult.png) +![](images/mult.png) 1.6. поиск минимума простым перебором @@ -128,7 +128,7 @@ plt.savefig('min.png') plt.show() ``` -![](images\min.png) +![](images/min.png) 1.4. вычисление полинома методом Горнера @@ -170,4 +170,4 @@ plt.savefig('horn.png') plt.show() ``` -![](images\horn.png) +![](images/horn.png) From 9f2ef072b5b2c751168794f69f167c508acaf71e Mon Sep 17 00:00:00 2001 From: po4k Date: Sun, 28 Sep 2025 21:05:01 +0300 Subject: [PATCH 06/26] add task 2 --- labs/lab_01/example/Untitled.md | 57 +++++++++++++++++++++++++++- labs/lab_01/example/images/matr.png | Bin 0 -> 26778 bytes 2 files changed, 56 insertions(+), 1 deletion(-) create mode 100644 labs/lab_01/example/images/matr.png diff --git a/labs/lab_01/example/Untitled.md b/labs/lab_01/example/Untitled.md index 9c00bd6..7ee4501 100644 --- a/labs/lab_01/example/Untitled.md +++ b/labs/lab_01/example/Untitled.md @@ -170,4 +170,59 @@ plt.savefig('horn.png') plt.show() ``` -![](images/horn.png) +Задание 2 + +```python +import random, usage_time +import matplotlib.pyplot as plt + + +def matrix_mult(matrix_a: list, matrix_b: list): + matrix_c = [ + [0 for _ in range(len(matrix_a))] + for _ in range(len(matrix_a)) + ] + + for y in range(len(matrix_a)): + for x in range(len(matrix_a)): + num = 0 + for i in range(len(matrix_a)): + num += matrix_a[y][i] * matrix_b[i][x] + matrix_c[y][x] = num + print(len(matrix_a)) + return matrix_c + + +items = range(1, 10**2 * (20 - 6), 100) +func = usage_time.get_usage_time()(matrix_mult) +times = [ + func( + [ + [ + random.randint(1, 3) + for _ in range(n) + ] + for _ in range(n) + ], + [ + [ + random.randint(4, 6) + for _ in range(n) + ] + for _ in range(n) + ] + ) + for n in items +] + +fig = plt.plot(items, times, 'bo-') +ax = plt.gca() + +plt.title('The execution time of the get matrix multiplication of list numbers algorithm') +ax.set_xlabel('Number of elements') +ax.set_ylabel('Time, sec') +plt.savefig('matr.png') +plt.show() +``` + +![](images/matr.png) diff --git a/labs/lab_01/example/images/matr.png b/labs/lab_01/example/images/matr.png new file mode 100644 index 0000000000000000000000000000000000000000..d337bdd13289ce943f4a037b97e93d18344d1ae9 GIT binary patch literal 26778 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 Itv!GE7h!`ak^lez literal 0 HcmV?d00001 From a347329cf92a72fb0aa354eaa76b3cc0514d3eb7 Mon Sep 17 00:00:00 2001 From: Evgenii-afk <69784610+Evgenii-afk@users.noreply.github.com> Date: Sun, 28 Sep 2025 21:07:07 +0300 Subject: [PATCH 07/26] Update Untitled.md --- labs/lab_01/example/Untitled.md | 1 + 1 file changed, 1 insertion(+) diff --git a/labs/lab_01/example/Untitled.md b/labs/lab_01/example/Untitled.md index 7ee4501..6db47da 100644 --- a/labs/lab_01/example/Untitled.md +++ b/labs/lab_01/example/Untitled.md @@ -169,6 +169,7 @@ plt.grid(True) plt.savefig('horn.png') plt.show() ``` +![](images/horn.png) Задание 2 From e0cd3d6501749ea69cf22687d623a48a7727c12a Mon Sep 17 00:00:00 2001 From: po4k Date: Mon, 29 Sep 2025 09:18:33 +0300 Subject: [PATCH 08/26] =?UTF-8?q?=D0=B4=D0=BE=D0=B1=D0=B0=D0=B2=D0=B8?= =?UTF-8?q?=D0=BB=20=D1=82=D0=B5=D0=BE=D1=80=D0=B8=D1=8E?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- labs/lab_01/example/Untitled.md | 63 +++++++++++++++++++++++++++++++++ 1 file changed, 63 insertions(+) diff --git a/labs/lab_01/example/Untitled.md b/labs/lab_01/example/Untitled.md index 6db47da..170e551 100644 --- a/labs/lab_01/example/Untitled.md +++ b/labs/lab_01/example/Untitled.md @@ -227,3 +227,66 @@ plt.show() ``` ![](images/matr.png) + + +## Контрольные вопросы по вычислительной сложности алгоритмов + +1. Вычислительная сложность алгоритма — это характеристика количества ресурсов (времени и памяти), которые требуются алгоритму для обработки данных в зависимости от размера входа. Анализ сложности важен для оценки эффективности алгоритма и прогноза его поведения при большом объеме данных. +2. Время выполнения — сколько времени требуется алгоритму для обработки входных данных. Пространство (память) — сколько памяти алгоритм использует. Иногда приходится жертвовать временем ради уменьшения памяти (например, жадные алгоритмы) или наоборот — использовать больше памяти для ускорения работы (например, хеш-таблицы). +3. Асимптотический анализ изучает поведение алгоритма при больших объемах данных, избавляясь от постоянных и малозначимых факторов. Это удобнее, чем точные замеры в наносекундах, которые сильно зависят от конкретного оборудования и условий выполнения. +4. Нотация «О-большое» (Big O) описывает верхнюю границу времени или памяти, которую может потребовать алгоритм в худшем случае при росте объема данных. +5. Классы сложности (в порядке возрастания): +| Класс сложности | Описание | Пример алгоритма | +| :-- | :-- | :-- | +| O(1) | Константная | Доступ к элементу по индексу | +| O(log n) | Логарифмическая | Бинарный поиск | +| O(n) | Линейная | Простое сканирование массива | +| O(n log n) | Линейно-логарифмическая | Быстрая сортировка (QuickSort) | +| O(n²) | Квадратичная | Сортировка пузырьком | +| O(2ⁿ) | Экспоненциальная | Наивное вычисление Фибоначчи | + +6. Сложность фрагментов кода: + +- Простой цикл от 0 до n — O(n). +- Два вложенных цикла от 0 до n — O(n²). +- Цикл с удвоением счетчика (i = i * 2) — O(log n). +- Цикл с делением счетчика на 2 (i = i / 2) — O(log n). +- Два независимых цикла подряд — O(n + m), при m=n — O(n). +- Рекурсивная функция, вызывающая себя дважды — O(2ⁿ). + +7. Сложность в худшем, среднем и лучшем случае отличается по объему потребляемых ресурсов для разных входных данных. Например, QuickSort имеет O(n²) в худшем (плохой выбор опорного элемента) и O(n log n) в среднем и лучшем. +8. Пространственная сложность — количество дополнительной памяти, используемой алгоритмом. Для рекурсивных функций учитывается память стека вызовов, равная глубине рекурсии. +9. При очень малых n алгоритм с O(2ⁿ) может быть быстрее, чем O(n³), так как для маленьких n экспонента не успеет «выстрелить». Однако для средних и больших n O(n³) рациональнее из-за экспоненциального роста. +10. Временная сложность операций: +| Операция | Сложность | +| :-- | :-- | +| Поиск в неотсортированном массиве | O(n) | +| Поиск в отсортированном массиве | O(log n) | +| Вставка в начало связного списка | O(1) | +| Вставка в хеш-таблицу (ср.случай) | O(1), (худший) O(n) | +| Поиск минимума в мин-куче | O(1) | + +11. Сравнение сортировок: + +- QuickSort: средний O(n log n), худший O(n²), зависит от выбора опорного элемента. +- MergeSort: всегда O(n log n), но из-за дополнительной памяти и копирования в практике медленнее. +- Insertion Sort: эффективнее MergeSort на почти отсортированных или очень маленьких массивах. + +12. Пространственно-временная дилемма — компромисс между временем и памятью, например, использование хеш-таблиц (больше памяти, меньше времени) vs. обход без дополнительной памяти (дольше). +13. NP-полнота — класс задач, решение которых можно проверить за полиномиальное время, но неизвестно, можно ли их решить за полиномиальное время. Класс P — задачи, решаемые за полиномиальное время. +14. Полиномиальное решение одной NP-полной задачи означает, что все NP-полные задачи можно быстро решить — важнейшая проблема теории алгоритмов (P=NP?). +15. NP-полноту доказывают сведением задачи к уже известной NP-полной задаче — так называемое "сведение по Карпу". +16. Омега (Ω) — нижняя оценка, тета (Θ) — точная оценка. В отличии от O, они дают соответственно минимум или точный порядок роста. +17. Сложность определяется по наибольшему слагаемому, так как при больших n остальные становятся несущественными. Константы отбрасываются для удобства анализа. +18. Не всегда. При малых n O(n) может быть быстрее O(log n) из-за констант и накладных расходов. +19. Для анализа можно предложить конкретный код. +20. Поиск двух чисел с суммой X в отсортированном массиве: + +- Используем два указателя — один слева, другой справа. +- Если сумма больше X — сдвигаем правый указатель, иначе левый. +- Сложность O(n), память O(1). +- Эффективнее чем полный перебор O(n²). + +21. Улучшение алгоритма: + +- Пример: из O(n²) сделать O(n) с помощью хеш-таблицы для поиска пар чисел. From 91b22e48d0336f2338e67789b91041e79478c4e9 Mon Sep 17 00:00:00 2001 From: Evgenii-afk <69784610+Evgenii-afk@users.noreply.github.com> Date: Mon, 29 Sep 2025 09:25:04 +0300 Subject: [PATCH 09/26] =?UTF-8?q?=D0=B4=D0=BE=D0=B1=D0=B0=D0=B2=D0=B8?= =?UTF-8?q?=D0=BB=20=D1=82=D0=B0=D0=B1=D0=BB=D0=B8=D1=87=D0=BA=D1=83?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- labs/lab_01/example/Untitled.md | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/labs/lab_01/example/Untitled.md b/labs/lab_01/example/Untitled.md index 170e551..fe4e175 100644 --- a/labs/lab_01/example/Untitled.md +++ b/labs/lab_01/example/Untitled.md @@ -258,13 +258,14 @@ plt.show() 8. Пространственная сложность — количество дополнительной памяти, используемой алгоритмом. Для рекурсивных функций учитывается память стека вызовов, равная глубине рекурсии. 9. При очень малых n алгоритм с O(2ⁿ) может быть быстрее, чем O(n³), так как для маленьких n экспонента не успеет «выстрелить». Однако для средних и больших n O(n³) рациональнее из-за экспоненциального роста. 10. Временная сложность операций: + | Операция | Сложность | -| :-- | :-- | -| Поиск в неотсортированном массиве | O(n) | -| Поиск в отсортированном массиве | O(log n) | -| Вставка в начало связного списка | O(1) | -| Вставка в хеш-таблицу (ср.случай) | O(1), (худший) O(n) | -| Поиск минимума в мин-куче | O(1) | +| :--: | :---: | +| Поиск в неотсортированном массиве | O(n) | +| Поиск в отсортированном массиве | O(log n) | +| Вставка в начало связного списка | O(1) | +| Вставка в хеш-таблицу (ср.случай) | O(1), (худший) O(n) | +| Поиск минимума в мин-куче | O(1) | 11. Сравнение сортировок: From aa4cf77bde4d1db0265f9810191f63db69376927 Mon Sep 17 00:00:00 2001 From: po4k Date: Mon, 29 Sep 2025 09:36:29 +0300 Subject: [PATCH 10/26] =?UTF-8?q?=D0=B4=D0=BE=D0=B1=D0=B0=D0=B2=D0=B8?= =?UTF-8?q?=D0=BB=20=D1=86=D0=B5=D0=BB=D0=B8=20=D0=B8=20=D0=B2=D1=8B=D0=B2?= =?UTF-8?q?=D0=BE=D0=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- labs/lab_01/example/Untitled.md | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/labs/lab_01/example/Untitled.md b/labs/lab_01/example/Untitled.md index fe4e175..5600e1e 100644 --- a/labs/lab_01/example/Untitled.md +++ b/labs/lab_01/example/Untitled.md @@ -12,6 +12,10 @@ jupyter: name: python3 --- +##Цель работы +Целью данной лабораторной работы является приобретение практических навыков эмпирического анализа временной сложности алгоритмов. Это включает проведение серии экспериментальных замеров времени работы различных алгоритмов при изменении размера входных данных, построение графиков зависимости времени от объема данных, а также проведение теоретического анализа и сопоставление полученных эмпирических результатов с теоретическими оценками временной сложности. + + 1.2 сумма ```python @@ -291,3 +295,15 @@ plt.show() 21. Улучшение алгоритма: - Пример: из O(n²) сделать O(n) с помощью хеш-таблицы для поиска пар чисел. + + +## Выводы по лабораторной работе + +В ходе лабораторной работы были успешно реализованы замеры времени работы алгоритмов для различных функций и операций на случайных данных разного объема. Полученные эмпирические графики временных затрат в целом соответствуют ожидаемым теоретическим оценкам асимптотической сложности алгоритмов. + +Эксперимент подтвердил, что для алгоритмов с разной сложностью рост времени их исполнения при возрастании размера входных данных соответствует классификации: от константной и линейной до квадратичной и кубической. По мере увеличения объема данных различия во временных сложностях становятся все более очевидными. + +Эмпирический анализ показал важность учета практических особенностей исполнения, таких как накладные расходы системы и случайные отклонения времени, что требует усреднения результатов по нескольким запускам. + +Таким образом, лабораторная работа продемонстрировала применение эмпирического подхода для оценки временной сложности алгоритмов, что является важным дополнением к теоретическому анализу и помогает лучше понять их поведение на практике. + From 356de463babad638be9b45fb9ef09b2a3447cafa Mon Sep 17 00:00:00 2001 From: Evgenii-afk <69784610+Evgenii-afk@users.noreply.github.com> Date: Mon, 29 Sep 2025 09:37:46 +0300 Subject: [PATCH 11/26] =?UTF-8?q?=D0=B8=D1=81=D0=BF=D1=80=D0=B0=D0=B2?= =?UTF-8?q?=D0=B8=D0=BB=20=D1=80=D0=B0=D0=B7=D0=BC=D0=B5=D1=82=D0=BA=D1=83?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- labs/lab_01/example/Untitled.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/labs/lab_01/example/Untitled.md b/labs/lab_01/example/Untitled.md index 5600e1e..98ea346 100644 --- a/labs/lab_01/example/Untitled.md +++ b/labs/lab_01/example/Untitled.md @@ -12,7 +12,8 @@ jupyter: name: python3 --- -##Цель работы +## Цель работы + Целью данной лабораторной работы является приобретение практических навыков эмпирического анализа временной сложности алгоритмов. Это включает проведение серии экспериментальных замеров времени работы различных алгоритмов при изменении размера входных данных, построение графиков зависимости времени от объема данных, а также проведение теоретического анализа и сопоставление полученных эмпирических результатов с теоретическими оценками временной сложности. From e7f7c9fda80d386ef6250e67beda384ebf5dbe15 Mon Sep 17 00:00:00 2001 From: po4k Date: Sun, 5 Oct 2025 23:36:39 +0300 Subject: [PATCH 12/26] =?UTF-8?q?=D0=BB=D0=B0=D0=B1=D0=B0=202=2050%?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- labs/lab_01/example/Untitled.md | 2 +- labs/lab_01/example/Untitled1.md | 9 + labs/lab_01/example/mult.png | Bin 0 -> 30980 bytes labs/lab_02/var6/Untitled.md | 313 +++++++++++++++++++++++++++++++ labs/lab_02/var6/comb.jpeg | Bin 0 -> 4109 bytes labs/lab_02/var6/comb_n1.png | Bin 0 -> 34984 bytes labs/lab_02/var6/usage_time.py | 129 +++++++++++++ 7 files changed, 452 insertions(+), 1 deletion(-) create mode 100644 labs/lab_01/example/Untitled1.md create mode 100644 labs/lab_01/example/mult.png create mode 100644 labs/lab_02/var6/Untitled.md create mode 100644 labs/lab_02/var6/comb.jpeg create mode 100644 labs/lab_02/var6/comb_n1.png create mode 100644 labs/lab_02/var6/usage_time.py diff --git a/labs/lab_01/example/Untitled.md b/labs/lab_01/example/Untitled.md index 98ea346..6882abb 100644 --- a/labs/lab_01/example/Untitled.md +++ b/labs/lab_01/example/Untitled.md @@ -65,7 +65,7 @@ import matplotlib.pyplot as plt def multiplication_nums(v: list): - mult = 1 + mult = 1.0 for num in v: mult *= num return mult diff --git a/labs/lab_01/example/Untitled1.md b/labs/lab_01/example/Untitled1.md new file mode 100644 index 0000000..01f385f --- /dev/null +++ b/labs/lab_01/example/Untitled1.md @@ -0,0 +1,9 @@ +--- +jupyter: + jupytext: + text_representation: + extension: .md + format_name: markdown + format_version: '1.3' + jupytext_version: 1.17.3 +--- diff --git a/labs/lab_01/example/mult.png b/labs/lab_01/example/mult.png new file mode 100644 index 0000000000000000000000000000000000000000..116927c3df5abc33b758bd3e26944c842a54c082 GIT binary patch literal 30980 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 1 или были перестановки: + - Сравнить элементы на расстоянии gap, при необходимости поменять + - Уменьшить gap (gap = gap / 1.3) +- Конец + +# 4. Псевдокод сортировки расчесткой + +```python +def comb_sort(arr): + gap = len(arr) + shrink = 1.247 # оптимальный коэффициент + sorted = False + + while not sorted: + gap = int(gap / shrink) + if gap <= 1: + gap = 1 + sorted = True + i = 0 + while i + gap < len(arr): + if arr[i] > arr[i + gap]: + arr[i], arr[i + gap] = arr[i + gap], arr[i] + sorted = False + i += 1 + return arr + +``` + +# 5. Достоинства и недостатки + +**Достоинства:** + +- Быстрее пузырьковой сортировки благодаря уменьшению инвертированных пар с большим шагом. +- Простая реализация. +- Работает на месте, не требует дополнительной памяти. + +**Недостатки:** + +- Неустойчивая сортировка. +- Сложность в худшем случае близка к $O(n^2)$, что медленнее более сложных алгоритмов (быстрой или поразрядной сортировки). +- Эффективность зависит от коэффициента уменьшения gap (обычно 1.3). + +*** + +# 6. Реализовать алгоритмы сортировки согласно номеру индивидуального варианта. + +```python +import random +import usage_time +import matplotlib.pyplot as plt +import numpy as np + +def comb_sort(arr): + # ваша функция сортировки + gap = len(arr) + shrink = 1.247 + sorted = False + while not sorted: + gap = int(gap / shrink) + if gap <= 1: + gap = 1 + sorted = True + i = 0 + while i + gap < len(arr): + if arr[i] > arr[i + gap]: + arr[i], arr[i + gap] = arr[i + gap], arr[i] + sorted = False + i += 1 + return arr + +%store comb_sort +``` + +# 7 Протестировать корректность реализации алгоритма +# 8 Провести ручную трассировку алгоритма + +```python +def quick_comb_sort_debug(arr): + gap = len(arr) + shrink = 1.247 + step = 0 + + print(f"Начало: {arr}") + + while True: + gap = max(1, int(gap / shrink)) + step += 1 + print(f"\nШаг {step}, gap={gap}:") + + swapped = False + for i in range(len(arr) - gap): + if arr[i] > arr[i + gap]: + arr[i], arr[i + gap] = arr[i + gap], arr[i] + swapped = True + print(f" Меняем {arr[i+gap]}↔{arr[i]}: {arr}") + + if gap == 1 and not swapped: + break + + print(f"\nФинальный результат: {arr}") + return arr + +# Быстрая проверка +test = [6, 2, 8, 1, 5, 3] +print("Быстрая проверка сортировки:") +quick_comb_sort_debug(test.copy()) +``` + +# Провести сравнение указанных алгоритмов сортировки массивов, содержащих n1, n2, n3 и n4 элементов. +# Каждую функцию сортировки вызывать трижды: для сортировки упорядоченного массива, массива, упорядоченного в обратном порядке и неупорядоченного массива. Сортируемая последовательность для всех методов должна быть одинаковой (сортировать копии одного массива). +# Проиллюстрировать эффективность алгоритмов сортировок по заданному критерию. Построить диаграммы указанных зависимостей. + +```python +sizes = [1000, 5000, 10000, 100000] + +# Типы массивов +def generate_arrays(size): + """Генерирует три типа массивов одного размера""" + # Упорядоченный массив + sorted_arr = list(range(size)) + + # Обратный порядок + reversed_arr = list(range(size, 0, -1)) + + # Случайный массив + random_arr = [random.randint(1, size * 10) for _ in range(size)] + + return { + 'sorted': sorted_arr, + 'reversed': reversed_arr, + 'random': random_arr + } + +# Измеряем время выполнения +func = usage_time.get_usage_time(ndigits=6)(comb_sort) + +# Словарь для хранения результатов +results = { + 'sorted': [], + 'reversed': [], + 'random': [] +} + +print("🔍 ИЗМЕРЕНИЕ ВРЕМЕНИ СОРТИРОВКИ РАСЧЕСКОЙ") +print("=" * 70) + +for size in sizes: + print(f"\n📊 Размер массива: {size} элементов") + print("-" * 50) + + # Генерируем массивы одного набора данных + arrays = generate_arrays(size) + + for array_type, arr in arrays.items(): + # Сортируем копию массива + time_taken = func(arr.copy()) + results[array_type].append(time_taken) + + print(f" {array_type:>8}: {time_taken:.6f} сек") + +# ВИЗУАЛИЗАЦИЯ РЕЗУЛЬТАТОВ + +# 1. График по типам массивов для каждого размера +plt.figure(figsize=(15, 10)) + +# Подграфик 1: Время для разных типов массивов +plt.subplot(2, 2, 1) +x_pos = np.arange(len(sizes)) +width = 0.25 + +plt.bar(x_pos - width, results['sorted'], width, label='Упорядоченный', alpha=0.8) +plt.bar(x_pos, results['reversed'], width, label='Обратный порядок', alpha=0.8) +plt.bar(x_pos + width, results['random'], width, label='Случайный', alpha=0.8) + +plt.xlabel('Размер массива') +plt.ylabel('Время, секунды') +plt.title('Время сортировки для разных типов массивов') +plt.xticks(x_pos, sizes) +plt.legend() +plt.grid(True, alpha=0.3) + +# Подграфик 2: Линейный график +plt.subplot(2, 2, 2) +for array_type, times in results.items(): + plt.plot(sizes, times, 'o-', linewidth=2, markersize=6, label=array_type) + +plt.xlabel('Размер массива') +plt.ylabel('Время, секунды') +plt.title('Зависимость времени от размера массива') +plt.xscale('log') +plt.yscale('log') +plt.legend() +plt.grid(True, alpha=0.3) + +# Подграфик 3: Отношение времени для разных типов +plt.subplot(2, 2, 3) +ratios_reversed = [rev/srt for srt, rev in zip(results['sorted'], results['reversed'])] +ratios_random = [rnd/srt for srt, rnd in zip(results['sorted'], results['random'])] + +plt.plot(sizes, ratios_reversed, 's-', label='Обратный/Упорядоченный') +plt.plot(sizes, ratios_random, 'o-', label='Случайный/Упорядоченный') +plt.axhline(y=1, color='red', linestyle='--', alpha=0.5) + +plt.xlabel('Размер массива') +plt.ylabel('Отношение времени') +plt.title('Относительная эффективность') +plt.legend() +plt.grid(True, alpha=0.3) + +# Подграфик 4: Таблица результатов +plt.subplot(2, 2, 4) +plt.axis('off') + +# Создаем таблицу +table_data = [] +headers = ['Размер'] + [f'{size}' for size in sizes] + +for array_type in ['sorted', 'reversed', 'random']: + row = [array_type] + [f'{time:.4f}' for time in results[array_type]] + table_data.append(row) + +table = plt.table(cellText=table_data, + colLabels=headers, + cellLoc='center', + loc='center', + bbox=[0, 0, 1, 1]) + +table.auto_set_font_size(False) +table.set_fontsize(10) +table.scale(1, 2) + +plt.title('Таблица результатов (секунды)') + +plt.tight_layout() +plt.show() + +# 2. Отдельные графики для каждого типа массива +plt.figure(figsize=(15, 5)) + +colors = {'sorted': 'green', 'reversed': 'red', 'random': 'blue'} + +for i, array_type in enumerate(['sorted', 'reversed', 'random'], 1): + plt.subplot(1, 3, i) + plt.plot(sizes, results[array_type], 'o-', color=colors[array_type], + linewidth=2, markersize=8) + + # Добавляем значения на точки + for size, time in zip(sizes, results[array_type]): + plt.annotate(f'{time:.4f}с', (size, time), + textcoords="offset points", xytext=(0,10), + ha='center', fontsize=8) + + plt.xlabel('Размер массива') + plt.ylabel('Время, секунды') + plt.title(f'Тип: {array_type}') + plt.grid(True, alpha=0.3) + +plt.tight_layout() +plt.show() + +# ВЫВОД СТАТИСТИКИ +print("\n📈 СТАТИСТИЧЕСКИЙ АНАЛИЗ") +print("=" * 70) + +for array_type in ['sorted', 'reversed', 'random']: + times = results[array_type] + print(f"\n{array_type.upper():>15}:") + for size, time in zip(sizes, times): + print(f" {size:6d} эл.: {time:8.4f} сек") + + # Вычисляем коэффициент роста + if len(times) > 1: + growth = times[-1] / times[0] + print(f" Рост времени ({sizes[-1]}/{sizes[0]}): {growth:.2f}x") + +# Сравнение эффективности +print(f"\n⚡ СРАВНЕНИЕ ЭФФЕКТИВНОСТИ:") +print(f"Упорядоченный массив сортируется в {results['reversed'][-1]/results['sorted'][-1]:.2f} раза медленнее") +print(f"Случайный массив сортируется в {results['random'][-1]/results['sorted'][-1]:.2f} раза медленнее") +``` diff --git a/labs/lab_02/var6/comb.jpeg b/labs/lab_02/var6/comb.jpeg new file mode 100644 index 0000000000000000000000000000000000000000..5fc01470e5d5efafb7cb2056865bdd9d5c40cc90 GIT binary patch literal 4109 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 literal 0 HcmV?d00001 diff --git a/labs/lab_02/var6/comb_n1.png b/labs/lab_02/var6/comb_n1.png new file mode 100644 index 0000000000000000000000000000000000000000..c7e55284b9da236d19fb04d55c432b1f79d96d76 GIT binary patch literal 34984 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 literal 0 HcmV?d00001 diff --git a/labs/lab_02/var6/usage_time.py b/labs/lab_02/var6/usage_time.py new file mode 100644 index 0000000..077358b --- /dev/null +++ b/labs/lab_02/var6/usage_time.py @@ -0,0 +1,129 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +"""Usage Time + +Project: TryPython +A collection of educational materials for learning the Python + +Author: Alexander Krasnikov aka askras + +License: BSD 3 clause +""" + +import functools +import timeit +import typing + + +def get_usage_time( + *, number: int = 1, setup: str = 'pass', ndigits: int = 3 +) -> typing.Callable: + """Decorator for measuring the speed of the function (in seconds) + + Parameters + ---------- + number : int, optional + Number of code repetitions. + setup : str, optional + Code executed once before timing. + ndigits : int, optionalgit status + Number of decimal places in the returned value. + + Returns + ------- + decorator: typing.Callable + Decorator for measuring the time of the function in seconds. + + See Also + -------- + timeit + Measure execution time of small code snippets. + + References + ---------- + [1] timeit documentation : https://docs.python.org/3/library/timeit.html + + Examples + -------- + Decorating an existing function: + + >>> import time + >>> def sleep_func(n): + ... time.sleep(n) + ... return n + ... + >>> get_usage_time_sleep_func = get_usage_time()(sleep_func) + >>> time_sleep_func = get_usage_time_sleep_func(2) + >>> print(f'The function was executed for {time_sleep_func} seconds') + The function was executed for 2.0 seconds + >>> get_usage_time(number=5)(sleep_func)(4) + 4.0 + + Measuring the running time of a function for different parameter values: + + >>> import time + >>> def sleep_func(n): + ... time.sleep(n) + ... return n + ... + >>> for n in range(1,4): + ... get_usage_time_sleep_func = get_usage_time(number=2)(sleep_func) + ... print(get_usage_time_sleep_func(n)) + 1.0 + 2.0 + 3.0 + + Using the `setup` option: + + >>> import time + >>> def sleep_func(n): + ... time.sleep(n) + ... return n + ... + >>> setup = 'print("Start setup"); time.sleep(10); print("End setup")' + >>> get_usage_time_sleep_func = get_usage_time(setup=setup)(sleep_func) + >>> print(get_usage_time_sleep_func(3)) + Start setup + End setup + 3.0 + + Decoding the generated function: + + >>> import time + >>> @get_usage_time(number=2, setup='print("Start");', ndigits=0) + ... def sleep_func(n): + ... time.sleep(n) + ... return n + ... + >>> time_sleep_func = sleep_func(3) + Start + >>> print(time_sleep_func) + 3.0 + """ + + def decorator(func: typing.Callable) -> typing.Callable: + @functools.wraps(func) + def wrapper(*args, **kwargs) -> float: + usage_time = timeit.timeit( + lambda: func(*args, **kwargs), + setup=setup, + number=number, + ) + return round(usage_time / number, ndigits) + + return wrapper + + return decorator + + +if __name__ == '__main__': + import time + + def sleep_func(n): + time.sleep(n) + return n + + for i in range(1, 4): + time_sleep_func = get_usage_time(number=3)(sleep_func) + print(time_sleep_func(i)) From 1fefb9085c783192fb7a36383f951e96ec4894d8 Mon Sep 17 00:00:00 2001 From: po4k Date: Mon, 6 Oct 2025 01:40:54 +0300 Subject: [PATCH 13/26] =?UTF-8?q?=D0=B4=D0=BE=D0=B4=D0=B5=D0=BB=D0=B0?= =?UTF-8?q?=D0=BB=20=D0=BB=D0=B0=D0=B1=D1=83=202?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- labs/lab_02/var6/Untitled.md | 733 +++++++++++++++++++++++++++++++++-- labs/lab_02/var6/comb.png | 55 +++ 2 files changed, 754 insertions(+), 34 deletions(-) create mode 100644 labs/lab_02/var6/comb.png diff --git a/labs/lab_02/var6/Untitled.md b/labs/lab_02/var6/Untitled.md index d30f0d2..51996cf 100644 --- a/labs/lab_02/var6/Untitled.md +++ b/labs/lab_02/var6/Untitled.md @@ -12,6 +12,7 @@ jupyter: name: python3 --- + ### Вариант 6 ## Сортировка расческой (Comb Sort) @@ -28,6 +29,8 @@ jupyter: ![](comb.jpeg) + + Пример основных шагов алгоритма: - Начать с gap = размер массива / 1.3 (обычно) @@ -37,6 +40,7 @@ jupyter: - Конец # 4. Псевдокод сортировки расчесткой + ```python def comb_sort(arr): @@ -104,8 +108,7 @@ def comb_sort(arr): %store comb_sort ``` -# 7 Протестировать корректность реализации алгоритма -# 8 Провести ручную трассировку алгоритма +# 7 Протестировать корректность реализации алгоритма и 8 Провести ручную трассировку алгоритма ```python def quick_comb_sort_debug(arr): @@ -139,23 +142,40 @@ print("Быстрая проверка сортировки:") quick_comb_sort_debug(test.copy()) ``` -# Провести сравнение указанных алгоритмов сортировки массивов, содержащих n1, n2, n3 и n4 элементов. -# Каждую функцию сортировки вызывать трижды: для сортировки упорядоченного массива, массива, упорядоченного в обратном порядке и неупорядоченного массива. Сортируемая последовательность для всех методов должна быть одинаковой (сортировать копии одного массива). -# Проиллюстрировать эффективность алгоритмов сортировок по заданному критерию. Построить диаграммы указанных зависимостей. +Провести сравнение указанных алгоритмов сортировки массивов, содержащих n1, n2, n3 и n4 элементов. +Каждую функцию сортировки вызывать трижды: для сортировки упорядоченного массива, массива, упорядоченного в обратном порядке и неупорядоченного массива. Сортируемая последовательность для всех методов должна быть одинаковой (сортировать копии одного массива). +Проиллюстрировать эффективность алгоритмов сортировок по заданному критерию. Построить диаграммы указанных зависимостей. ```python +import random +import usage_time +import matplotlib.pyplot as plt +import numpy as np + +def comb_sort(arr): + gap = len(arr) + shrink = 1.247 + sorted_flag = False + + while not sorted_flag: + gap = int(gap / shrink) + if gap <= 1: + gap = 1 + sorted_flag = True + + i = 0 + while i + gap < len(arr): + if arr[i] > arr[i + gap]: + arr[i], arr[i + gap] = arr[i + gap], arr[i] + sorted_flag = False + i += 1 + return arr + sizes = [1000, 5000, 10000, 100000] -# Типы массивов def generate_arrays(size): - """Генерирует три типа массивов одного размера""" - # Упорядоченный массив sorted_arr = list(range(size)) - - # Обратный порядок reversed_arr = list(range(size, 0, -1)) - - # Случайный массив random_arr = [random.randint(1, size * 10) for _ in range(size)] return { @@ -164,39 +184,31 @@ def generate_arrays(size): 'random': random_arr } -# Измеряем время выполнения func = usage_time.get_usage_time(ndigits=6)(comb_sort) -# Словарь для хранения результатов results = { 'sorted': [], 'reversed': [], 'random': [] } -print("🔍 ИЗМЕРЕНИЕ ВРЕМЕНИ СОРТИРОВКИ РАСЧЕСКОЙ") +print("ИЗМЕРЕНИЕ ВРЕМЕНИ СОРТИРОВКИ РАСЧЕСКОЙ") print("=" * 70) for size in sizes: - print(f"\n📊 Размер массива: {size} элементов") + print(f"Размер массива: {size} элементов") print("-" * 50) - # Генерируем массивы одного набора данных arrays = generate_arrays(size) for array_type, arr in arrays.items(): - # Сортируем копию массива time_taken = func(arr.copy()) results[array_type].append(time_taken) print(f" {array_type:>8}: {time_taken:.6f} сек") -# ВИЗУАЛИЗАЦИЯ РЕЗУЛЬТАТОВ - -# 1. График по типам массивов для каждого размера plt.figure(figsize=(15, 10)) -# Подграфик 1: Время для разных типов массивов plt.subplot(2, 2, 1) x_pos = np.arange(len(sizes)) width = 0.25 @@ -212,7 +224,6 @@ plt.xticks(x_pos, sizes) plt.legend() plt.grid(True, alpha=0.3) -# Подграфик 2: Линейный график plt.subplot(2, 2, 2) for array_type, times in results.items(): plt.plot(sizes, times, 'o-', linewidth=2, markersize=6, label=array_type) @@ -225,7 +236,6 @@ plt.yscale('log') plt.legend() plt.grid(True, alpha=0.3) -# Подграфик 3: Отношение времени для разных типов plt.subplot(2, 2, 3) ratios_reversed = [rev/srt for srt, rev in zip(results['sorted'], results['reversed'])] ratios_random = [rnd/srt for srt, rnd in zip(results['sorted'], results['random'])] @@ -240,11 +250,9 @@ plt.title('Относительная эффективность') plt.legend() plt.grid(True, alpha=0.3) -# Подграфик 4: Таблица результатов plt.subplot(2, 2, 4) plt.axis('off') -# Создаем таблицу table_data = [] headers = ['Размер'] + [f'{size}' for size in sizes] @@ -267,7 +275,6 @@ plt.title('Таблица результатов (секунды)') plt.tight_layout() plt.show() -# 2. Отдельные графики для каждого типа массива plt.figure(figsize=(15, 5)) colors = {'sorted': 'green', 'reversed': 'red', 'random': 'blue'} @@ -277,7 +284,6 @@ for i, array_type in enumerate(['sorted', 'reversed', 'random'], 1): plt.plot(sizes, results[array_type], 'o-', color=colors[array_type], linewidth=2, markersize=8) - # Добавляем значения на точки for size, time in zip(sizes, results[array_type]): plt.annotate(f'{time:.4f}с', (size, time), textcoords="offset points", xytext=(0,10), @@ -291,23 +297,682 @@ for i, array_type in enumerate(['sorted', 'reversed', 'random'], 1): plt.tight_layout() plt.show() -# ВЫВОД СТАТИСТИКИ -print("\n📈 СТАТИСТИЧЕСКИЙ АНАЛИЗ") +print("СТАТИСТИЧЕСКИЙ АНАЛИЗ") print("=" * 70) for array_type in ['sorted', 'reversed', 'random']: times = results[array_type] - print(f"\n{array_type.upper():>15}:") + print(f"{array_type.upper():>15}:") for size, time in zip(sizes, times): print(f" {size:6d} эл.: {time:8.4f} сек") - # Вычисляем коэффициент роста if len(times) > 1: growth = times[-1] / times[0] print(f" Рост времени ({sizes[-1]}/{sizes[0]}): {growth:.2f}x") -# Сравнение эффективности -print(f"\n⚡ СРАВНЕНИЕ ЭФФЕКТИВНОСТИ:") +print("СРАВНЕНИЕ ЭФФЕКТИВНОСТИ:") print(f"Упорядоченный массив сортируется в {results['reversed'][-1]/results['sorted'][-1]:.2f} раза медленнее") print(f"Случайный массив сортируется в {results['random'][-1]/results['sorted'][-1]:.2f} раза медленнее") ``` + + +## Поразрядная сортировка +# 1. Классификация алгоритмов сортировки + +- Внутренняя сортировка (работает в оперативной памяти) +- Устойчивая сортировка (сохраняет порядок элементов с одинаковыми ключами) +- Использует дополнительную память для промежуточных структур +- Линейная временная сложность при фиксированной длине ключей: $O(n \cdot k)$, где $n$ — количество элементов, $k$ — количество разрядов +- Сортирует методом обхода и группировки по разрядам из системы счисления (основание radix) + + +# 2. Теоретическое описание алгоритма + +Поразрядная сортировка "Radix Sort" обрабатывает элементы по разрядам ключа, сначала группирует их по младшему разряду (LSD) или по старшему (MSD). + +Основные шаги: + +1. Определяется максимальное количество разрядов у элементов. +2. На каждом шаге выполняется устойчивая сортировка по текущему разряду (например, сортировка подсчётом). +3. После сортировки по всем разрядам массив оказывается полностью отсортированным. + +Преимущество — отсутствие прямых сравнений элементов, что ускоряет работу при ограниченной длине ключей. + +# 3. Блок-схема алгоритма + +- Начало +- Найти максимальный элемент и определить количество разрядов $d$ +- Цикл по $i = 1 \text{ до } d$: + - Устойчивая сортировка массива по $i$-му разряду +- Конец — массив отсортирован + + +# 4. Псевдокод алгоритма (LSD-версия) + +``` +function radixSort(array A): + maxVal = max(A) + d = число_разрядов(maxVal) + for digit in 1 to d: + A = stableSortByDigit(A, digit) + return A +``` + +Где `stableSortByDigit` — устойчивая сортировка массива по $digit$-му разряду, чаще всего применяется сортировка подсчётом. + +# 5. Достоинства и недостатки + +| Достоинства | Недостатки | +| :-- | :-- | +| Линейная сложность при фиксированном $k$ | Требует дополнительной памяти для подсчёта | +| Стабильность сортировки | Неэффективна при очень больших или длинных ключах | +| Отсутствие прямых сравнений элементов | Требует знания основания системы счисления | + +# 6. Реализовать алгоритмы сортировки согласно номеру индивидуального варианта. + + +```python +def radix_sort(arr): + if not arr: + return arr + + max_num = max(arr) + + exp = 1 + while max_num // exp > 0: + counting_sort_for_radix(arr, exp) + exp *= 10 + + return arr + +def counting_sort_for_radix(arr, exp): + """ + Вспомогательная функция для сортировки подсчетом по текущему разряду + """ + n = len(arr) + output = [0] * n + count = [0] * 10 + + for i in range(n): + index = (arr[i] // exp) % 10 + count[index] += 1 + + for i in range(1, 10): + count[i] += count[i - 1] + + for i in range(n - 1, -1, -1): + index = (arr[i] // exp) % 10 + output[count[index] - 1] = arr[i] + count[index] -= 1 + + for i in range(n): + arr[i] = output[i] +``` + +# 7. Ручная тестировка + +```python +def radix_sort_visual(arr): + print("Начало сортировки") + print(f"Исходный массив: {arr}") + + if not arr: + return arr + + max_num = max(arr) + print(f"Максимальное число: {max_num}") + + exp = 1 + iteration = 1 + + while max_num // exp > 0: + print(f"\n--- Итерация {iteration}: разряд {exp} ---") + arr = counting_sort_visual(arr, exp) + exp *= 10 + iteration += 1 + + print(f"\nСортировка завершена!") + print(f"Результат: {arr}") + return arr + +def counting_sort_visual(arr, exp): + n = len(arr) + output = [0] * n + count = [0] * 10 + + print("Шаг 1: Подсчет цифр") + for i in range(n): + digit = (arr[i] // exp) % 10 + count[digit] += 1 + print(f"{arr[i]} -> цифра {digit}") + + print(f"Count: {count}") + + print("Шаг 2: Преобразование count") + for i in range(1, 10): + count[i] += count[i - 1] + + print(f"Positions: {count}") + + print("Шаг 3: Построение output") + print(f"Исходный: {arr}") + + for i in range(n - 1, -1, -1): + digit = (arr[i] // exp) % 10 + position = count[digit] - 1 + output[position] = arr[i] + count[digit] -= 1 + print(f"{arr[i]} (цифра {digit}) -> позиция {position}") + print(f"Output: {output}") + + print(f"Результат: {output}") + return output + +def simple_radix_sort_visual(arr): + print(f"Сортируем: {arr}") + + if len(arr) <= 1: + return arr + + max_num = max(arr) + exp = 1 + + while max_num // exp > 0: + print(f"\nРазряд: {exp}") + + n = len(arr) + count = [0] * 10 + output = [0] * n + + print("Цифры чисел:") + for num in arr: + digit = (num // exp) % 10 + count[digit] += 1 + print(f"{num} -> {digit}") + + print(f"Count: {count}") + + for i in range(1, 10): + count[i] += count[i - 1] + + print(f"Позиции: {count}") + + for i in range(n - 1, -1, -1): + num = arr[i] + digit = (num // exp) % 10 + pos = count[digit] - 1 + output[pos] = num + count[digit] -= 1 + print(f"{num} -> позиция {pos}: {output}") + + arr = output + exp *= 10 + + print(f"\nИтог: {arr}") + return arr + +# Тестирование +if __name__ == "__main__": + print("ТЕСТ 1:") + test1 = [170, 45, 75, 90] + radix_sort_visual(test1.copy()) + + print("\n" + "="*40 + "\n") + + print("ТЕСТ 2:") + test2 = [42, 17, 89, 5] + simple_radix_sort_visual(test2.copy()) +``` + +# Пункты 9, 10, 11 + +```python +import random +import usage_time +import matplotlib.pyplot as plt +import numpy as np + +def radix_sort(arr): + if not arr: + return arr + + max_num = max(arr) + exp = 1 + + while max_num // exp > 0: + counting_sort_for_radix(arr, exp) + exp *= 10 + + return arr + +def counting_sort_for_radix(arr, exp): + n = len(arr) + output = [0] * n + count = [0] * 10 + + for i in range(n): + index = (arr[i] // exp) % 10 + count[index] += 1 + + for i in range(1, 10): + count[i] += count[i - 1] + + for i in range(n - 1, -1, -1): + index = (arr[i] // exp) % 10 + output[count[index] - 1] = arr[i] + count[index] -= 1 + + for i in range(n): + arr[i] = output[i] + +sizes = [1000, 5000, 10000, 100000] + +def generate_arrays(size): + sorted_arr = list(range(size)) + reversed_arr = list(range(size, 0, -1)) + random_arr = [random.randint(1, size * 10) for _ in range(size)] + + return { + 'sorted': sorted_arr, + 'reversed': reversed_arr, + 'random': random_arr + } + +func = usage_time.get_usage_time(ndigits=6)(radix_sort) + +results = { + 'sorted': [], + 'reversed': [], + 'random': [] +} + +print("ИЗМЕРЕНИЕ ВРЕМЕНИ ПОРАЗРЯДНОЙ СОРТИРОВКИ") +print("=" * 70) + +for size in sizes: + print(f"Размер массива: {size} элементов") + print("-" * 50) + + arrays = generate_arrays(size) + + for array_type, arr in arrays.items(): + time_taken = func(arr.copy()) + results[array_type].append(time_taken) + + print(f" {array_type:>8}: {time_taken:.6f} сек") + +plt.figure(figsize=(15, 10)) + +plt.subplot(2, 2, 1) +x_pos = np.arange(len(sizes)) +width = 0.25 + +plt.bar(x_pos - width, results['sorted'], width, label='Упорядоченный', alpha=0.8, color='green') +plt.bar(x_pos, results['reversed'], width, label='Обратный порядок', alpha=0.8, color='red') +plt.bar(x_pos + width, results['random'], width, label='Случайный', alpha=0.8, color='blue') + +plt.xlabel('Размер массива') +plt.ylabel('Время, секунды') +plt.title('Поразрядная сортировка: время для разных типов массивов') +plt.xticks(x_pos, sizes) +plt.legend() +plt.grid(True, alpha=0.3) + +plt.subplot(2, 2, 2) +colors = {'sorted': 'green', 'reversed': 'red', 'random': 'blue'} +for array_type, times in results.items(): + plt.plot(sizes, times, 'o-', linewidth=2, markersize=6, label=array_type, color=colors[array_type]) + +plt.xlabel('Размер массива') +plt.ylabel('Время, секунды') +plt.title('Поразрядная сортировка: зависимость времени от размера массива') +plt.xscale('log') +plt.yscale('log') +plt.legend() +plt.grid(True, alpha=0.3) + +plt.subplot(2, 2, 3) +ratios_reversed = [rev/srt if srt > 0 else 0 for srt, rev in zip(results['sorted'], results['reversed'])] +ratios_random = [rnd/srt if srt > 0 else 0 for srt, rnd in zip(results['sorted'], results['random'])] + +plt.plot(sizes, ratios_reversed, 's-', label='Обратный/Упорядоченный', color='red') +plt.plot(sizes, ratios_random, 'o-', label='Случайный/Упорядоченный', color='blue') +plt.axhline(y=1, color='black', linestyle='--', alpha=0.5) + +plt.xlabel('Размер массива') +plt.ylabel('Отношение времени') +plt.title('Поразрядная сортировка: относительная эффективность') +plt.legend() +plt.grid(True, alpha=0.3) + +plt.subplot(2, 2, 4) +plt.axis('off') + +table_data = [] +headers = ['Тип массива'] + [f'{size}' for size in sizes] + +for array_type in ['sorted', 'reversed', 'random']: + row = [array_type] + [f'{time:.6f}' for time in results[array_type]] + table_data.append(row) + +table = plt.table(cellText=table_data, + colLabels=headers, + cellLoc='center', + loc='center', + bbox=[0.1, 0.1, 0.9, 0.8]) + +table.auto_set_font_size(False) +table.set_fontsize(9) +table.scale(1, 2) + +plt.title('Поразрядная сортировка: таблица результатов (секунды)', fontweight='bold', y=0.9) + +plt.tight_layout() +plt.show() + +plt.figure(figsize=(15, 5)) + +colors = {'sorted': 'green', 'reversed': 'red', 'random': 'blue'} + +for i, array_type in enumerate(['sorted', 'reversed', 'random'], 1): + plt.subplot(1, 3, i) + plt.plot(sizes, results[array_type], 'o-', color=colors[array_type], + linewidth=2, markersize=8, markerfacecolor='white', markeredgewidth=2) + + for size, time in zip(sizes, results[array_type]): + plt.annotate(f'{time:.4f}с', (size, time), + textcoords="offset points", xytext=(0,10), + ha='center', fontsize=8, fontweight='bold') + + plt.xlabel('Размер массива') + plt.ylabel('Время, секунды') + plt.title(f'Поразрядная сортировка: {array_type}') + plt.grid(True, alpha=0.3) + +plt.tight_layout() +plt.show() + +print("СТАТИСТИЧЕСКИЙ АНАЛИЗ") +print("=" * 70) + +for array_type in ['sorted', 'reversed', 'random']: + times = results[array_type] + print(f"{array_type.upper():>15}:") + for size, time in zip(sizes, times): + print(f" {size:6d} эл.: {time:8.4f} сек") + + if len(times) > 1: + growth = times[-1] / times[0] + print(f" Рост времени ({sizes[-1]}/{sizes[0]}): {growth:.2f}x") + +print("СРАВНЕНИЕ ЭФФЕКТИВНОСТИ:") +print(f"Обратный порядок сортируется в {results['reversed'][-1]/results['sorted'][-1]:.2f} раза медленнее упорядоченного") +print(f"Случайный массив сортируется в {results['random'][-1]/results['sorted'][-1]:.2f} раза медленнее упорядоченного") + +print("АНАЛИЗ ВРЕМЕННОЙ СЛОЖНОСТИ:") +print("Поразрядная сортировка имеет сложность O(d*n), где:") +print(" d - количество разрядов в максимальном числе") +print(" n - количество элементов") +print("Для массивов размером 100000 элементов максимальное число ~ 1,000,000 (6 разрядов)") +print("Ожидаемое время: O(6 * n) = O(n) - линейная сложность") +``` + + +1. В чем состоит суть метода сортировки вставками? +Суть метода заключается в том, что массив делится на отсортированную и неотсортированную части. На каждом шаге берется очередной элемент из неотсортированной части и вставляется на правильную позицию в отсортированной части. + +2. Какие шаги выполняет алгоритм сортировки вставками? + +Начинаем со второго элемента (i = 1) + +Сохраняем текущий элемент в временную переменную + +Сдвигаем элементы отсортированной части, которые больше текущего элемента, вправо + +Вставляем текущий элемент на освободившееся место + +Повторяем для всех элементов массива + +3. Как программно реализуется сортировка вставками? + +```python +def insertion_sort(arr): + for i in range(1, len(arr)): + key = arr[i] + j = i - 1 + while j >= 0 and arr[j] > key: + arr[j + 1] = arr[j] + j -= 1 + arr[j + 1] = key + return arr +``` +4. В чем достоинства и недостатки метода сортировки вставками? +Достоинства: простая реализация, эффективен на небольших массивах, устойчив, адаптивен +Недостатки: O(n²) в худшем случае, неэффективен на больших массивах + +5. Приведите практический пример сортировки массива методом вставок +Массив: [5, 2, 4, 6, 1, 3] +Шаги: [2, 5, 4, 6, 1, 3] → [2, 4, 5, 6, 1, 3] → [2, 4, 5, 6, 1, 3] → [1, 2, 4, 5, 6, 3] → [1, 2, 3, 4, 5, 6] + +6. В чем состоит суть сортировки методом Шелла? +Суть в сравнении элементов, стоящих на определенном расстоянии друг от друга (с убывающим шагом), что позволяет быстрее перемещать элементы на большие расстояния. + +7. За счет чего метод Шелла дает лучшие показатели по сравнению с простейшими методами? +За счет предварительной сортировки элементов на больших расстояниях, что уменьшает количество инверсий и позволяет быстрее упорядочивать массив. + +8. Приведите практический пример сортировки массива методом Шелла +Массив: [8, 3, 7, 4, 1, 9, 2, 6, 5] +Шаг 4: [1, 3, 7, 4, 8, 9, 2, 6, 5] +Шаг 2: [1, 3, 2, 4, 5, 6, 7, 9, 8] +Шаг 1: [1, 2, 3, 4, 5, 6, 7, 8, 9] + +9. Какой фактор оказывает наибольшее влияние на эффективность сортировки методом Шелла? +Выбор последовательности шагов (интервалов) для сравнения элементов. + +10. Какие последовательности шагов группировки рекомендуются для практического использования в методе Шелла? +Последовательность Кнута: 1, 4, 13, 40, 121... или последовательность Седжвика: 1, 8, 23, 77, 281... + +11. Как программно реализуется сортировка методом Шелла? + +```python +def shell_sort(arr): + n = len(arr) + gap = n // 2 + while gap > 0: + for i in range(gap, n): + temp = arr[i] + j = i + while j >= gap and arr[j - gap] > temp: + arr[j] = arr[j - gap] + j -= gap + arr[j] = temp + gap //= 2 + return arr +``` +12. В чем состоит суть метода сортировки выбором? +На каждом шаге находится минимальный элемент из неотсортированной части и помещается в конец отсортированной части. + +13. Какие шаги выполняет алгоритм сортировки выбором? + +Находим минимальный элемент в неотсортированной части + +Меняем его местами с первым элементом неотсортированной части + +Увеличиваем границу отсортированной части на 1 + +Повторяем пока весь массив не будет отсортирован + +14. Как программно реализуется сортировка выбором? + +```python +def selection_sort(arr): + for i in range(len(arr)): + min_idx = i + for j in range(i + 1, len(arr)): + if arr[j] < arr[min_idx]: + min_idx = j + arr[i], arr[min_idx] = arr[min_idx], arr[i] + return arr +``` + +15. В чем достоинства и недостатки метода сортировки выбором? +Достоинства: простая реализация, минимальное количество перестановок +Недостатки: O(n²) в любом случае, неустойчив + + +16. Приведите практический пример сортировки массива методом выбора +Массив: [64, 25, 12, 22, 11] +Шаги: [11, 25, 12, 22, 64] → [11, 12, 25, 22, 64] → [11, 12, 22, 25, 64] → [11, 12, 22, 25, 64] + +17. В чем состоит суть метода сортировки обменом? +Сравниваются соседние элементы и меняются местами, если они находятся в неправильном порядке. + +18. Какие шаги выполняет алгоритм сортировки обменом? + +Проходим по массиву несколько раз + +На каждой итерации сравниваем соседние элементы + +Если порядок неправильный - меняем их местами + +Повторяем до тех пор, пока массив не будет отсортирован + +19. Как программно реализуется сортировка обменом? + +```python +def bubble_sort(arr): + n = len(arr) + for i in range(n): + for j in range(0, n - i - 1): + if arr[j] > arr[j + 1]: + arr[j], arr[j + 1] = arr[j + 1], arr[j] + return arr +``` +20. В чем достоинства и недостатки метода сортировки обменом? +Достоинства: простая реализация, устойчив +Недостатки: O(n²) в худшем случае, медленный на больших массивах + +21. Приведите практический пример сортировки массива методом обмена +Массив: [5, 1, 4, 2, 8] +1 проход: [1, 5, 4, 2, 8] → [1, 4, 5, 2, 8] → [1, 4, 2, 5, 8] → [1, 4, 2, 5, 8] +2 проход: [1, 4, 2, 5, 8] → [1, 2, 4, 5, 8] → [1, 2, 4, 5, 8] + +22. В чем состоит суть метода быстрой сортировки? +Выбирается опорный элемент, массив разбивается на две части: элементы меньше опорного и элементы больше опорного, затем рекурсивно сортируются обе части. + +23. За счет чего метод быстрой сортировки дает лучшие показатели по сравнению с простейшими методами? +За счет принципа "разделяй и властвуй" и в среднем случае времени O(n log n). + +24. Что такое опорный элемент в методе быстрой сортировки и как он используется? +Опорный элемент - это элемент, относительно которого происходит разделение массива. Элементы меньше опорного перемещаются влево, больше - вправо. + +25. Приведите практический пример быстрой сортировки массива +Массив: [10, 80, 30, 90, 40, 50, 70] +Опорный: 70 +Разделение: [10, 30, 40, 50] 70 [80, 90] +Рекурсивная сортировка обеих частей + +26. Что можно сказать о применимости метода быстрой сортировки с точки зрения его эффективности? +Эффективен для больших массивов, но может деградировать до O(n²) при неудачном выборе опорного элемента. + +27. Какой фактор оказывает решающее влияние на эффективность метода быстрой сортировки? +Выбор опорного элемента. + +28. Почему выбор серединного элемента в качестве опорного в методе быстрой сортировки может резко ухудшать эффективность метода? +Если массив уже отсортирован или почти отсортирован, выбор серединного элемента может привести к несбалансированному разделению. + +29. Какое правило выбора опорного элемента в методе быстрой сортировки является наилучшим и почему его сложно использовать? +Медиана трех элементов (первого, среднего и последнего). Сложно использовать из-за дополнительных сравнений. + +30. Какое простое правило выбора опорного элемента в методе быстрой сортировки рекомендуется использовать на практике? +Случайный выбор или медиана трех. + +31. Какие усовершенствования имеет базовый алгоритм метода быстрой сортировки? + +Выбор опорного элемента через медиану трех + +Использование insertion sort для маленьких подмассивов + +Итеративная реализация для избежания переполнения стека + +32. Почему быстрая сортировка проще всего программно реализуется с помощью рекурсии? +Рекурсия естественным образом отражает принцип "разделяй и властвуй". + +33. Как программно реализуется рекурсивный вариант метода быстрой сортировки? + +```python +def quick_sort(arr): + if len(arr) <= 1: + return arr + pivot = arr[len(arr) // 2] + left = [x for x in arr if x < pivot] + middle = [x for x in arr if x == pivot] + right = [x for x in arr if x > pivot] + return quick_sort(left) + middle + quick_sort(right) +``` + +34. Какие особенности имеет не рекурсивная программная реализация метода быстрой сортировки? +Использует стек для хранения границ подмассивов, требует ручного управления памятью. + +35. В чем состоит суть метода пирамидальной сортировки? +Строится двоичная куча из элементов массива, затем многократно извлекается максимальный элемент и перестраивается куча. + +36. Какой набор данных имеет пирамидальную организацию? +Двоичная куча - полное двоичное дерево, где каждый узел больше (max-heap) или меньше (min-heap) своих потомков. + +37. Чем отличаются друг от друга дерево поиска и пирамидальное дерево? +Дерево поиска: левый потомок < родитель < правый потомок +Пирамидальное дерево: родитель > потомков (max-heap) или родитель < потомков (min-heap) + +38. Приведите пример пирамидального дерева с целочисленными ключами + + +```text + 100 + / \ + 19 36 + / \ / + 17 3 25 +``` +39. Какие полезные свойства имеет пирамидальное дерево? + +Максимальный/минимальный элемент всегда в корне + +Эффективные операции вставки и извлечения за O(log n) + +40. Какие шаги выполняются при построении пирамидального дерева? + +Начинаем с последнего нелистового узла + +Просеиваем узел вниз до правильной позиции + +Переходим к предыдущему узлу + +Повторяем до корня + +41. Что такое просеивание элемента через пирамиду? +Процесс перемещения элемента вниз по дереву до тех пор, пока он не займет правильную позицию относительно своих потомков. + +42. Приведите практический пример построения пирамидального дерева +Массив: [4, 10, 3, 5, 1] +Построение: [10, 5, 3, 4, 1] + +43. Какие шаги выполняются на втором этапе пирамидальной сортировки? + +Меняем корень (максимальный элемент) с последним элементом + +Уменьшаем размер кучи на 1 + +Просеиваем новый корень + +Повторяем пока куча не пуста + +44. Приведите практический пример реализации второго этапа пирамидальной сортировки +Куча: [10, 5, 3, 4, 1] +Шаг 1: [1, 5, 3, 4, 10] → Просеиваем: [5, 4, 3, 1, 10] +Шаг 2: [1, 4, 3, 5, 10] → Просеиваем: [4, 1, 3, 5, 10] +и т.д. + +45. Что можно сказать о трудоемкости метода пирамидальной сортировки? +Время: O(n log n) в худшем, среднем и лучшем случае. Память: O(1). + diff --git a/labs/lab_02/var6/comb.png b/labs/lab_02/var6/comb.png new file mode 100644 index 0000000..f45c72a --- /dev/null +++ b/labs/lab_02/var6/comb.png @@ -0,0 +1,55 @@ +┌─────────────────────────────────────────────────────────────────┐ +│ НАЧАЛО СОРТИРОВКИ РАСЧЕСКОЙ │ +└─────────────────────────────────────────────────────────────────┘ + │ + ▼ +┌─────────────────────────────────────────────────────────────────┐ +│ Инициализация: │ +│ - gap = длина(массив) │ +│ - swapped = true │ +│ - factor = 1.3 (коэффициент уменьшения) │ +└─────────────────────────────────────────────────────────────────┘ + │ + ▼ + ┌───────────────┐ + │ gap > 1 ИЛИ │ + │ swapped = true? │ + └───────────────┘ + │ + ┌─────────────┴─────────────┐ + ▼ ▼ + НЕТ ┌─────────────────┐ ДА ┌─────────────────┐ + │ КОНЕЦ │ │ swapped = false │ + └─────────────────┘ └─────────────────┘ + │ + ▼ + ┌─────────────────────────┐ + │ gap = max(1, gap/factor)│ + │ i = 0 │ + └─────────────────────────┘ + │ + ▼ + ┌─────────────────────────────────┐ + │ i + gap < длина(массива)? │ + └─────────────────────────────────┘ + │ + ┌─────────────┴─────────────┐ + ▼ ▼ + НЕТ ┌─────────────────┐ ДА ┌─────────────────┐ + │ Возврат к │ │ array[i] > │ + │ проверке gap │ │ array[i+gap]? │ + └─────────────────┘ └─────────────────┘ + │ + ┌─────────────┴─────────────┐ + ▼ ▼ + НЕТ ┌─────────────────┐ ДА ┌─────────────────┐ + │ i = i + 1 │ │ Поменять местами│ + └─────────────────┘ │ array[i] и │ + │ array[i+gap] │ + │ swapped = true │ + └─────────────────┘ + │ + ▼ + ┌─────────────────────┐ + │ i = i + 1 │ + └─────────────────────┘ \ No newline at end of file From dc6af66e635ec66377d17885099a610881ebecf8 Mon Sep 17 00:00:00 2001 From: po4k Date: Mon, 6 Oct 2025 01:46:51 +0300 Subject: [PATCH 14/26] =?UTF-8?q?=D0=B4=D0=BE=D0=B1=D0=B0=D0=B2=D0=B8?= =?UTF-8?q?=D0=BB=20=D0=B1=D0=BB=D0=BE=D0=BA=20=D1=81=D1=85=D0=B5=D0=BC?= =?UTF-8?q?=D1=83?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- labs/lab_02/var6/Untitled.md | 110 ++++++++++++++++++++++++++++++++++- 1 file changed, 107 insertions(+), 3 deletions(-) diff --git a/labs/lab_02/var6/Untitled.md b/labs/lab_02/var6/Untitled.md index 51996cf..0488d3e 100644 --- a/labs/lab_02/var6/Untitled.md +++ b/labs/lab_02/var6/Untitled.md @@ -12,7 +12,6 @@ jupyter: name: python3 --- - ### Вариант 6 ## Сортировка расческой (Comb Sort) @@ -29,7 +28,63 @@ jupyter: ![](comb.jpeg) - +```text +┌─────────────────────────────────────────────────────────────────┐ +│ НАЧАЛО СОРТИРОВКИ РАСЧЕСКОЙ │ +└─────────────────────────────────────────────────────────────────┘ + │ + ▼ +┌─────────────────────────────────────────────────────────────────┐ +│ Инициализация: │ +│ - gap = длина(массив) │ +│ - swapped = true │ +│ - factor = 1.3 (коэффициент уменьшения) │ +└─────────────────────────────────────────────────────────────────┘ + │ + ▼ + ┌───────────────┐ + │ gap > 1 ИЛИ │ + │ swapped = true? │ + └───────────────┘ + │ + ┌─────────────┴─────────────┐ + ▼ ▼ + НЕТ ┌─────────────────┐ ДА ┌─────────────────┐ + │ КОНЕЦ │ │ swapped = false │ + └─────────────────┘ └─────────────────┘ + │ + ▼ + ┌─────────────────────────┐ + │ gap = max(1, gap/factor)│ + │ i = 0 │ + └─────────────────────────┘ + │ + ▼ + ┌─────────────────────────────────┐ + │ i + gap < длина(массива)? │ + └─────────────────────────────────┘ + │ + ┌─────────────┴─────────────┐ + ▼ ▼ + НЕТ ┌─────────────────┐ ДА ┌─────────────────┐ + │ Возврат к │ │ array[i] > │ + │ проверке gap │ │ array[i+gap]? │ + └─────────────────┘ └─────────────────┘ + │ + ┌─────────────┴─────────────┐ + ▼ ▼ + НЕТ ┌─────────────────┐ ДА ┌─────────────────┐ + │ i = i + 1 │ │ Поменять местами│ + └─────────────────┘ │ array[i] и │ + │ array[i+gap] │ + │ swapped = true │ + └─────────────────┘ + │ + ▼ + ┌─────────────────────┐ + │ i = i + 1 │ + └─────────────────────┘ +``` Пример основных шагов алгоритма: @@ -40,7 +95,6 @@ jupyter: - Конец # 4. Псевдокод сортировки расчесткой - ```python def comb_sort(arr): @@ -340,6 +394,56 @@ print(f"Случайный массив сортируется в {results['rand # 3. Блок-схема алгоритма +```text +┌─────────────────────────────────────────────────────────────────┐ +│ НАЧАЛО ПОРАЗРЯДНОЙ СОРТИРОВКИ │ +└─────────────────────────────────────────────────────────────────┘ + │ + ▼ +┌─────────────────────────────────────────────────────────────────┐ +│ Найти максимальный элемент в массиве для определения │ +│ количества разрядов │ +└─────────────────────────────────────────────────────────────────┘ + │ + ▼ +┌─────────────────────────────────────────────────────────────────┐ +│ exp = 1 (текущий разряд: единицы) │ +└─────────────────────────────────────────────────────────────────┘ + │ + ▼ + ┌───────────────┐ + │ max/exp > 0? │ + └───────────────┘ + │ + ┌─────────────┴─────────────┐ + ▼ ▼ + НЕТ ┌─────────────────┐ ДА ┌─────────────────┐ + │ КОНЕЦ │ │ Создать 10 корзин│ + └─────────────────┘ │ (0-9) │ + └─────────────────┘ + │ + ▼ + ┌─────────────────────────┐ + │ Для каждого элемента: │ + │ индекс = (A[i]/exp) % 10│ + │ Добавить в корзину │ + │ с индексом │ + └─────────────────────────┘ + │ + ▼ + ┌─────────────────────────┐ + │ Объединить корзины │ + │ в порядке 0-9 в массив │ + └─────────────────────────┘ + │ + ▼ + ┌─────────────────────────┐ + │ exp = exp * 10 │ + │ (переход к следующему │ + │ разряду) │ + └─────────────────────────┘ +``` + - Начало - Найти максимальный элемент и определить количество разрядов $d$ - Цикл по $i = 1 \text{ до } d$: From a6251be5cf74ec3ced0e83295b5560c6a4703190 Mon Sep 17 00:00:00 2001 From: po4k Date: Mon, 6 Oct 2025 09:11:18 +0300 Subject: [PATCH 15/26] =?UTF-8?q?=D0=BF=D0=BE=D0=BF=D0=B0=D0=B2=D0=B8?= =?UTF-8?q?=D0=BB=20=D0=BA=D0=BE=D0=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- labs/lab_02/var6/Untitled.md | 317 +++++++++++++++++++---------------- 1 file changed, 176 insertions(+), 141 deletions(-) diff --git a/labs/lab_02/var6/Untitled.md b/labs/lab_02/var6/Untitled.md index 0488d3e..f1812ba 100644 --- a/labs/lab_02/var6/Untitled.md +++ b/labs/lab_02/var6/Untitled.md @@ -142,7 +142,6 @@ import matplotlib.pyplot as plt import numpy as np def comb_sort(arr): - # ваша функция сортировки gap = len(arr) shrink = 1.247 sorted = False @@ -261,101 +260,197 @@ for size in sizes: print(f" {array_type:>8}: {time_taken:.6f} сек") -plt.figure(figsize=(15, 10)) +plt.figure(figsize=(15, 5)) -plt.subplot(2, 2, 1) -x_pos = np.arange(len(sizes)) -width = 0.25 +colors = {'sorted': 'green', 'reversed': 'red', 'random': 'blue'} -plt.bar(x_pos - width, results['sorted'], width, label='Упорядоченный', alpha=0.8) -plt.bar(x_pos, results['reversed'], width, label='Обратный порядок', alpha=0.8) -plt.bar(x_pos + width, results['random'], width, label='Случайный', alpha=0.8) +for i, array_type in enumerate(['sorted', 'reversed', 'random'], 1): + plt.subplot(1, 3, i) + plt.plot(sizes, results[array_type], 'o-', color=colors[array_type], + linewidth=2, markersize=8) + + for size, time in zip(sizes, results[array_type]): + plt.annotate(f'{time:.4f}с', (size, time), + textcoords="offset points", xytext=(0,10), + ha='center', fontsize=8) + + plt.xlabel('Размер массива') + plt.ylabel('Время, секунды') + plt.title(f'Тип: {array_type}') + plt.grid(True, alpha=0.3) -plt.xlabel('Размер массива') -plt.ylabel('Время, секунды') -plt.title('Время сортировки для разных типов массивов') -plt.xticks(x_pos, sizes) -plt.legend() -plt.grid(True, alpha=0.3) +plt.tight_layout() +plt.show() -plt.subplot(2, 2, 2) -for array_type, times in results.items(): - plt.plot(sizes, times, 'o-', linewidth=2, markersize=6, label=array_type) +print("СТАТИСТИЧЕСКИЙ АНАЛИЗ") +print("=" * 70) -plt.xlabel('Размер массива') -plt.ylabel('Время, секунды') -plt.title('Зависимость времени от размера массива') -plt.xscale('log') -plt.yscale('log') -plt.legend() -plt.grid(True, alpha=0.3) +for array_type in ['sorted', 'reversed', 'random']: + times = results[array_type] + print(f"{array_type.upper():>15}:") + for size, time in zip(sizes, times): + print(f" {size:6d} эл.: {time:8.4f} сек") + + if len(times) > 1: + growth = times[-1] / times[0] + print(f" Рост времени ({sizes[-1]}/{sizes[0]}): {growth:.2f}x") -plt.subplot(2, 2, 3) -ratios_reversed = [rev/srt for srt, rev in zip(results['sorted'], results['reversed'])] -ratios_random = [rnd/srt for srt, rnd in zip(results['sorted'], results['random'])] +print("СРАВНЕНИЕ ЭФФЕКТИВНОСТИ:") +print(f"Упорядоченный массив сортируется в {results['reversed'][-1]/results['sorted'][-1]:.2f} раза медленнее") +print(f"Случайный массив сортируется в {results['random'][-1]/results['sorted'][-1]:.2f} раза медленнее") +``` -plt.plot(sizes, ratios_reversed, 's-', label='Обратный/Упорядоченный') -plt.plot(sizes, ratios_random, 'o-', label='Случайный/Упорядоченный') -plt.axhline(y=1, color='red', linestyle='--', alpha=0.5) +## Сравнение -plt.xlabel('Размер массива') -plt.ylabel('Отношение времени') -plt.title('Относительная эффективность') -plt.legend() -plt.grid(True, alpha=0.3) +```python +import random +import usage_time +import matplotlib.pyplot as plt +import numpy as np -plt.subplot(2, 2, 4) -plt.axis('off') +def comb_sort(arr): + gap = len(arr) + shrink = 1.247 + sorted_flag = False + + while not sorted_flag: + gap = int(gap / shrink) + if gap <= 1: + gap = 1 + sorted_flag = True + + i = 0 + while i + gap < len(arr): + if arr[i] > arr[i + gap]: + arr[i], arr[i + gap] = arr[i + gap], arr[i] + sorted_flag = False + i += 1 + return arr -table_data = [] -headers = ['Размер'] + [f'{size}' for size in sizes] +def radix_sort(arr): + if not arr: + return arr + + max_num = max(arr) + exp = 1 + + while max_num // exp > 0: + counting_sort_for_radix(arr, exp) + exp *= 10 + + return arr -for array_type in ['sorted', 'reversed', 'random']: - row = [array_type] + [f'{time:.4f}' for time in results[array_type]] - table_data.append(row) +def counting_sort_for_radix(arr, exp): + n = len(arr) + output = [0] * n + count = [0] * 10 + + for i in range(n): + index = (arr[i] // exp) % 10 + count[index] += 1 + + for i in range(1, 10): + count[i] += count[i - 1] + + for i in range(n - 1, -1, -1): + index = (arr[i] // exp) % 10 + output[count[index] - 1] = arr[i] + count[index] -= 1 + + for i in range(n): + arr[i] = output[i] -table = plt.table(cellText=table_data, - colLabels=headers, - cellLoc='center', - loc='center', - bbox=[0, 0, 1, 1]) +sizes = [1000, 5000, 10000, 100000] -table.auto_set_font_size(False) -table.set_fontsize(10) -table.scale(1, 2) +def generate_arrays(size): + sorted_arr = list(range(size)) + reversed_arr = list(range(size, 0, -1)) + random_arr = [random.randint(1, size * 10) for _ in range(size)] + + return { + 'sorted': sorted_arr, + 'reversed': reversed_arr, + 'random': random_arr + } -plt.title('Таблица результатов (секунды)') +comb_func = usage_time.get_usage_time(ndigits=6)(comb_sort) +radix_func = usage_time.get_usage_time(ndigits=6)(radix_sort) -plt.tight_layout() -plt.show() +comb_results = { + 'sorted': [], + 'reversed': [], + 'random': [] +} -plt.figure(figsize=(15, 5)) +radix_results = { + 'sorted': [], + 'reversed': [], + 'random': [] +} -colors = {'sorted': 'green', 'reversed': 'red', 'random': 'blue'} +print("ИЗМЕРЕНИЕ ВРЕМЕНИ СОРТИРОВКИ РАСЧЕСКОЙ") +print("=" * 70) + +for size in sizes: + print(f"Размер массива: {size} элементов") + print("-" * 50) + + arrays = generate_arrays(size) + + for array_type, arr in arrays.items(): + time_taken = comb_func(arr.copy()) + comb_results[array_type].append(time_taken) + + print(f" {array_type:>8}: {time_taken:.6f} сек") + +print("\nИЗМЕРЕНИЕ ВРЕМЕНИ ПОРАЗРЯДНОЙ СОРТИРОВКИ") +print("=" * 70) + +for size in sizes: + print(f"Размер массива: {size} элементов") + print("-" * 50) + + arrays = generate_arrays(size) + + for array_type, arr in arrays.items(): + time_taken = radix_func(arr.copy()) + radix_results[array_type].append(time_taken) + + print(f" {array_type:>8}: {time_taken:.6f} сек") + +plt.figure(figsize=(15, 5)) for i, array_type in enumerate(['sorted', 'reversed', 'random'], 1): plt.subplot(1, 3, i) - plt.plot(sizes, results[array_type], 'o-', color=colors[array_type], - linewidth=2, markersize=8) - for size, time in zip(sizes, results[array_type]): - plt.annotate(f'{time:.4f}с', (size, time), + plt.plot(sizes, comb_results[array_type], 'o-', color='red', + linewidth=2, markersize=8, label='Comb Sort') + + plt.plot(sizes, radix_results[array_type], 's-', color='blue', + linewidth=2, markersize=8, label='Radix Sort') + + for j, size in enumerate(sizes): + plt.annotate(f'{comb_results[array_type][j]:.4f}с', (size, comb_results[array_type][j]), textcoords="offset points", xytext=(0,10), - ha='center', fontsize=8) + ha='center', fontsize=7, color='red') + plt.annotate(f'{radix_results[array_type][j]:.4f}с', (size, radix_results[array_type][j]), + textcoords="offset points", xytext=(0,-15), + ha='center', fontsize=7, color='blue') plt.xlabel('Размер массива') plt.ylabel('Время, секунды') plt.title(f'Тип: {array_type}') + plt.legend() plt.grid(True, alpha=0.3) plt.tight_layout() plt.show() -print("СТАТИСТИЧЕСКИЙ АНАЛИЗ") +print("СТАТИСТИЧЕСКИЙ АНАЛИЗ - СОРТИРОВКА РАСЧЕСКОЙ") print("=" * 70) for array_type in ['sorted', 'reversed', 'random']: - times = results[array_type] + times = comb_results[array_type] print(f"{array_type.upper():>15}:") for size, time in zip(sizes, times): print(f" {size:6d} эл.: {time:8.4f} сек") @@ -364,9 +459,25 @@ for array_type in ['sorted', 'reversed', 'random']: growth = times[-1] / times[0] print(f" Рост времени ({sizes[-1]}/{sizes[0]}): {growth:.2f}x") -print("СРАВНЕНИЕ ЭФФЕКТИВНОСТИ:") -print(f"Упорядоченный массив сортируется в {results['reversed'][-1]/results['sorted'][-1]:.2f} раза медленнее") -print(f"Случайный массив сортируется в {results['random'][-1]/results['sorted'][-1]:.2f} раза медленнее") +print("\nСТАТИСТИЧЕСКИЙ АНАЛИЗ - ПОРАЗРЯДНАЯ СОРТИРОВКА") +print("=" * 70) + +for array_type in ['sorted', 'reversed', 'random']: + times = radix_results[array_type] + print(f"{array_type.upper():>15}:") + for size, time in zip(sizes, times): + print(f" {size:6d} эл.: {time:8.4f} сек") + + if len(times) > 1: + growth = times[-1] / times[0] + print(f" Рост времени ({sizes[-1]}/{sizes[0]}): {growth:.2f}x") + +print("\nСРАВНЕНИЕ ЭФФЕКТИВНОСТИ:") +print(f"Comb Sort - обратный/упорядоченный: {comb_results['reversed'][-1]/comb_results['sorted'][-1]:.2f}x") +print(f"Comb Sort - случайный/упорядоченный: {comb_results['random'][-1]/comb_results['sorted'][-1]:.2f}x") +print(f"Radix Sort - обратный/упорядоченный: {radix_results['reversed'][-1]/radix_results['sorted'][-1]:.2f}x") +print(f"Radix Sort - случайный/упорядоченный: {radix_results['random'][-1]/radix_results['sorted'][-1]:.2f}x") +print(f"Comb/Radix на случайных данных: {comb_results['random'][-1]/radix_results['random'][-1]:.2f}x") ``` @@ -705,75 +816,6 @@ for size in sizes: print(f" {array_type:>8}: {time_taken:.6f} сек") -plt.figure(figsize=(15, 10)) - -plt.subplot(2, 2, 1) -x_pos = np.arange(len(sizes)) -width = 0.25 - -plt.bar(x_pos - width, results['sorted'], width, label='Упорядоченный', alpha=0.8, color='green') -plt.bar(x_pos, results['reversed'], width, label='Обратный порядок', alpha=0.8, color='red') -plt.bar(x_pos + width, results['random'], width, label='Случайный', alpha=0.8, color='blue') - -plt.xlabel('Размер массива') -plt.ylabel('Время, секунды') -plt.title('Поразрядная сортировка: время для разных типов массивов') -plt.xticks(x_pos, sizes) -plt.legend() -plt.grid(True, alpha=0.3) - -plt.subplot(2, 2, 2) -colors = {'sorted': 'green', 'reversed': 'red', 'random': 'blue'} -for array_type, times in results.items(): - plt.plot(sizes, times, 'o-', linewidth=2, markersize=6, label=array_type, color=colors[array_type]) - -plt.xlabel('Размер массива') -plt.ylabel('Время, секунды') -plt.title('Поразрядная сортировка: зависимость времени от размера массива') -plt.xscale('log') -plt.yscale('log') -plt.legend() -plt.grid(True, alpha=0.3) - -plt.subplot(2, 2, 3) -ratios_reversed = [rev/srt if srt > 0 else 0 for srt, rev in zip(results['sorted'], results['reversed'])] -ratios_random = [rnd/srt if srt > 0 else 0 for srt, rnd in zip(results['sorted'], results['random'])] - -plt.plot(sizes, ratios_reversed, 's-', label='Обратный/Упорядоченный', color='red') -plt.plot(sizes, ratios_random, 'o-', label='Случайный/Упорядоченный', color='blue') -plt.axhline(y=1, color='black', linestyle='--', alpha=0.5) - -plt.xlabel('Размер массива') -plt.ylabel('Отношение времени') -plt.title('Поразрядная сортировка: относительная эффективность') -plt.legend() -plt.grid(True, alpha=0.3) - -plt.subplot(2, 2, 4) -plt.axis('off') - -table_data = [] -headers = ['Тип массива'] + [f'{size}' for size in sizes] - -for array_type in ['sorted', 'reversed', 'random']: - row = [array_type] + [f'{time:.6f}' for time in results[array_type]] - table_data.append(row) - -table = plt.table(cellText=table_data, - colLabels=headers, - cellLoc='center', - loc='center', - bbox=[0.1, 0.1, 0.9, 0.8]) - -table.auto_set_font_size(False) -table.set_fontsize(9) -table.scale(1, 2) - -plt.title('Поразрядная сортировка: таблица результатов (секунды)', fontweight='bold', y=0.9) - -plt.tight_layout() -plt.show() - plt.figure(figsize=(15, 5)) colors = {'sorted': 'green', 'reversed': 'red', 'random': 'blue'} @@ -812,13 +854,6 @@ for array_type in ['sorted', 'reversed', 'random']: print("СРАВНЕНИЕ ЭФФЕКТИВНОСТИ:") print(f"Обратный порядок сортируется в {results['reversed'][-1]/results['sorted'][-1]:.2f} раза медленнее упорядоченного") print(f"Случайный массив сортируется в {results['random'][-1]/results['sorted'][-1]:.2f} раза медленнее упорядоченного") - -print("АНАЛИЗ ВРЕМЕННОЙ СЛОЖНОСТИ:") -print("Поразрядная сортировка имеет сложность O(d*n), где:") -print(" d - количество разрядов в максимальном числе") -print(" n - количество элементов") -print("Для массивов размером 100000 элементов максимальное число ~ 1,000,000 (6 разрядов)") -print("Ожидаемое время: O(6 * n) = O(n) - линейная сложность") ``` From 5584a7bb4333005e6d4a434041835262cd910fc9 Mon Sep 17 00:00:00 2001 From: po4k Date: Mon, 6 Oct 2025 09:29:37 +0300 Subject: [PATCH 16/26] =?UTF-8?q?=D1=81=D0=BE=D0=B7=D1=80=D0=B0=D0=BD?= =?UTF-8?q?=D0=B5=D0=BD=D0=B8=D0=B5=20=D0=BF=D0=B5=D1=80=D0=B5=D0=B4=20LaT?= =?UTF-8?q?ex?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- labs/lab_02/var6/Untitled.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/labs/lab_02/var6/Untitled.md b/labs/lab_02/var6/Untitled.md index f1812ba..98a740d 100644 --- a/labs/lab_02/var6/Untitled.md +++ b/labs/lab_02/var6/Untitled.md @@ -780,7 +780,7 @@ def counting_sort_for_radix(arr, exp): for i in range(n): arr[i] = output[i] -sizes = [1000, 5000, 10000, 100000] +sizes = [1000, 2000, 4000, 8000] def generate_arrays(size): sorted_arr = list(range(size)) From 934292d7b2ea4ba546915512312e836f8c26c402 Mon Sep 17 00:00:00 2001 From: po4k Date: Mon, 6 Oct 2025 12:31:10 +0300 Subject: [PATCH 17/26] =?UTF-8?q?=D0=B1=D0=BB=D0=BE=D0=BA=20=D1=81=D1=85?= =?UTF-8?q?=D0=B5=D0=BC=D1=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- labs/lab_02/var6/LaTeX/comb_sort.pdf | Bin 0 -> 13179 bytes labs/lab_02/var6/LaTeX/comb_sort.png | Bin 0 -> 33772 bytes labs/lab_02/var6/LaTeX/comb_sort.tex | 54 ++++++++++++ labs/lab_02/var6/LaTeX/radix_sort.pdf | Bin 0 -> 21653 bytes labs/lab_02/var6/LaTeX/radix_sort.png | Bin 0 -> 23908 bytes labs/lab_02/var6/LaTeX/radix_sort.tex | 43 ++++++++++ labs/lab_02/var6/Untitled.md | 115 +------------------------- 7 files changed, 100 insertions(+), 112 deletions(-) create mode 100644 labs/lab_02/var6/LaTeX/comb_sort.pdf create mode 100644 labs/lab_02/var6/LaTeX/comb_sort.png create mode 100644 labs/lab_02/var6/LaTeX/comb_sort.tex create mode 100644 labs/lab_02/var6/LaTeX/radix_sort.pdf create mode 100644 labs/lab_02/var6/LaTeX/radix_sort.png create mode 100644 labs/lab_02/var6/LaTeX/radix_sort.tex diff --git a/labs/lab_02/var6/LaTeX/comb_sort.pdf b/labs/lab_02/var6/LaTeX/comb_sort.pdf new file mode 100644 index 0000000000000000000000000000000000000000..53f9fe19085610ec13c0e1bbb790f71f528799a8 GIT binary patch literal 13179 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 literal 0 HcmV?d00001 diff --git a/labs/lab_02/var6/LaTeX/comb_sort.tex b/labs/lab_02/var6/LaTeX/comb_sort.tex new file mode 100644 index 0000000..d2cf5ab --- /dev/null +++ b/labs/lab_02/var6/LaTeX/comb_sort.tex @@ -0,0 +1,54 @@ +\documentclass[tikz,border=3.14mm]{standalone} +\usepackage{tikz} +\usetikzlibrary{shapes.geometric, arrows.meta, positioning} + +\tikzset{ + startstop/.style = {rectangle, rounded corners, minimum width=3cm, minimum height=1cm, text centered, draw=black, fill=red!30}, + process/.style = {rectangle, minimum width=3cm, minimum height=1cm, text centered, draw=black, fill=orange!30}, + decision/.style = {diamond, minimum width=3cm, minimum height=1cm, text centered, draw=black, fill=green!30}, + arrow/.style = {thick, -Stealth} +} + +\begin{document} +\begin{tikzpicture}[node distance=1.5cm] + +% Main algorithm flow +\node (start) [startstop] {Start Comb Sort}; +\node (init) [process, below=of start] {gap = n\\shrink = 1.3\\sorted = false}; +\node (dec1) [decision, below=of init] {gap > 1 OR\\not sorted?}; +\node (update) [process, below=of dec1] {gap = max(1, floor(gap/shrink))\\sorted = true}; +\node (init_i) [process, below=of update] {i = 0}; +\node (dec2) [decision, below=of init_i] {i + gap < n?}; + +% Inner loop - comparison and swap +\node (dec3) [decision, right=2cm of dec2] {array[i] > array[i+gap]?}; +\node (swap) [process, below=of dec3] {Swap array[i] and array[i+gap]\\sorted = false}; +\node (increment) [process, below=2cm of dec2] {i = i + 1}; +\node (stop) [startstop, below=2.5cm of dec1] {End}; + +% Connections - main flow +\draw [arrow] (start) -- (init); +\draw [arrow] (init) -- (dec1); +\draw [arrow] (dec1) -- node[right] {Yes} (update); +\draw [arrow] (update) -- (init_i); +\draw [arrow] (init_i) -- (dec2); + +% Connections - inner loop +\draw [arrow] (dec2) -- node[above] {Yes} (dec3); +\draw [arrow] (dec3) -- node[right] {Yes} (swap); +\draw [arrow] (swap) |- (increment); + +% Connections - no swap path +\draw [arrow] (dec3.east) -- ++(0.5,0) node[above] {No} |- (increment.east); + +% Connections - loop back +\draw [arrow] (increment.west) -| node[below left] {Continue inner loop} ([xshift=-1cm]dec2.west) -- (dec2.west); + +% Connections - exit conditions +\draw [arrow] (dec2.south) -- node[left] {No} (increment.north); +\draw [arrow] (increment.south) -- ++(0,-0.5) -| node[below right] {Next iteration} ([xshift=1cm]dec1.east) -- (dec1.east); + +\draw [arrow] (dec1.west) -- node[above] {No} ++(-2,0) |- (stop.west); + +\end{tikzpicture} +\end{document} diff --git a/labs/lab_02/var6/LaTeX/radix_sort.pdf b/labs/lab_02/var6/LaTeX/radix_sort.pdf new file mode 100644 index 0000000000000000000000000000000000000000..c8d491712085ae50d0704d213dbe769ad16e933b GIT binary patch literal 21653 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 F{2vpkS|b1e literal 0 HcmV?d00001 diff --git a/labs/lab_02/var6/LaTeX/radix_sort.tex b/labs/lab_02/var6/LaTeX/radix_sort.tex new file mode 100644 index 0000000..11aa754 --- /dev/null +++ b/labs/lab_02/var6/LaTeX/radix_sort.tex @@ -0,0 +1,43 @@ +\documentclass[tikz,border=3.14mm]{standalone} +\usepackage{tikz} +\usetikzlibrary{shapes.geometric, arrows.meta, positioning} + +\tikzset{ + startstop/.style = {rectangle, rounded corners, minimum width=3cm, minimum height=1cm, text centered, draw=black, fill=red!30}, + process/.style = {rectangle, minimum width=3cm, minimum height=1cm, text centered, draw=black, fill=orange!30}, + decision/.style = {diamond, minimum width=2.5cm, minimum height=1.5cm, text centered, draw=black, fill=green!30, align=center}, + arrow/.style = {thick, -Stealth} +} + +\begin{document} +\begin{tikzpicture}[node distance=1.2cm] + +\node (start) [startstop] {Start}; +\node (findMax) [process, below=of start] {Find maximum number}; +\node (initExp) [process, below=of findMax] {Set digit position = 1}; +\node (dec1) [decision, below=of initExp] {More digits?}; +\node (sortDigit) [process, below=of dec1] {Stable sort by current digit}; +\node (nextDigit) [process, below=of sortDigit] {Move to next digit position}; +\node (stop) [startstop, below=2cm of dec1] {End}; + +% Main flow +\draw [arrow] (start) -- (findMax); +\draw [arrow] (findMax) -- (initExp); +\draw [arrow] (initExp) -- (dec1); +\draw [arrow] (dec1) -- node[right] {Yes} (sortDigit); +\draw [arrow] (sortDigit) -- (nextDigit); +\draw [arrow] (nextDigit.west) -- ++(-1,0) |- (dec1.west); +\draw [arrow] (dec1.east) -- node[above] {No} ++(1,0) |- (stop.east); + +% Algorithm details +\node [right=1cm of sortDigit, align=left, font=\small] { + \textbf{For each digit (LSD first):}\\ + • Use Counting Sort\\ + • Sort by current digit\\ + • Maintain relative order\\ + • Time: O(d*(n+k))\\ + • Space: O(n+k) +}; + +\end{tikzpicture} +\end{document} diff --git a/labs/lab_02/var6/Untitled.md b/labs/lab_02/var6/Untitled.md index 98a740d..db7516e 100644 --- a/labs/lab_02/var6/Untitled.md +++ b/labs/lab_02/var6/Untitled.md @@ -28,71 +28,9 @@ jupyter: ![](comb.jpeg) -```text -┌─────────────────────────────────────────────────────────────────┐ -│ НАЧАЛО СОРТИРОВКИ РАСЧЕСКОЙ │ -└─────────────────────────────────────────────────────────────────┘ - │ - ▼ -┌─────────────────────────────────────────────────────────────────┐ -│ Инициализация: │ -│ - gap = длина(массив) │ -│ - swapped = true │ -│ - factor = 1.3 (коэффициент уменьшения) │ -└─────────────────────────────────────────────────────────────────┘ - │ - ▼ - ┌───────────────┐ - │ gap > 1 ИЛИ │ - │ swapped = true? │ - └───────────────┘ - │ - ┌─────────────┴─────────────┐ - ▼ ▼ - НЕТ ┌─────────────────┐ ДА ┌─────────────────┐ - │ КОНЕЦ │ │ swapped = false │ - └─────────────────┘ └─────────────────┘ - │ - ▼ - ┌─────────────────────────┐ - │ gap = max(1, gap/factor)│ - │ i = 0 │ - └─────────────────────────┘ - │ - ▼ - ┌─────────────────────────────────┐ - │ i + gap < длина(массива)? │ - └─────────────────────────────────┘ - │ - ┌─────────────┴─────────────┐ - ▼ ▼ - НЕТ ┌─────────────────┐ ДА ┌─────────────────┐ - │ Возврат к │ │ array[i] > │ - │ проверке gap │ │ array[i+gap]? │ - └─────────────────┘ └─────────────────┘ - │ - ┌─────────────┴─────────────┐ - ▼ ▼ - НЕТ ┌─────────────────┐ ДА ┌─────────────────┐ - │ i = i + 1 │ │ Поменять местами│ - └─────────────────┘ │ array[i] и │ - │ array[i+gap] │ - │ swapped = true │ - └─────────────────┘ - │ - ▼ - ┌─────────────────────┐ - │ i = i + 1 │ - └─────────────────────┘ -``` -Пример основных шагов алгоритма: +![](LaTeX/comb_sort.png) -- Начать с gap = размер массива / 1.3 (обычно) -- Пока gap > 1 или были перестановки: - - Сравнить элементы на расстоянии gap, при необходимости поменять - - Уменьшить gap (gap = gap / 1.3) -- Конец # 4. Псевдокод сортировки расчесткой @@ -505,55 +443,8 @@ print(f"Comb/Radix на случайных данных: {comb_results['random'] # 3. Блок-схема алгоритма -```text -┌─────────────────────────────────────────────────────────────────┐ -│ НАЧАЛО ПОРАЗРЯДНОЙ СОРТИРОВКИ │ -└─────────────────────────────────────────────────────────────────┘ - │ - ▼ -┌─────────────────────────────────────────────────────────────────┐ -│ Найти максимальный элемент в массиве для определения │ -│ количества разрядов │ -└─────────────────────────────────────────────────────────────────┘ - │ - ▼ -┌─────────────────────────────────────────────────────────────────┐ -│ exp = 1 (текущий разряд: единицы) │ -└─────────────────────────────────────────────────────────────────┘ - │ - ▼ - ┌───────────────┐ - │ max/exp > 0? │ - └───────────────┘ - │ - ┌─────────────┴─────────────┐ - ▼ ▼ - НЕТ ┌─────────────────┐ ДА ┌─────────────────┐ - │ КОНЕЦ │ │ Создать 10 корзин│ - └─────────────────┘ │ (0-9) │ - └─────────────────┘ - │ - ▼ - ┌─────────────────────────┐ - │ Для каждого элемента: │ - │ индекс = (A[i]/exp) % 10│ - │ Добавить в корзину │ - │ с индексом │ - └─────────────────────────┘ - │ - ▼ - ┌─────────────────────────┐ - │ Объединить корзины │ - │ в порядке 0-9 в массив │ - └─────────────────────────┘ - │ - ▼ - ┌─────────────────────────┐ - │ exp = exp * 10 │ - │ (переход к следующему │ - │ разряду) │ - └─────────────────────────┘ -``` + +![](LaTeX/radix_sort.png) - Начало - Найти максимальный элемент и определить количество разрядов $d$ From 7f296fbb85eee9caaaea0245aef587d9cc33d2ca Mon Sep 17 00:00:00 2001 From: po4k Date: Sun, 12 Oct 2025 18:06:13 +0300 Subject: [PATCH 18/26] =?UTF-8?q?4/6=20=D0=B2=D0=B5=D1=80=D1=81=D0=B8?= =?UTF-8?q?=D0=B9=20=D0=B3=D0=BE=D1=82=D0=BE=D0=B2=D1=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- labs/lab_03/Untitled.md | 297 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 297 insertions(+) create mode 100644 labs/lab_03/Untitled.md diff --git a/labs/lab_03/Untitled.md b/labs/lab_03/Untitled.md new file mode 100644 index 0000000..a858e56 --- /dev/null +++ b/labs/lab_03/Untitled.md @@ -0,0 +1,297 @@ +--- +jupyter: + jupytext: + text_representation: + extension: .md + format_name: markdown + format_version: '1.3' + jupytext_version: 1.17.3 + kernelspec: + display_name: '' + name: '' +--- + +## Лабораторная работа №3 +# Вариант 6 +Цели лабораторной работы: +- Изучить, что такое линейный список — структура данных, где элементы связаны ссылками, а не расположены подряд в памяти. +- Научиться создавать и использовать односвязные линейные списки в программе. +- Освоить основные операции со списками: добавление, удаление, поиск элементов. +- Развить навыки работы с динамической памятью при построении и изменении списков. +- Научиться писать функции для обработки списков (например, удаление повторов, разворот, сортировка). +- Приобрести умения структурного и модульного программирования через реализацию этих задач. + +# Задание 1 +Версия 1: + +```python +from typing import Any, Self +import doctest + +class Node: + def __init__(self, data: Any = None, next: 'Node' = None): + self.data = data + self.next = next + + def __repr__(self): + return f'Node(data={self.data}, next={self.next})' + + +class SingleLinkedListV1: + def __init__(self) -> Self: + self._head = None + + def insert_first_node(self, value: Any) -> None: + '''Добавить элемент в начало списка''' + self._head = Node(value, self._head) + + def remove_first_node(self) -> Any: + '''Удалить первый элемент списка''' + if self._head is None: + raise ValueError("Список пуст") + temp = self._head.data + self._head = self._head.next + return temp + + def insert_last_node(self, value: Any) -> None: + '''Добавить элемент в конец списка''' + if self._head is None: + self.insert_first_node(value) + else: + current_node = self._head + while current_node.next is not None: + current_node = current_node.next + current_node.next = Node(value) + + def remove_last_node(self) -> Any: + '''Удалить последний элемент списка''' + if self._head is None: + raise ValueError("Список пуст") + + if self._head.next is None: + return self.remove_first_node() + + current_node = self._head + while current_node.next.next is not None: + current_node = current_node.next + temp = current_node.next.data + current_node.next = None + return temp + + def __repr__(self) -> str: + return f'SingleLinkedListV1({self._head})' + + def __str__(self): + node = self._head + elements = [] + while node: + elements.append(str(node.data)) + node = node.next + return 'LinkedList.head -> ' + ' -> '.join(elements) + ' -> None' + +``` + +Версия 2: Добавлены методы поиска, замены и удаления по значению + получение размера + +```python +class SingleLinkedListV2(SingleLinkedListV1): + def get_size(self) -> int: + '''Вернуть размер списка (сложность O(n))''' + count = 0 + current = self._head + while current: + count += 1 + current = current.next + return count + + def find_node(self, value: Any) -> Node: + '''Найти первый узел с заданным значением''' + current = self._head + while current: + if current.data == value: + return current + current = current.next + return None + + def replace_node(self, old_value: Any, new_value: Any) -> bool: + '''Заменить значение первого найденного узла''' + node = self.find_node(old_value) + if node: + node.data = new_value + return True + return False + + def remove_node(self, value: Any) -> bool: + '''Удалить первый узел с заданным значением''' + if self._head is None: + return False + + # Если удаляем голову + if self._head.data == value: + self.remove_first_node() + return True + + # Поиск элемента для удаления + current = self._head + while current.next: + if current.next.data == value: + current.next = current.next.next + return True + current = current.next + + return False +``` + +Версия 3: Добавлено хранение размера списка для оптимизации + +```python +class SingleLinkedListV3(SingleLinkedListV2): + def __init__(self) -> Self: + '''Инициализация с счетчиком размера''' + super().__init__() + self.size = 0 + + def insert_first_node(self, value: Any) -> None: + '''Добавление в начало с обновлением размера''' + super().insert_first_node(value) + self.size += 1 + + def insert_last_node(self, value: Any) -> None: + '''Добавление в конец с обновлением размера''' + super().insert_last_node(value) + self.size += 1 + + def remove_first_node(self) -> Any: + '''Удаление из начала с обновлением размера''' + result = super().remove_first_node() + self.size -= 1 + return result + + def remove_last_node(self) -> Any: + '''Удаление из конца с обновлением размера''' + result = super().remove_last_node() + self.size -= 1 + return result + + def remove_node(self, value: Any) -> bool: + '''Удаление узла по значению с обновлением размера''' + if super().remove_node(value): + self.size -= 1 + return True + return False + + def get_size(self) -> int: + '''Получение размера за O(1)''' + return self.size +``` + +Версия 4: Добавлены методы для работы с соседними узлами + +```python +class SingleLinkedListV4(SingleLinkedListV3): + def find_previous_node(self, value: Any) -> Any: + '''Найти значение предыдущего узла относительно узла с заданным значением''' + if self._head is None or self._head.data == value: + return None + + current = self._head + while current.next: + if current.next.data == value: + return current.data + current = current.next + return None + + def find_next_node(self, value: Any) -> Any: + '''Найти значение следующего узла относительно узла с заданным значением''' + node = self.find_node(value) + if node and node.next: + return node.next.data + return None + + def insert_before_node(self, target_value: Any, new_value: Any) -> bool: + '''Вставить новый узел перед узлом с заданным значением''' + if self._head is None: + return False + + # Вставка перед головой + if self._head.data == target_value: + self.insert_first_node(new_value) + return True + + # Поиск узла, предшествующего целевому + current = self._head + while current.next: + if current.next.data == target_value: + new_node = Node(new_value, current.next) + current.next = new_node + self.size += 1 + return True + current = current.next + + return False + + def insert_after_node(self, target_value: Any, new_value: Any) -> bool: + '''Вставить новый узел после узла с заданным значением''' + node = self.find_node(target_value) + if node: + new_node = Node(new_value, node.next) + node.next = new_node + self.size += 1 + return True + return False + + def replace_previous_node(self, target_value: Any, new_value: Any) -> bool: + '''Заменить значение в предыдущем узле относительно узла с заданным значением''' + if self._head is None or self._head.data == target_value: + return False # У головы нет предыдущего узла + + current = self._head + while current.next: + if current.next.data == target_value: + current.data = new_value + return True + current = current.next + return False + + def replace_next_node(self, target_value: Any, new_value: Any) -> bool: + '''Заменить значение в следующем узле относительно узла с заданным значением''' + node = self.find_node(target_value) + if node and node.next: + node.next.data = new_value + return True + return False + + def remove_previous_node(self, target_value: Any) -> Any: + '''Удалить предыдущий узел относительно узла с заданным значением''' + if self._head is None or self._head.data == target_value: + return None # У головы нет предыдущего узла + + # Если целевой узел - второй в списке + if self._head.next and self._head.next.data == target_value: + return self.remove_first_node() + + # Поиск узла, который находится за два до целевого + current = self._head + while current.next and current.next.next: + if current.next.next.data == target_value: + removed_data = current.next.data + current.next = current.next.next + self.size -= 1 + return removed_data + current = current.next + return None + + def remove_next_node(self, target_value: Any) -> Any: + '''Удалить следующий узел относительно узла с заданным значением''' + node = self.find_node(target_value) + if node and node.next: + removed_data = node.next.data + node.next = node.next.next + self.size -= 1 + return removed_data + return None +``` + +```python + +``` From 4a61ba520364bd1ea3f930195e664ca25aadf6fe Mon Sep 17 00:00:00 2001 From: po4k Date: Sun, 12 Oct 2025 20:15:59 +0300 Subject: [PATCH 19/26] =?UTF-8?q?=D0=B4=D0=BE=D0=B4=D0=B5=D0=BB=D0=B0?= =?UTF-8?q?=D0=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- labs/lab_03/Untitled.md | 372 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 370 insertions(+), 2 deletions(-) diff --git a/labs/lab_03/Untitled.md b/labs/lab_03/Untitled.md index a858e56..236396f 100644 --- a/labs/lab_03/Untitled.md +++ b/labs/lab_03/Untitled.md @@ -7,8 +7,9 @@ jupyter: format_version: '1.3' jupytext_version: 1.17.3 kernelspec: - display_name: '' - name: '' + display_name: Python 3 (ipykernel) + language: python + name: python3 --- ## Лабораторная работа №3 @@ -292,6 +293,373 @@ class SingleLinkedListV4(SingleLinkedListV3): return None ``` +Версия 5: Добавлен указатель на хвост для оптимизации операций + +```python +class SingleLinkedListV5(SingleLinkedListV4): + def __init__(self) -> Self: + '''Инициализация с указателем на хвост''' + super().__init__() + self._tail = None + + def insert_first_node(self, value: Any) -> None: + '''Добавление в начало с обновлением хвоста''' + super().insert_first_node(value) + if self.size == 1: + self._tail = self._head + + def insert_last_node(self, value: Any) -> None: + '''Добавление в конец за O(1) с использованием хвоста''' + if self._head is None: + self.insert_first_node(value) + else: + new_node = Node(value) + self._tail.next = new_node + self._tail = new_node + self.size += 1 + + def remove_first_node(self) -> Any: + '''Удаление из начала с обновлением хвоста''' + result = super().remove_first_node() + if self.size == 0: + self._tail = None + return result + + def remove_last_node(self) -> Any: + '''Удаление из конца с обновлением хвоста''' + if self._head is None: + raise ValueError("Список пуст") + + if self._head.next is None: + return self.remove_first_node() + + current = self._head + while current.next != self._tail: + current = current.next + + result = self._tail.data + current.next = None + self._tail = current + self.size -= 1 + + return result + + def find_node(self, value: Any) -> Node: + '''Оптимизированный поиск: O(1) для головы и хвоста''' + if self._head is None: + return None + + if self._head.data == value: + return self._head + + if self._tail and self._tail.data == value: + return self._tail + + return super().find_node(value) + + def insert_after_node(self, target_value: Any, new_value: Any) -> bool: + '''Оптимизированная вставка после узла: O(1) для хвоста''' + if self._tail and self._tail.data == target_value: + new_node = Node(new_value) + self._tail.next = new_node + self._tail = new_node + self.size += 1 + return True + + return super().insert_after_node(target_value, new_value) + + def replace_node(self, old_value: Any, new_value: Any) -> bool: + '''Оптимизированная замена: O(1) для головы и хвоста''' + if self._head is None: + return False + + if self._head.data == old_value: + self._head.data = new_value + return True + + if self._tail and self._tail.data == old_value: + self._tail.data = new_value + return True + + return super().replace_node(old_value, new_value) + + def remove_node(self, value: Any) -> bool: + '''Оптимизированное удаление: O(1) для головы и хвоста''' + if self._head is None: + return False + + if self._head.data == value: + self.remove_first_node() + return True + + if self._tail and self._tail.data == value: + self.remove_last_node() + return True + + return super().remove_node(value) + + def replace_next_node(self, target_value: Any, new_value: Any) -> bool: + '''Оптимизированная замена следующего узла: O(1) проверка для хвоста''' + if self._tail and self._tail.data == target_value: + return False + + return super().replace_next_node(target_value, new_value) + + def remove_next_node(self, target_value: Any) -> Any: + '''Оптимизированное удаление следующего узла: O(1) проверка для хвоста''' + if self._tail and self._tail.data == target_value: + return None + + return super().remove_next_node(target_value) + + def find_next_node(self, value: Any) -> Any: + '''Оптимизированный поиск следующего узла: O(1) проверка для хвоста''' + if self._tail and self._tail.data == value: + return None + + return super().find_next_node(value) + + def get_tail(self) -> Any: + '''Получить значение хвоста за O(1)''' + return self._tail.data if self._tail else None + + def __str__(self): + '''Строковое представление с информацией о хвосте''' + base_str = super().__str__() + tail_info = f" (tail: {self.get_tail()})" if self._tail else " (tail: None)" + return base_str + tail_info +``` + +Версия 6: Оптимизация операций через замену значений + ```python +class SingleLinkedListV6(SingleLinkedListV5): + + def insert_before_node_optimized(self, target_node: Node, new_value: Any) -> bool: + '''Оптимизированная вставка перед узлом за O(1) через замену значений''' + if target_node is None: + return False + + new_node = Node(target_node.data, target_node.next) + target_node.data = new_value + target_node.next = new_node + + if self._tail == target_node: + self._tail = new_node + + self.size += 1 + return True + + def remove_node_optimized(self, target_node: Node) -> Any: + '''Оптимизированное удаление узла за O(1) через замену значений''' + if target_node is None or target_node.next is None: + return None + + removed_data = target_node.data + target_node.data = target_node.next.data + target_node.next = target_node.next.next + + if target_node.next is None: + self._tail = target_node + + self.size -= 1 + return removed_data + + def remove_previous_node_optimized(self, target_node: Node) -> Any: + '''Оптимизированное удаление предыдущего узла за O(1)''' + if (target_node is None or self._head is None or + self._head == target_node or self._head.next == target_node): + return None + + if self._head.next == target_node: + return self.remove_first_node() + + # Находим узел за два до целевого + current = self._head + while current.next and current.next.next: + if current.next.next == target_node: + removed_data = current.next.data + current.next = target_node + self.size -= 1 + return removed_data + current = current.next + return None + + def insert_before_node(self, target_value: Any, new_value: Any) -> bool: + '''Переопределение для использования оптимизации при наличии узла''' + # Сначала пытаемся найти узел + target_node = self.find_node(target_value) + if target_node: + return self.insert_before_node_optimized(target_node, new_value) + return False + + def remove_node(self, value: Any) -> bool: + '''Переопределение для использования оптимизации при наличии узла''' + if self._head and self._head.data == value: + self.remove_first_node() + return True + + if self._tail and self._tail.data == value: + self.remove_last_node() + return True + + target_node = self.find_node(value) + if target_node: + self.remove_node_optimized(target_node) + return True + + return False + + def remove_previous_node(self, target_value: Any) -> Any: + '''Переопределение для использования оптимизации при наличии узла''' + if self._head is None or self._head.data == target_value: + return None + + target_node = self.find_node(target_value) + if target_node: + return self.remove_previous_node_optimized(target_node) + return None + + def reverse(self) -> None: + '''Переворот списка''' + prev = None + current = self._head + self._tail = self._head + + while current: + next_node = current.next + current.next = prev + prev = current + current = next_node + + self._head = prev + + def sort(self) -> None: + '''Сортировка списка (пузырьковая сортировка)''' + if self.size < 2: + return + + for i in range(self.size): + current = self._head + for j in range(self.size - i - 1): + if current.data > current.next.data: + current.data, current.next.data = current.next.data, current.data + current = current.next + + def is_sorted(self) -> bool: + ''' + Индивидуальное задание (вариант 6): + Проверить, является ли список упорядоченным по возрастанию + ''' + if self.size < 2: + return True + + current = self._head + while current.next: + if current.data > current.next.data: + return False + current = current.next + + return True + + def get_middle_node(self) -> Node: + '''Найти средний узел за один проход (для демонстрации)''' + if self._head is None: + return None + + slow = self._head + fast = self._head + + while fast and fast.next: + slow = slow.next + fast = fast.next.next + + return slow + #Задание 2 + + def reverse(self) -> None: + if self._head is None or self._head.next is None: + return + + prev = None + current = self._head + self._tail = self._head + + while current: + next_node = current.next + current.next = prev + prev = current + current = next_node + + self._head = prev + + #Задание 3 (сортировка вставками) + + def sort_insertion(self) -> None: + if self.size < 2: + return + + sorted_head = None + + current = self._head + while current: + next_node = current.next + + if sorted_head is None or current.data < sorted_head.data: + current.next = sorted_head + sorted_head = current + else: + temp = sorted_head + while temp.next and temp.next.data < current.data: + temp = temp.next + current.next = temp.next + temp.next = current + + current = next_node + + self._head = sorted_head + + if self._head: + current = self._head + while current.next: + current = current.next + self._tail = current +``` + +# Задание 2 +Сложность: O(n), Память: O(1) + +# Задание 3 +1. Лучший случай (уже отсортированный список): +- Вставка всегда происходит в начало: O(1) на элемент +- Итого: O(n) +2. Худший случай (обратно отсортированный список): +- Каждый новый элемент вставляется в конец отсортированной части +- Для i-го элемента нужно пройти i узлов +- Сумма: 1 + 2 + 3 + ... + (n-1) = n(n-1)/2 +- Итого: O(n²) +3. Средний случай: +- В среднем для каждого элемента нужно пройти половину отсортированной части +- Итого: O(n²) + +# Задание 4 + +```python +def remove_consecutive_duplicates(linked_list: 'SingleLinkedListV6') -> None: + if linked_list._head is None or linked_list._head.next is None: + return + + current = linked_list._head + + while current and current.next: + if current.data == current.next.data: + current.next = current.next.next + linked_list.size -= 1 + + if current.next is None: + linked_list._tail = current + else: + # Переходим к следующему узлу + current = current.next ``` From a5bc159de80ca2c4003dc4bc831eb25d92d4dd35 Mon Sep 17 00:00:00 2001 From: po4k Date: Sun, 12 Oct 2025 21:04:29 +0300 Subject: [PATCH 20/26] =?UTF-8?q?=D0=B4=D0=BE=D0=B1=D0=B0=D0=B2=D0=B8?= =?UTF-8?q?=D0=BB=20=D1=82=D0=B0=D0=B1=D0=BB=D0=B8=D1=87=D0=BA=D1=83?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- labs/lab_03/Untitled.md | 37 +++++++++++++++++++++++++------------ 1 file changed, 25 insertions(+), 12 deletions(-) diff --git a/labs/lab_03/Untitled.md b/labs/lab_03/Untitled.md index 236396f..3068fef 100644 --- a/labs/lab_03/Untitled.md +++ b/labs/lab_03/Untitled.md @@ -13,7 +13,7 @@ jupyter: --- ## Лабораторная работа №3 -# Вариант 6 +## Вариант 6 Цели лабораторной работы: - Изучить, что такое линейный список — структура данных, где элементы связаны ссылками, а не расположены подряд в памяти. - Научиться создавать и использовать односвязные линейные списки в программе. @@ -22,7 +22,7 @@ jupyter: - Научиться писать функции для обработки списков (например, удаление повторов, разворот, сортировка). - Приобрести умения структурного и модульного программирования через реализацию этих задач. -# Задание 1 +## Задание 1 Версия 1: ```python @@ -127,12 +127,10 @@ class SingleLinkedListV2(SingleLinkedListV1): if self._head is None: return False - # Если удаляем голову if self._head.data == value: self.remove_first_node() return True - # Поиск элемента для удаления current = self._head while current.next: if current.next.data == value: @@ -214,12 +212,10 @@ class SingleLinkedListV4(SingleLinkedListV3): if self._head is None: return False - # Вставка перед головой if self._head.data == target_value: self.insert_first_node(new_value) return True - # Поиск узла, предшествующего целевому current = self._head while current.next: if current.next.data == target_value: @@ -244,7 +240,7 @@ class SingleLinkedListV4(SingleLinkedListV3): def replace_previous_node(self, target_value: Any, new_value: Any) -> bool: '''Заменить значение в предыдущем узле относительно узла с заданным значением''' if self._head is None or self._head.data == target_value: - return False # У головы нет предыдущего узла + return False current = self._head while current.next: @@ -474,7 +470,6 @@ class SingleLinkedListV6(SingleLinkedListV5): if self._head.next == target_node: return self.remove_first_node() - # Находим узел за два до целевого current = self._head while current.next and current.next.next: if current.next.next == target_node: @@ -487,7 +482,6 @@ class SingleLinkedListV6(SingleLinkedListV5): def insert_before_node(self, target_value: Any, new_value: Any) -> bool: '''Переопределение для использования оптимизации при наличии узла''' - # Сначала пытаемся найти узел target_node = self.find_node(target_value) if target_node: return self.insert_before_node_optimized(target_node, new_value) @@ -627,10 +621,10 @@ class SingleLinkedListV6(SingleLinkedListV5): self._tail = current ``` -# Задание 2 +## Задание 2 Сложность: O(n), Память: O(1) -# Задание 3 +## Задание 3 1. Лучший случай (уже отсортированный список): - Вставка всегда происходит в начало: O(1) на элемент - Итого: O(n) @@ -643,7 +637,7 @@ class SingleLinkedListV6(SingleLinkedListV5): - В среднем для каждого элемента нужно пройти половину отсортированной части - Итого: O(n²) -# Задание 4 +## Задание 4 ```python def remove_consecutive_duplicates(linked_list: 'SingleLinkedListV6') -> None: @@ -663,3 +657,22 @@ def remove_consecutive_duplicates(linked_list: 'SingleLinkedListV6') -> None: # Переходим к следующему узлу current = current.next ``` + +## Таблица из контрольных вопросов +| Операция | Односвязный список (без tail) | Односвязный список (с tail) | Двусвязный список (с tail) | +| :--- | :---: | :---: | :---: | +| Вставка в начало | O(1) | O(1) | O(1) | +| Вставка в конец | O(n) | O(1) | O(1) | +| Удаление из начала | O(1) | O(1) | O(1) | +| Удаление из конца | O(n) | O(n) | O(1) | +| Поиск элемента по значению | O(n) | O(n) | O(n) | +| Вставка после известного узла | O(1) | O(1) | O(1) | +| Удаление известного узла | O(n) | O(n) | O(1) | +| Доступ к элементу по индексу | O(n) | O(n) | O(n) | + +## Выводы +- Линейные списки — это важная структура данных, позволяющая динамически хранить и обрабатывать упорядоченные наборы элементов без необходимости contiguous памяти. +- В ходе лабораторной работы были изучены основные виды списков (односвязный, двусвязный, кольцевой), а также реализованы базовые операции над ними: добавление, удаление, обход. +- Выполнение заданий позволило закрепить навыки работы с динамической памятью и освоить приемы структурного программирования на языке C++. +- Реализация функций обработки списков (удаление повторов, реверс, сортировка) помогла понять особенности алгоритмов и их временную сложность при работе со связными структурами. +- Полученные знания и практические навыки пригодятся при работе с более сложными структурами данных и алгоритмами в программировании. From 884ec0620af1a04530290a833a96e22a28e00d8d Mon Sep 17 00:00:00 2001 From: po4k Date: Mon, 13 Oct 2025 09:10:55 +0300 Subject: [PATCH 21/26] =?UTF-8?q?=D0=BA=D0=BE=D0=B5=20=D1=87=D1=82=D0=BE?= =?UTF-8?q?=20=D0=B8=D0=B7=D0=BC=D0=B5=D0=BD=D0=BB=D0=B8=D0=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- labs/lab_03/Untitled.md | 20 +------------------- 1 file changed, 1 insertion(+), 19 deletions(-) diff --git a/labs/lab_03/Untitled.md b/labs/lab_03/Untitled.md index 3068fef..2a1c6a4 100644 --- a/labs/lab_03/Untitled.md +++ b/labs/lab_03/Untitled.md @@ -261,13 +261,11 @@ class SingleLinkedListV4(SingleLinkedListV3): def remove_previous_node(self, target_value: Any) -> Any: '''Удалить предыдущий узел относительно узла с заданным значением''' if self._head is None or self._head.data == target_value: - return None # У головы нет предыдущего узла + return None - # Если целевой узел - второй в списке if self._head.next and self._head.next.data == target_value: return self.remove_first_node() - # Поиск узла, который находится за два до целевого current = self._head while current.next and current.next.next: if current.next.next.data == target_value: @@ -540,22 +538,6 @@ class SingleLinkedListV6(SingleLinkedListV5): current.data, current.next.data = current.next.data, current.data current = current.next - def is_sorted(self) -> bool: - ''' - Индивидуальное задание (вариант 6): - Проверить, является ли список упорядоченным по возрастанию - ''' - if self.size < 2: - return True - - current = self._head - while current.next: - if current.data > current.next.data: - return False - current = current.next - - return True - def get_middle_node(self) -> Node: '''Найти средний узел за один проход (для демонстрации)''' if self._head is None: From c3e5ee6872adbeee7f524d8d3954516088b5d0a1 Mon Sep 17 00:00:00 2001 From: Evgenii-afk <69784610+Evgenii-afk@users.noreply.github.com> Date: Mon, 13 Oct 2025 09:17:14 +0300 Subject: [PATCH 22/26] Update Untitled.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit убрал лишнее --- labs/lab_03/Untitled.md | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/labs/lab_03/Untitled.md b/labs/lab_03/Untitled.md index 2a1c6a4..056b7c5 100644 --- a/labs/lab_03/Untitled.md +++ b/labs/lab_03/Untitled.md @@ -512,20 +512,6 @@ class SingleLinkedListV6(SingleLinkedListV5): return self.remove_previous_node_optimized(target_node) return None - def reverse(self) -> None: - '''Переворот списка''' - prev = None - current = self._head - self._tail = self._head - - while current: - next_node = current.next - current.next = prev - prev = current - current = next_node - - self._head = prev - def sort(self) -> None: '''Сортировка списка (пузырьковая сортировка)''' if self.size < 2: From bbdfaa5ab5514a8e61035babdaecbb468fd49c45 Mon Sep 17 00:00:00 2001 From: po4k Date: Sun, 19 Oct 2025 18:53:15 +0300 Subject: [PATCH 23/26] lab 4 --- labs/lab_04/Untitled.md | 577 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 577 insertions(+) create mode 100644 labs/lab_04/Untitled.md diff --git a/labs/lab_04/Untitled.md b/labs/lab_04/Untitled.md new file mode 100644 index 0000000..fd12007 --- /dev/null +++ b/labs/lab_04/Untitled.md @@ -0,0 +1,577 @@ +--- +jupyter: + jupytext: + text_representation: + extension: .md + format_name: markdown + format_version: '1.3' + jupytext_version: 1.17.3 + kernelspec: + display_name: Python 3 (ipykernel) + language: python + name: python3 +--- + +## Лаборатрная работа №4 +Цели: +- Познакомиться со структурами данных стек, очередь и дек, понять, как они устроены и работают. +- Научиться реализовывать эти структуры на основе массивов и связных списков. +- Изучить основные операции для каждой структуры (добавление, удаление, просмотр элементов). +- На практике применить стек для решения задач: проверка правильности скобок и вычисление выражений в обратной польской записи. +- Освоить перевод математических выражений из обычной записи в постфиксную форму. +### Базовые классы: + +```python +class Stack: + """Базовый класс стека""" + def __init__(self): + self.items = [] + + def push(self, item): + raise NotImplementedError("Метод должен быть реализован в подклассе") + + def pop(self): + raise NotImplementedError("Метод должен быть реализован в подклассе") + + def peek(self): + raise NotImplementedError("Метод должен быть реализован в подклассе") + + def is_empty(self): + raise NotImplementedError("Метод должен быть реализован в подклассе") + + def size(self): + raise NotImplementedError("Метод должен быть реализован в подклассе") + +class Queue: + """Базовый класс очереди""" + def __init__(self): + self.items = [] + + def enqueue(self, item): + raise NotImplementedError("Метод должен быть реализован в подклассе") + + def dequeue(self): + raise NotImplementedError("Метод должен быть реализован в подклассе") + + def front(self): + raise NotImplementedError("Метод должен быть реализован в подклассе") + + def is_empty(self): + raise NotImplementedError("Метод должен быть реализован в подклассе") + + def size(self): + raise NotImplementedError("Метод должен быть реализован в подклассе") + +class Deque: + """Базовый класс дека с методами по ТЗ""" + def __init__(self): + self.items = [] + + def insert_left(self, value): + raise NotImplementedError("Метод должен быть реализован в подклассе") + + def insert_right(self, value): + raise NotImplementedError("Метод должен быть реализован в подклассе") + + def remove_left(self): + raise NotImplementedError("Метод должен быть реализован в подклассе") + + def remove_right(self): + raise NotImplementedError("Метод должен быть реализован в подклассе") + + def get_left(self): + raise NotImplementedError("Метод должен быть реализован в подклассе") + + def get_right(self): + raise NotImplementedError("Метод должен быть реализован в подклассе") + + def is_empty(self): + raise NotImplementedError("Метод должен быть реализован в подклассе") + + def size(self): + raise NotImplementedError("Метод должен быть реализован в подклассе") +``` + +### Задание 1 +1. Реализовать стек на основе массива + +```python +class ArrayStack(Stack): + def __init__(self): + super().__init__() + self.items = [] + + def push(self, item): + self.items.append(item) + + def pop(self): + if self.is_empty(): + raise IndexError("Стек пуст") + return self.items.pop() + + def peek(self): + if self.is_empty(): + raise IndexError("Стек пуст") + return self.items[-1] + + def is_empty(self): + return len(self.items) == 0 + + def size(self): + return len(self.items) + + def __str__(self): + return f"ArrayStack({self.items})" +``` + +2. Реализовать стек на основе связного списка. + +```python +class Node: + """Узел связного списка""" + def __init__(self, data): + self.data = data + self.next = None + +class LinkedListStack(Stack): + def __init__(self): + super().__init__() + self.head = None + self._size = 0 + + def push(self, item): + new_node = Node(item) + new_node.next = self.head + self.head = new_node + self._size += 1 + + def pop(self): + if self.is_empty(): + raise IndexError("Стек пуст") + data = self.head.data + self.head = self.head.next + self._size -= 1 + return data + + def peek(self): + if self.is_empty(): + raise IndexError("Стек пуст") + return self.head.data + + def is_empty(self): + return self.head is None + + def size(self): + return self._size + + def __str__(self): + items = [] + current = self.head + while current: + items.append(current.data) + current = current.next + return f"LinkedListStack({items})" +``` + +3. Реализовать очередь на основе массива. + +```python +class ArrayQueue(Queue): + def __init__(self): + super().__init__() + self.items = [] + + def enqueue(self, item): + self.items.append(item) + + def dequeue(self): + if self.is_empty(): + raise IndexError("Очередь пуста") + return self.items.pop(0) + + def front(self): + if self.is_empty(): + raise IndexError("Очередь пуста") + return self.items[0] + + def is_empty(self): + return len(self.items) == 0 + + def size(self): + return len(self.items) + + def __str__(self): + return f"ArrayQueue({self.items})" +``` + +4. Реализовать очередь на основе связного списка. + +```python +class LinkedListQueue(Queue): + def __init__(self): + super().__init__() + self.head = None + self.tail = None + self._size = 0 + + def enqueue(self, item): + new_node = Node(item) + if self.is_empty(): + self.head = self.tail = new_node + else: + self.tail.next = new_node + self.tail = new_node + self._size += 1 + + def dequeue(self): + if self.is_empty(): + raise IndexError("Очередь пуста") + data = self.head.data + self.head = self.head.next + if self.head is None: + self.tail = None + self._size -= 1 + return data + + def front(self): + if self.is_empty(): + raise IndexError("Очередь пуста") + return self.head.data + + def is_empty(self): + return self.head is None + + def size(self): + return self._size + + def __str__(self): + items = [] + current = self.head + while current: + items.append(current.data) + current = current.next + return f"LinkedListQueue({items})" +``` + +5. Реализовать дек на основе массива. + +```python +class ArrayDeque(Deque): + """Дек на основе массива""" + def __init__(self): + super().__init__() + self.items = [] + + def insert_left(self, value): + """Помещает объект на левый конец дека""" + self.items.insert(0, value) + + def insert_right(self, value): + """Помещает объект на правый конец дека""" + self.items.append(value) + + def remove_left(self): + """Удаляет первый объект с левого конца дека и возвращает его""" + if self.is_empty(): + raise IndexError("Дек пуст") + return self.items.pop(0) + + def remove_right(self): + """Удаляет первый объект с правого конца дека и возвращает его""" + if self.is_empty(): + raise IndexError("Дек пуст") + return self.items.pop() + + def get_left(self): + """Возвращает первый объект с левого конца дека не удаляя его""" + if self.is_empty(): + raise IndexError("Дек пуст") + return self.items[0] + + def get_right(self): + """Возвращает первый объект с правого конца дека не удаляя его""" + if self.is_empty(): + raise IndexError("Дек пуст") + return self.items[-1] + + def is_empty(self): + return len(self.items) == 0 + + def size(self): + return len(self.items) + + def __str__(self): + return f"ArrayDeque({self.items})" +``` + +6. Реализовать дек на основе связного списка. + +```python +class LinkedListDeque(Deque): + """Дек на основе связного списка с методами по ТЗ""" + def __init__(self): + super().__init__() + self.head = None + self.tail = None + self._size = 0 + + def insert_left(self, value): + """Помещает объект на левый конец дека""" + new_node = DoublyNode(value) + if self.is_empty(): + self.head = self.tail = new_node + else: + new_node.next = self.head + self.head.prev = new_node + self.head = new_node + self._size += 1 + + def insert_right(self, value): + """Помещает объект на правый конец дека""" + new_node = DoublyNode(value) + if self.is_empty(): + self.head = self.tail = new_node + else: + new_node.prev = self.tail + self.tail.next = new_node + self.tail = new_node + self._size += 1 + + def remove_left(self): + """Удаляет первый объект с левого конца дека и возвращает его""" + if self.is_empty(): + raise IndexError("Дек пуст") + data = self.head.data + if self.head == self.tail: + self.head = self.tail = None + else: + self.head = self.head.next + self.head.prev = None + self._size -= 1 + return data + + def remove_right(self): + """Удаляет первый объект с правого конца дека и возвращает его""" + if self.is_empty(): + raise IndexError("Дек пуст") + data = self.tail.data + if self.head == self.tail: + self.head = self.tail = None + else: + self.tail = self.tail.prev + self.tail.next = None + self._size -= 1 + return data + + def get_left(self): + """Возвращает первый объект с левого конца дека не удаляя его""" + if self.is_empty(): + raise IndexError("Дек пуст") + return self.head.data + + def get_right(self): + """Возвращает первый объект с правого конца дека не удаляя его""" + if self.is_empty(): + raise IndexError("Дек пуст") + return self.tail.data + + def is_empty(self): + return self.head is None + + def size(self): + return self._size + + def __str__(self): + items = [] + current = self.head + while current: + items.append(current.data) + current = current.next + return f"LinkedListDeque({items})" +``` + +### Задание 2 +Используя операции со стеком, написать программу, проверяющую своевременность закрытия скобок «(, ), [, ] ,{, }» в строке символов (строка состоит из одних скобок этих типов). + +В процессе решения анализируются символы строки. Если встречена одна из открывающихся скобок, то она записывается в стек. При обнаружении закрывающейся скобки, соответствующей скобке, находящейся в вершине стека, последняя удаляется. При несоответствии скобки выдается сообщение об ошибке, которое фиксируется в логической переменной. + +```python +def check_brackets(expression): + """ + Проверяет корректность расстановки скобок в выражении + Возвращает True если скобки расставлены правильно, False в противном случае + """ + stack = ArrayStack() + brackets = {'(': ')', '[': ']', '{': '}'} + + for char in expression: + if char in brackets.keys(): + stack.push(char) + elif char in brackets.values(): + if stack.is_empty(): + return False + opening_bracket = stack.pop() + if brackets[opening_bracket] != char: + return False + + return stack.is_empty() + +def test_bracket_checker(): + test_cases = [ + ("()", True), + ("()[]{}", True), + ("(]", False), + ("([)]", False), + ("{[]}", True), + ("((()))", True), + ("((())", False), + ("", True) + ] + + print("Тестирование проверки скобочной последовательности:") + print("=" * 55) + print(f"{'Выражение':<15} {'Результат':<10} {'Ожидалось':<10} {'Статус':<6}") + print("-" * 55) + + for expr, expected in test_cases: + result = check_brackets(expr) + status = "✓" if result == expected else "✗" + print(f"{expr:<15} {str(result):<10} {str(expected):<10} {status:<6}") + + print("=" * 55) + +test_bracket_checker() +``` + +### Задание 3 + +Написать программу вычисления значения выражения, представленного в обратной польской записи (в постфиксной записи). Выражение состоит из цифр от 1 до 9 и знаков операции. + +| Обычная (инфиксная) запись | Обратная польская (постфиксная) запись | +|:---|:---| +| (a+b) * c | a b + c * | +| a + (b+c)*d | a b c + d * + | + +Просматривая строку, анализируем очередной символ, если это: + - цифра, то записываем ее в стек; + - знак, то читаем два элемента из стека, выполняем математическую операцию, определяемую этим знаком, и заносим результат в стек. + +После просмотра всей строки в стеке должен оставаться один элемент, он и является решением задачи. + +```python +def evaluate_rpn(expression): + """ + Вычисляет значение выражения в обратной польской записи + """ + stack = ArrayStack() + operators = { + '+': lambda x, y: x + y, + '-': lambda x, y: x - y, + '*': lambda x, y: x * y, + '/': lambda x, y: x / y + } + + for token in expression.split(): + if token.isdigit() or (token[0] == '-' and token[1:].isdigit()): + stack.push(float(token)) + elif token in operators: + if stack.size() < 2: + raise ValueError("Недостаточно операндов для операции") + y = stack.pop() + x = stack.pop() + result = operators[token](x, y) + stack.push(result) + else: + raise ValueError(f"Неизвестный токен: {token}") + + if stack.size() != 1: + raise ValueError("Некорректное выражение") + + return stack.pop() + +def test_rpn_evaluator(): + test_cases = [ + ("3 4 +", 7), + ("5 2 * 3 +", 13), + ("10 5 / 2 *", 4), + ("4 2 + 3 * 6 -", 12), + ("1 2 + 4 * 3 +", 15) + ] + + print("Тестирование вычисления RPN выражений:") + print("-" * 50) + for expr, expected in test_cases: + result = evaluate_rpn(expr) + status = "Правильно" if abs(result - expected) < 1e-9 else "Не правиильно" + print(f"{status} '{expr}' = {result} (ожидалось: {expected})") + print() + +test_rpn_evaluator() +``` + +### Задание 4 +Реализовать перевод математических выражений из инфиксной в постфиксную форму записи. + +```python +def infix_to_postfix(expression): + """ + Переводит инфиксное выражение в постфиксную запись (обратную польскую) + """ + precedence = {'+': 1, '-': 1, '*': 2, '/': 2, '^': 3} + + output = [] + stack = ArrayStack() + + for token in expression.split(): + if token.isdigit() or (token[0] == '-' and token[1:].isdigit()): + output.append(token) + elif token == '(': + stack.push(token) + elif token == ')': + while not stack.is_empty() and stack.peek() != '(': + output.append(stack.pop()) + stack.pop() + elif token in precedence: + while (not stack.is_empty() and + stack.peek() != '(' and + precedence.get(stack.peek(), 0) >= precedence[token]): + output.append(stack.pop()) + stack.push(token) + + while not stack.is_empty(): + output.append(stack.pop()) + + return ' '.join(output) + +def test_infix_to_postfix(): + test_cases = [ + ("3 + 4", "3 4 +"), + ("3 + 4 * 2", "3 4 2 * +"), + ("( 3 + 4 ) * 2", "3 4 + 2 *"), + ("3 + 4 * 2 / ( 1 - 5 )", "3 4 2 * 1 5 - / +"), + ("a + b * c", "a b c * +") + ] + + print("Тестирование перевода из инфиксной в постфиксную запись:") + print("-" * 50) + for infix, expected_postfix in test_cases: + result = infix_to_postfix(infix) + status = "Правиьно" if result == expected_postfix else "Не правильно" + print(f"{status} '{infix}' -> '{result}' (ожидалось: '{expected_postfix}')") + print() + +test_infix_to_postfix() +``` + +### Контрольные вопросы + +| Операция | Стек (список) | Очередь (список) | Дек (двусвязный список) | Дек (массив) | +| :--- | :---: | :---: | :---: | :---: | +| `push` / `enqueue` / `pushBack` | **O(1)** | **O(1)** | **O(1)** | **O(1)*** | +| `pop` / `dequeue` / `popBack` | **O(1)** | **O(1)** | **O(1)** | **O(1)*** | +| `pushFront` | — | — | **O(1)** | **O(n)** | +| `popFront` | — | — | **O(1)** | **O(n)** | +| `peek` / `front` / `back` | **O(1)** | **O(1)** | **O(1)** | **O(1)** | +| `isEmpty` | **O(1)** | **O(1)** | **O(1)** | **O(1)** | + + From 761a31fc10840ff3334698cb5a6e92116d1844ac Mon Sep 17 00:00:00 2001 From: po4k Date: Sat, 25 Oct 2025 09:39:23 +0300 Subject: [PATCH 24/26] add two task lab_05 --- labs/lab_05/Untitled.md | 252 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 252 insertions(+) create mode 100644 labs/lab_05/Untitled.md diff --git a/labs/lab_05/Untitled.md b/labs/lab_05/Untitled.md new file mode 100644 index 0000000..e442cc3 --- /dev/null +++ b/labs/lab_05/Untitled.md @@ -0,0 +1,252 @@ +--- +jupyter: + jupytext: + text_representation: + extension: .md + format_name: markdown + format_version: '1.3' + jupytext_version: 1.17.3 + kernelspec: + display_name: Python 3 (ipykernel) + language: python + name: python3 +--- + +## Хеш-функции и хеш-таблицы + +## Задание 1: + +```python +class HashTableChaining: + def __init__(self, size=10): + self.size = size + self.table = [[] for _ in range(size)] + self.count = 0 + + def _hash(self, key): + return hash(key) % self.size + + def insert(self, key, value): + index = self._hash(key) + bucket = self.table[index] + + for i, (k, v) in enumerate(bucket): + if k == key: + bucket[i] = (key, value) + return + + bucket.append((key, value)) + self.count += 1 + + if self.count / self.size > 0.7: + self._rehash() + + def search(self, key): + index = self._hash(key) + bucket = self.table[index] + + for k, v in bucket: + if k == key: + return v + return None + + def delete(self, key): + index = self._hash(key) + bucket = self.table[index] + + for i, (k, v) in enumerate(bucket): + if k == key: + del bucket[i] + self.count -= 1 + return True + return False + + def _rehash(self): + old_table = self.table + self.size *= 2 + self.table = [[] for _ in range(self.size)] + self.count = 0 + + for bucket in old_table: + for key, value in bucket: + self.insert(key, value) + + def __str__(self): + result = [] + for i, bucket in enumerate(self.table): + if bucket: + result.append(f"{i}: {bucket}") + return "\n".join(result) +``` + +Тест: + +```python +print("=== Тестирование HashTableChaining ===") + +ht = HashTableChaining(5) + +ht.insert("apple", 1) +ht.insert("banana", 2) +ht.insert("cherry", 3) + +assert ht.search("apple") == 1, "Ошибка поиска apple" +assert ht.search("banana") == 2, "Ошибка поиска banana" +assert ht.search("cherry") == 3, "Ошибка поиска cherry" +assert ht.search("unknown") is None, "Ошибка поиска неизвестного ключа" +print("✓ Тест вставки и поиска пройден") + +ht.insert("apple", 10) +assert ht.search("apple") == 10, "Ошибка обновления значения" +print("✓ Тест обновления значения пройден") + +# Тест удаления +assert ht.delete("banana") == True, "Ошибка удаления существующего ключа" +assert ht.search("banana") is None, "Ошибка: ключ не удален" +assert ht.delete("unknown") == False, "Ошибка удаления несуществующего ключа" +print("✓ Тест удаления пройден") + +ht2 = HashTableChaining(1) +ht2.insert("key1", "value1") +ht2.insert("key2", "value2") +ht2.insert("key3", "value3") + +assert ht2.search("key1") == "value1", "Ошибка при коллизии" +assert ht2.search("key2") == "value2", "Ошибка при коллизии" +assert ht2.search("key3") == "value3", "Ошибка при коллизии" +print("✓ Тест коллизий пройден") + +print("Все тесты HashTableChaining пройдены успешно!\n") +``` + +## Задание 2: + +```python +class HashTableOpenAddressing: + def __init__(self, size=10): + self.size = size + self.table = [None] * size + self.count = 0 + self.DELETED = object() + + def _hash(self, key, i=0): + return (hash(key) + i) % self.size + + def insert(self, key, value): + if self.count / self.size > 0.7: + self._rehash() + + i = 0 + while i < self.size: + index = self._hash(key, i) + + if self.table[index] is None or self.table[index] is self.DELETED: + self.table[index] = (key, value) + self.count += 1 + return + elif self.table[index][0] == key: + self.table[index] = (key, value) + return + + i += 1 + + self._rehash() + self.insert(key, value) + + def search(self, key): + i = 0 + while i < self.size: + index = self._hash(key, i) + + if self.table[index] is None: + return None + elif self.table[index] is not self.DELETED and self.table[index][0] == key: + return self.table[index][1] + + i += 1 + + return None + + def delete(self, key): + i = 0 + while i < self.size: + index = self._hash(key, i) + + if self.table[index] is None: + return False + elif self.table[index] is not self.DELETED and self.table[index][0] == key: + self.table[index] = self.DELETED + self.count -= 1 + return True + + i += 1 + + return False + + def _rehash(self): + old_table = self.table + self.size *= 2 + self.table = [None] * self.size + self.count = 0 + + for item in old_table: + if item is not None and item is not self.DELETED: + self.insert(item[0], item[1]) + + def __str__(self): + result = [] + for i, item in enumerate(self.table): + if item is not None and item is not self.DELETED: + result.append(f"{i}: {item}") + elif item is self.DELETED: + result.append(f"{i}: DELETED") + return "\n".join(result) +``` + +Тесты + +```python +print("=== Тестирование HashTableOpenAddressing ===") + +# Создаем хеш-таблицу +ht = HashTableOpenAddressing(5) + +# Тест вставки и поиска +ht.insert("apple", 1) +ht.insert("banana", 2) +ht.insert("cherry", 3) + +assert ht.search("apple") == 1, "Ошибка поиска apple" +assert ht.search("banana") == 2, "Ошибка поиска banana" +assert ht.search("cherry") == 3, "Ошибка поиска cherry" +assert ht.search("unknown") is None, "Ошибка поиска неизвестного ключа" +print("✓ Тест вставки и поиска пройден") + +# Тест обновления значения +ht.insert("apple", 10) +assert ht.search("apple") == 10, "Ошибка обновления значения" +print("✓ Тест обновления значения пройден") + +# Тест удаления +assert ht.delete("banana") == True, "Ошибка удаления существующего ключа" +assert ht.search("banana") is None, "Ошибка: ключ не удален" +assert ht.delete("unknown") == False, "Ошибка удаления несуществующего ключа" +print("✓ Тест удаления пройден") + +# Тест коллизий +ht2 = HashTableOpenAddressing(3) +ht2.insert("key1", "value1") +ht2.insert("key2", "value2") +ht2.insert("key3", "value3") + +assert ht2.search("key1") == "value1", "Ошибка при коллизии" +assert ht2.search("key2") == "value2", "Ошибка при коллизии" +assert ht2.search("key3") == "value3", "Ошибка при коллизии" +print("✓ Тест коллизий пройден") + +print("Все тесты HashTableOpenAddressing пройдены успешно!\n") +``` + +```python + +``` From 3fd0d0b3e25fba1c35950e3fea01284ad9055ccc Mon Sep 17 00:00:00 2001 From: po4k Date: Sun, 26 Oct 2025 16:01:40 +0300 Subject: [PATCH 25/26] lab 5 done --- labs/lab_05/Untitled.md | 196 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 191 insertions(+), 5 deletions(-) diff --git a/labs/lab_05/Untitled.md b/labs/lab_05/Untitled.md index e442cc3..945dcea 100644 --- a/labs/lab_05/Untitled.md +++ b/labs/lab_05/Untitled.md @@ -208,10 +208,8 @@ class HashTableOpenAddressing: ```python print("=== Тестирование HashTableOpenAddressing ===") -# Создаем хеш-таблицу ht = HashTableOpenAddressing(5) -# Тест вставки и поиска ht.insert("apple", 1) ht.insert("banana", 2) ht.insert("cherry", 3) @@ -222,18 +220,15 @@ assert ht.search("cherry") == 3, "Ошибка поиска cherry" assert ht.search("unknown") is None, "Ошибка поиска неизвестного ключа" print("✓ Тест вставки и поиска пройден") -# Тест обновления значения ht.insert("apple", 10) assert ht.search("apple") == 10, "Ошибка обновления значения" print("✓ Тест обновления значения пройден") -# Тест удаления assert ht.delete("banana") == True, "Ошибка удаления существующего ключа" assert ht.search("banana") is None, "Ошибка: ключ не удален" assert ht.delete("unknown") == False, "Ошибка удаления несуществующего ключа" print("✓ Тест удаления пройден") -# Тест коллизий ht2 = HashTableOpenAddressing(3) ht2.insert("key1", "value1") ht2.insert("key2", "value2") @@ -247,6 +242,197 @@ print("✓ Тест коллизий пройден") print("Все тесты HashTableOpenAddressing пройдены успешно!\n") ``` +## Задание 4 + +```python +def array_intersection_custom(arr1, arr2): + """Проверка пересечения массивов через нашу хеш-таблицу""" + ht = HashTableChaining(len(arr1)) + + for item in arr1: + ht.insert(item, True) + + for item in arr2: + if ht.search(item) is not None: + return True + + return False + +print("=== Пересечение через HashTableChaining ===") +arr1 = [1, 2, 3, 4, 5] +arr2 = [4, 5, 6, 7, 8] +result = array_intersection_custom(arr1, arr2) +print(f"Массивы {arr1} и {arr2} пересекаются: {result}") +``` + +## Здание 5 + +```python +def has_unique_elements(arr): + """Проверка уникальности""" + ht = HashTableOpenAddressing(len(arr)) + + for item in arr: + if ht.search(item) is not None: + return False + ht.insert(item, True) + + return True + + +print("\n=== Уникальность через HashTableOpenAddressing ===") +arr = [1, 2, 3, 2, 4, 1] +arr2 = [1, 3, 4, 6] +print(f"Массив {arr} уникален: {has_unique_elements(arr)}") +print(f"Массив {arr2} уникален: {has_unique_elements(arr2)}") +``` + +## Задание 6 + +```python +def find_pairs_with_sum(arr, target_sum): + """Поиск пар с заданной суммой""" + ht = HashTableChaining(len(arr)) + pairs = [] + + for num in arr: + complement = target_sum - num + + if ht.search(complement) is not None: + pairs.append((complement, num)) + + ht.insert(num, True) + + return pairs + +print("\n=== Пары с суммой через HashTableChaining ===") +arr = [1, 4, 2, 3, 5, 6, 7] +target = 7 +pairs = find_pairs_with_sum(arr, target) +print(f"Пары с суммой {target} в {arr}: {pairs}") +``` + +## Задание 7 + +```python +def are_anagrams_custom(str1, str2): + """Проверка анаграмм через нашу хеш-таблицу""" + if len(str1) != len(str2): + return False + + ht = HashTableOpenAddressing(26) + + for char in str1: + current_count = ht.search(char) + if current_count is None: + ht.insert(char, 1) + else: + ht.insert(char, current_count + 1) + + for char in str2: + current_count = ht.search(char) + if current_count is None or current_count == 0: + return False + ht.insert(char, current_count - 1) + + return True + +print("\n=== Анаграммы через HashTableOpenAddressing ===") +str1 = "listen" +str2 = "silent" +print(f"'{str1}' и '{str2}' - анаграммы: {are_anagrams_custom(str1, str2)}") +``` + +## Задание 2 + +```python +import hashlib +import time +import json + +class Block: + def __init__(self, data, previous_hash=""): + self.timestamp = time.time() + self.data = data + self.previous_hash = previous_hash + self.hash = self.calculate_hash() + + def calculate_hash(self): + """Вычисляет хеш блока на основе его данных""" + import hashlib + data_string = f"{self.timestamp}{self.data}{self.previous_hash}" + return hashlib.sha256(data_string.encode()).hexdigest() + + def __str__(self): + return f"Данные: {self.data}\nХеш: {self.hash[:20]}...\nПредыдущий: {self.previous_hash[:20]}...\n" + +class BlockchainWithCustomHashTable: + def __init__(self): + self.chain = HashTableChaining(10) + self.current_hash = None + self.create_genesis_block() + + def create_genesis_block(self): + """Создает генезис-блок используя нашу хеш-таблицу""" + genesis_data = "Genesis Block" + genesis_hash = self._calculate_hash(genesis_data, "0") + self.chain.insert(genesis_hash, Block(genesis_data, "0")) + self.current_hash = genesis_hash + print("✓ Создан генезис-блок (в нашей хеш-таблице)") + + def _calculate_hash(self, data, previous_hash): + """Вычисляет хеш для блока""" + import hashlib + data_string = f"{data}{previous_hash}" + return hashlib.sha256(data_string.encode()).hexdigest() + + def add_block(self, data): + """Добавляет блок используя нашу хеш-таблицу""" + previous_hash = self.current_hash + new_hash = self._calculate_hash(data, previous_hash) + + new_block = Block(data, previous_hash) + self.chain.insert(new_hash, new_block) + self.current_hash = new_hash + + print(f"✓ Добавлен блок: {data}") + return new_hash + + def is_chain_valid(self): + """Проверяет целостность через нашу хеш-таблицу""" + current = self.current_hash + + while current: + block = self.chain.search(current) + if not block: + return False + + previous_hash = block.previous_hash + + if previous_hash == "0": + return True + + if block.calculate_hash() != current: + return False + + current = previous_hash + + return False + +def test_custom_blockchain(): + print("\n" + "="*60) + print("БЛОКЧЕЙН С НАШЕЙ HASHTableChaining") + print("="*60) + + blockchain = BlockchainWithCustomHashTable() + blockchain.add_block("Транзакция 1: Alice -> Bob") + blockchain.add_block("Транзакция 2: Bob -> Carol") + + print(f"✓ Цепочка валидна: {blockchain.is_chain_valid()}") + +test_custom_blockchain() +``` + ```python ``` From 33d6556e27236ca2aa1c180b2c0e1314804ad579 Mon Sep 17 00:00:00 2001 From: po4k Date: Mon, 27 Oct 2025 12:34:47 +0300 Subject: [PATCH 26/26] done --- labs/lab_05/Untitled.md | 1 - 1 file changed, 1 deletion(-) diff --git a/labs/lab_05/Untitled.md b/labs/lab_05/Untitled.md index 945dcea..c563e73 100644 --- a/labs/lab_05/Untitled.md +++ b/labs/lab_05/Untitled.md @@ -100,7 +100,6 @@ ht.insert("apple", 10) assert ht.search("apple") == 10, "Ошибка обновления значения" print("✓ Тест обновления значения пройден") -# Тест удаления assert ht.delete("banana") == True, "Ошибка удаления существующего ключа" assert ht.search("banana") is None, "Ошибка: ключ не удален" assert ht.delete("unknown") == False, "Ошибка удаления несуществующего ключа"