diff --git a/2024/R/day17.qmd b/2024/R/day17.qmd index 689e314..079e8d1 100644 --- a/2024/R/day17.qmd +++ b/2024/R/day17.qmd @@ -12,13 +12,13 @@ author: # Libraries library(tidyverse) library(unglue) +library(bit64) # Read input from file input <- read_lines("../input/day17.txt", skip_empty_rows = TRUE) |> unglue_data(patterns = c( "{label}: {value}" )) - ``` ## Part 1 @@ -89,11 +89,30 @@ run_machine <- function(machine) { operand <- machine$program[machine$pointer + 2] machine <- run_opcode(machine, opcode, operand) } - print(machine$output) + return(machine$output) } ``` +Need to define custom bitwise XOR function to handle very large integers without error: + +```{r} +bitwXor64 <- function(x, y) { + x <- as.bitstring(as.integer64(x)) + y <- as.bitstring(as.integer64(y)) + + base::xor( + as.integer(str_split_1(x, "")), + as.integer(str_split_1(y, "")) + ) |> + as.integer() |> + str_c(collapse = "") |> + structure(class = "bitstring") |> + as.integer64() |> + as.numeric() +} +``` + Define the opcode functions: ```{r} @@ -105,7 +124,7 @@ adv <- function(machine, operand) { } bxl <- function(machine, operand) { - machine$B <- bitwXor(machine$B, operand) + machine$B <- bitwXor64(machine$B, operand) machine$pointer <- machine$pointer + 2 return(machine) } @@ -125,16 +144,15 @@ jnz <- function(machine, operand) { } bxc <- function(machine, operand) { - machine$B <- bitwXor(machine$B, machine$C) + machine$B <- bitwXor64(machine$B, machine$C) machine$pointer <- machine$pointer + 2 return(machine) } out <- function(machine, operand) { - machine$output <- str_c( + machine$output <- c( machine$output, - combo(machine, operand) %% 8, - sep = "," + combo(machine, operand) %% 8 ) machine$pointer <- machine$pointer + 2 return(machine) @@ -158,8 +176,46 @@ Run on puzzle input: ```{r} -run_machine(machine) +run_machine(machine) |> + str_c(collapse = ",") ``` +## Part 2 + +Reverse engineer, testing sequences of 3 bits at a time. Thanks to hints from [Reddit](https://www.reddit.com/r/adventofcode/comments/1hg38ah/comment/m2odsfl/?utm_source=share&utm_medium=web3x&utm_name=web3xcss&utm_term=1&utm_content=share_button): +```{r} + +run_machine_a <- function(a) run_machine(list( + program = program, + A = a, + B = B, + C = C, + pointer = 0L, + output = NULL +)) + +reveng <- function(program, digit = 1, a = 0) { + if (digit > length(program)) + return(a) + + df <- tibble(candidates = 8 * a + 0:7) |> + mutate( + output = map(candidates, run_machine_a), + output = map(output, head, n = 1) + ) |> + filter(output == rev(program)[digit]) |> + mutate( + res = map_dbl(candidates, ~ reveng(program, digit + 1, .x)) + ) |> + filter(!is.na(res)) + + if (nrow(df) == 0) return(Inf) + else return(min(df$res)) +} + +reveng(program) |> + format(scientific = FALSE) + +``` diff --git a/2024/R/day22.qmd b/2024/R/day22.qmd new file mode 100644 index 0000000..4a2ee38 --- /dev/null +++ b/2024/R/day22.qmd @@ -0,0 +1,121 @@ +--- +title: "Day 22" +date: 2024-12-22 +author: + name: https://adventofcode.com/2024/day/22 + url: https://adventofcode.com/2024/day/22 +--- + +## Setup + +```{r setup} +# Libraries +library(tidyverse) +library(bit64) +library(memoise) + +# Read input from file +input <- read_lines("../input/day22.txt", skip_empty_rows = TRUE) |> + as.numeric() +``` + +## Part 1 + +Define custom bitwise XOR function, needed to handle large integers: + +```{r} +bitwXor64 <- function(x, y) { + x <- as.bitstring(as.integer64(x)) + y <- as.bitstring(as.integer64(y)) + + map2_chr( + x |> str_split("") |> map(as.integer), + y |> str_split("") |> map(as.integer), + ~ base::xor(.x, .y) |> + as.integer() |> + str_c(collapse = "") + ) |> + structure(class = "bitstring") |> + as.integer64() |> + as.numeric() +} +``` + +Define the algorithm for producing a sequence of "secret" numbers: + +```{r} + +mix <- memoise::memoise(\(a, b) bitwXor64(a, b)) +prune <- \(x) x %% 16777216 + +secret_alg <- function(x) { + x1 <- prune(mix(x, x * 64)) + x2 <- prune(mix(x1, floor(x1 / 32))) + x3 <- prune(mix(x2, x2 * 2048)) + return(x3) +} + +secret_seq <- function(init, len) { + out <- list(init) + for (i in 2:len) { + out[[i]] <- secret_alg(pluck(out, i - 1)) + } + out +} + +``` + +Run puzzle input: + +```{r} + +secret_nums <- secret_seq(input, len = 2001) + +secret_nums |> + tail(n = 1) |> + unlist() |> + sum() + +``` + +## Part 2 + +```{r} + +# Convert sequences to a data frame by buyer and time +diffs <- secret_nums |> + imap_dfr(\(x, idx) tibble(time = idx, secret_number = x)) |> + mutate( + buyer_id = row_number(), + .by = time + ) |> + mutate( + # Get the price at each time by taking the ones digit of each secret number + price = secret_number %% 10L, + # Compute the difference in price at the current time vs the previous time + diff = price - lag(price), + # Compute the sequence of 4 price changes preceeding the current price + lag1 = lag(diff, n = 1L), + lag2 = lag(diff, n = 2L), + lag3 = lag(diff, n = 3L), + diff_seq = str_c(lag3, lag2, lag1, diff, sep = ","), + .by = buyer_id + ) |> + arrange(buyer_id, time) + +# For each price change seq, compute the bananas you will get from each buyer: +bananas_by_seq <- diffs |> + filter(!is.na(diff_seq)) |> + summarize( + bananas = head(price, 1), + .by = c(buyer_id, diff_seq) + ) + +# Find the most advantageous sequence: +bananas_by_seq |> + summarize(bananas = sum(bananas), .by = diff_seq) |> + slice_max(bananas) |> + pull(bananas) + +``` + diff --git a/2024/input/day22.txt b/2024/input/day22.txt new file mode 100644 index 0000000..b6e2c2d --- /dev/null +++ b/2024/input/day22.txt @@ -0,0 +1,2420 @@ +5862483 +1171926 +4315535 +11443159 +1181105 +3092672 +11815792 +14012179 +11177019 +12662897 +1369984 +9485149 +4374378 +3373786 +11696791 +10994026 +4241487 +3425444 +5713541 +2378462 +2836358 +7020562 +4241166 +15317199 +2776172 +11013114 +1357534 +1719708 +7163972 +5262115 +16180428 +14589586 +6830700 +3191647 +7950621 +16472871 +2249759 +3745385 +8607199 +15412721 +4250130 +16626256 +10731392 +9258244 +10532898 +12891533 +10080323 +10502397 +2885218 +16080215 +1465396 +13447569 +10245972 +15176909 +3901558 +7203187 +5759891 +3130046 +12917510 +15433463 +3903507 +252788 +3136249 +2644253 +7465004 +15386079 +7968882 +7097976 +3779518 +6613183 +12065423 +14287549 +7093109 +11929354 +4565901 +14325215 +1288333 +8854490 +3621979 +5501461 +4694727 +6322015 +14918610 +5800550 +724199 +8413466 +7657135 +15867674 +7814885 +3242386 +15007554 +16098769 +7961375 +8591392 +4481728 +1013207 +5759476 +15213057 +7928020 +13448221 +4144114 +12132379 +244982 +2912781 +4767277 +2001412 +1036987 +1873277 +3597717 +7131340 +11660062 +14123812 +7902443 +1260529 +14824302 +7388667 +11183300 +3494007 +4528945 +12448370 +1664294 +7306924 +15552513 +4790661 +5930137 +14880886 +14813426 +14465889 +11067400 +2275647 +12644789 +13854900 +2888090 +16008079 +214045 +7645831 +6398368 +3885150 +4040788 +15378459 +148426 +9427650 +4506722 +4992574 +3298158 +14283082 +2469436 +6031713 +1899296 +9961142 +4465639 +8227005 +12481987 +2006771 +1975977 +12722947 +6166856 +14226802 +10990742 +13338947 +13276328 +7948242 +11825709 +3262704 +6128375 +1584531 +1077217 +14260076 +15148135 +3193952 +12212442 +10976747 +10724032 +10953116 +10648652 +5484837 +16263483 +6205335 +4963606 +4987618 +10200764 +5762975 +7319405 +3015005 +271719 +9604200 +10841492 +14886680 +11471334 +8362725 +16453279 +11791100 +16551984 +1809560 +1736820 +13068647 +14334337 +9008817 +14277673 +16369957 +14897129 +16033507 +1467645 +15235178 +8214125 +12055271 +7092749 +10566484 +1136801 +13728739 +10849523 +818385 +7713215 +10480808 +6739784 +10852707 +16165022 +10873497 +8729099 +9434813 +13677433 +9903777 +2783149 +729353 +12804911 +2836228 +3297124 +7480412 +809412 +6526511 +6517289 +12161997 +15254013 +16518848 +5925532 +3384736 +10514049 +8850440 +687265 +152077 +12385400 +4081925 +6175595 +8398420 +2158738 +14788757 +4016167 +4883738 +5053552 +4129031 +8823873 +4797793 +1834418 +13112745 +3050436 +10067957 +3079814 +4172555 +1688046 +14286220 +5720381 +5032126 +13248410 +7693248 +13399169 +4548157 +5905345 +5722486 +7068612 +4467305 +9110920 +6728295 +11708210 +13491849 +2830635 +8219186 +9172670 +7514412 +6899740 +6127504 +11955448 +8917907 +15385939 +6083895 +8947528 +6086489 +12465167 +9012577 +8606083 +2784012 +15555738 +15621114 +4428345 +8043812 +8260599 +1787939 +14254839 +5756532 +14181271 +1060091 +11367283 +15933860 +16437633 +8517971 +1884160 +11838877 +879221 +7420829 +2337223 +8746720 +5081817 +8196134 +1423878 +6054127 +4178750 +9087360 +5847125 +16039573 +935570 +2261781 +13248000 +9148351 +4498692 +6560186 +7890347 +5179113 +3777463 +10793845 +781858 +11972804 +2603375 +5049269 +14667930 +1800113 +11476809 +6076848 +12951018 +1203197 +9743772 +6473984 +16216585 +791161 +13882347 +12617242 +14105015 +5424897 +13763297 +10227415 +16724655 +12900594 +12563442 +14172167 +12139129 +12015134 +6025045 +13461951 +3947276 +808706 +6525324 +8352279 +12541345 +3671611 +10330546 +12138217 +15733618 +1804048 +689238 +7661649 +15622378 +7056608 +3387261 +13003975 +11209104 +14987460 +11364088 +16624147 +2922772 +200025 +6412275 +7448960 +15212616 +12467174 +10830629 +2502508 +8362542 +6433623 +10918335 +13800357 +14159413 +2980479 +4558238 +4904665 +7921549 +12805377 +9198824 +15881963 +1736379 +14165747 +4001683 +14923276 +3311883 +3715041 +927232 +11203634 +7923961 +16497725 +10241529 +11675054 +6412972 +15521173 +6351622 +407984 +8839045 +4581358 +10476343 +9690558 +15938364 +10141361 +1488379 +15500671 +8174398 +14229299 +9808582 +8920455 +1091089 +1293255 +640169 +16052837 +5174042 +1694065 +8550938 +602054 +1395586 +15420912 +14665871 +11680793 +16667213 +11541692 +6569334 +1024266 +1684270 +10301904 +7622012 +14910939 +3902881 +14279105 +5004034 +10662863 +10857144 +10051964 +11215046 +4471713 +227413 +15949414 +14870988 +11338612 +15909643 +12935983 +2905761 +4228008 +12077170 +1736619 +5203443 +3071102 +12035534 +1870905 +7028374 +6955967 +3406298 +2540832 +13287107 +11376208 +11297804 +6676752 +9452425 +10115842 +8908545 +4606327 +14417643 +14823375 +4943566 +13626620 +14354264 +1703532 +3173792 +4590970 +5511839 +1545735 +14934436 +7818556 +3501449 +2761718 +12813637 +15373306 +16296656 +13128025 +2764493 +2604306 +14547963 +7394712 +412945 +15894269 +3835965 +7068486 +6296590 +5976494 +4361257 +9741049 +1652119 +12285879 +11818141 +14390363 +1181403 +13698646 +3398375 +5207581 +14838549 +4773021 +3935127 +6567749 +11599341 +3431098 +1681443 +15649996 +4060170 +453150 +6402245 +10927022 +13739490 +15898345 +14420895 +16082457 +3692388 +10955844 +7216004 +14737622 +13215221 +15829447 +10538786 +16158907 +1451321 +8528098 +3521735 +3804551 +5284233 +8243322 +13021724 +8230037 +11713621 +1051506 +1312427 +11982943 +7674494 +14800558 +16154166 +16133938 +202382 +10089829 +710919 +11559187 +9125895 +3354924 +8046550 +903301 +15090974 +11458294 +13238710 +698524 +593173 +13604258 +7018749 +15327919 +5150208 +9338432 +4684501 +11946990 +1958125 +185360 +15603859 +2184487 +8264334 +13065150 +4299954 +5925439 +14021643 +1710015 +16384906 +12656899 +12547916 +2200796 +3208363 +11081066 +13611760 +11855672 +13598946 +5314995 +4359233 +1615558 +12574128 +8745071 +2760687 +4332577 +13008128 +14301943 +11621539 +10845483 +1987246 +5674425 +4056224 +2213221 +12930135 +5919333 +7060558 +6105619 +4112027 +4686865 +13153033 +14436259 +2218213 +1744956 +4675790 +10904950 +5949787 +7775975 +9698851 +5054789 +9245046 +6635744 +15893347 +11379919 +13454404 +726003 +6482126 +14973226 +3421486 +3116478 +9920722 +7664702 +11580530 +5918127 +16486876 +4984917 +16116061 +13119978 +14517096 +11650172 +9643179 +1654734 +5086019 +13652108 +7097093 +15887431 +15352579 +5610045 +14525464 +7094309 +3600918 +11993935 +1794344 +12904058 +12324489 +16315705 +10064506 +7480349 +8287333 +16694804 +1865794 +15836543 +5998997 +2743931 +7566896 +8515646 +6429083 +279097 +5309185 +15984167 +14043338 +16733994 +3146682 +14372046 +11647354 +5370003 +16555935 +8402245 +7892640 +12081786 +14809585 +1949738 +1733964 +1901062 +12702966 +7127271 +12601858 +9981674 +10820038 +15840456 +1121897 +16545813 +9829800 +16104791 +13068195 +367741 +12327850 +1083017 +4701357 +829906 +10660734 +13616686 +4802139 +13346593 +9900140 +4995151 +14257918 +16511779 +10063960 +16408926 +3608183 +4433380 +5838534 +3278968 +5998445 +9526711 +6401468 +13580122 +215876 +7452973 +1686092 +16179257 +15162413 +10558633 +13447036 +15020362 +13940163 +7289762 +7449608 +1019764 +13684187 +15230261 +6613362 +13466497 +14524121 +16421602 +7196784 +15395842 +16628555 +2658408 +1373122 +10971146 +8287963 +9158345 +7264764 +12665111 +2884197 +3310394 +2315444 +11491989 +9392073 +4951907 +2675478 +2425008 +4719934 +6364165 +9570951 +13517974 +3540774 +377652 +6493597 +6446766 +13103613 +2872759 +10689361 +837082 +11469744 +8804629 +13908410 +9200280 +7644072 +12579510 +2462809 +8700765 +6365938 +13376061 +16417086 +11932321 +4659585 +4084443 +12686831 +4076476 +14717418 +3787433 +9449552 +16097265 +5708290 +7117179 +9546806 +10616315 +3398594 +2262937 +14950300 +1569214 +5414425 +358873 +12241127 +1316089 +6846683 +4629820 +2727871 +11702860 +15866046 +1958395 +2635133 +3700566 +14456856 +1889859 +6521143 +11327056 +1152648 +13192524 +14272722 +1534240 +15383481 +7049613 +11452297 +9641171 +6031439 +14993902 +12357276 +2628104 +6492848 +6980480 +2222552 +8141587 +9229182 +11545908 +5825235 +11401328 +6436542 +6382166 +9629364 +6655346 +14285368 +3773735 +4376178 +11153191 +2828090 +14857725 +7695442 +14793733 +13554905 +8038025 +12183188 +9582856 +6092769 +14028208 +11669993 +3475144 +3304969 +12646454 +5403242 +14947173 +10599046 +13612806 +10484350 +8250119 +9116131 +2477669 +4354049 +5399920 +2861568 +13783956 +16069830 +14407936 +16570460 +14461338 +7783253 +14479491 +9407535 +1352658 +12707693 +10544730 +8878727 +13385418 +4427446 +15190655 +9412735 +4032376 +6401137 +12398447 +8542657 +14167955 +1242861 +8274211 +15286197 +9800938 +9230802 +13074164 +3258237 +9521914 +7055655 +10277523 +168298 +9597693 +11762008 +10156316 +6919083 +3686541 +1819680 +7496939 +5204760 +9812386 +15445153 +11893932 +16314226 +7045485 +5306754 +11129890 +11439104 +1165243 +16590389 +16019992 +4131149 +10783766 +2088968 +527110 +7534819 +13321652 +3226603 +2965052 +7481121 +2822492 +13795907 +7088551 +12466628 +13899296 +13296191 +6894505 +11467384 +6111873 +4012448 +6732023 +2206647 +7917290 +7314418 +6861603 +4362858 +1190370 +2807944 +1087718 +8845307 +11976554 +12588186 +14823767 +14231141 +2699532 +264753 +13251534 +10883400 +13592804 +2668654 +13503828 +7326813 +12773564 +10854932 +233344 +11655084 +15390907 +13641469 +11765965 +3302534 +3852460 +7100533 +8917414 +12563154 +6065398 +6478357 +7981253 +9808962 +7990936 +8135956 +10304235 +9179662 +10777919 +6997392 +13732494 +12943681 +8906091 +6294640 +670090 +6672651 +4537371 +13701196 +9645778 +16311698 +11808513 +3065750 +13173179 +15662966 +4476270 +4018687 +13951367 +15617192 +7449697 +7418378 +1873831 +555400 +10029320 +11730213 +10877819 +10821874 +14422502 +5954739 +10183748 +9379514 +14236006 +7653325 +8077174 +11487537 +13325887 +13076565 +2739165 +2048924 +606282 +7668092 +5720696 +15645719 +9272496 +761217 +2280083 +9255688 +16544861 +9883606 +12416047 +5236822 +10763390 +6814612 +3807396 +2130608 +10871945 +5850979 +3109412 +1957555 +7854331 +13413288 +14894531 +10763839 +3874603 +5521678 +13587887 +16433982 +5439253 +4335608 +14506061 +3357713 +10990811 +10594486 +6812226 +135757 +1486555 +3144642 +13421222 +5356980 +10680295 +16174199 +8609550 +7519566 +11213017 +13075216 +6176403 +4173366 +3797810 +16773105 +14949530 +13044503 +10807495 +6587753 +8711111 +12242809 +4439206 +5837389 +15559754 +491202 +7190631 +15682038 +12889231 +3127170 +13639904 +4944180 +12885358 +5427134 +1726220 +3053307 +6985926 +5518869 +8269640 +6545010 +5732578 +8336686 +3814315 +13881911 +11558140 +7989879 +10970936 +11827596 +4032964 +13692458 +16681192 +5647135 +12052743 +6713529 +10170470 +10930690 +11978580 +10684422 +11267078 +6904682 +16035540 +5610854 +3990077 +1544808 +10754444 +8383293 +8622385 +4791800 +8878017 +1031659 +452429 +8388658 +6248299 +7548689 +7272701 +15859588 +8377418 +2343833 +16745336 +16258893 +14988188 +11377545 +1232024 +10788892 +11556701 +5611173 +355614 +13001818 +9113958 +6101214 +5533580 +3268585 +470036 +15982061 +10207957 +7019453 +12153223 +8557308 +4538247 +13419827 +13181488 +6350838 +15593722 +2152250 +15961083 +15961898 +13933584 +7220521 +7342868 +4182253 +6738854 +14884702 +6472003 +1857923 +1483156 +13667421 +12201618 +16707856 +2542416 +5167480 +11195180 +16140100 +8717505 +14755713 +638039 +1502813 +16683957 +11570767 +13060787 +16093866 +8891530 +3817545 +11037761 +16640982 +5535291 +2902362 +13047293 +10734689 +5081807 +2143756 +14744937 +8912965 +2550388 +11439036 +3129092 +13289007 +4048142 +9407747 +3404076 +16774618 +11985147 +2455982 +12493045 +11678195 +9142284 +7910066 +16301319 +16098158 +3853889 +5440680 +15775706 +4323216 +11637467 +11020668 +4242310 +14282720 +8393867 +6184948 +6884229 +7371757 +6620983 +8751304 +877087 +8372055 +566723 +4229359 +14830694 +2669199 +761492 +881356 +13872954 +10660297 +8691525 +14489529 +16776764 +13511430 +14587099 +5194861 +2449718 +13920678 +12794719 +15722623 +5538372 +1831598 +11635505 +579370 +11883707 +16019713 +13614502 +6256945 +11892698 +6937331 +10348229 +12234913 +5072410 +1573648 +6289610 +2953930 +14499896 +12446631 +3539200 +3567255 +13852445 +2002788 +13809190 +11469055 +9238327 +13590676 +5195795 +3908108 +16635889 +9427893 +9871525 +5387889 +6547653 +16054484 +1761347 +10002253 +11763608 +2607254 +3694125 +11781953 +11300866 +9917984 +2193375 +14748807 +2817438 +6565113 +6044742 +11771684 +16138904 +12994970 +10146144 +9382872 +5999702 +418774 +10567192 +8307657 +5730398 +361287 +14157946 +5964114 +16025731 +9680594 +9204610 +9064381 +9295052 +13115584 +8964274 +3639540 +8028317 +5623881 +14436956 +728469 +2383182 +5181254 +5868869 +7222286 +9358229 +15126157 +918692 +3593875 +11689221 +5250247 +12424166 +1038616 +13589587 +6910399 +4433855 +8897407 +4533246 +13298429 +11562274 +402533 +11625673 +10169619 +11833964 +14506497 +10585450 +12173112 +14485242 +15297473 +288984 +10200044 +5664940 +5901342 +14974439 +8937718 +438136 +14584428 +11968223 +15157912 +11370032 +10443563 +8093800 +8970469 +5365456 +8593008 +7661881 +2458138 +14414231 +1940199 +15435201 +1915236 +15899095 +6824903 +5394810 +12555728 +2950157 +14232822 +8106081 +2965801 +12250969 +4291939 +12368823 +14909783 +152197 +6506627 +11705177 +12214303 +3109929 +6324084 +5539229 +5854353 +10899259 +5283129 +6422816 +11525661 +5354328 +131589 +14480048 +14707477 +3810208 +16665692 +7988279 +13597331 +8735113 +4974171 +1549428 +6061048 +15514731 +2608683 +7805232 +11158467 +14013375 +15879445 +5892818 +7456324 +16368362 +288099 +11204383 +11623336 +9304995 +13631122 +6649470 +13979128 +13500492 +16432639 +14616844 +2064426 +2669726 +14400134 +12117170 +4734186 +8458505 +13713422 +3661929 +2802599 +10452666 +8472407 +506120 +4065904 +2254873 +9927363 +2465310 +3533455 +9557429 +5188888 +3319733 +14289959 +3107619 +14866318 +9792817 +15227404 +14718009 +11996102 +4493319 +3047855 +6941260 +163950 +2293662 +16149358 +6386835 +11038629 +7353427 +15011008 +4677597 +2363453 +3941216 +2379616 +9099753 +8055364 +432708 +11064945 +7093600 +15351598 +13024070 +7566227 +6823504 +15469101 +12585904 +16081424 +726376 +16664899 +9620621 +15176951 +11174833 +10391204 +6811108 +16661850 +6531759 +12470246 +5695455 +16076824 +6893286 +12707986 +1577616 +4283781 +7984814 +9577332 +12384691 +16128188 +366078 +9026814 +14730051 +11536353 +11785066 +13376745 +1213347 +4262250 +10451991 +3191061 +11376032 +3712130 +4636048 +8731497 +11756996 +2028258 +14546609 +5786442 +6034481 +14993593 +4660642 +5842157 +8238206 +14711607 +14158321 +14755966 +3831065 +10233546 +11399235 +9049287 +9149712 +7140246 +13839030 +4794280 +13890935 +5693360 +15400817 +9092661 +11407390 +2085727 +13657839 +819723 +15990203 +16642898 +5466044 +9499853 +15847302 +12418732 +16520744 +11077987 +7139527 +12008195 +7527990 +8450033 +4493792 +1713625 +13616549 +3668238 +16086302 +15694238 +4699456 +1698316 +2831308 +6890300 +693520 +11332271 +16458995 +564274 +5421034 +505816 +681110 +672653 +11758094 +9671233 +10084190 +5522818 +14466305 +4046688 +1368369 +2022715 +1721021 +14936348 +9007753 +5713475 +937102 +11563518 +6235684 +13402667 +14450802 +9396957 +15729692 +9487212 +16374745 +6232090 +1476207 +3829520 +7292342 +4434625 +4487867 +14662528 +11861424 +6183126 +14600944 +2466550 +12383199 +14039898 +7944408 +10099484 +15887896 +9335661 +15328087 +1556758 +5207612 +15066659 +14202540 +9392307 +3283465 +6331261 +15517493 +5015181 +15489594 +136182 +10155685 +503510 +3485044 +1398019 +10971964 +2667810 +10466669 +1125070 +4746507 +4692944 +3066672 +13371437 +1287202 +14015395 +756720 +8394983 +10928436 +11554063 +4480004 +12079323 +8517199 +14834685 +2280188 +16681127 +8899594 +9032733 +14310253 +11782386 +6399703 +16414390 +13565237 +10728528 +5334323 +10003088 +13906526 +11352145 +2549696 +12974799 +5414783 +10564606 +11070889 +5601745 +14354839 +4731027 +4501307 +11960509 +1535713 +12678117 +15209481 +260877 +16549574 +3941991 +11251393 +16764556 +5122388 +4506701 +4525157 +5094189 +1122584 +2495924 +6878379 +7023306 +12717284 +13641804 +13198060 +515645 +13378421 +9546050 +7538781 +8715094 +4973093 +12594100 +5877292 +9555209 +1805308 +5421615 +11650679 +15209643 +12488783 +793653 +12563268 +956258 +13091328 +5883615 +7727148 +9672146 +8395518 +13174063 +16255932 +13763801 +13014309 +10599593 +6354501 +857211 +9272058 +6930732 +6294131 +16004429 +1581518 +15670019 +14773719 +210043 +8520952 +5527426 +5929547 +8323631 +12128395 +9048665 +14357058 +5279024 +1442493 +307228 +9166576 +13701334 +6172585 +6736990 +16698747 +13104878 +8504457 +4680410 +3349905 +2733490 +630685 +10913544 +13243697 +655904 +11059782 +11230100 +11133109 +8939476 +9417834 +11114221 +11899103 +10449186 +15426905 +14995244 +7514149 +7639946 +11093941 +7192913 +6926924 +2758016 +8111491 +5460412 +4145932 +12130947 +4096182 +7448971 +3938185 +12085420 +4981955 +10694984 +12677174 +2867016 +13635748 +13715725 +4711170 +12361685 +15861668 +748549 +15633840 +11802987 +2460635 +14193857 +12434336 +14012903 +8128733 +5577889 +5807764 +5209928 +11395416 +14323200 +14277774 +8588899 +9566392 +11455122 +2784075 +7311798 +16710593 +12847311 +1016242 +5307169 +8960548 +15353818 +1097244 +4572546 +2838686 +7236794 +9900894 +5158548 +7348451 +9632086 +15264579 +12150281 +15174643 +7184612 +10336585 +13390780 +13047227 +3181047 +13529458 +7281630 +8888302 +13184944 +7828060 +1592400 +7108386 +11869424 +6122730 +2425289 +12667327 +12548505 +5928029 +11779398 +470590 +3020377 +10851610 +13419002 +824930 +7899793 +2059272 +15149397 +10125750 +5866805 +6449657 +5641441 +8199025 +6475930 +3554203 +11326600 +14610743 +3677542 +3970024 +8866406 +1864118 +12094924 +658285 +562052 +9950748 +820093 +1930869 +13059581 +3410084 +9268114 +6808968 +10952852 +9348898 +12873710 +7156672 +6980957 +6923110 +10227795 +7383789 +1486885 +12455583 +7135902 +2149333 +2320700 +6338987 +1180739 +11662965 +4036031 +13698063 +9061191 +3121339 +12519156 +1806307 +6065560 +13989608 +16142884 +7261062 +4841131 +15299991 +11618651 +12526609 +2979808 +3895125 +7756449 +11804372 +8893471 +2227355 +988864 +984547 +11204024 +6119988 +12603718 +14669271 +14154331 +11351325 +11112791 +9558584 +1570711 +12677471 +3620096 +5776612 +16328204 +6305943 +10770167 +10658757 +16543214 +6533747 +694357 +3471793 +2986040 +10789606 +3925130 +5370883 +5830748 +4758677 +14468284 +532656 +6364620 +7962502 +16707843 +11067660 +884524 +444993 +5019720 +11841088 +2850171 +7443238 +10859324 +1574563 +5906401 +7114518 +14766767 +3582121 +701506 +10614361 +7116180 +6222328 +1683708 +8083256 +4214362 +8659273 +9815207 +4015020 +13293999 +3678585 +12905681 +1141588 +7682439 +3656922 +13778985 +8722678 +7806504 +10304306 +10817165 +7768522 +5540647 +2276429 +361941 +10311973 +16095138 +14435854 +10508348 +1231640 +7356053 +12785936 +1397893 +5011807 +663044 +10587023 +11703296 +16219385 +11970737 +8960323 +13314752 +8139190 +13692489 +10637607 +3747387 +2295141 +1863830 +10879402 +14856637 +12461890 +4731058 +840178 +12190182 +4420575 +9264489 +13491438 +3482751 +7508722 +12841670 +7719656 +4807631 +994609 +9814646 +2265330 +1984386 +9668048 +9327596 +230717 +15013119 +14029591 +4839979 +8580295 +9115909 +6699294 +3416844 +4428829 +16248827 +16625392 +14768136 +14920471 +15656283 +5428726 +2169601 +10187875 +4956201 +11156469 +4579635 +4191872 +14212682 +5787099 +5786440 +3466894 +9637386 +8450822 +15266485 +10469053 +13154290 +6372076 +6752698 +15676551 +2721416 +634783 +984075 +1900319 +6168886 +11029529 +11209146 +8560244 +1609499 +6613756 +16280614 +10106915 +15282462 +1867544 +14083243 +8315712 +6624238 +12525556 +308845 +143283 +988736 +4937582 +2064135 +2441984 +626909 +12185506 +8432871 +13339873 +16677013 +1400658 +14304516 +12940010 +13611372 +9557079 +3957794 +529822 +12194247 +10849472 +9844998 +14271485 +1355653 +8443385 +2166012 +6370885 +8389481 +13935223 +4996570 +3487509 +15627310 +1411139 +13383640 +6163578 +10315296 +2118213 +6546943 +6316681 +8005883 +13476096 +5082230 +11563067 +11890733 +12763989 +6906081 +14411530 +4686970 +6728137 +15384812 +7104402 +7234911 +9448671 +11853417 +13023976 +5547842 +8500817 +1298936 +398042 +11159006 +16741111 +5501097 +8899690 +7527165 +7249362 +8726064 +2191608 +4318423 +1712336 +3674910 +4285803 +1634323 +13237146 +12475706 +12541057 +6599548 +6797631 +7245383 +1528800 +8409660 +9384015 +4002728 +10736685 +13508691 +1975233 +6123011 +14230644 +16529332 +1229552 +8051587 +12124813 +2551390 +16710110 +4141184 +4961776 +5671499 +16373289 +16060735 +15108711 +15162114 +5744166 +733994 +15668620 +2381065 +1371123 +2362390 +15294125 +10636607 +8823714 +10465893 +7007711 +2333875 +1369888 +5861494 +12443246 +3546147 +5028345 +10055795 +6609817 +10261715 +3612626 +14623391 +11800260 +5553665 +15192093 +6866796 +5420205 +1580696 +9205105 +15826692 +8297994 +8742242 +9821387 +7735702 +13711394 +12020278 +6786594 +4724114 +6610283 +7124010 +13343139 +14000895 +15447594 +15494930 +2746716 +14429303 +5639956 +4505844 +12708656 +12545719 +4655541 +3324521 +1314958 +1820292 +12273931 +470551 +8809888 +6037889 +2602534 +16371642 +6096513 +2019527 +13418004 +15304032 +12927872 +12159840 +5252445 +3015076 +16653152 +14316154 +10059654 +9629414 +1712454 +11059405 +13556662 +13780347 +2392341 +1851874 +3259523 +7482637 +3972594 +15858692 +5439799 +855883 +1269986 +13129783 +1909892 +11504415 +1576598 +472624 +16504975 +11911055 +13617388 +13887030 +13329559 +2629505 +16097294 +6821868 +8234519 +9803591 +6262165 +1311351 +13088847 +13788681 +9043897 +6025172 +15213182 +5407420 +11612255 +13103654 +3291317 +6408790 +9613688 +1629605 +13885005 +218781 +15926081 +4138029 +9434444 +8732101 +3813055 +8277929 +6354162 +9590465 +12784906 +11632261 +652399 +16148459 +1644561 +12603362 +1972091 +13633852 +4585695 +1078446 +13564428 +1532949 +15605667 +10153411 +3100840 +8614920 +14037083 +8431105 +943396 +8409550 +14147957 +12406999 +11660684 +8777476 +4121946 +8288737 +9410032 +16663009 +9542329 +14200882 +2535264 +8892286 +14202374 +3954566 +3874862 +11680984 +1155015 +4491786 +8311990 +12131842 +4102949 +8433242 +10980968 +6243187 +3968362 +9242191 +11641272 +6415029 +3237442 +11733920 +5811380 +7290123 +557025 +7499426 +11196577 +876520 +9960108 +11399541 +9581264 +4901740 +10622794 +9639302 +1117465 +13700658 +5323241 +2951880 +6108936 +5041945 +10862294 +15590950 +12379807 +15587514 +6201757 +962407 +595159 +14109296 +7113095 +11478415 +9977784 +13251577 +16502383 +7238329 +5792676 +11707830 +13042888 +830904 +3381499 +5452977 +8617224 +9350984 +12139408 +2038149 +6004397 +465454 +12161209 +8218698 +14563239 +14461104 +14505919 +14153871 +12430112 +11271629 +14219621 +11574110 +10724442 +16512274 +12101385 +9647415 +6009035 +673880 +9486946 +12195491 +6643056 +8939177 +2592118 +3183366 +13071378 +6390352 +7024755 +16328189 +16737063 +7579033 +7043717 +8288101 +14431199 +7632098 +3791976 +7338217 +953129 +5575062 +5671312 +1745060 +7584136 diff --git a/_freeze/2024/R/day17/execute-results/html.json b/_freeze/2024/R/day17/execute-results/html.json index f65e422..17c573a 100644 --- a/_freeze/2024/R/day17/execute-results/html.json +++ b/_freeze/2024/R/day17/execute-results/html.json @@ -1,8 +1,8 @@ { - "hash": "1189b9f3ffd6e66d870d14df1cad1b74", + "hash": "6daf45ec1cbf88c920653b54d57c20eb", "result": { "engine": "knitr", - "markdown": "---\ntitle: \"Day 17\"\ndate: 2024-12-17\nauthor:\n name: https://adventofcode.com/2024/day/17\n url: https://adventofcode.com/2024/day/17\n---\n\n\n\n\n## Setup\n\n\n\n\n::: {.cell}\n\n```{.r .cell-code}\n# Libraries\nlibrary(tidyverse)\nlibrary(unglue)\n\n# Read input from file\ninput <- read_lines(\"../input/day17.txt\", skip_empty_rows = TRUE) |> \n unglue_data(patterns = c(\n \"{label}: {value}\"\n ))\n```\n:::\n\n\n\n\n## Part 1\n\nInitialize the machine from the text input:\n\n\n\n\n::: {.cell}\n\n```{.r .cell-code}\nprogram <- input |> \n filter(label == \"Program\") |> \n pull(value) |> \n str_split_1(\",\") |> \n as.integer()\n\nA <- input |> \n filter(label == \"Register A\") |> \n pull(value) |> \n as.integer()\n\nB <- input |> \n filter(label == \"Register B\") |> \n pull(value) |> \n as.integer()\n\nC <- input |> \n filter(label == \"Register C\") |> \n pull(value) |> \n as.integer()\n\nmachine <- list(program = program, A = A, B = B, C = C, pointer = 0L, output = NULL)\n```\n:::\n\n\n\n\nDefine machine's helper functions:\n\n\n\n\n::: {.cell}\n\n```{.r .cell-code}\ncombo <- function(machine, operand) {\n case_match(operand,\n 0 ~ 0,\n 1 ~ 1,\n 2 ~ 2,\n 3 ~ 3,\n 4 ~ machine$A,\n 5 ~ machine$B,\n 6 ~ machine$C\n )\n}\n\nrun_opcode <- function(machine, opcode, operand) {\n func <- case_match(opcode, \n 0 ~ \"adv\",\n 1 ~ \"bxl\",\n 2 ~ \"bst\",\n 3 ~ \"jnz\",\n 4 ~ \"bxc\",\n 5 ~ \"out\",\n 6 ~ \"bdv\",\n 7 ~ \"cdv\"\n )\n \n get(func)(machine, operand)\n}\n\nrun_machine <- function(machine) {\n while (machine$pointer < length(machine$program)) {\n opcode <- machine$program[machine$pointer + 1]\n operand <- machine$program[machine$pointer + 2]\n machine <- run_opcode(machine, opcode, operand)\n }\n print(machine$output)\n}\n```\n:::\n\n\n\n\nDefine the opcode functions:\n\n\n\n\n::: {.cell}\n\n```{.r .cell-code}\nadv <- function(machine, operand) {\n machine$A <- floor(machine$A / 2^combo(machine, operand))\n machine$pointer <- machine$pointer + 2\n return(machine)\n}\n\nbxl <- function(machine, operand) {\n machine$B <- bitwXor(machine$B, operand)\n machine$pointer <- machine$pointer + 2\n return(machine)\n}\n\nbst <- function(machine, operand) {\n machine$B <- combo(machine, operand) %% 8\n machine$pointer <- machine$pointer + 2\n return(machine)\n}\n\njnz <- function(machine, operand) {\n if (machine$A != 0) \n machine$pointer <- operand\n else \n machine$pointer <- machine$pointer + 2\n return(machine)\n}\n\nbxc <- function(machine, operand) {\n machine$B <- bitwXor(machine$B, machine$C)\n machine$pointer <- machine$pointer + 2\n return(machine)\n}\n\nout <- function(machine, operand) {\n machine$output <- str_c(\n machine$output, \n combo(machine, operand) %% 8, \n sep = \",\"\n )\n machine$pointer <- machine$pointer + 2\n return(machine)\n}\n\nbdv <- function(machine, operand) {\n machine$B <- floor(machine$A / 2^combo(machine, operand))\n machine$pointer <- machine$pointer + 2\n return(machine)\n}\n\ncdv <- function(machine, operand) {\n machine$C <- floor(machine$A / 2^combo(machine, operand))\n machine$pointer <- machine$pointer + 2\n return(machine)\n}\n```\n:::\n\n\n\n\nRun on puzzle input:\n\n\n\n\n::: {.cell}\n\n```{.r .cell-code}\nrun_machine(machine)\n```\n\n::: {.cell-output .cell-output-stdout}\n\n```\n[1] \"3,1,4,3,1,7,1,6,3\"\n```\n\n\n:::\n:::\n", + "markdown": "---\ntitle: \"Day 17\"\ndate: 2024-12-17\nauthor:\n name: https://adventofcode.com/2024/day/17\n url: https://adventofcode.com/2024/day/17\n---\n\n\n\n\n## Setup\n\n\n\n\n::: {.cell}\n\n```{.r .cell-code}\n# Libraries\nlibrary(tidyverse)\nlibrary(unglue)\nlibrary(bit64)\n\n# Read input from file\ninput <- read_lines(\"../input/day17.txt\", skip_empty_rows = TRUE) |> \n unglue_data(patterns = c(\n \"{label}: {value}\"\n ))\n```\n:::\n\n\n\n\n## Part 1\n\nInitialize the machine from the text input:\n\n\n\n\n::: {.cell}\n\n```{.r .cell-code}\nprogram <- input |> \n filter(label == \"Program\") |> \n pull(value) |> \n str_split_1(\",\") |> \n as.integer()\n\nA <- input |> \n filter(label == \"Register A\") |> \n pull(value) |> \n as.integer()\n\nB <- input |> \n filter(label == \"Register B\") |> \n pull(value) |> \n as.integer()\n\nC <- input |> \n filter(label == \"Register C\") |> \n pull(value) |> \n as.integer()\n\nmachine <- list(program = program, A = A, B = B, C = C, pointer = 0L, output = NULL)\n```\n:::\n\n\n\n\nDefine machine's helper functions:\n\n\n\n\n::: {.cell}\n\n```{.r .cell-code}\ncombo <- function(machine, operand) {\n case_match(operand,\n 0 ~ 0,\n 1 ~ 1,\n 2 ~ 2,\n 3 ~ 3,\n 4 ~ machine$A,\n 5 ~ machine$B,\n 6 ~ machine$C\n )\n}\n\nrun_opcode <- function(machine, opcode, operand) {\n func <- case_match(opcode, \n 0 ~ \"adv\",\n 1 ~ \"bxl\",\n 2 ~ \"bst\",\n 3 ~ \"jnz\",\n 4 ~ \"bxc\",\n 5 ~ \"out\",\n 6 ~ \"bdv\",\n 7 ~ \"cdv\"\n )\n \n get(func)(machine, operand)\n}\n\nrun_machine <- function(machine) {\n while (machine$pointer < length(machine$program)) {\n opcode <- machine$program[machine$pointer + 1]\n operand <- machine$program[machine$pointer + 2]\n machine <- run_opcode(machine, opcode, operand)\n }\n return(machine$output)\n}\n```\n:::\n\n\n\n\nNeed to define custom bitwise XOR function to handle very large integers without error:\n\n\n\n\n::: {.cell}\n\n```{.r .cell-code}\nbitwXor64 <- function(x, y) {\n x <- as.bitstring(as.integer64(x))\n y <- as.bitstring(as.integer64(y))\n \n base::xor(\n as.integer(str_split_1(x, \"\")), \n as.integer(str_split_1(y, \"\"))\n ) |> \n as.integer() |> \n str_c(collapse = \"\") |> \n structure(class = \"bitstring\") |> \n as.integer64() |> \n as.numeric()\n}\n```\n:::\n\n\n\n\nDefine the opcode functions:\n\n\n\n\n::: {.cell}\n\n```{.r .cell-code}\nadv <- function(machine, operand) {\n machine$A <- floor(machine$A / 2^combo(machine, operand))\n machine$pointer <- machine$pointer + 2\n return(machine)\n}\n\nbxl <- function(machine, operand) {\n machine$B <- bitwXor64(machine$B, operand)\n machine$pointer <- machine$pointer + 2\n return(machine)\n}\n\nbst <- function(machine, operand) {\n machine$B <- combo(machine, operand) %% 8\n machine$pointer <- machine$pointer + 2\n return(machine)\n}\n\njnz <- function(machine, operand) {\n if (machine$A != 0) \n machine$pointer <- operand\n else \n machine$pointer <- machine$pointer + 2\n return(machine)\n}\n\nbxc <- function(machine, operand) {\n machine$B <- bitwXor64(machine$B, machine$C)\n machine$pointer <- machine$pointer + 2\n return(machine)\n}\n\nout <- function(machine, operand) {\n machine$output <- c(\n machine$output, \n combo(machine, operand) %% 8\n )\n machine$pointer <- machine$pointer + 2\n return(machine)\n}\n\nbdv <- function(machine, operand) {\n machine$B <- floor(machine$A / 2^combo(machine, operand))\n machine$pointer <- machine$pointer + 2\n return(machine)\n}\n\ncdv <- function(machine, operand) {\n machine$C <- floor(machine$A / 2^combo(machine, operand))\n machine$pointer <- machine$pointer + 2\n return(machine)\n}\n```\n:::\n\n\n\n\nRun on puzzle input:\n\n\n\n\n::: {.cell}\n\n```{.r .cell-code}\nrun_machine(machine) |> \n str_c(collapse = \",\")\n```\n\n::: {.cell-output .cell-output-stdout}\n\n```\n[1] \"3,1,4,3,1,7,1,6,3\"\n```\n\n\n:::\n:::\n\n\n\n\n## Part 2\n\nReverse engineer, testing sequences of 3 bits at a time. Thanks to hints from [Reddit](https://www.reddit.com/r/adventofcode/comments/1hg38ah/comment/m2odsfl/?utm_source=share&utm_medium=web3x&utm_name=web3xcss&utm_term=1&utm_content=share_button):\n\n\n\n\n::: {.cell}\n\n```{.r .cell-code}\nrun_machine_a <- function(a) run_machine(list(\n program = program, \n A = a, \n B = B, \n C = C, \n pointer = 0L, \n output = NULL\n))\n\nreveng <- function(program, digit = 1, a = 0) {\n if (digit > length(program))\n return(a)\n \n df <- tibble(candidates = 8 * a + 0:7) |> \n mutate(\n output = map(candidates, run_machine_a),\n output = map(output, head, n = 1)\n ) |> \n filter(output == rev(program)[digit]) |> \n mutate(\n res = map_dbl(candidates, ~ reveng(program, digit + 1, .x))\n ) |> \n filter(!is.na(res))\n \n if (nrow(df) == 0) return(Inf)\n else return(min(df$res))\n}\n\nreveng(program) |> \n format(scientific = FALSE)\n```\n\n::: {.cell-output .cell-output-stdout}\n\n```\n[1] \"37221270076916\"\n```\n\n\n:::\n:::\n", "supporting": [], "filters": [ "rmarkdown/pagebreak.lua" diff --git a/_freeze/2024/R/day22/execute-results/html.json b/_freeze/2024/R/day22/execute-results/html.json new file mode 100644 index 0000000..d529867 --- /dev/null +++ b/_freeze/2024/R/day22/execute-results/html.json @@ -0,0 +1,15 @@ +{ + "hash": "232b0bfc32266424f67365963e2a708d", + "result": { + "engine": "knitr", + "markdown": "---\ntitle: \"Day 22\"\ndate: 2024-12-22\nauthor:\n name: https://adventofcode.com/2024/day/22\n url: https://adventofcode.com/2024/day/22\n---\n\n\n\n## Setup\n\n\n\n::: {.cell}\n\n```{.r .cell-code}\n# Libraries\nlibrary(tidyverse)\nlibrary(bit64)\nlibrary(memoise)\n\n# Read input from file\ninput <- read_lines(\"../input/day22.txt\", skip_empty_rows = TRUE) |> \n as.numeric()\n```\n:::\n\n\n\n## Part 1\n\nDefine custom bitwise XOR function, needed to handle large integers:\n\n\n\n::: {.cell}\n\n```{.r .cell-code}\nbitwXor64 <- function(x, y) {\n x <- as.bitstring(as.integer64(x))\n y <- as.bitstring(as.integer64(y))\n \n map2_chr(\n x |> str_split(\"\") |> map(as.integer), \n y |> str_split(\"\") |> map(as.integer),\n ~ base::xor(.x, .y) |> \n as.integer() |> \n str_c(collapse = \"\")\n ) |> \n structure(class = \"bitstring\") |>\n as.integer64() |>\n as.numeric()\n}\n```\n:::\n\n\n\nDefine the algorithm for producing a sequence of \"secret\" numbers:\n\n\n\n::: {.cell}\n\n```{.r .cell-code}\nmix <- memoise::memoise(\\(a, b) bitwXor64(a, b))\nprune <- \\(x) x %% 16777216\n\nsecret_alg <- function(x) {\n x1 <- prune(mix(x, x * 64))\n x2 <- prune(mix(x1, floor(x1 / 32)))\n x3 <- prune(mix(x2, x2 * 2048))\n return(x3)\n}\n\nsecret_seq <- function(init, len) {\n out <- list(init)\n for (i in 2:len) {\n out[[i]] <- secret_alg(pluck(out, i - 1))\n }\n out\n}\n```\n:::\n\n\n\nRun puzzle input:\n\n\n\n::: {.cell}\n\n```{.r .cell-code}\nsecret_nums <- secret_seq(input, len = 2001)\n\nsecret_nums |> \n tail(n = 1) |> \n unlist() |> \n sum()\n```\n\n::: {.cell-output .cell-output-stdout}\n\n```\n[1] 20401393616\n```\n\n\n:::\n:::\n\n\n\n## Part 2\n\n\n\n::: {.cell}\n\n```{.r .cell-code}\n# Convert sequences to a data frame by buyer and time\ndiffs <- secret_nums |> \n imap_dfr(\\(x, idx) tibble(time = idx, secret_number = x)) |> \n mutate(\n buyer_id = row_number(),\n .by = time\n ) |> \n mutate(\n # Get the price at each time by taking the ones digit of each secret number\n price = secret_number %% 10L,\n # Compute the difference in price at the current time vs the previous time\n diff = price - lag(price),\n # Compute the sequence of 4 price changes preceeding the current price\n lag1 = lag(diff, n = 1L),\n lag2 = lag(diff, n = 2L),\n lag3 = lag(diff, n = 3L),\n diff_seq = str_c(lag3, lag2, lag1, diff, sep = \",\"),\n .by = buyer_id\n ) |> \n arrange(buyer_id, time)\n\n# For each price change seq, compute the bananas you will get from each buyer:\nbananas_by_seq <- diffs |> \n filter(!is.na(diff_seq)) |> \n summarize(\n bananas = head(price, 1),\n .by = c(buyer_id, diff_seq)\n )\n\n# Find the most advantageous sequence:\nbananas_by_seq |> \n summarize(bananas = sum(bananas), .by = diff_seq) |> \n slice_max(bananas) |> \n pull(bananas)\n```\n\n::: {.cell-output .cell-output-stdout}\n\n```\n[1] 2272\n```\n\n\n:::\n:::\n", + "supporting": [], + "filters": [ + "rmarkdown/pagebreak.lua" + ], + "includes": {}, + "engineDependencies": {}, + "preserve": {}, + "postProcess": true + } +} \ No newline at end of file diff --git a/docs/2022/R/day01.html b/docs/2022/R/day01.html index c5ce35a..bcf57bb 100644 --- a/docs/2022/R/day01.html +++ b/docs/2022/R/day01.html @@ -67,7 +67,7 @@ - + @@ -269,6 +269,12 @@

