195 lines
14 KiB
Plaintext
195 lines
14 KiB
Plaintext
{
|
|
"cells": [
|
|
{
|
|
"cell_type": "markdown",
|
|
"id": "8305bcb5-9815-4609-80ed-0a04528acf42",
|
|
"metadata": {},
|
|
"source": [
|
|
"# Puzzle 2 of AoC 2025\n",
|
|
"Author: Victoria Ramírez López\n",
|
|
"\n",
|
|
"Date: Dec 2, 2025"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 49,
|
|
"id": "d0cea50a-491a-4ddb-8e38-7de6e98a0063",
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"# Read product ID ranges file\n",
|
|
"\n",
|
|
"import csv\n",
|
|
"input_file = open('product_id_ranges.txt', mode ='r') # Open in 'read only' mode\n",
|
|
"id_ranges_csv = csv.reader(input_file)\n",
|
|
"id_ranges_list = list(id_ranges_csv)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 52,
|
|
"id": "d007b15c-6628-4447-b5be-22c8a30bf237",
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"[[959595, 959959, 960960, 961961, 962962, 963963, 964964, 965965, 966966, 967967, 968968, 969696, 969969, 970970, 971971, 972972, 973973, 974974, 975975, 976976, 977977, 978978, 979797, 979979, 980980, 981981, 982982, 983983, 984984, 985985, 986986, 987987, 988988, 989898, 989989, 990990, 991991, 992992, 993993, 994994], [389389389], [777, 888, 999, 1010, 1111, 1212, 1313], [22222], [99999, 100100, 101010, 101101, 102102, 103103, 104104, 105105, 106106, 107107, 108108, 109109, 110110, 111111, 112112, 113113, 114114, 115115, 116116, 117117, 118118, 119119, 120120, 121121, 121212, 122122, 123123, 124124, 125125, 126126, 127127, 128128, 129129, 130130, 131131, 131313, 132132, 133133, 134134, 135135, 136136], [11], [6767, 6868, 6969, 7070, 7171, 7272, 7373, 7474, 7575, 7676, 7777, 7878, 7979, 8080, 8181, 8282, 8383, 8484, 8585, 8686, 8787, 8888, 8989, 9090, 9191, 9292, 9393, 9494, 9595, 9696, 9797, 9898, 9999, 11111], [92859285, 92869286, 92879287, 92889288, 92899289, 92909290, 92919291, 92929292, 92939293, 92949294, 92959295, 92969296, 92979297, 92989298, 92999299, 93009300, 93019301, 93029302, 93039303, 93049304, 93059305], [66, 77, 88, 99], [6868686868], [535353, 535535, 536536, 537537, 538538, 539539, 540540, 541541, 542542, 543543, 544544, 545454, 545545, 546546, 547547, 548548, 549549, 550550, 551551, 552552, 553553, 554554, 555555, 556556, 557557, 558558, 559559, 560560, 561561, 562562, 563563, 564564, 565565, 565656, 566566, 567567, 568568, 569569, 570570], [826826, 827827, 828282, 828828, 829829, 830830, 831831, 832832, 833833, 834834, 835835, 836836, 837837, 838383, 838838, 839839, 840840, 841841, 842842, 843843, 844844, 845845, 846846, 847847, 848484, 848848, 849849, 850850, 851851, 852852, 853853, 854854, 855855, 856856, 857857, 858585, 858858, 859859, 860860, 861861, 862862, 863863, 864864, 865865, 866866, 867867, 868686, 868868, 869869, 870870, 871871, 872872, 873873, 874874, 875875, 876876, 877877, 878787, 878878, 879879, 880880, 881881, 882882, 883883, 884884, 885885, 886886, 887887, 888888, 889889, 890890, 891891, 892892, 893893, 894894, 895895, 896896, 897897, 898898, 898989, 899899, 900900, 901901, 902902, 903903, 904904, 905905, 906906, 907907, 908908, 909090, 909909, 910910, 911911, 912912, 913913, 914914, 915915, 916916, 917917, 918918, 919191, 919919, 920920, 921921, 922922, 923923, 924924, 925925, 926926, 927927, 928928, 929292, 929929, 930930, 931931, 932932, 933933, 934934, 935935, 936936, 937937, 938938, 939393, 939939, 940940, 941941, 942942, 943943, 944944, 945945, 946946, 947947, 948948, 949494, 949949, 950950, 951951, 952952, 953953, 954954, 955955, 956956], [366366, 367367, 368368, 369369, 370370, 371371, 372372, 373373, 373737, 374374, 375375, 376376, 377377, 378378, 379379, 380380, 381381, 382382, 383383, 383838, 384384, 385385, 386386, 387387, 388388, 389389, 390390, 391391, 392392, 393393, 393939, 394394, 395395, 396396, 397397, 398398, 399399, 400400, 401401, 402402, 403403, 404040, 404404, 405405, 406406, 407407, 408408, 409409, 410410, 411411, 412412, 413413, 414141, 414414, 415415, 416416, 417417, 418418, 419419, 420420, 421421, 422422, 423423, 424242, 424424, 425425, 426426, 427427, 428428, 429429, 430430, 431431, 432432, 433433, 434343, 434434, 435435, 436436, 437437, 438438, 439439, 440440, 441441, 442442, 443443, 444444, 445445, 446446, 447447, 448448, 449449, 450450, 451451, 452452, 453453, 454454, 454545, 455455, 456456, 457457, 458458, 459459, 460460, 461461, 462462, 463463, 464464, 464646, 465465, 466466, 467467, 468468, 469469, 470470, 471471, 472472, 473473, 474474, 474747, 475475, 476476, 477477, 478478, 479479, 480480, 481481, 482482, 483483, 484484, 484848, 485485, 486486, 487487, 488488, 489489, 490490, 491491, 492492, 493493, 494494, 494949, 495495, 496496, 497497, 498498, 499499, 500500, 501501, 502502, 503503, 504504, 505050, 505505, 506506, 507507, 508508, 509509, 510510, 511511, 512512, 513513, 514514, 515151, 515515, 516516, 517517, 518518, 519519, 520520, 521521, 522522, 523523, 524524, 525252, 525525, 526526, 527527, 528528, 529529, 530530, 531531, 532532, 533533], [1515, 1616, 1717, 1818, 1919, 2020, 2121, 2222, 2323, 2424, 2525, 2626, 2727], [310310, 311311, 312312, 313131, 313313, 314314, 315315, 316316, 317317, 318318, 319319, 320320, 321321, 322322, 323232, 323323, 324324, 325325, 326326, 327327, 328328, 329329, 330330, 331331, 332332, 333333, 334334, 335335, 336336, 337337, 338338, 339339, 340340, 341341, 342342, 343343, 343434, 344344, 345345, 346346, 347347, 348348, 349349, 350350, 351351], [79117911, 79127912, 79137913, 79147914, 79157915, 79167916], [18291829, 18301830, 18311831, 18321832, 18331833, 18341834, 18351835, 18361836, 18371837, 18381838, 18391839, 18401840, 18411841, 18421842, 18431843, 18441844, 18451845, 18461846, 18471847, 18481848], [44444, 55555], [33, 44, 55], [3333233332, 3333333333, 3333433334], [202020, 202202, 203203, 204204, 205205, 206206, 207207, 208208, 209209, 210210, 211211, 212121, 212212, 213213, 214214, 215215, 216216, 217217, 218218, 219219, 220220, 221221, 222222, 223223, 224224, 225225, 226226, 227227, 228228, 229229, 230230, 231231, 232232, 232323, 233233, 234234, 235235, 236236, 237237, 238238, 239239, 240240, 241241, 242242, 242424, 243243, 244244, 245245, 246246, 247247, 248248, 249249, 250250, 251251, 252252, 252525, 253253, 254254, 255255, 256256, 257257, 258258, 259259, 260260, 261261, 262262, 262626, 263263, 264264, 265265, 266266, 267267, 268268, 269269, 270270, 271271, 272272, 272727, 273273, 274274, 275275, 276276, 277277, 278278, 279279, 280280, 281281, 282282, 282828, 283283, 284284, 285285, 286286, 287287, 288288, 289289, 290290, 291291, 292292, 292929, 293293, 294294, 295295, 296296, 297297, 298298, 299299, 300300, 301301, 302302, 303030, 303303, 304304, 305305, 306306], [], [9999999, 10001000, 10011001, 10021002, 10031003, 10041004, 10051005], [], [5142851428], [1111111], [46314631, 46324632, 46334633, 46344634, 46354635, 46364636, 46374637, 46384638, 46394639, 46404640], [3434, 3535, 3636, 3737, 3838, 3939, 4040, 4141, 4242, 4343, 4444, 4545, 4646, 4747, 4848, 4949, 5050, 5151, 5252, 5353, 5454, 5555, 5656, 5757, 5858, 5959, 6060], [333, 444], [592592, 593593, 594594, 595595, 595959, 596596, 597597, 598598, 599599, 600600, 601601, 602602, 603603, 604604, 605605, 606060, 606606, 607607, 608608, 609609, 610610, 611611, 612612, 613613, 614614, 615615, 616161, 616616, 617617, 618618, 619619, 620620, 621621, 622622, 623623, 624624, 625625, 626262, 626626, 627627, 628628, 629629, 630630, 631631, 632632, 633633, 634634, 635635, 636363, 636636, 637637, 638638, 639639, 640640, 641641, 642642, 643643, 644644, 645645, 646464, 646646, 647647, 648648, 649649, 650650, 651651, 652652, 653653, 654654, 655655, 656565, 656656, 657657, 658658, 659659, 660660, 661661, 662662, 663663, 664664, 665665, 666666, 667667, 668668, 669669, 670670, 671671, 672672, 673673, 674674, 675675, 676676, 676767, 677677, 678678, 679679, 680680, 681681, 682682, 683683, 684684, 685685, 686686, 686868, 687687, 688688, 689689, 690690, 691691, 692692, 693693, 694694, 695695, 696696, 696969, 697697, 698698, 699699, 700700, 701701, 702702, 703703, 704704, 705705, 706706, 707070, 707707, 708708, 709709, 710710, 711711, 712712, 713713, 714714, 715715, 716716, 717171, 717717, 718718, 719719, 720720, 721721, 722722, 723723, 724724, 725725, 726726, 727272, 727727, 728728, 729729, 730730, 731731, 732732, 733733, 734734, 735735, 736736, 737373, 737737, 738738, 739739, 740740, 741741, 742742, 743743, 744744, 745745, 746746, 747474, 747747, 748748, 749749, 750750, 751751, 752752, 753753, 754754, 755755, 756756, 757575, 757757, 758758, 759759, 760760, 761761, 762762, 763763, 764764, 765765, 766766, 767676, 767767, 768768, 769769, 770770, 771771, 772772, 773773, 774774, 775775, 776776, 777777, 778778, 779779, 780780, 781781, 782782, 783783, 784784, 785785, 786786, 787787, 787878, 788788, 789789, 790790, 791791, 792792]]\n",
|
|
"26202168557\n"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"# Get invalid ids and calculate answer\n",
|
|
"\n",
|
|
"invalid_ids = []\n",
|
|
"id_ranges = []\n",
|
|
"\n",
|
|
"for id_range in id_ranges_list[0]:\n",
|
|
" # invalid_ids_range = find_invalid_ids(id_range) # For part 1 answer\n",
|
|
" invalid_ids_range = find_all_invalid_ids(id_range) # For part 2 answer\n",
|
|
" invalid_ids.append(invalid_ids_range[:])\n",
|
|
"\n",
|
|
"sum_invalid_ids = sum(sum(invalid_ids,[]))\n",
|
|
"# print(invalid_ids)\n",
|
|
"print(sum_invalid_ids)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 18,
|
|
"id": "bda31f8c-7c2d-47af-80cc-cbab2abb3114",
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"def find_invalid_ids(id_range=''):\n",
|
|
" # This function finds the invalid ids within the specified range (part 1)\n",
|
|
" # input: id_range = String\n",
|
|
" # output: invalid_ids = int []\n",
|
|
"\n",
|
|
" invalid_ids = []\n",
|
|
" invalid_id = []\n",
|
|
" \n",
|
|
" # Extract the upper and lower bounds of the range\n",
|
|
" lb = int(id_range.split('-')[0])\n",
|
|
" ub = int(id_range.split('-')[1]) + 1\n",
|
|
"\n",
|
|
" # Generate the series of product ids withing the range\n",
|
|
" product_ids = range(lb,ub)\n",
|
|
"\n",
|
|
" # Find invalid ids\n",
|
|
" for id in product_ids:\n",
|
|
" id_string = str(id) # Convert each product id to string\n",
|
|
" \n",
|
|
" if len(id_string) % 2 == 0:\n",
|
|
" middle_point = len(id_string) // 2 # Find where to split the product id in 2\n",
|
|
"\n",
|
|
" # Compare the two halves of the id to determine if the id is invalid\n",
|
|
" first_half = id_string[0:middle_point]\n",
|
|
" second_half = id_string[middle_point:]\n",
|
|
" \n",
|
|
" if first_half == second_half: # If the two halves are equal, the id is invalid\n",
|
|
" invalid_id = int(id_string)\n",
|
|
" invalid_ids.append(invalid_id)\n",
|
|
"\n",
|
|
" return invalid_ids"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 51,
|
|
"id": "d8635605-2749-41c0-9fdd-b49a9b8228d6",
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"def find_all_invalid_ids(id_range=''):\n",
|
|
" # This function finds all the invalid ids within the specified range (part 2)\n",
|
|
" # input: id_range = String\n",
|
|
" # output: invalid_ids = int [[]]\n",
|
|
"\n",
|
|
" invalid_ids = []\n",
|
|
" invalid_id = []\n",
|
|
" \n",
|
|
" # Extract the upper and lower bounds of the range\n",
|
|
" lb = int(id_range.split('-')[0])\n",
|
|
" ub = int(id_range.split('-')[1]) + 1\n",
|
|
"\n",
|
|
" # Generate the series of product ids withing the range\n",
|
|
" product_ids = range(lb,ub)\n",
|
|
"\n",
|
|
" # Find invalid ids\n",
|
|
" for id in product_ids:\n",
|
|
" id_string = str(id) # Convert each product id to string\n",
|
|
"\n",
|
|
" chopped_ids = chop_product_id(id) # Chop each product id into equal-sized pieces\n",
|
|
"\n",
|
|
" # Identify ids with a repeating pattern\n",
|
|
" for list in chopped_ids:\n",
|
|
" chunks_set = set(list) # Convert each group of equal-sized chunks into a set\n",
|
|
" \n",
|
|
" if len(chunks_set) == 1: # If the resulting set has only 1 element, the id is invalid\n",
|
|
" invalid_id = int(id_string)\n",
|
|
" invalid_ids.append(invalid_id)\n",
|
|
" break\n",
|
|
" \n",
|
|
" return(invalid_ids)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 33,
|
|
"id": "5260533a-74bf-4b97-a157-f433cd3e11a3",
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"def chop_product_id(id):\n",
|
|
" # This function chops a product id into chunks of equal sizes\n",
|
|
" # input: id = int\n",
|
|
" # output: chopped_id = [[]]\n",
|
|
"\n",
|
|
" id_string = str(id)\n",
|
|
" chunks = []\n",
|
|
" chopped_id = []\n",
|
|
"\n",
|
|
" # Find divisors to split the id into equal-sized chunks\n",
|
|
" # (aka: how many ways to split the id into equal-sized chunks are there?)\n",
|
|
" for divisor in range(2,len(id_string) + 1): \n",
|
|
" if len(id_string) % divisor == 0:\n",
|
|
" chunks = []\n",
|
|
" chunk_size = len(id_string) // divisor # Determine how big a chunk would be\n",
|
|
"\n",
|
|
" for i in range(1,len(id_string)+1,chunk_size): # Chop the id\n",
|
|
" chunk = id_string[i-1:(i-1 + chunk_size)]\n",
|
|
" chunks.append(chunk)\n",
|
|
"\n",
|
|
" chopped_id.append(chunks)\n",
|
|
" \n",
|
|
" return chopped_id "
|
|
]
|
|
}
|
|
],
|
|
"metadata": {
|
|
"kernelspec": {
|
|
"display_name": "Python 3 (ipykernel)",
|
|
"language": "python",
|
|
"name": "python3"
|
|
},
|
|
"language_info": {
|
|
"codemirror_mode": {
|
|
"name": "ipython",
|
|
"version": 3
|
|
},
|
|
"file_extension": ".py",
|
|
"mimetype": "text/x-python",
|
|
"name": "python",
|
|
"nbconvert_exporter": "python",
|
|
"pygments_lexer": "ipython3",
|
|
"version": "3.10.12"
|
|
}
|
|
},
|
|
"nbformat": 4,
|
|
"nbformat_minor": 5
|
|
}
|