From c936d7d5739e5dd416d970b984378b446e9fa663 Mon Sep 17 00:00:00 2001 From: FaultyBranches Date: Tue, 2 Dec 2025 07:55:08 -0600 Subject: [PATCH] feat: Redo of the AoC repo starting over with 2015 and keeping up with 2025 (completed day 2 so far) --- 15/1/__pycache__/main.cpython-313.pyc | Bin 0 -> 1908 bytes .../test_day1.cpython-313-pytest-8.4.2.pyc | Bin 0 -> 1840 bytes .../test_day1.cpython-313-pytest-9.0.1.pyc | Bin 0 -> 3128 bytes 15/1/main.py | 59 ++++++++++++ 15/1/test_day1.py | 28 ++++++ 15/2/__pycache__/main.cpython-313.pyc | Bin 0 -> 1956 bytes .../test_day2.cpython-313-pytest-9.0.1.pyc | Bin 0 -> 5232 bytes 15/2/main.py | 38 ++++++++ 15/2/test_day2.py | 27 ++++++ 15/3/__pycache__/main.cpython-313.pyc | Bin 0 -> 2453 bytes .../test_day3.cpython-313-pytest-9.0.1.pyc | Bin 0 -> 3015 bytes 15/3/main.py | 66 +++++++++++++ 15/3/test_day3.py | 20 ++++ 15/4/__pycache__/main.cpython-313.pyc | Bin 0 -> 1108 bytes .../test_main.cpython-313-pytest-9.0.1.pyc | Bin 0 -> 2005 bytes 15/4/main.py | 26 ++++++ 15/4/test_main.py | 11 +++ 15/5/__pycache__/main.cpython-313.pyc | Bin 0 -> 3317 bytes .../test_main.cpython-313-pytest-9.0.1.pyc | Bin 0 -> 9332 bytes 15/5/main.py | 81 ++++++++++++++++ 15/5/test_main.py | 77 ++++++++++++++++ 25/1/__pycache__/main.cpython-313.pyc | Bin 0 -> 2290 bytes .../test_main.cpython-313-pytest-9.0.1.pyc | Bin 0 -> 3784 bytes 25/1/main.py | 59 ++++++++++++ 25/1/test_main.py | 41 +++++++++ 25/2/__pycache__/main.cpython-313.pyc | Bin 0 -> 2621 bytes .../test_main.cpython-313-pytest-9.0.1.pyc | Bin 0 -> 5874 bytes 25/2/main.py | 48 ++++++++++ 25/2/test_main.py | 87 ++++++++++++++++++ 29 files changed, 668 insertions(+) create mode 100644 15/1/__pycache__/main.cpython-313.pyc create mode 100644 15/1/__pycache__/test_day1.cpython-313-pytest-8.4.2.pyc create mode 100644 15/1/__pycache__/test_day1.cpython-313-pytest-9.0.1.pyc create mode 100644 15/1/main.py create mode 100644 15/1/test_day1.py create mode 100644 15/2/__pycache__/main.cpython-313.pyc create mode 100644 15/2/__pycache__/test_day2.cpython-313-pytest-9.0.1.pyc create mode 100644 15/2/main.py create mode 100644 15/2/test_day2.py create mode 100644 15/3/__pycache__/main.cpython-313.pyc create mode 100644 15/3/__pycache__/test_day3.cpython-313-pytest-9.0.1.pyc create mode 100644 15/3/main.py create mode 100644 15/3/test_day3.py create mode 100644 15/4/__pycache__/main.cpython-313.pyc create mode 100644 15/4/__pycache__/test_main.cpython-313-pytest-9.0.1.pyc create mode 100644 15/4/main.py create mode 100644 15/4/test_main.py create mode 100644 15/5/__pycache__/main.cpython-313.pyc create mode 100644 15/5/__pycache__/test_main.cpython-313-pytest-9.0.1.pyc create mode 100644 15/5/main.py create mode 100644 15/5/test_main.py create mode 100644 25/1/__pycache__/main.cpython-313.pyc create mode 100644 25/1/__pycache__/test_main.cpython-313-pytest-9.0.1.pyc create mode 100644 25/1/main.py create mode 100644 25/1/test_main.py create mode 100644 25/2/__pycache__/main.cpython-313.pyc create mode 100644 25/2/__pycache__/test_main.cpython-313-pytest-9.0.1.pyc create mode 100644 25/2/main.py create mode 100644 25/2/test_main.py diff --git a/15/1/__pycache__/main.cpython-313.pyc b/15/1/__pycache__/main.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..69fb6bdefe2ee450b66af12144f135925980638f GIT binary patch literal 1908 zcmcIkTWcFf6h3>?WhJGN-B^xmiJrVId8 zRsvdJ<`V!T1hAqcVY+=7fl{y(OoeLk_l!-FB~Fn{Udm3B*~K|OYT1>lr@J1t?2;d# zrdOqQUg-FPz103rme4?#1Y5{KFWeXcu*ICHiTuhSKu*x4@fgkuH_zfo)MSPfM1Y(9 zZ8X8rVSoq_Tt5marS`)|#+pein;16!(HYWm2FC?bvhJAVwvk^W-l|E8>yAT-T`k`> zDbBiPfjBltEE_jf^Pc6{?u4p-U~Ycq&;psIC3i;c4v~!E!W0=N8jqOe!nE^F0gviF zLsf6_Ot8%!uD;fFvwF<3;|pWQEKR=8oz$;_%# zHZ!j6IBtfT75uYXGe+T#X?wa;)cG(woylg(hGkDwHvQKt)XAH!t9J)LF~gh__X-+Y z(CmSp-mUqkX9w%@VdS;lshul_(Z0Qr?Zq$W4`cCN?W^U}@o!;>4>h9@?c0~no#1wO zInx`6w3uE#RYDG?+ct8a0;poZl?yqk&3~Yq|HTN-bM_4sIM)Sd9xdfm6QhWTs2IG< z6$y-TO_TzuVC~OWDFVsrCg~*#!Ms{b1dLavn6Bl>vu84ubAYL*j5BG1idwZij{z-x zCC9VL|3gDdUA}euh0fFy5PzroIZBYm;G@LEcBHQSTSnV0 z8SQjrRG)tmIk(sIbL5RDz5RRHdzT+Z2cN~EKSR&pfqDE+8;gQHfRlav-G_g~q+vzV zq|2fRHss(ITk}He)Gk|CW(nafCv+rei_0uIylHYyJOfi=2P3c??qILjp}e?5!^)`z zrr8_DhV?Qq0%;g)4WWR-FQP<;5n`R9aj-_z!u*j=cpF|#sd~ln zw~?+8FD3j9?8y-wlz6J7E+2YI~CLRL)0`1>y~Zux9uwxRH?^#N=d$0Ty52s zfK&CbI(8~bi(i@53Ob06@^|zx8e4D_j@8#1*B^${-;0Nd^WWUPclYbh>(O817aQvb z@u_;?C=}Zb?e*=2_Roy`6iOb&lZ~qf@k{>!evgAX{!2LhD4hPoWqR6~m1Yytj|p}5 zV$cuiI=fxh7cdn;T`xF!UH2u_u`jUzSfS!kaR1nH+bEm5P8mI1EUg$qSIbVJx^BKp zlL%n0!M%>ZrX&c$V@NdRxX{;dn}FQ|_c`mDW4*#qW3CCH`Ia;qB SNar8Rp)amAC6EXBMSlao@7Wvx literal 0 HcmV?d00001 diff --git a/15/1/__pycache__/test_day1.cpython-313-pytest-8.4.2.pyc b/15/1/__pycache__/test_day1.cpython-313-pytest-8.4.2.pyc new file mode 100644 index 0000000000000000000000000000000000000000..a669850d8d699b9e20cd76037fad427049f7ee34 GIT binary patch literal 1840 zcmb_cPiquO6tC*;`QvmZ{)=FeLxwb-hZuU-$! zbc3a@n!=xP?>0i6yt1wql{S*|aC>dMj4iD_7H3&&q%keM6IVidtWJ#lls2E; z$z`B=bNlw2RI5gE9(6LHPN4F2X7+g>$rfhHm%M+)vQpnY%LDiPRaqYJhAfS-N__Eb z?X0F&?z^8Sdn4a;>j%8yJUJ`BXq<)D#H93#DRTor8W#8ZkJ$$8Y)RW?de z=;Ia+@j4=hptU}0tro$9rG;v^b)N9jqg1K1DpFe_yeeg#a8i0)X(eofa3-5altvvW zidhF5LI+Pd)#Y?vPL08&!#QP99JWcgB%8#H<1pDlOtz#bT?x11pbis9?XKf_Hlrcy z2K~@sR7`-`zPsUik?V7j_X1eK#Yvmr3pTu7ywqOzg1e4q`%a&VLpFETsEi;cug3ek zfq#v$fQjSwTEO~FWJBJb<2w;ph#^e5Lz3#baj=|##OJ~|xX5MkDlkN|b}#7D8ux>M z*I-weyFriEoZbWKM|QAg$FSb0)obx7d(KvUG29a67|~6qA9|EC=u;%W!h9R1C+M9y z_oB3Cp58H<+nc*)^R1@caS(6}Wi%`rLcWMhh@z?yI}C)Fwv(zZCKn4gy~yZ8=0;GVj1q;EV`b@+Ph5o2 zcU(VtZlJRJVgg-*A2jrVl#C_#cFx xp{M2dXyFYm{672J>}x!|i>G&Hmj1l_m$`H9#vZ=;QN#G+P)FJ=9IJ8Y{{hOoVaWgh literal 0 HcmV?d00001 diff --git a/15/1/__pycache__/test_day1.cpython-313-pytest-9.0.1.pyc b/15/1/__pycache__/test_day1.cpython-313-pytest-9.0.1.pyc new file mode 100644 index 0000000000000000000000000000000000000000..f6b0703a87273e5258168e042ddc0b8b27532ce0 GIT binary patch literal 3128 zcmeHJ&1)n@6tC*8`Rqw_*{GRGmK|qT>}EBSm>DOi5kNX+iY8{+b>)2Lm2FY|*@WzxQ6fdi}cl zS3MXT%M%#On=iM&R|)wQK{QgKGWZdcJH#X=T_&9Rv$CWLrA(F>Pn82tny0~|EN7Oo zJiCWL7-6bwSe`#tvXM5NEAeA{6O66PBfI#o+AtQi3R#N{QN2-> zc4=gFAr6d{vsQmdP1R)Qs&Z;%pEIi*b~CQ-`H@v;RySM)Rk1|B&yH524w$L`ynY(x zK3DzmDyTnYrf1lz@br7k%$V6#HcNe!T6-pXAc;GCHnI)p3Rz7>RYbD`bh1eMS2l@} zyRkJ$T!;{I(h^(lcBkcsTALkr-R@XDyX(lDCF~6cGsy9G{axE`?|sf)E-zXe zF7Mi&1=V)!p6!8WFU|4w;A4188txU8`dSjy0uZczJqZ>BexPN4$VPR`?K)M_b6rt| z3P3j9mQ%G`p90}o?uO;Vxq5Z3>fdq8-kF=}@5o}jYw-2<&F$=Fl*4Wps#V}AFu*Q*gIW``Q!odEJHSXn;ArXSb zPi8#AeUs4%6q_Mv0QCX^OKO}TGXmYFfR=$|k(i&7Ds~6QQ&RPhu77hV#Ps+-CRLt; zXUa7c_@6N37Cw&fA`1LV1M>6z&!GX%Hp1~gjZdN|qJYzwaOeu*(g1yZjzrxn1$CNtLs~u_6vGHIO z2KI-ncK2p7Bto$G$&5$1Z!$W8VlxEst5CHuF0&Em`<;x-)0(u6HoZ-%AyzK$w z$0nHxZ5;b5)4>wSx^}x4^xHqV0P|Z?gX0Ab4EXKbb$pujd$vdX0)hr--|D)p?T+&{ zpND)%W8xNwQ int: + '''Take in an input string and give back the floor number based on the instructions. + + Keyword Args: + input_string (str) - String of encoded instructions + + Return: + int - Floor number + ''' + curr_floor = 0 + + for char in input_string: + if char == '(': + curr_floor += 1 + elif char == ')': + curr_floor -= 1 + + return curr_floor + + +def find_the_basement(input_string: str) -> int: + '''Take in an input string of instructions and give back the position of the instruction entering the basement, or hitting floor "-1". + + Keyword Args: + input_string (str) - String of encoded instructions + + Return: + int - Position of instruction in the string + ''' + curr_floor = 0 + + for index, char in enumerate(input_string): + if char == '(': + curr_floor += 1 + elif char == ')': + curr_floor -= 1 + + if curr_floor == -1: + # Add one to give the 1s based position instead of the 0s based index + return index + 1 + + +def main(): + '''Entrypoint''' + with open('input.txt', encoding='utf-8') as fh: + input_string = fh.readline() + output = process_input_string(input_string) + + print(f'Part 1: {output}') + + output = find_the_basement(input_string) + + print(f'Part 2: {output}') + + +if __name__ == "__main__": + main() diff --git a/15/1/test_day1.py b/15/1/test_day1.py new file mode 100644 index 0000000..e93c088 --- /dev/null +++ b/15/1/test_day1.py @@ -0,0 +1,28 @@ +import pytest + +from main import find_the_basement, process_input_string + + +@pytest.mark.parametrize('test_input, expected', + [ + ('(())', 0), + ('()()', 0), + ('(((', 3), + ('(()(()(', 3), + ('))(((((', 3), + ('())', -1), + ('))(', -1), + (')))', -3), + (')())())', -3) + ]) +def test_instruction_examples(test_input, expected): + assert process_input_string(test_input) == expected + + +@pytest.mark.parametrize('test_input, expected', + [ + (')', 1), + ('()())', 5) + ]) +def test_basement_instructions(test_input, expected): + assert find_the_basement(test_input) == expected diff --git a/15/2/__pycache__/main.cpython-313.pyc b/15/2/__pycache__/main.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..3a4f2329db33ad9801b7688f2435f61cb7556f5c GIT binary patch literal 1956 zcmZ`(-ESL35Z}E!+vl_6By~U3R3dAFplO{NH+4VKmMVnOO3>197$POo>1v+aBInIP2%NX{4T&fI1BVo;J@J54UixO5NEJLWduOL@D0AAG-I=-B zncvRtc2AFlfC{f1(u8;)Y(iNz6pjU1Y(@xiP9_RwNlRFU zX<7-Ym4Ro>td>x-cQnIR%$(vblc~hXL`l_+6XkiQFR$53Cr^dtNkb5gMYN6sTSVv?0_J{DxR@V<$z3#! znFpgO7wxHi4DBhxc!E!LtbjAFo^o-14&W$52gixsU4yj4<*Ma{C;vBQ^ig9c%T zE+&+9aHq(knz^N@C9`7Kv=7uh%ww_t30Rz$K@P=G93Axx zC<|!hz%mFv%PG%C zi{#+B>fjBP+9Vl=C#1yse3q)^GB}X3TGr?oxjyW71hcFej?XF=b=%<~wtIEm)^>bl z%3ha%!{rJN4?!HEs2dtR1o8Ji9}GKqJ{Wn|MPQEu9R&4$7}nRo7SWC$Ns-#E#+6@# z@eS@lq_@UD+JCV2&Vx6O|5#nCZVY|DuyydvcMFZ!H Q?VYuS&4Xu_uGGetV}FEu z??;Ck~BTU*dl_Fg_;!d>UrIjQJS9B)#1ea70C6MJUR3z#yO~Su>+3 zbO8Q(1`=f##VwP$8)``d7uMQt!+TJO7fNQfQqvL_j8yq2N28w1aknv96+>1j4#xqZ3Lp>iKZtuqB~6a#2?0I+OH!a VT&r&JhaU>!7w@)tBn-G&{tM(*t~&q# literal 0 HcmV?d00001 diff --git a/15/2/__pycache__/test_day2.cpython-313-pytest-9.0.1.pyc b/15/2/__pycache__/test_day2.cpython-313-pytest-9.0.1.pyc new file mode 100644 index 0000000000000000000000000000000000000000..239411912169404dd6a7049356e229c823105a1f GIT binary patch literal 5232 zcmeHL-ESL35Z|@W=Z}liBn6ZYw>Tj|x!}ehjR^$;1ZY92RMea-RSMGSVqX%gw$JQc z2nj+0fy7@>DH1P{cxnEdSV^05FI3_InWunx>Ju~f-ot^#dhi7)L z6_3XVl~7)Tc9kx+%bxE=GwN%O_4QEk$2F$D3$S!-UFVY$DG&u6N)FQ zCzKN%WVFN~Iz*wa$uKwGM&N9DrtdeY;#S$~E2OD;ikn=BTW1Y1@^OWh!r0 zv~{H-*OaPiMrB>uP|<@qxNMDD)@s)o)0lZt-q2W8F=W79QEG|-Er$^{43lCbNG>9I z0p}>-s5a;Yzwo*(*nZxy!P!DKqhpv$I>lT}Z)sIEt=BY7PXipFMXjW!mD1;G&5*SX z*%Gt)bS`a8zohKu=IguWuqElf+`v-c7_)8b4rNY;xhLm4Iy*N zIlp5rb0kcAqRl+uGAF`>r)+eJw*DcP*q{;AxdtRVtFJeOi$t56=lPt^2sDL{uVM!#DNT!gyf@B)W43bxY zbcB8O8fe@Q?z`}_Ea>CdCFQu3EZy#ijg_$ERdw;YcWKTKgcg$svgc(n?nFn0< zL`ZnbMyF`&A9C6K+kO+D3~Aa=h$pX8~*$d2JdX2gA) zSgFDslkL~cy#0897sfnOcUakgmx-q`!;X&OzL>n-#pJ3=xn?IId}uM;IaIQ{rT}jt zc-Cc3GN4|~!N^UgB zjmI?n{lqsDr*yPIM~}u*j}zjf#N1gZI6lz|a)HF}F-o&70k|{d&Ug}t{H??6qlDN~ Qhwc$_)(ALO&RWmE0C&N@B>(^b literal 0 HcmV?d00001 diff --git a/15/2/main.py b/15/2/main.py new file mode 100644 index 0000000..c8bffa8 --- /dev/null +++ b/15/2/main.py @@ -0,0 +1,38 @@ +'''AoC day 2''' + +def get_surface_area(l: int, w: int, h: int) -> int: + '''Take the dimensions of the box and return its surface area + + Keyword args: + l (int) - Length + w (int) - Width + h (int) - Height + ''' + return 2*l*w + 2*w*h + 2*h*l + +def get_slack_amount(l: int, w: int, h: int) -> int: + '''Take dimensions and return the value of the smallest''' + return min([l*w, w*h, h*l]) + +def get_ribbon_amount(l: int, w: int, h: int) -> int: + return min([2*h + 2*w, 2*l + 2*w, 2*h + 2*l]) + (l*w*h) + +def main(): + '''Entrypoint''' + # Surface area for wrapping paper + with open('input.txt', encoding='utf-8') as fh: + sum = 0 + r_sum = 0 + + for line in fh: + l, w, h = [int(x) for x in line.split('x')] + # print(f'{l} {w} {h}') + sum += get_surface_area(l, w, h) + sum += get_slack_amount(l, w, h) + r_sum += get_ribbon_amount(l, w, h) + + print(f'Part 1, sum of wrapping paper: {sum}') + print(f'Part 2, sum of ribbon: {r_sum}') + +if __name__ == "__main__": + main() diff --git a/15/2/test_day2.py b/15/2/test_day2.py new file mode 100644 index 0000000..fa51a5a --- /dev/null +++ b/15/2/test_day2.py @@ -0,0 +1,27 @@ +import pytest + +from main import get_slack_amount, get_surface_area, get_ribbon_amount + +@pytest.mark.parametrize('l, w, h, expected', + [ + (2, 3, 4, 52), + (1, 1, 10, 42) + ]) +def test_surface_area(l, w, h, expected): + assert get_surface_area(l, w, h) == expected + +@pytest.mark.parametrize('l, w, h, expected', + [ + (2, 3, 4, 6), + (1, 1, 10, 1) + ]) +def test_slack_amount(l, w, h, expected): + assert get_slack_amount(l, w, h) == expected + +@pytest.mark.parametrize('l, w, h, expected', + [ + (2, 3, 4, 34), + (1, 1, 10, 14) + ]) +def test_ribbon_amount(l, w, h, expected): + assert get_ribbon_amount(l, w, h) == expected diff --git a/15/3/__pycache__/main.cpython-313.pyc b/15/3/__pycache__/main.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..4175b4b76906607c9eab3ee36cb81281e7f65aec GIT binary patch literal 2453 zcmai0TTdHD6h3>gcYVWvL%5`cC4|d15SIj`gj`zGrX@{_nry8`0(G^q7uXhd-Ptt> zNL6{MObf|aO#LSt2{&sFX@vLkSg`5XLfC3Bhn1=%6>gRr;}yOOzU2vDHxlqh z0!k2(!C65OCT;;}BEW3$B#c*GN-!_Zi*jf+G--V#WwaIPY?`gDi!E3E?frqB4M;Hx z5|Y{PMp}B{N>_S%P${nO%-n3zg}#8KQB~{K{T;8T}eQ=ZIdg7 zPP_ru?8D-RVPc`>ex#t?kNe)DJ}mMUnCQa-km$?{&mygB(|Z^zxbeD^QElCEgG6_7 z#7xtptrbcFdRTjlSZyFtM;Q}YgZY32O!WYm+{^*~R^ND)ZD?n1(s_qUiXE?_CHSHj zAOaH1&^5f0Vrte?AhWA~-^`hkvp}re{DP!O7@}m&Np(@%l4D7J(1_C|Gq-eGClr)3 zjqh{1v|#0I-IkUO+i>(uIDB1Sxnq%xq>*`hB3$Q*?q3>0qR7&S^szy7k1yIHB8hdU zeoYBMhB+_I8_Tp=vX*fH39<5iLU;f&=h4aKv`oh3 z7IjnRNehm^l~&?9-*b4Ey$QUo}{3bXXMZnKn_`xy_!O~8wpYc@>HQ4VCH~9 zxB45Hb-);0rdk@9HQX?F{9rDJtUPKiSBnQ(`B{~fDBFH%U?o58rRoLcxhFR=?}l_F zo=z|yUjE22YHPzv4tn_`$Fc8*Y|V5uPm@B#x@|dLH(;0<{jQ%u+`E^-S`IsFIi&E$ zMB?Er zF6OV5qy3Mg^24ZHkawbEyKfkO8H1h+`zT0<(~j#N6dJfE5=HE6z-vKJ@J&;=3oHvJ zJ`_g@Lha=;nWJRDWa;ba7llu;O>nMGKxXKr@yhEIAb4GE32EXNOUc;XqdWp3*A5#WyB#gkw_tSZo$9mF<-g- zn~txSmwI2u4&88`zDI<{K88R0Ypm8_Hx$c%xAo~?q2X<|-1W}yr++>D+ekkCv}3rS zmO3uyW4mH(UD%AR|5$7qd?XI-9#3w^OUFOVM|?wM{fA;x|08kWpB4y@JPr--gogjM zslMEsKik8T{emm1DqUSwr)AL0QQ@mGA5NmRO9nD+{O6~Jb@Z=W`mffx?i k6~JcO-lxs0?l3c0=>k5QUoCN+Pk8aCPbwVnUEXT{0oNZbkpKVy literal 0 HcmV?d00001 diff --git a/15/3/__pycache__/test_day3.cpython-313-pytest-9.0.1.pyc b/15/3/__pycache__/test_day3.cpython-313-pytest-9.0.1.pyc new file mode 100644 index 0000000000000000000000000000000000000000..33f9710669f64127399949d49acbca9bef5fd08a GIT binary patch literal 3015 zcmeHJPj4GV6rb6hwbx!drD~!1hicrWWC_HH9peg`s1-s~sZ>N(mXLz7+Sr@a!uDFT zo6rPR0)fOQ=sm|;;v;b610+h?NPD3Y2b5c=IrYSQv)=WZ=0GG496I*CdGF1eH@|(m z^PBBuvuOg2-kE7Uk_h=7jj$0WYK zZr*h=0#LDF`*`Qy!GSEZKkPF0MU(hmOz-B1pq#US(XU>zyNE8NHlCdn=O{%LW znDf3a`IkG~soAb;HrlSow`yL)X}kVd=;hA3Gc>e&VY9Jqx8Kj%4?A|vv+KGHS?JOU z0@kHnwzjl=>x2bHdTl%W@dUVP{ksB{kR)6(T)khw`fA_UP^)KDAr`KZnxgR_2hXch5p z3}R8slhw!(;tf$+<3qDEQDCH;HT!dF$ObzX%88+M&O|w=W`ypop;>358_WV!ELQKc zqouF{hVq}|r(y1M;g4nke#J=4vJc?tx0#VN)GC{!!ctZ*gbyTkhi`eJL$2cIoci)O2U3q`T>F`$}#xhuWO(PGdi>yL$RjZZYtdb(iB7 z@D;JCd^OxuUFOR$3B^2$5{mN65zBRL?um>Q-9=|bPX#H`w>vwY?Ruug{flPJYBo)7 zcX-Wdbu4cC85lO#w;D|kHoBi^IuPOdqo(`7*=p8BsJYp6)~%-5wpzBIGF@xK#ti<* z9kD79!>61(+`nXQIJ{+fCZKIvZ3`)*o8b6n@GRbqhHC{-i*aKiFoM}1#*LdU?#-NN zex>lhY1sw0?Ko}$5P+;Xb-Q5Ifp|RA*)WAUUoMmi;*RUqPHDEY<6jh3oXGe!NQ?CC z{tV(f^4AE-=R zKqGtv%}Xfo;|X|9jK7HvIKc?V&nG^LVhjbGxr9Si2%kjpHi#Ij@I2W56~Pcdh+c8% ztA@V|qj(sEJdq}uslDobN-q^JTt%{m;i2x8(SH0D8>RU~FiO)km{DyNk zK%B~y(%%UAk^GSTgWP^jlRr&-KXFV)59sLr*n2M|Ha^jl6>0L%45g)B7PM2;PE{hQ YL!r+nr%q)Fqh*LzDZSZCg_^+eHx?89i2wiq literal 0 HcmV?d00001 diff --git a/15/3/main.py b/15/3/main.py new file mode 100644 index 0000000..2d12eec --- /dev/null +++ b/15/3/main.py @@ -0,0 +1,66 @@ +'''AoC day 2''' + +def get_new_pos(curr_pos, instruction): + if instruction == '<': + new_pos = (curr_pos[0] - 1, curr_pos[1]) + elif instruction == '>': + new_pos = (curr_pos[0] + 1, curr_pos[1]) + elif instruction == '^': + new_pos = (curr_pos[0], curr_pos[1] + 1) + elif instruction == 'v': + new_pos = (curr_pos[0], curr_pos[1] - 1) + else: + new_pos = (0, 0) + + return new_pos + + +def process_instructions(instruction_set: str) -> int: + '''Run through a set of instructions to return the number of unique houses visited + + Keyword args: + instruction_set (str) - Directional arrow instruction string giving moves to new locations + + Returns: + int - Number of unique houses visited + ''' + visited_house_coordinates = {(0,0)} + curr_pos = (0, 0) + + for instruction in instruction_set: + curr_pos = get_new_pos(curr_pos, instruction) + + visited_house_coordinates.add(curr_pos) + + return len(visited_house_coordinates) + +def process_robo_instructions(instruction_set: str) -> int: + visited_house_coordinates = {(0,0)} + santa_pos = (0,0) + robot_pos = (0,0) + + for index, instruction in enumerate(instruction_set): + if index % 2 == 0: + santa_pos = get_new_pos(santa_pos, instruction) + visited_house_coordinates.add(santa_pos) + else: + robot_pos = get_new_pos(robot_pos, instruction) + visited_house_coordinates.add(robot_pos) + + return len(visited_house_coordinates) + +def main(): + '''Entrypoint''' + with open('input.txt', encoding='utf-8') as fh: + instruction_set = fh.readline() + unique_houses = process_instructions(instruction_set) + + print(f'Part1: {unique_houses}') + + robo_houses = process_robo_instructions(instruction_set) + + print(f'Part2: {robo_houses}') + + +if __name__ == "__main__": + main() diff --git a/15/3/test_day3.py b/15/3/test_day3.py new file mode 100644 index 0000000..a030a94 --- /dev/null +++ b/15/3/test_day3.py @@ -0,0 +1,20 @@ +import pytest + +from main import process_instructions, process_robo_instructions + +@pytest.mark.parametrize('given, expected', + [ + ('>', 2), + ('^>v<', 4), + ('^v^v^v^v^v', 2) + ]) +def test_instructions(given, expected): + assert process_instructions(given) == expected + + +@pytest.mark.parametrize('given, expected', + [ + ('^v', 3) + ]) +def test_part2_instructions(given, expected): + assert process_robo_instructions(given) == expected diff --git a/15/4/__pycache__/main.cpython-313.pyc b/15/4/__pycache__/main.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b15f719e047042dd45266e9b72954a63806b1dce GIT binary patch literal 1108 zcmZuw%}*0S6o32CW$D@~lGFfNDrjOOSU^e$8bid0ACZ`DnwZeIS=zO&&~2SrR5#Bx|?!F19&gF1vMs4o*cjUd`2qa@*KenEx+1X~P466S^0iKH0! zB4XTz!o1F08w%7fJ2TdOmfS%>~t|>v5uTcb4&RJCKWPq)|s& zByG)nRIB|X_3&ghJXs4*ZL59zp$qR9-z{zr#A~66dT6>Dny!UzSF}AXRM#$6wTqk4 zx;9kRhIYC`l?QvOR(bJOtw_JRKs(*U8z9YDi`v7mgqHOqL!b+~8284;hWYjo=u#4b zaJ@Yuk>fG)e`9Eb4*PyrdLa)VuATaIIVU(##b4giZI31J;T^kBr3XXV!jgg z--!w&h;S)?@(Afd&Sc(P(t{#b=>)Pe?E24b_%~;3{-N^BuH0FfU7J~pS7Kk~-hJ0| zujU^<=J_V~l5U<(H4L86Fro_KUzy;~!|A}gT^#O3{E%%HEW`K!Zqy+X^=6@%SzfYk zkub(^i1Y@sh9n5W4+u77P3YPfYyfUshui1DKV18L-Y4`m&VYQXvRadRzRT*HyA26E GNPhw2Y30rU literal 0 HcmV?d00001 diff --git a/15/4/__pycache__/test_main.cpython-313-pytest-9.0.1.pyc b/15/4/__pycache__/test_main.cpython-313-pytest-9.0.1.pyc new file mode 100644 index 0000000000000000000000000000000000000000..e6be165c6cc192f7fef98ffedb3e930e8206d436 GIT binary patch literal 2005 zcmb_d%WoS+7@ygfpGgZPRbDEqNUgFE;>59=rr-)B5Rgbz^2$;rS6XfCiM{H2*UW4R zF#>@=s)VZED)q<_{ud633KY$SN{9ouB6I4g-|Wk4nggJY>~FsJ_nVn-X2&x#MFiuE z4_|j~VT67cLNe5t8IORuk4$9ZJw$OhOS>|YbhN8bRgWwh)xaX{<#zKlucMn<^W`Mb zWNyw)_=GcMQ!&+wRF@)+sV$;05o9^$8oD?>V=Lx26y5 zpwnN|$)`io2}swFxn}Qoy5xYX8)7);_6i8Jx#7o@1&6n(Sef%JK8reXTu4lL_zQX5 z1bQE}VLzgA11H%0t(J841BCo{S7Y1zxO)$wc8ndNrjkTW<`vkvmQur}bfa36>am9@ zx3$ElDQf>?tfaf}CRnQr=-C_n}M^1@N!|Ai`z0#s_I3r=5yoYXM27mi;_a;InhZ+10}0{ohp zTUXzJp7c~RZx&kW1`Z{yeI{v>%nHvYy2-qPT3Ui4nF+iX4Lq#%kWqvy{8VZ*3_RMo zxH>$l8LaqO%;*hWa2p0&74xRS)e#MpQ8J_*e=xKu;bkye z`-hGjI3DAg>w^d5^A_v-hi*4?wR*06f>X8to*v<+&EC+#lH28L2(->;sOs*jZT_fV-GmoBAZ#QdyO?>181$&?hSe^IIr=CU3cDfReH&3Ysf zB!9l*PXbrgJ0qoPa2msUkWuFOpn0Gj0_u!NxRXC1szU_5Aj0x*4gBt*ORmw^Kosvay9VTmj4}QV zp>NRFGk>59k8$qK(pO85@cap$KVH~;yuAJE^3D@gUR)Z>inRP!5#z0KDdEEW&j91; Bdei^_ literal 0 HcmV?d00001 diff --git a/15/4/main.py b/15/4/main.py new file mode 100644 index 0000000..2ba3c3a --- /dev/null +++ b/15/4/main.py @@ -0,0 +1,26 @@ +import hashlib + +def search_hashes(secret: str, match_str: str) -> int: + num = 1 + + while True: + search_string_bytes = (secret + str(num)).encode() + + hash_string = hashlib.md5(search_string_bytes).hexdigest() + + if hash_string.startswith(match_str): + return num + + num += 1 + + +def main(): + num = search_hashes('ckczppom', '00000') + print(f'Part1: {num}') + + num = search_hashes('ckczppom', '000000') + print(f'Part2: {num}') + + +if __name__ == "__main__": + main() diff --git a/15/4/test_main.py b/15/4/test_main.py new file mode 100644 index 0000000..2052a7d --- /dev/null +++ b/15/4/test_main.py @@ -0,0 +1,11 @@ +import pytest + +from main import search_hashes + +@pytest.mark.parametrize('given, match, expected', + [ + ('abcdef', '00000', 609043), + ('pqrstuv', '00000', 1048970) + ]) +def test_searching(given, match, expected): + assert search_hashes(given, match) == expected diff --git a/15/5/__pycache__/main.cpython-313.pyc b/15/5/__pycache__/main.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..fa28d023637f867f31c245eecacf93e5a3450f77 GIT binary patch literal 3317 zcmaJ@T}&L;6~6Pgzx?d7*u>Z_gH3D}u}~bSYmA)`CwA=0*vYV|8`Exv-PvWEWoCV6 z790A46s01yRN*>SNh`J3swze_s2_%eOG($ zopaBed(U^y`R?r0*9QpN(_hB2C%uF`W)GDnmnS=a!sG$b$QaRtF`-}9#8&cinTncJ zmB?Ho)kqXBk!#-aaEVeQ@p6f$M&jcVZ;iyyB|a_CN~nJToQf{}S6;lJ|+x}U+HUU>7iU$j4fGE5PU=~+CqM1_hcbp~+{x4PZclQ;NPYkv)4`&h zFs;P6o=PMqbZYku<*cNhv(NWb^%-n-1l@N}$She6bUpGf9Gh?c_247_Q=2V*7;Y9W zjz$Gn(#`3p$j|Eft0rxB_V-oVfWbZdg1sr*gh6e$q5E!@xS`J3%m4BQHUeD_{p*3Q zEpOMFw`;qx`Ricg4pfM%WX*iR*#o%(Igj%1FnK^~V_S(M;2$ESfOF-W;({i`Pyw1a z_z5CgPsok3gc*v9JlCL!z(`yd(wodaZ*fwwIoL!<3VK(2%NDTy%mQD*p3DjlGRvJO z%-1K(&gjKu(e)cN>Vc`DEX0UzHSQ%cvymsOTpPkq|@fsAq@srlBVjZaq(`H!SgE_;4WBxiO;0e?e zPx25UrWhABp5`0_Bsox&V!+uHt^zZL1|%{^AAn?(j3?@y`RG!1%20JRX%$RIwbJU8 zb=%0WpGR3JZYP_|DR8>T9n^d{Zfg-#>Ay>tU?3jOFcFVprE$aD=6q#}@myyq#;_&W+fsf0wsnZ?47O z+_-Xcb?p7EEBe|M{dqp)k}4(JBTQ<2)`a~EQxgYRYNAERyMitD5?d_uZ|Fu?6JuDB z$#t>9zov-fWg4wWQ7JCIQ^kZE;a%m@G36VtGY03W4gF{3ZHp@QF@-ciq4PANz#pjt zPFJXIW(;~5&#siW@=>KknL^g}+WB18DdZ{Y1Bu5GwAlev)=Ct5q=c(!nbwp+b9z3H zVo2Z`Fm%VJ%pFh=u{Csnxg)yN{#R|K`7b~DOxWlcTyHr0MaSU6t@+^v;a>9YFV;E+ zXD_WboPFGIU{2f)wfr`CFL=L16`R4stn9s{@nA84vVZz*BWWDsr};EATqo~g0Cq+O z^NxwGHYm>$36LTOYFHPV`vt7Zq=%l%q_6|1Mb4yBR30f~OYsIPOID=x2{H*k4%xnQ&IWHo6>MfDisdI|%rJo@Y=?y%b$0wpSrdxUn}tn6spaG84u^@nAC<-!{?DEoe@Q15=}1C zJkD>5HKBZA%~USTiqpJyj`M3lDPId<2o~C#tkQYYJaM6cydqZKRq-jxegiDhXh;Uq zPP#e2u;&zDNuvVWu)@~PNo^!8M7<+3ett{zICq>GrQoDvKg4H?&oJ@5gd!@{DdYJW z?{&b}H>l$KPPX!f$?3~g*v*r7l|1erhkc!;CtSs`96jgCxvXjIy#ZwQ?L`M+?gIYy zyXX)BfBoDCiw=7V!@?0QJ(=)&k9-~05v-;ZrIcC9ydZHEplgzp7@ zqu}B_(6U=c{0;No1!eyBYD3$GPyKg<1Y%qM?l1k_|FLn;lDi$l5$SI&=>8E247Yn- zUn0Q{kVuR~gRX>=yYjeY<^G4bxnnh1#S(^}nZ0l7lSU%JZ#$kNB?9sdOn_%OGN1jCZE%Z6gJ0@3jz!LZb^%Z6fuAY2!ieKxWU*!Zm{AhZ`-iCi}~ Tvo0O_O7?wpu_zI_mHY8u;!3Dx literal 0 HcmV?d00001 diff --git a/15/5/__pycache__/test_main.cpython-313-pytest-9.0.1.pyc b/15/5/__pycache__/test_main.cpython-313-pytest-9.0.1.pyc new file mode 100644 index 0000000000000000000000000000000000000000..87a9db6ee32b2279d6c66cf17248977999a1ce4c GIT binary patch literal 9332 zcmeHM&2JmW72hR?6vZVaO0pf0Qqe>Hfcyu&kRT-$dr5$vdQ-vz0dmTl8SZij3PJ_tPzYQs z-@Nzcy*F=XIlrBcPB^=Asku@jXo1o&^o!&zI#H7u>zjBVjMpgXM~G0d6hWnKzcOpaq|gsai*>k2cApf@(FQq zZe1}>n2R&U#kqaOIOANL2p8wh72`~BaVEJqZ{@|<)PKm^`y@7E&twZ~c2~~onyC~u zL)LUTqvYglLBWPS$trWYl_{xAX-_cSp1!Y^z|GQ3JIqwYZCNX3ReP3+ny%@4DlRFN zN>R(pSgojvY1nVES|-XWSk!d0pkjNfFN$1Iu=%V$o-gjH+LNeSt*BX3&Baj6V|x{~ zxB=xzRjI3aeUI?tpwq1$q4j0$O(mN#Kg@RjxAZSN0@Mq?&R29SZHZJ1WK&3Wd3|nE zT=_^4^ydrR%HN2&Ukk#P8)qFkUcGV-M&+jWg_!ny{`Lz`s%w$Pu!#~Pm3&*{&I{q5 zFyiQX<(#nTbFy$s6;OXwtjyEHVV2`%287}U(z#5 zN!FCIYLCi>vaON`_Si3Jt3_S=0An2hLf+PKSuthEwxno^2{p%lJP8kir^wStq%D@} zGhTSX1m^vc7v3|-*o@N4eibk1Wi@VSx^BcF1E5(wr^b~WK#(cx+W>bUCR6cLoIY_G z5Ob+gv!|%UAtK-%jzM4&-1rBO-wXeZ2%-B2n=NU+f#QeNrW8Lz-MfY24QbvL8FPZ- zZE4n3Hv2`UKSl9_P2R+jz1Y955LZLJtnqmh`BB5=ViilsH4(yM+=B>5(fk<^(0$(tTIi>=&8-6eSK+-o%l> zc`#y|w98v_lB)(I{4Qi2^Wa4&05$LvD2GS^oxrXkQruLeAS;Z^kb>4<3n|7ZQn-sX zoP-uhKnEj2Lg<}Ct0g^cpye;8o6_fSB1+>oBSB4bX_a$EYDt8Dg*On-`&4=vur zk-&K{Vw<$fTXT}D1|xZ~~to9UzOh6(#*+N|@Va+NR z%UZcmA+wN3LFu1{P-Sk?#NdXkZ&0;Xtr3XvRe`Gl$lw?7C_}V>PGHv% zEp94WkX_Kr(1O-q3oY16hU@}YdfUMGeP}lUKWCN#E188OUrSnQpp`Edn$pS{>fSB1 z(vX&1kufJ|r7gYVDx3Wx)1RW1BOh<#NZ>peu}#|LtvSh6gHdmm;svnSz~qks7!p)6 z*_^tq<_pCQ{G93hnUaF@g&~eWcd%=SBR3UC0`P(_!x374EgZQ+XB`9QMHtRw1TqD2 zkOZb5^M|RH6lLd1&Q&)1MW#PRsl#3vFmWVs9*o!~ z?eYOR$yI|9LlSb36?wB$*ejUzYW>Zdo!xRJzbmf=k)Tf zQn#{u`Lb0TA`F8UphJYYsR%O)Z}&2Uq4n277eh$3A`OU)v z*iL!eK*=N6PD!4j?%hJkhVIqoSiLUbsrZ^ICFDV_DENUNr&2g=3*mq(uL`k72N?R zXNQ=sC+ReiVmx^b#1QY=5_Bb;<(arxSLrzz-M^+ARCLiuCxH~dG3n)Ffu_v%zXLxn z>p82WzK_?Tik!zAp8-AhilX?nApA-AWB7X{h`Q%{sMS5+QhM$eJb^#Y{9)!yoNkKK zjl1uD=keW}>3IE~*>A^0G0_422H=2jsI&ldG7NP z2Luj5QC#Urz?~Cr(BV6epO}t-X+#vCbS8j1C)`D*d>XIaG+tlyaD3F4Zq%0-Mdkb9 N8SMwsBhP4;{|MedOVR)U literal 0 HcmV?d00001 diff --git a/15/5/main.py b/15/5/main.py new file mode 100644 index 0000000..9ff922a --- /dev/null +++ b/15/5/main.py @@ -0,0 +1,81 @@ +def check_contains_no_bad_chars(test: str) -> bool: + bad_chars = ['ab', 'cd', 'pq', 'xy'] + + if any(el in test for el in bad_chars): + return False + + return True + + +def check_doubled_char(input: str) -> bool: + for index, letter in enumerate(input): + if index - 1 > 0 and input[index - 1] == letter: + return True + if index + 1 < len(input) and input[index + 1] == letter: + return True + + return False + + +def check_vowel_count(input: str) -> bool: + '''Give a count of vowels in a string + + Keyword args: + input (str) - String to search to vowels + + Return: + int - The number of found vowels + ''' + sum = 0 + + for letter in input: + if letter in 'aeiou': + sum += 1 + + if sum > 2: + return True + + return False + +def check_if_nice(test: str) -> bool: + if check_contains_no_bad_chars(test) and check_doubled_char(test) and check_vowel_count(test): + return True + + return False + + +def check_nonoverlapping_repeats(test: str) -> bool: + splitup = [test[i:i+2] for i in range(0, len(test), 2)] + + for el in splitup: + check = splitup.pop() + if check in splitup: + return True + + return False + +def check_repeat_everyother(test: str) -> bool: + for index, letter in enumerate(test): + if index + 2 < len(test) and test[index+2] == letter: + return True + + return False + +def check_if_nice_part2(test: str) -> bool: + return check_nonoverlapping_repeats(test) and check_repeat_everyother(test) + +def main(): + with open('input.txt', encoding='utf-8') as fh: + total = 0 + + for line in fh: + # print(line.strip()) + + if check_if_nice(line.strip()): + total += 1 + + print(f'Part1: {total}') + + +if __name__ == "__main__": + main() diff --git a/15/5/test_main.py b/15/5/test_main.py new file mode 100644 index 0000000..92e20b0 --- /dev/null +++ b/15/5/test_main.py @@ -0,0 +1,77 @@ +import pytest + +from main import check_contains_no_bad_chars, check_doubled_char, check_vowel_count, check_if_nice, check_nonoverlapping_repeats, check_repeat_everyother, check_if_nice_part2 + + +@pytest.mark.parametrize('given, expected', + [ + ('aei', True), + ('xazegov', True), + ('aeiouaeiouaeiou', True), + ('mnqpcbt', False) + ]) +def test_vowel_counting(given, expected): + assert check_vowel_count(given) == expected + + +@pytest.mark.parametrize('given, expected', + [ + ('aabbccdd', True), + ('whythisword', False), + ('hegwjzuvuyypxyu', True) + ]) +def test_double_counting(given, expected): + assert check_doubled_char(given) == expected + + +@pytest.mark.parametrize('given, expected', + [ + ('aabbccdd', False), + ('whythisword', True) + ]) +def test_bad_chars(given, expected): + assert check_contains_no_bad_chars(given) == expected + + +@pytest.mark.parametrize('given, expected', + [ + ('ugknbfddgicrmopn', True), + ('aaa', True), + ('jchzalrnumimnmhp', False), + ('haegwjzuvuyypxyu', False), + ('dvszwmarrgswjxmb', False) + ]) +def test_examples(given, expected): + assert check_if_nice(given) == expected + + +@pytest.mark.parametrize('given, expected', + [ + ('xyxy', True), + ('xxyxx', True), + ('aaa', False) + ]) +def test_nonopverlapping(given, expected): + assert check_nonoverlapping_repeats(given) == expected + +@pytest.mark.parametrize('given, expected', + [ + ('xyx', True), + ('xxyxx', True), + ('abcdefeghi', True), + ('aaa', True), + ('blargh', False) + ]) +def test_repeat_everyother(given, expected): + assert check_repeat_everyother(given) == expected + + +@pytest.mark.parametrize('given, expected', + [ + ('qjhvhtzxzqqjkmpb', True), + ('xxyxx', True), + ('uurcxstgmygtbstg', False), + ('ieodomkazucvgmuy', False) + ]) +def test_part2_examples(given, expected): + assert check_if_nice_part2(given) == expected diff --git a/25/1/__pycache__/main.cpython-313.pyc b/25/1/__pycache__/main.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..a63f4567e3ee9c1327ee41fe8669fefa4b7fe099 GIT binary patch literal 2290 zcma)7OHUhD6u$HD8-s%hCJ@4alQb?E0)dLU*C9K|(bgb?qz(k0%{Ar@cRl`sY#2B&>8W9meS+0ae)N1Ill%Bz+Vg^Kl zBr4WG-=dyU`wXn>MjugOu`jMC)V^5aCIq4ANrepuhWh&ZQZWtprterTng@kOOuS%- zdNWRg%AxI+?zPEM%WzRVn!CQ$5LmrgYzr3~de?)+`k~zTmZvc{y$d_hD_L~F1dV(5 zA5j07MVW)F@iNaq1&^}=%cl_e2|zvpSr_MO=*-Zt4oO$-MA(DSK0;x*1hXqLyAfs= z3RmVL(2otgj@>zW2PO~`Ju4jaaL5z2dZJiPu;N z19}fuTNj}707W79bgEiIkTqF&kCR2r9pEmKMcF3S>I3t$je|U(W6$=?us6V9z|{D~ zz^G76(kq}*hA>Pl?p<;O91Y2dA(VKXE!ioVRfK|=&OvSc&Vm}-YvgO+#>Z8dkU zcCO$xq14>H!ml66UH{$dTW%|SP?%ZnD0w?`*S0)O8=m7E;_*rn;8aa$8L%XrhSb1Y z%V9_WhSwJJFRv{N^xALpJiXC3mquQh1`~V44dRmS_i;(;1NI!&#X(s>5SQH-ZrzgjF}7% z1Ex+D!z-!bg$l}9$NMp2_D7^jXCNYlY?i2}Rm@mp+2Bt_OS8ArvZV^* zdOLa!$5N`IJVdO>D{qr?B&8=ZOX>yE4VwT>WayyE0>^RBP}6hdDT{W_Ul7U&nzbNn z)`NR=RBrTgfr3#+(5(Ae^T@wPM`g*zwXe!$1kGA}{oL9|d$jwPuaP@deiMmx`D{rz Q_Dpnsd95rUv6Th%A10RgGynhq literal 0 HcmV?d00001 diff --git a/25/1/__pycache__/test_main.cpython-313-pytest-9.0.1.pyc b/25/1/__pycache__/test_main.cpython-313-pytest-9.0.1.pyc new file mode 100644 index 0000000000000000000000000000000000000000..ced7ce087eeecf8a52179270ce28e41544ccef61 GIT binary patch literal 3784 zcmeHK&2Jk;6rcU@cbtAvlr*I^Q4w95#_Pn6ozftXKtX9#gjZ231!=XlH;GlpYrS=# zEkXi;#08;VD)q>*`BxA^iPAP=E+BD0z7@i$C*GUc-K^7!Qq*Hd)|>a<{N~M@nceqW z@8$DZhV7e&ldaJtW51ITwnU)p{fNpPW-(xvVyTxDP(`mT=)PKD3kgUT!bU6s9AcES&5I8iYh%;@&u~{gOGpDIH_2ibS%#Bs%m6- zs^|K>R%f+O;V&C1&-6B+V>eq)n;&khxsB^~13cfiZ@J*z8fk0*xSifaVYT(C+nFf1 zH@a@4=QfQYL+ejr2(B&8)cSSQ3=PuKF>UtC(m^N8wR*V*nsiXd)x}ERmUdnOX3Tz7 zIt~fPVx@9mMycPBfTI#HJ39c->ZNjjSR#%~L~W{HkPf_E#uN3DX_`PfW-48ak*h(8 zg^jjB_Ff(39k#5516QLP@}`&63m-D(y?-_soL8FPGqxPuAY*ksoVDMNx(`J8! zPqw8$SC(S~>pV5fCH6#i_`bwW@TuAD&%&&9EAhg!QvO#~(Jag=@ytDF;Tl%*h3Bt^ zv7NHY!pEcGSBpAe2I!#A>D6z1gcjNt>l zJvx8*8Y~lWh+XJ|D6DHE*Nc6i|D$?Ok))cE?$FdB*mg z6_+CL;rGOT)3Y(hSzk9P7~{S&-PYqVNO+wrJ~sPy3^`Rc5m{d zfz@lQAzcVM0IJbcs{Ef&e98VUu%Y9(uk7T`Z0Y8`^mfkN)q~%TZf@nyM5a_8=;n8` zk#BpzlJ1APdHYHn5wjx1T{n&hEe!tTiuWn6I67uUZUpV&ei(6@AO@fV>{I0oI1MtW zhkQe|400r9C4#5|s8)ptA~hf~3K8_$0KF%nLrghB4$^QHVl_B+5b;V3L97P!JrTyB zi+~Xneaa|IoxU#M0*aT6hKC^9OGXQ8@N+T3OGXPHAnc#XXn-F)3|=Eae;y8$ad@44 zZ<3%pK(Y}agB)*>I7ecF#CZ~vB#IxmBlaWQ1Wb)G}YM-uNr3;zre_W>R6CKH*+J4jz#_nI4R_Z^tWA)*X_ z1;ryxQIua;{#X2e$-d72!6trFQs0h!HMXmaY%3#Mqtkz>`4eM%+OT@^&r^z0+B=Qf UBhntFnVS9=XiY$AQcdLX4_TpM82|tP literal 0 HcmV?d00001 diff --git a/25/1/main.py b/25/1/main.py new file mode 100644 index 0000000..b0114f4 --- /dev/null +++ b/25/1/main.py @@ -0,0 +1,59 @@ +'''AoC 2025 Day 1''' +import math + +def turn_dial(curr_pos: int, instruction: str) -> int: + '''Turn dial from current position to the new one''' + direction, amount = process_instruction(instruction) + + new_pos = (curr_pos + (direction * amount)) % 100 + + return new_pos + + +def check_cross_zero(curr_pos: int, instruction: str) -> int: + '''Check for if the instruction crosses 0 and lands on it''' + direction, amount = process_instruction(instruction) + + total_zeros = 0 + + if direction == 1 and curr_pos + amount >= 100: + total_zeros += math.floor((curr_pos + amount) / 100) + if direction == -1 and curr_pos - amount <= 0: + total_zeros += math.floor(abs((curr_pos - amount) / 100)) + if curr_pos != 0: + total_zeros += 1 + + return total_zeros + + +def process_instruction(instruction: str) -> (int, int): + '''Returns the direction and amount of the turn''' + direction = -1 if instruction[0] == 'L' else 1 + amount = int(instruction[1:]) + + return direction, amount + + +def main(): + '''Entrypoint''' + curr_pos = 50 + + num_zero = 0 + crossing_zero = 0 + + with open('input.txt', encoding='utf-8') as fh: + for line in fh: + crossing_zero += check_cross_zero(curr_pos, line.strip()) + + curr_pos = turn_dial(curr_pos, line.strip()) + + if curr_pos == 0: + num_zero += 1 + + print(f'Part1: {num_zero}') + + print(f'Part2: {crossing_zero}') + + +if __name__ == "__main__": + main() diff --git a/25/1/test_main.py b/25/1/test_main.py new file mode 100644 index 0000000..bf0e56a --- /dev/null +++ b/25/1/test_main.py @@ -0,0 +1,41 @@ +'''testing''' +import pytest + +from main import turn_dial, check_cross_zero + +@pytest.mark.parametrize('current, given, expected', + [ + (50, 'L68', 82), + (82, 'L30', 52), + (52, 'R48', 0), + (0, 'L5', 95), + (95, 'R60', 55), + (55, 'L55', 0), + (0, 'L1', 99), + (99, 'L99', 0), + (0, 'R14', 14), + (14, 'L82', 32), + (50, 'R1000', 50), + (50, 'L1000', 50) + ]) +def test_matching_zero(current, given, expected): + assert turn_dial(current, given) == expected + + +@pytest.mark.parametrize('current, given, expected', + [ + (50, 'L68', 1), + (82, 'L30', 0), + (52, 'R48', 1), + (0, 'L5', 0), + (95, 'R60', 1), + (55, 'L55', 1), + (0, 'L1', 0), + (99, 'L99', 1), + (0, 'R14', 0), + (14, 'L82', 1), + (50, 'R1000', 10), + (50, 'L1000', 10) + ]) +def test_crossing_zero(current, given, expected): + assert check_cross_zero(current, given) == expected diff --git a/25/2/__pycache__/main.cpython-313.pyc b/25/2/__pycache__/main.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..d055e97161bdcd31e0008aaa35041dcf4001abf1 GIT binary patch literal 2621 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 literal 0 HcmV?d00001 diff --git a/25/2/main.py b/25/2/main.py new file mode 100644 index 0000000..7f2a0b3 --- /dev/null +++ b/25/2/main.py @@ -0,0 +1,48 @@ +'''AoC Day 2''' +import re + +def part1(range_list: list) -> int: + '''Part 1''' + total = 0 + + for id_range in range_list: + for x in range(int(id_range[0]), int(id_range[1]) + 1): + if not check_valid_id(str(x)): + total += x + + return total + +def part2(range_list: list) -> int: + '''Part 2''' + total = 0 + + for id_range in range_list: + for x in range(int(id_range[0]), int(id_range[1]) + 1): + if not check_extended_id(str(x)): + total += x + + return total + +def check_valid_id(id: str) -> bool: + '''Checks a given ID for validity using the silly rules''' + return re.fullmatch(r'(.*?)\1', id) is None + +def check_extended_id(id: str) -> bool: + '''Checks for extended rule checking, at least two repeats''' + return re.fullmatch(r'(.*?)\1+', id) is None + +def main(): + '''Entrypoint''' + with open('input.txt', encoding='utf-8') as fh: + range_list = [(y[0].strip(), y[1].strip()) for y in (x.split('-') for x in fh.readline().split(','))] + + total = part1(range_list) + + print(f'Part1: {total}') + + total2 = part2(range_list) + + print(f'Part2: {total2}') + +if __name__ == "__main__": + main() diff --git a/25/2/test_main.py b/25/2/test_main.py new file mode 100644 index 0000000..d1a813a --- /dev/null +++ b/25/2/test_main.py @@ -0,0 +1,87 @@ +import pytest + +from main import check_valid_id, check_extended_id, part1, part2 + +@pytest.mark.parametrize('given, expected', + [ + ('1', True), + ('11', False), + ('12', True), + ('22', False), + ('1010', False), + ('1012', True), + ('1188511885', False), + ('222222', False), + ('446446', False), + ('565656', True), + ('446447', True), + ('38593859', False), + ('385385385', True) + ]) +def test_check_valid_id(given, expected): + assert check_valid_id(given) == expected + +@pytest.mark.parametrize('given, expected', + [ + ('1', True), + ('12', True), + ('1012', True), + ('446447', True), + ('11', False), + ('22', False), + ('99', False), + ('111', False), + ('999', False), + ('1010', False), + ('1188511885', False), + ('222222', False), + ('446446', False), + ('565656', False), + ('38593859', False), + ('385385385', False), + ('824824824', False), + ('2121212121', False) + ]) +def test_extended_valid_id(given, expected): + assert check_extended_id(given) == expected + +@pytest.mark.parametrize('given, expected', + [ + ( + [ + ('11', '22'), + ('95', '115'), + ('998', '1012'), + ('1188511880', '1188511890'), + ('222220', '222224'), + ('1698522', '1698528'), + ('446443', '446449'), + ('38593856', '38593862') + ], + 1227775554 + ) + ]) +def test_part1_examples(given, expected): + assert part1(given) == expected + +@pytest.mark.parametrize('given, expected', + [ + ( + [ + ('11', '22'), + ('95', '115'), + ('998', '1012'), + ('1188511880', '1188511890'), + ('222220', '222224'), + ('1698522', '1698528'), + ('446443', '446449'), + ('38593856', '38593862'), + ('565653', '565659'), + ('824824821', '824824827'), + ('2121212118', '2121212124') + ], + 4174379265 + ) + ]) +def test_part2_examples(given, expected): + assert part2(given) == expected