Day 1

Day 21 + + @@ -895,8 +901,8 @@

Part 2

@@ -429,12 +436,13 @@

Setup

# Libraries
 library(tidyverse)
 library(unglue)
-
-# Read input from file
-input <- read_lines("../input/day17.txt", skip_empty_rows = TRUE) |> 
-  unglue_data(patterns = c(
-    "{label}: {value}"
-  ))
+library(bit64) + +# Read input from file +input <- read_lines("../input/day17.txt", skip_empty_rows = TRUE) |> + unglue_data(patterns = c( + "{label}: {value}" + ))
@@ -499,72 +507,128 @@

Part 1

operand <- machine$program[machine$pointer + 2] machine <- run_opcode(machine, opcode, operand) } - print(machine$output) + return(machine$output) } +

Need to define custom bitwise XOR function to handle very large integers without error:

+
+
bitwXor64 <- function(x, y) {
+  x <- as.bitstring(as.integer64(x))
+  y <- as.bitstring(as.integer64(y))
+  
+  base::xor(
+    as.integer(str_split_1(x, "")), 
+    as.integer(str_split_1(y, ""))
+  ) |> 
+    as.integer() |> 
+    str_c(collapse = "") |> 
+    structure(class = "bitstring") |> 
+    as.integer64() |> 
+    as.numeric()
+}
+

Define the opcode functions:

-
adv <- function(machine, operand) {
-  machine$A <- floor(machine$A / 2^combo(machine, operand))
-  machine$pointer <- machine$pointer + 2
-  return(machine)
-}
-
-bxl <- function(machine, operand) {
-  machine$B <- bitwXor(machine$B, operand)
-  machine$pointer <- machine$pointer + 2
-  return(machine)
-}
-
-bst <- function(machine, operand) {
-  machine$B <- combo(machine, operand) %% 8
-  machine$pointer <- machine$pointer + 2
-  return(machine)
-}
-
-jnz <- function(machine, operand) {
-  if (machine$A != 0) 
-    machine$pointer <- operand
-  else 
-    machine$pointer <- machine$pointer + 2
-  return(machine)
-}
-
-bxc <- function(machine, operand) {
-  machine$B <- bitwXor(machine$B, machine$C)
-  machine$pointer <- machine$pointer + 2
-  return(machine)
-}
-
-out <- function(machine, operand) {
-  machine$output <- str_c(
-    machine$output, 
-    combo(machine, operand) %% 8, 
-    sep = ","
-  )
-  machine$pointer <- machine$pointer + 2
-  return(machine)
-}
-
-bdv <- function(machine, operand) {
-  machine$B <- floor(machine$A / 2^combo(machine, operand))
-  machine$pointer <- machine$pointer + 2
-  return(machine)
-}
-
-cdv <- function(machine, operand) {
-  machine$C <- floor(machine$A / 2^combo(machine, operand))
-  machine$pointer <- machine$pointer + 2
-  return(machine)
-}
+
adv <- function(machine, operand) {
+  machine$A <- floor(machine$A / 2^combo(machine, operand))
+  machine$pointer <- machine$pointer + 2
+  return(machine)
+}
+
+bxl <- function(machine, operand) {
+  machine$B <- bitwXor64(machine$B, operand)
+  machine$pointer <- machine$pointer + 2
+  return(machine)
+}
+
+bst <- function(machine, operand) {
+  machine$B <- combo(machine, operand) %% 8
+  machine$pointer <- machine$pointer + 2
+  return(machine)
+}
+
+jnz <- function(machine, operand) {
+  if (machine$A != 0) 
+    machine$pointer <- operand
+  else 
+    machine$pointer <- machine$pointer + 2
+  return(machine)
+}
+
+bxc <- function(machine, operand) {
+  machine$B <- bitwXor64(machine$B, machine$C)
+  machine$pointer <- machine$pointer + 2
+  return(machine)
+}
+
+out <- function(machine, operand) {
+  machine$output <- c(
+    machine$output, 
+    combo(machine, operand) %% 8
+  )
+  machine$pointer <- machine$pointer + 2
+  return(machine)
+}
+
+bdv <- function(machine, operand) {
+  machine$B <- floor(machine$A / 2^combo(machine, operand))
+  machine$pointer <- machine$pointer + 2
+  return(machine)
+}
+
+cdv <- function(machine, operand) {
+  machine$C <- floor(machine$A / 2^combo(machine, operand))
+  machine$pointer <- machine$pointer + 2
+  return(machine)
+}

Run on puzzle input:

-
run_machine(machine)
+
run_machine(machine) |> 
+  str_c(collapse = ",")
[1] "3,1,4,3,1,7,1,6,3"
+
+
+

Part 2

+

Reverse engineer, testing sequences of 3 bits at a time. Thanks to hints from Reddit:

+
+
run_machine_a <- function(a) run_machine(list(
+  program = program, 
+  A = a, 
+  B = B, 
+  C = C, 
+  pointer = 0L, 
+  output = NULL
+))
+
+reveng <- function(program, digit = 1, a = 0) {
+  if (digit > length(program))
+    return(a)
+  
+  df <- tibble(candidates = 8 * a + 0:7) |> 
+    mutate(
+      output = map(candidates, run_machine_a),
+      output = map(output, head, n = 1)
+    ) |> 
+    filter(output == rev(program)[digit]) |> 
+    mutate(
+      res = map_dbl(candidates, ~ reveng(program, digit + 1, .x))
+    ) |> 
+    filter(!is.na(res))
+  
+  if (nrow(df) == 0) return(Inf)
+  else return(min(df$res))
+}
+
+reveng(program) |> 
+  format(scientific = FALSE)
+
+
[1] "37221270076916"
+
+
diff --git a/docs/2024/R/day18.html b/docs/2024/R/day18.html index 7086129..c23415b 100644 --- a/docs/2024/R/day18.html +++ b/docs/2024/R/day18.html @@ -269,6 +269,12 @@

Day 18

Day 21 + + diff --git a/docs/2024/R/day19.html b/docs/2024/R/day19.html index 4f2017b..370f822 100644 --- a/docs/2024/R/day19.html +++ b/docs/2024/R/day19.html @@ -269,6 +269,12 @@

Day 19

Day 21 + + diff --git a/docs/2024/R/day20.html b/docs/2024/R/day20.html index 8344e66..d4bc5ca 100644 --- a/docs/2024/R/day20.html +++ b/docs/2024/R/day20.html @@ -269,6 +269,12 @@

Day 20

Day 21 + + diff --git a/docs/2024/R/day21.html b/docs/2024/R/day21.html index 9e76959..ab3f30c 100644 --- a/docs/2024/R/day21.html +++ b/docs/2024/R/day21.html @@ -66,7 +66,7 @@ - + @@ -269,6 +269,12 @@

Day 21

Day 21 + + @@ -1019,8 +1025,8 @@

Part 2

diff --git a/docs/2024/R/day22.html b/docs/2024/R/day22.html new file mode 100644 index 0000000..1af8fc5 --- /dev/null +++ b/docs/2024/R/day22.html @@ -0,0 +1,979 @@ + + + + + + + + + + + +Day 22 – Advent of Code: Worked Solutions + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ +
+ +
+ + +
+ + + +
+ +
+
+

Day 22

+

Advent of Code: Worked Solutions

+
+ + + +
+ +
+
About
+ +
+ +
+
Date
+
+

December 22, 2024

+
+
+ + +
+ + + +
+ + +
+

Setup

+
+
# Libraries
+library(tidyverse)
+library(bit64)
+library(memoise)
+
+# Read input from file
+input <- read_lines("../input/day22.txt", skip_empty_rows = TRUE) |> 
+  as.numeric()
+
+
+
+

Part 1

+

Define custom bitwise XOR function, needed to handle large integers:

+
+
bitwXor64 <- function(x, y) {
+  x <- as.bitstring(as.integer64(x))
+  y <- as.bitstring(as.integer64(y))
+  
+  map2_chr(
+    x |> str_split("") |> map(as.integer), 
+    y |> str_split("") |> map(as.integer),
+    ~ base::xor(.x, .y) |> 
+      as.integer() |> 
+      str_c(collapse = "")
+  ) |> 
+    structure(class = "bitstring") |>
+    as.integer64() |>
+    as.numeric()
+}
+
+

Define the algorithm for producing a sequence of “secret” numbers:

+
+
mix   <- memoise::memoise(\(a, b) bitwXor64(a, b))
+prune <- \(x) x %% 16777216
+
+secret_alg <- function(x) {
+  x1 <- prune(mix(x, x * 64))
+  x2 <- prune(mix(x1, floor(x1 / 32)))
+  x3 <- prune(mix(x2, x2 * 2048))
+  return(x3)
+}
+
+secret_seq <- function(init, len) {
+  out <- list(init)
+  for (i in 2:len) {
+    out[[i]] <- secret_alg(pluck(out, i - 1))
+  }
+  out
+}
+
+

Run puzzle input:

+
+
secret_nums <- secret_seq(input, len = 2001)
+
+secret_nums |> 
+  tail(n = 1) |> 
+  unlist() |> 
+  sum()
+
+
[1] 20401393616
+
+
+
+
+

Part 2

+
+
# Convert sequences to a data frame by buyer and time
+diffs <- secret_nums |> 
+  imap_dfr(\(x, idx) tibble(time = idx, secret_number = x)) |> 
+  mutate(
+    buyer_id = row_number(),
+    .by = time
+  ) |> 
+  mutate(
+    # Get the price at each time by taking the ones digit of each secret number
+    price = secret_number %% 10L,
+    # Compute the difference in price at the current time vs the previous time
+    diff = price - lag(price),
+    # Compute the sequence of 4 price changes preceeding the current price
+    lag1 = lag(diff, n = 1L),
+    lag2 = lag(diff, n = 2L),
+    lag3 = lag(diff, n = 3L),
+    diff_seq = str_c(lag3, lag2, lag1, diff, sep = ","),
+    .by = buyer_id
+  ) |> 
+  arrange(buyer_id, time)
+
+# For each price change seq, compute the bananas you will get from each buyer:
+bananas_by_seq <- diffs |> 
+  filter(!is.na(diff_seq)) |> 
+  summarize(
+    bananas = head(price, 1),
+    .by = c(buyer_id, diff_seq)
+  )
+
+# Find the most advantageous sequence:
+bananas_by_seq |> 
+  summarize(bananas = sum(bananas), .by = diff_seq) |> 
+  slice_max(bananas) |> 
+  pull(bananas)
+
+
[1] 2272
+
+
+ + +
+ +
+ + +
+ + + + + \ No newline at end of file diff --git a/docs/index.html b/docs/index.html index df9232b..81da907 100644 --- a/docs/index.html +++ b/docs/index.html @@ -7,7 +7,7 @@ - + Advent of Code: Worked Solutions