Skip to content

Instantly share code, notes, and snippets.

@tiegz
Last active December 27, 2016 17:37
Show Gist options
  • Select an option

  • Save tiegz/abe6efbfb6950dd22b2dfe7e98a7dba0 to your computer and use it in GitHub Desktop.

Select an option

Save tiegz/abe6efbfb6950dd22b2dfe7e98a7dba0 to your computer and use it in GitHub Desktop.
Advent of Code 2016
inputs = "L2, L3, L3, L4, R1, R2, L3, R3, R3, L1, L3, R2, R3, L3, R4, R3, R3, L1, L4, R4, L2, R5, R1, L5, R1, R3, L5, R2, L2, R2, R1, L1, L3, L3, R4, R5, R4, L1, L189, L2, R2, L5, R5, R45, L3, R4, R77, L1, R1, R194, R2, L5, L3, L2, L1, R5, L3, L3, L5, L5, L5, R2, L1, L2, L3, R2, R5, R4, L2, R3, R5, L2, L2, R3, L3, L2, L1, L3, R5, R4, R3, R2, L1, R2, L5, R4, L5, L4, R4, L2, R5, L3, L2, R4, L1, L2, R2, R3, L2, L5, R1, R1, R3, R4, R1, R2, R4, R5, L3, L5, L3, L3, R5, R4, R1, L3, R1, L3, R3, R3, R3, L1, R3, R4, L5, L3, L1, L5, L4, R4, R1, L4, R3, R3, R5, R4, R3, R3, L1, L2, R1, L4, L4, L3, L4, L3, L5, R2, R4, L2".split(',').map(&:strip)
directions = %w(N E S W)
Location = Struct.new(:x, :y, :locations_visited, :first_location_visited_twice) do
def distance
x.abs + y.abs
end
def distance_from_first_location_visited_twice
first_location_visited_twice.map(&:abs).sum
end
def travel_east(distance)
until distance == 0
l = [x + 1, y]
distance -= 1
if !first_location_visited_twice && locations_visited[l]
self.first_location_visited_twice = l
end
self.locations_visited[l] = true
self.x = l[0]
end
end
def travel_south(distance)
until distance == 0
l = [x, y - 1]
distance += 1
if !first_location_visited_twice && locations_visited[l]
self.first_location_visited_twice = l
end
self.locations_visited[l] = true
self.y = l[1]
end
end
def travel_west(distance)
until distance == 0
l = [x - 1, y]
distance += 1
if !first_location_visited_twice && locations_visited[l]
self.first_location_visited_twice = l
end
self.locations_visited[l] = true
self.x = l[0]
end
end
def travel_north(distance)
until distance == 0
l = [x, y + 1]
distance -= 1
if !first_location_visited_twice && locations_visited[l]
self.first_location_visited_twice = l
end
self.locations_visited[l] = true
self.y = l[1]
end
end
end
location = inputs.
inject([]) { |memo, obj|
turn, amount = obj[0], obj[1..-1].to_i
direction = memo.last ? memo.last[0] : "N"
direction_idx = directions.index(direction)
new_direction_idx = case turn
when "R"
direction_idx.succ % directions.size
when "L"
direction_idx.pred % directions.size
end
memo << [directions[new_direction_idx], amount]
}.inject(Location.new(0, 0, {})) { |memo, obj|
direction, amount = obj[0], obj[1]
case direction
when "N" then memo.travel_north(amount)
when "E" then memo.travel_east(amount)
when "S" then memo.travel_south(-amount)
when "W" then memo.travel_west(-amount)
end
memo
}
print "Part 1: #{location.x}, #{location.y}, #{location.distance}"
print "Part 2: #{location.distance_from_first_location_visited_twice}"
(forgot to keep)
inputs = "101 301 501
102 302 502
103 303 503
201 401 601
202 402 602
203 403 603"
puts "Valid triangles by row are "
puts inputs.lines.select { |line|
line.
split(' ').
map(&:strip).map(&:to_i).
permutation(3).to_a.
all? { |perm|
perm[0] + perm[1] > perm[2]
}
}.size
puts "Valid triangles by col are "
pp inputs.lines.map { |line|
line.split(' ').map(&:strip).map(&:to_i)
}.inject([[],[],[]]) { |memo, i|
# invert rows / cols
memo[0] << i[0]
memo[1] << i[1]
memo[2] << i[2]
memo
}.map { |inverted_line|
inverted_line.in_groups_of(3)
}.flatten(1).select { |triplet|
triplet.
permutation(3).to_a.
all? { |perm|
perm[0] + perm[1] > perm[2]
}
}.size
inputs = "vxupkizork-sgmtkzoi-pkrrehkgt-zxgototm-644[kotgr]
mbiyqoxsm-pvygob-nocsqx-900[obmqs]
veqtekmrk-ikk-hitpscqirx-334[nrtws]
gvcskirmg-fyrrc-irkmriivmrk-932[rikmc]
xmtjbzidx-xviyt-yzqzgjkhzio-187[yzfeu]
bwx-amkzmb-kivlg-kwibqvo-lmaqov-798[bkmva]
vcibutulxiom-ohmnuvfy-yaa-mylpcwym-890[iyaun]
ajvyjprwp-lqxlxujcn-jwjuhbrb-251[muivb]
szfyrqriuflj-avccpsvre-kirzezex-971[rezcf]
kwvacumz-ozilm-akidmvomz-pcvb-uizsmbqvo-590[uslyz]
ucynmlgxcb-afmamjyrc-jmegqrgaq-626[rybxt]
oaxadrgx-pkq-abqdmfuaze-872[xtbnw]
tfejldvi-xiruv-tcrjjzwzvu-gcrjkzt-xirjj-tfekrzedvek-971[krmax]
pwcvonofrcig-suu-rsgwub-740[baiys]
udskkaxawv-tskcwl-dgyaklauk-632[lqcfd]
vqr-ugetgv-dcumgv-fgxgnqrogpv-258[ctwyp]
laffe-igtje-gtgreyoy-124[uscwl]
iehepwnu-cnwza-oywrajcan-dqjp-lqnydwoejc-368[sypjw]
mbiyqoxsm-excdklvo-pvygob-bocokbmr-640[hslwz]
houngfgxjuay-pkrrehkgt-jkvruesktz-930[nsbth]
tcfkqcevkxg-lgnnadgcp-eqpvckpogpv-388[ausbh]
hcd-gsqfsh-wbhsfbohwcboz-pibbm-aofyshwbu-532[bhsfo]
jyfvnlupj-zjhclunly-obua-huhsfzpz-461[jopil]
pbybeshy-rtt-fgbentr-819[vxcue]
kwtwznct-akidmvomz-pcvb-lmaqov-564[mvack]
pdjqhwlf-udeelw-uhdftxlvlwlrq-595[ldwef]
aoubshwq-gqojsbusf-vibh-gsfjwqsg-922[qfetx]
wfintfhynaj-wfruflnsl-gzssd-ijajqturjsy-931[mkhsc]
qspkfdujmf-kfmmzcfbo-eftjho-675[skbda]
dmbttjgjfe-fhh-ufdiopmphz-129[nbqyz]
tinnm-tzcksf-obozmgwg-194[mduaf]
iwcjapey-qjopwxha-ywjzu-ykwpejc-skngodkl-706[kjfog]
kwtwznct-xzwrmkbqtm-lgm-bmkpvwtwog-356[wmtkb]
bkwzkqsxq-wkqxodsm-mrymyvkdo-nozkbdwoxd-640[unlfi]
avb-abpfdk-185[cwyms]
xfbqpojafe-kfmmzcfbo-vtfs-uftujoh-857[nserj]
gsvvswmzi-jpsaiv-pefsvexsvc-516[hbidf]
tfejldvi-xiruv-treup-kvtyefcfxp-321[mntlv]
sxdobxkdsyxkv-mrymyvkdo-mecdywob-cobfsmo-588[emgkf]
luxciuwncpy-vohhs-mylpcwym-292[yiojz]
ide-htrgti-hrpktcvtg-wjci-bpcpvtbtci-583[tcipb]
surmhfwloh-fkrfrodwh-hqjlqhhulqj-621[hflqr]
zuv-ykixkz-yigbktmkx-natz-xkikobotm-540[zyvui]
xmtjbzidx-wpiit-hvivbzhzio-759[kgzsj]
mvkccspson-nio-ckvoc-666[mnklu]
zixppfcfba-yrkkv-ildfpqfzp-991[amdtz]
vjpwncrl-bljenwpna-qdwc-cajrwrwp-251[tgzku]
gntmfefwitzx-xhfajsljw-mzsy-uzwhmfxnsl-671[fmswx]
ajmrxjlcren-yujbcrl-pajbb-fxatbqxy-407[tszqw]
votubcmf-cjpibabsepvt-qmbtujd-hsbtt-nbobhfnfou-129[btfou]
etyyx-rbzudmfdq-gtms-nodqzshnmr-339[okzyu]
bxaxipgn-vgpst-rpcsn-rdcipxcbtci-557[nmtks]
zlilocri-oxyyfq-pxibp-939[ilopx]
xqvwdeoh-hjj-uhvhdufk-985[uixsv]
frqvxphu-judgh-gbh-vhuylfhv-907[gxkts]
rkpqxyib-oxyyfq-obpbxoze-315[jysdq]
ckgvutofkj-jek-giwaoyozout-436[tsfzu]
zilqwikbqdm-ntwemz-lmaqov-616[mqilw]
pkl-oaynap-acc-qoan-paopejc-446[muyva]
lxuxaodu-ajkkrc-bnaerlnb-771[yzint]
wfruflnsl-gzssd-ijuqtdrjsy-515[zdeyi]
mvhkvbdib-wpiit-nzmqdxzn-421[tryva]
aoubshwq-foppwh-sbuwbssfwbu-558[zhyen]
encuukhkgf-gii-hkpcpekpi-414[kipce]
sehheiylu-rkddo-bqrehqjeho-608[pfmot]
irdgrxzex-avccpsvre-ivtvzmzex-529[intur]
ykhknbqh-ywjzu-klanwpekjo-784[khjnw]
gpewwmjmih-tvsnigxmpi-fewoix-vigimzmrk-594[unmjc]
vxupkizork-vrgyzoi-mxgyy-gtgreyoy-826[kmnot]
qmpmxevc-kvehi-wgezirkiv-lyrx-xiglrspskc-438[gdkrm]
ixccb-fkrfrodwh-orjlvwlfv-933[nyhrz]
lujbbrornm-ljwmh-lxjcrwp-lxwcjrwvnwc-511[wjlrc]
eqpuwogt-itcfg-ecpfa-wugt-vguvkpi-934[nchrl]
nwlddtqtpo-mldvpe-wlmzclezcj-691[gznml]
rdchjbtg-vgpst-rpcsn-rdpixcv-uxcpcrxcv-453[zyutx]
willimcpy-wuhxs-xypyfijgyhn-942[vxyeb]
qzchnzbshud-eknvdq-rsnqzfd-521[dnqzh]
froruixo-mhoobehdq-rshudwlrqv-179[mbthd]
mvydjvxodqz-nxvqzibzm-cpio-mzxzdqdib-837[yzntw]
yknnkoera-bhksan-iwjwcaiajp-394[aknij]
xjgjmapg-wpiit-vivgtndn-993[cyqvm]
xgvnndadzy-xjmmjndqz-xviyt-xjvodib-gjbdnodxn-265[kgvsh]
sbnqbhjoh-tdbwfohfs-ivou-fohjoffsjoh-467[ofcde]
cybyjqho-whqtu-zubboruqd-tufbeocudj-842[rqply]
bkwzkqsxq-zvkcdsm-qbkcc-nocsqx-406[xydnz]
tinnm-foadouwbu-dzoghwq-ufogg-obozmgwg-142[rakqb]
rdchjbtg-vgpst-rpcsn-rdpixcv-bpcpvtbtci-765[mkoez]
pinovwgz-mvwwdo-zibdizzmdib-395[smtjh]
pyknyegle-njyqrga-epyqq-bcnjmwkclr-782[yxcjz]
vkrhzxgbv-cxeeruxtg-phkdlahi-709[tyzhs]
udskkaxawv-vqw-vwnwdghewfl-658[wvadk]
gsrwyqiv-kvehi-ikk-asvowlst-438[iksvw]
lahxpnwrl-mhn-vjwjpnvnwc-173[nwhjl]
rzvkjiduzy-ytz-xjiovdihzio-993[sumvy]
avw-zljyla-yhiipa-zhslz-825[mitza]
udpsdjlqj-udglrdfwlyh-mhoobehdq-whfkqrorjb-673[dhjlo]
iruzfrtkzmv-wlqqp-wcfnvi-jyzggzex-841[wszry]
rtqlgevkng-lgnnadgcp-ujkrrkpi-986[wpktr]
ktwbhtvmbox-utldxm-ftgtzxfxgm-995[uqlbn]
dlhwvupglk-qlssfilhu-zopwwpun-149[tvkqz]
gcfcnuls-aluxy-yaa-omyl-nymncha-292[aycln]
jrncbavmrq-enqvbnpgvir-pnaql-qrirybczrag-455[ybfie]
fydelmwp-mfyyj-cplnbftdtetzy-613[whuxk]
vetllbybxw-lvtoxgzxk-angm-mxvaghehzr-475[eswan]
aoubshwq-pibbm-fsoqeiwgwhwcb-662[qfaze]
iutyaskx-mxgjk-vrgyzoi-mxgyy-iayzuskx-ykxboik-722[sxnli]
wihmogyl-aluxy-wuhxs-wiuncha-xyjulngyhn-578[pntgy]
ktiaaqnqml-kzgwomvqk-xtiabqk-oziaa-twoqabqka-226[aqkio]
rgndvtcxr-tvv-ldgzhwde-999[tbefa]
qyujihctyx-vcibutulxiom-wuhxs-wiuncha-xymcah-552[sdmer]
fmsledevhsyw-fyrrc-xiglrspskc-386[yrhfz]
qekrixmg-hci-ywiv-xiwxmrk-490[tynsr]
gcfcnuls-aluxy-vumeyn-yhachyylcha-604[xtfeg]
iutyaskx-mxgjk-pkrrehkgt-gtgreyoy-384[gyblm]
hmsdqmzshnmzk-rbzudmfdq-gtms-kzanqzsnqx-937[grhez]
eqttqukxg-gii-cpcnauku-362[zypxw]
ynukcajey-xekdwvwnzkqo-xqjju-odellejc-316[jglep]
mfklstdw-uzgugdslw-lwuzfgdgyq-320[topmx]
buzahisl-ihzrla-zopwwpun-487[rzsag]
vcibutulxiom-vumeyn-mylpcwym-916[tjvzx]
mvydjvxodqz-nxvqzibzm-cpio-gjbdnodxn-733[xtcbl]
frqvxphu-judgh-udeelw-xvhu-whvwlqj-595[huvwd]
fhezusjybu-tou-skijecuh-iuhlysu-608[uhsei]
houngfgxjuay-vrgyzoi-mxgyy-sgxqkzotm-124[mgfhr]
odkasqzuo-uzfqdzmfuazmx-eomhqzsqd-tgzf-fqotzaxask-508[tmxza]
fydelmwp-upwwjmply-dlwpd-873[gyzjx]
yuxufmdk-sdmpq-dmnnuf-dqeqmdot-742[dmquf]
xst-wigvix-fewoix-wepiw-464[mltfd]
jsehsyafy-tskcwl-dgyaklauk-190[aksyl]
fubrjhqlf-fdqgb-uhdftxlvlwlrq-855[flqbd]
wifilzof-xsy-mbcjjcha-422[olxnw]
bknsykmdsfo-mrymyvkdo-nofovyzwoxd-614[oydkm]
rtqlgevkng-hnqygt-tgceswkukvkqp-232[gkqte]
vjpwncrl-lqxlxujcn-vjatncrwp-407[cjlnp]
sbnqbhjoh-dpssptjwf-fhh-gjobodjoh-935[ckpbr]
vcibutulxiom-dyffsvyuh-lyuwkocmcncih-838[flhey]
nzydfxpc-rclop-dnlgpyrpc-sfye-opawzjxpye-899[pycde]
dzczkrip-xiruv-treup-drerxvdvek-373[rdevi]
ryexqpqhteki-muqfedyput-isqludwuh-xkdj-qdqboiyi-244[qdiue]
vkrhzxgbv-ktfitzbgz-vahvhetmx-vnlmhfxk-lxkobvx-735[smnif]
ajvyjprwp-snuuhknjw-bqryyrwp-329[mdzxw]
wihmogyl-aluxy-luvvcn-guhuaygyhn-188[qjwtv]
xgvnndadzy-zbb-kpmxcvndib-395[bdnvx]
dkqjcbctfqwu-ecpfa-eqcvkpi-ncdqtcvqta-726[paioe]
tbxmlkfwba-avb-cfkxkzfkd-133[gmhkl]
tfcfiwlc-gifavtkzcv-avccpsvre-cfxzjkztj-139[cusqi]
hafgnoyr-enoovg-npdhvfvgvba-351[vgnoa]
lzfmdshb-etyyx-cxd-rsnqzfd-547[clnoz]
sawlkjevaz-zua-nawymqeoepekj-316[fpaeb]
pbafhzre-tenqr-pnaql-pbngvat-znexrgvat-299[iymnw]
dmybmsuzs-nmewqf-emxqe-768[tzycl]
dlhwvupglk-qlssfilhu-lunpullypun-695[tidnq]
hafgnoyr-pubpbyngr-erprvivat-741[vynbz]
odiih-mhn-jlzdrbrcrxw-459[rdhib]
tcfkqcevkxg-tcddkv-tgugctej-986[mejtb]
vkrhzxgbv-ietlmbv-zktll-kxtvjnblbmbhg-189[blvkt]
gsvvswmzi-ikk-eguymwmxmsr-282[bkasy]
jqwpihizlwca-rmttgjmiv-ivitgaqa-694[eibnd]
kzeed-jll-fsfqdxnx-697[abodg]
xtwtelcj-rclop-prr-hzcvdsza-977[crlpt]
nuatmlmdpage-ngzzk-dqmocgueufuaz-872[oldhw]
pybgmyargtc-pyzzgr-kylyeckclr-678[ycgrk]
yhwooebeaz-acc-klanwpekjo-316[xmynz]
qzlozfhmf-azrjds-vnqjrgno-781[ycnzs]
qvbmzvibqwvit-zijjqb-bziqvqvo-252[tcfan]
kfg-jvtivk-nvrgfezqvu-treup-cfxzjkztj-217[vfjkt]
pelbtravp-rtt-bcrengvbaf-845[evbkq]
pkl-oaynap-zua-iwngapejc-420[nkjyh]
qekrixmg-gerhc-gsexmrk-gsrxemrqirx-490[ciuyw]
qczcftiz-pibbm-oqeiwgwhwcb-324[kzdfm]
foadouwbu-qvcqczohs-gvwddwbu-454[qsnwz]
tfiifjzmv-treup-tfekrzedvek-555[usbvt]
nglmtuex-ietlmbv-zktll-kxtvjnblbmbhg-891[lbtme]
ixccb-fdqgb-fxvwrphu-vhuylfh-179[kesml]
rzvkjiduzy-nxvqzibzm-cpio-mznzvmxc-941[vzopy]
nwzekwypera-bhksan-klanwpekjo-498[kaenw]
njmjubsz-hsbef-tdbwfohfs-ivou-xpsltipq-571[sbfhi]
rdchjbtg-vgpst-rdadguja-eaphixr-vgphh-tcvxcttgxcv-765[fzjti]
xfbqpojafe-gmpxfs-vtfs-uftujoh-493[pshct]
tcfkqcevkxg-ecpfa-tgceswkukvkqp-154[kcefg]
hqtyeqsjylu-rkddo-huiuqhsx-530[hquds]
qzoggwtwsr-qcffcgwjs-qvcqczohs-zcuwghwqg-246[jiwnp]
wlqqp-sleep-ivtvzmzex-555[vsoly]
tcfkqcevkxg-dwppa-wugt-vguvkpi-986[hcpyu]
dpmpsgvm-xfbqpojafe-dipdpmbuf-tijqqjoh-805[wgnqv]
ksodcbwnsr-dzoghwq-ufogg-zopcfohcfm-870[dxmtj]
tcfkqcevkxg-dcumgv-wugt-vguvkpi-856[ehozy]
fbebmtkr-zktwx-cxeeruxtg-ftgtzxfxgm-709[tuvsx]
diozmivodjivg-pinovwgz-wvnfzo-rjmfncjk-863[tqdns]
vkppo-zubboruqd-bqrehqjeho-842[qfsjm]
mbiyqoxsm-nio-nozvyiwoxd-614[mstez]
ohmnuvfy-yaa-uhufsmcm-214[muafh]
nzcczdtgp-ojp-afcnsldtyr-769[cdnpt]
tinnm-xszzmpsob-fsqswjwbu-558[sbmnw]
hwbba-uecxgpigt-jwpv-fgrnqaogpv-752[upmvg]
mvydjvxodqz-xcjxjgvoz-jkzmvodjin-187[jvdox]
wdjcvuvmyjpn-mvwwdo-xpnojhzm-nzmqdxz-889[mdjnv]
bpvctixr-qjccn-sthxvc-817[ctvxb]
rdadguja-rwdrdapit-steadnbtci-271[coqre]
kfg-jvtivk-treup-tfrkzex-fgvirkzfej-373[sptcw]
nbhofujd-dboez-dpbujoh-tfswjdft-493[sftdx]
ksodcbwnsr-pogysh-qighcasf-gsfjwqs-116[tvqso]
bqvvu-ywjzu-paydjkhkcu-810[rgpzu]
cvabijtm-lgm-zmamizkp-954[tsrpy]
npmhcargjc-qaytclecp-fslr-rcaflmjmew-834[lgkrj]
aflwjfslagfsd-kusnwfywj-zmfl-ksdwk-164[enmyr]
jlidywncfy-dyffsvyuh-qilembij-422[jmryi]
dmybmsuzs-dmnnuf-dqeqmdot-586[hdgkv]
qspkfdujmf-cbtlfu-mphjtujdt-701[zatkl]
nvrgfezqvu-sleep-ivrthlzjzkzfe-373[udyzv]
tbxmlkfwba-yxphbq-pqloxdb-809[tzsjm]
pelbtravp-enoovg-grpuabybtl-559[oqctv]
dkqjcbctfqwu-ecpfa-ewuvqogt-ugtxkeg-544[cegqt]
xgsvgmotm-xghhoz-lotgtiotm-384[gotmh]
udskkaxawv-jsvagsulanw-kusnwfywj-zmfl-klgjsyw-346[swakj]
krxqjijamxdb-kjbtnc-ujkxajcxah-173[izxny]
myvybpev-lkcuod-nocsqx-770[yzjqg]
upq-tfdsfu-cbtlfu-eftjho-623[ftubc]
npmhcargjc-qaytclecp-fslr-jmegqrgaq-444[nocrz]
iuxxuyobk-vrgyzoi-mxgyy-giwaoyozout-566[kymts]
avw-zljyla-qlssfilhu-klwhyatlua-513[tskre]
mvhkvbdib-kmjezxodgz-agjrzm-mznzvmxc-135[suyop]
qzlozfhmf-azrjds-dmfhmddqhmf-183[dfmhz]
kgjgrypw-epybc-cee-qcptgacq-418[gqyos]
guahyncw-vcibutulxiom-yaa-qilembij-968[xgtow]
lugjuacha-wihmogyl-aluxy-wuhxs-xyjulngyhn-864[qbefr]
iehepwnu-cnwza-ykjoqian-cnwza-zua-lqnydwoejc-680[pfmiz]
mtzslklcozfd-upwwjmply-cpdplcns-743[rngoy]
dfcxsqhwzs-foppwh-difqvogwbu-454[fwdho]
irdgrxzex-jtrmvexvi-ylek-nfibjyfg-139[kwabl]
jvyyvzpcl-tpspahyf-nyhkl-msvdly-ylhjxbpzpapvu-695[oyedt]
qmpmxevc-kvehi-fewoix-qerekiqirx-282[tzsca]
hcd-gsqfsh-suu-gozsg-870[nmehc]
hwdtljsnh-xhfajsljw-mzsy-xytwflj-697[jhlsw]
udpsdjlqj-iorzhu-pdunhwlqj-959[djuhl]
enqvbnpgvir-onfxrg-svanapvat-507[nvagp]
rzvkjiduzy-wpiit-mznzvmxc-213[ntuoi]
gsrwyqiv-kvehi-fyrrc-xiglrspskc-776[hgnvt]
gvaaz-cbtlfu-mbcpsbupsz-103[bacps]
hplazytkpo-mfyyj-opawzjxpye-197[pyajo]
raphhxuxts-gpbepvxcv-rpcsn-rdpixcv-stepgibtci-531[omniy]
cxy-bnlanc-kdwwh-mnyuxhvnwc-251[ditcg]
htsxzrjw-lwfij-hmthtqfyj-yjhmstqtld-307[conpl]
ikhcxvmbex-vtgwr-lxkobvxl-345[cdftu]
sgmtkzoi-pkrrehkgt-lotgtiotm-566[tgkoi]
gbc-frperg-onfxrg-freivprf-455[nymsw]
ide-htrgti-hrpktcvtg-wjci-apqdgpidgn-531[gitdp]
dpmpsgvm-gmpxfs-tupsbhf-259[hgopn]
xmrrq-kusnwfywj-zmfl-wfyafwwjafy-892[fwyaj]
qfmcusbwq-tinnm-pogysh-rsdzcmasbh-428[bgfat]
zhdsrqlchg-lqwhuqdwlrqdo-vfdyhqjhu-kxqw-ghyhorsphqw-803[smjtn]
crwwv-pzxsbkdbo-erkq-pxibp-601[tnzmy]
xgjougizobk-jek-jkvruesktz-592[wsdmo]
bnqqnrhud-okzrshb-fqzrr-cdozqsldms-963[jtram]
qjopwxha-fahhuxawj-qoan-paopejc-472[ahjop]
amppmqgtc-amjmpdsj-afmamjyrc-kylyeckclr-184[yxzuq]
thnulapj-ihzrla-mpuhujpun-643[uhpaj]
lzfmdshb-oqnidbshkd-rbzudmfdq-gtms-btrsnldq-rdquhbd-833[dbqsh]
nzwzcqfw-mldvpe-cpdplcns-119[sejuv]
iqmbazulqp-omzpk-oamfuzs-dqeqmdot-950[qylkj]
lxaaxbren-lqxlxujcn-mnyuxhvnwc-849[frqsy]
nzwzcqfw-xtwtelcj-rclop-nlyoj-nzletyr-xlylrpxpye-743[lycen]
fubrjhqlf-sodvwlf-judvv-rshudwlrqv-621[ghonw]
iuxxuyobk-yigbktmkx-natz-ygrky-514[meayn]
wkqxodsm-nio-myxdksxwoxd-692[rqmey]
jvuzbtly-nyhkl-jvsvymbs-msvdly-klwsvftlua-305[yxmzb]
wlqqp-wcfnvi-uvmvcfgdvek-581[xriqe]
qcffcgwjs-tzcksf-fsqswjwbu-116[ztnym]
lahxpnwrl-kdwwh-mnenuxyvnwc-719[nwhlx]
muqfedyput-cqwdujys-fbqijys-whqii-mehaixef-634[iqefu]
eqpuwogt-itcfg-ejqeqncvg-gpikpggtkpi-232[kzfyv]
iwcjapey-xwogap-lqnydwoejc-420[styzx]
tagzsrsjvgmk-jsttal-mkwj-lwklafy-502[nrteu]
frqvxphu-judgh-udeelw-sxufkdvlqj-725[hzbtv]
kzgwomvqk-kivlg-kwibqvo-uizsmbqvo-746[epcdb]
ckgvutofkj-pkrrehkgt-ygrky-696[yblnm]
ydjuhdqjyedqb-vbemuh-tuiywd-894[oybua]
dwbcjkun-mhn-bjunb-121[srjlk]
ejpanjwpekjwh-qjopwxha-acc-qoan-paopejc-290[bsjiz]
irgyyolokj-inuiurgzk-xkgiwaoyozout-774[oigku]
mfklstdw-xdgowj-vwhsjlewfl-320[xyfdh]
sawlkjevaz-xwogap-klanwpekjo-420[mpkso]
fbebmtkr-zktwx-vhehkyne-lvtoxgzxk-angm-vnlmhfxk-lxkobvx-241[kxvbe]
irdgrxzex-vxx-glityrjzex-893[sxqom]
hqtyeqsjylu-rkddo-cqhaujydw-946[gastx]
lujbbrornm-kjbtnc-bjunb-251[xazbt]
iehepwnu-cnwza-bhksan-zarahkliajp-680[hlqnu]
xcjxjgvoz-vivgtndn-629[yubnv]
ixeumktoi-lruckx-sgtgmksktz-332[mrldq]
qxdwpopgsdjh-rpcsn-rdpixcv-ldgzhwde-765[rxoey]
glrcplyrgmlyj-njyqrga-epyqq-pcacgtgle-158[stgxu]
ojk-nzxmzo-kgvnodx-bmvnn-nzmqdxzn-525[nzmox]
froruixo-mhoobehdq-fxvwrphu-vhuylfh-933[ycnsx]
hdgdovmt-bmvyz-wvnfzo-omvdidib-395[hdygz]
aczupnetwp-ncjzrpytn-nlyoj-nzletyr-ecltytyr-535[ntyce]
fnjyxwrinm-ajkkrc-cajrwrwp-537[nczta]
rgllk-gzefmnxq-omzpk-oamfuzs-fqotzaxask-300[ztbqp]
muqfedyput-sqdto-fkhsxqiydw-218[npsrc]
buzahisl-jovjvshal-jvuahputlua-747[lsatz]
iuruxlar-lruckx-sgtgmksktz-826[krugl]
thnulapj-jovjvshal-ylzlhyjo-513[mtegl]
jshzzpmplk-lnn-shivyhavyf-201[hlnps]
qekrixmg-jpsaiv-pefsvexsvc-646[ryhkz]
mhi-lxvkxm-unggr-kxlxtkva-163[fkcax]
lugjuacha-wbiwifuny-wihnuchgyhn-396[huinw]
sbejpbdujwf-tdbwfohfs-ivou-tfswjdft-545[pnmzi]
nwilwcejc-zua-bejwjyejc-524[jcewa]
xlrypetn-awldetn-rcldd-xlcvpetyr-249[jgkyr]
amlqskcp-epybc-bwc-pcacgtgle-990[iyqge]
ktfitzbgz-lvtoxgzxk-angm-ybgtgvbgz-761[gtzbk]
avw-zljyla-ihzrla-huhsfzpz-253[banhu]
pualyuhapvuhs-ihzrla-ylhjxbpzpapvu-903[xsuvo]
qfkkj-nlyoj-xlcvpetyr-587[jklyc]
iruzfrtkzmv-irsszk-rthlzjzkzfe-451[zrkfi]
iqmbazulqp-vqxxknqmz-pqbxakyqzf-534[qxzab]
udskkaxawv-kusnwfywj-zmfl-ljsafafy-892[afksw]
gzefmnxq-ngzzk-etubbuzs-118[yjzkl]
molgbzqfib-ciltbo-zlkqxfkjbkq-809[isjze]
rnqnyfwd-lwfij-ojqqdgjfs-wjhjnansl-671[jnfqw]
fruurvlyh-ixccb-exqqb-uhfhlylqj-751[hlqub]
pinovwgz-zbb-nvgzn-343[sdhnt]
joufsobujpobm-dipdpmbuf-eftjho-181[ltrqy]
qzchnzbshud-rbzudmfdq-gtms-bnmszhmldms-209[seypq]
xfbqpojafe-dboez-sftfbsdi-649[fbdeo]
qjopwxha-ywjzu-zalhkuiajp-238[diyme]
ocipgvke-ecpfa-gpikpggtkpi-310[moyvi]
lxwbdvna-pajmn-vjpwncrl-bljenwpna-qdwc-vjwjpnvnwc-589[pvqom]
glrcplyrgmlyj-zyqicr-pcacgtgle-964[djtcm]
ckgvutofkj-kmm-jkbkruvsktz-254[twvxe]
pyknyegle-bwc-bcnyprkclr-522[oktmn]
amjmpdsj-zyqicr-asqrmkcp-qcptgac-314[campq]
qvbmzvibqwvit-akidmvomz-pcvb-zmamizkp-902[zvsto]
vxupkizork-igtje-iugzotm-jkvruesktz-748[bvyza]
kpvgtpcvkqpcn-dcumgv-wugt-vguvkpi-596[znbmg]
zovldbkfz-ciltbo-abmxoqjbkq-705[tknsq]
tagzsrsjvgmk-xdgowj-jwuwanafy-476[agjws]
mrxivrexmsrep-glsgspexi-hitevxqirx-256[atzwx]
pelbtravp-enoovg-znantrzrag-195[wdneq]
ocipgvke-eqttqukxg-dcumgv-ugtxkegu-102[soynm]
eqnqthwn-ejqeqncvg-tgugctej-908[zkyam]
hwbba-tcddkv-ocpcigogpv-206[vadln]
aflwjfslagfsd-tmffq-ogjckzgh-528[fgajl]
nij-mywlyn-zotts-luvvcn-jolwbumcha-838[lncjm]
jvsvymbs-zjhclunly-obua-zhslz-409[bpesx]
wfintfhynaj-hfsid-htfynsl-htsyfnsrjsy-359[ozaby]
nzcczdtgp-upwwjmply-dpcgtnpd-795[pcdgn]
excdklvo-lkcuod-bomosfsxq-978[kczes]
mrxivrexmsrep-fmsledevhsyw-ikk-vieguymwmxmsr-516[mersi]
willimcpy-yaa-mylpcwym-864[iucxs]
nsyjwsfyntsfq-hfsid-btwpxmtu-957[miqnp]
jvsvymbs-kfl-klzpnu-149[tyzxi]
amlqskcp-epybc-aylbw-amyrgle-bcnjmwkclr-730[ytmsd]
bkwzkqsxq-nio-cdybkqo-562[anfrp]
ide-htrgti-rpcsn-rdpixcv-rdcipxcbtci-635[zcbyd]
aflwjfslagfsd-tmffq-jwkwsjuz-606[fjswa]
foadouwbu-foppwh-oqeiwgwhwcb-714[toynm]
nzydfxpc-rclop-prr-dezclrp-795[tszpi]
mfklstdw-jsttal-ksdwk-944[autpj]
jvsvymbs-jhukf-zlycpjlz-409[borjv]
lnkfaypeha-ydkykhwpa-zalwnpiajp-342[twaxy]
pbybeshy-cynfgvp-tenff-npdhvfvgvba-741[fvbnp]
shoewudys-uww-tufbeocudj-764[iacnf]
iutyaskx-mxgjk-jek-giwaoyozout-566[koagi]
xcitgcpixdcpa-eaphixr-vgphh-hpath-401[xwtyn]
dlhwvupglk-wshzapj-nyhzz-lunpullypun-643[atizk]
jlidywncfy-mwupyhayl-bohn-mbcjjcha-214[wgcya]
eqpuwogt-itcfg-fag-qrgtcvkqpu-960[gqtcf]
fab-eqodqf-eomhqzsqd-tgzf-eqdhuoqe-950[zoeyv]
oazegyqd-sdmpq-nmewqf-pqhqxabyqzf-872[pkotu]
hqtyeqsjylu-uww-qsgkyiyjyed-946[yqejs]
pejji-mrymyvkdo-bomosfsxq-614[mojsy]
gzefmnxq-omzpk-xasuefuoe-378[iutjy]
hjgbwuladw-uzgugdslw-ksdwk-840[wdguk]
kpvgtpcvkqpcn-gii-ujkrrkpi-674[juebo]
encuukhkgf-gii-ugtxkegu-258[gukei]
xcitgcpixdcpa-eaphixr-vgphh-rdcipxcbtci-167[pkozr]
gcfcnuls-aluxy-wuhxs-wiuncha-lyuwkocmcncih-526[cuhln]
dmbttjgjfe-gmpxfs-mphjtujdt-441[jtmdf]
tcfkqcevkxg-hnqygt-tgceswkukvkqp-154[jgnim]
xqvwdeoh-udeelw-uhdftxlvlwlrq-309[swfid]
nzwzcqfw-ojp-wzrtdetnd-665[wzdnt]
shoewudys-sqdto-seqjydw-iqbui-816[zyxmn]
gzefmnxq-rxaiqd-mzmxkeue-300[cxpzy]
sawlkjevaz-zua-zarahkliajp-472[azjkl]
ktfitzbgz-ietlmbv-zktll-lxkobvxl-345[zgpbs]
cjpibabsepvt-gvaaz-cvooz-sftfbsdi-857[absvc]
eqpuwogt-itcfg-gii-ceswkukvkqp-128[rykin]
tbxmlkfwba-ciltbo-pqloxdb-653[yaqrn]
qzchnzbshud-okzrshb-fqzrr-dmfhmddqhmf-495[shpge]
dszphfojd-upq-tfdsfu-gmpxfs-pqfsbujpot-129[tefni]
aietsrmdih-ikk-hitpscqirx-100[ihkrs]
ykhknbqh-ywjzu-ykwpejc-qoan-paopejc-992[mgfrs]
oxmeeuruqp-eomhqzsqd-tgzf-ogefayqd-eqdhuoq-768[dsutf]
nwzekwypera-ywjzu-ykwpejc-yqopkian-oanreya-134[yaewk]
etyyx-idkkxadzm-zmzkxrhr-807[kxzdm]
kgjgrypw-epybc-aylbw-amyrgle-bcnyprkclr-418[yrbcg]
slqryzjc-njyqrga-epyqq-ylyjwqgq-418[saunh]
nuatmlmdpage-qss-xasuefuoe-794[rtesp]
jvuzbtly-nyhkl-msvdly-wbyjohzpun-617[gjidl]
bkzrrhehdc-azrjds-trdq-sdrshmf-417[dregf]
jqwpihizlwca-akidmvomz-pcvb-bmkpvwtwog-122[dywqz]
gntmfefwitzx-idj-jslnsjjwnsl-463[xcwpd]
myvybpev-bkllsd-domrxyvyqi-978[otdny]
qlm-pbzobq-pzxsbkdbo-erkq-xkxivpfp-263[jfzsm]
lujbbrornm-kdwwh-jwjuhbrb-953[svzbm]
dwbcjkun-yaxsnlcrun-ajkkrc-mnyuxhvnwc-303[lntzx]
froruixo-sodvwlf-judvv-ghvljq-595[ghbyq]
hjgbwuladw-ugjjgkanw-xdgowj-vwhsjlewfl-944[jiyqa]
egdytrixat-gpbepvxcv-qjccn-itrwcdadvn-687[xdpsn]
szfyrqriuflj-jtrmvexvi-ylek-uvgrikdvek-477[vbldh]
uzfqdzmfuazmx-pkq-dqmocgueufuaz-352[owbht]
rnqnyfwd-lwfij-gntmfefwitzx-gzssd-qfgtwfytwd-905[fwtdg]
ykhknbqh-xqjju-odellejc-498[yuzlk]
dwbcjkun-ouxfna-bqryyrwp-485[bnruw]
eqttqukxg-etaqigpke-tcddkv-ceswkukvkqp-492[muprn]
jvyyvzpcl-ibuuf-zlycpjlz-487[imbad]
udglrdfwlyh-gbh-whfkqrorjb-127[fvnah]
inputs = "aaaaa-bbb-z-y-x-123[abxyz]
a-b-c-d-e-f-g-h-987[abcde]
not-a-real-room-404[oarel]
totally-real-room-200[decoy]"
valid_rooms = inputs.lines.map { |line|
parts = line.split('-')
_, id, checksum = *parts.pop.match(/(\d+)\[(\w+)\]/)
[parts, id.to_i, checksum]
}.select { |parts, id, checksum|
puts
mychecksum = parts.join('').chars.
group_by { |c| c }.
map { |letter, instances| [letter, instances.size] }.
group_by { |letter, count| count }.
sort_by(&:first).reverse.
map { |count, combos|
combos.map(&:first).sort # pick letters in each group and order alphabetically
}.
flatten.join('')[0, 5]
pp [mychecksum, checksum, mychecksum == checksum]
mychecksum == checksum
}
puts "Part 1: sum of ids of valid rooms is:"
puts valid_rooms.map(&:second).sum
puts "Part 2: id of the room which has the decrypted name 'northpole objects storage'"
puts valid_rooms.find { |parts, id, checksum|
encrypted = parts.join(' ')
decrypted = parts.join(' ').chars.map { |c|
next ' ' if c == ' '
id.times { |i|
c = c.ord.succ > "z".ord ? "a" : c.ord.succ.chr
}
c
}.join
decrypted == "northpole object storage"
}[1]
input = "ffykfhsq"
password = ""
int = 0
while password.size < 8
hex = Digest::MD5.hexdigest(input + int.to_s)
if hex[0,5] == "00000"
puts "#{int} produces: #{hex}"
password << hex[5]
end
int += 1
end
puts "Part 1: the password is #{password}"
password = " "
int = 0
while password.index(" ")
hex = Digest::MD5.hexdigest(input + int.to_s)
if hex =~ /^00000[0-7]/
puts "Testing: #{hex}"
pos, char = hex[5].to_i, hex[6]
if pos.in?(0..7) && password[pos] == " "
password[pos] = char
puts "#{int} produces: #{hex} , password is now #{password}"
end
end
int += 1
end
puts "Part 2: the password is #{password}"
inputs = "eedadn
drvtee
eandsr
raavrd
atevrs
tsrnev
sdttsa
rasrtv
nssdts
ntnada
svetve
tesnvt
vntsnd
vrdear
dvrsen
enarar"
puts "Part 1: the secret (by most common char) extracted from the noise is: "
puts inputs.lines.map(&:strip). # prepare
map { |line| line.split('') }.transpose. # create/invert nested array
map { |line|
line.
group_by { |c| c }.
map { |c, values| [c, values.size] }.
sort_by(&:last).reverse.first.first
}.join; nil
puts "Part 2: the secret (by least common char) extracted from the noise is: "
puts inputs.lines.map(&:strip). # prepare
map { |line| line.split('') }.transpose. # create/invert nested array
map { |line|
line.
group_by { |c| c }.
map { |c, values| [c, values.size] }.
sort_by(&:last).first.first
}.join; nil
# Part 1
inputs = "abba[mnop]qrst
abcd[bddb]xyyx
aaaa[qwer]tyui
ioxxoj[asdfgh]zxcvbn"
# Part 2
inputs = "aba[bab]xyz
xyx[xyx]xyx
aaa[kek]eke
zazbz[bzb]cdb"
puts "Part 1: the number of IPs that match ABBA but no ABBA in hypernet brackets is: "
puts inputs.lines.map(&:strip).select { |line|
matches = line.
scan(/([a-z])([a-z])\2\1/).
select { |m| m[0] != m[1] }.
map { |m| "#{m[0]}#{m[1]}#{m[1]}#{m[0]}" }
hypernet_matches = line.
scan(/\[\w*(\w{1,1})(\w{1,1})\2\1\w*\]/).
select { |m| m[0] != m[1] }
matches.present? && hypernet_matches.blank?
}.size; nil
puts "Part two: the number of IPs that match ABA outside and BAB inside hypernet:"
puts inputs.lines.map(&:strip).select { |line|
supernets = line.gsub(/(\[[^\]]*\])/, '-')
hypernets = line.scan(/\[([^\]]*)\]/).join('-')
matches = supernets.
size.times.map { |i| supernets[i..-1].scan(/\w\w\w/) }.flatten.uniq.
select { |tri| tri[0] == tri[2] && tri[0] != tri[1] }
has_bab = matches.map { |m|
hypernets.scan(/(#{m[1]}#{m[0]}#{m[1]})/)
}.select(&:present?)
matches.present? && has_bab.present?
}.size; nil
inputs = "rect 1x1
rotate row y=0 by 5
rect 1x1
rotate row y=0 by 6
rect 1x1
rotate row y=0 by 5
rect 1x1
rotate row y=0 by 2
rect 1x1
rotate row y=0 by 5
rect 2x1
rotate row y=0 by 2
rect 1x1
rotate row y=0 by 4
rect 1x1
rotate row y=0 by 3
rect 2x1
rotate row y=0 by 7
rect 3x1
rotate row y=0 by 3
rect 1x1
rotate row y=0 by 3
rect 1x2
inputs = "rotate column x=1 by 1
rotate row y=0 by 4
rotate column x=1 by 1"
screen = [
Array.new(50, false),
Array.new(50, false),
Array.new(50, false),
Array.new(50, false),
Array.new(50, false),
Array.new(50, false)
]
inputs.lines.map(&:strip).each { |line|
if rect = line.match(/rect (\d+x\d+)/)
x,y = rect[1].split('x').map(&:to_i)
y.times { |row|
x.times { |col|
screen[row][col] = '#' if row < 6 && col < 50
}
}
elsif rotate = line.match(/rotate (column|row) ([xy])=(\d+) by (\d+)/)
axis, number, amount = rotate[2], rotate[3].to_i, rotate[4].to_i
if axis == "x"
tranposed = screen.transpose
amount.times { |_|
tranposed[number].unshift tranposed[number].pop
}
screen = tranposed.transpose
elsif axis == "y"
amount.times { |_|
screen[number].unshift screen[number].pop
}
end
end
screen.each { |row|
puts row.map { |cell| cell ? "#" : "." }.join('')
}
}
puts "Part 1: the screen has this many pixels lit: "
puts screen.map { |row| row.select { |cell| cell == '#' }.size }.sum
puts "Part 2: the screen says "
results = [
["(3x3)XYZ", "XYZXYZXYZ".size],
["X(8x2)(3x3)ABCY", "XABCABCABCABCABCABCY".size],
["(27x12)(20x12)(13x14)(7x10)(1x12)A", ("A" * 241920).size],
["(25x3)(3x3)ABC(2x3)XY(5x2)PQRSTX(18x9)(3x2)TWO(5x7)SEVEN", 445],
[File.read("day_9_input.txt"), 10755693147] # wrong answer: 10755693148
]
def decompressed_size(str)
size = 0
while str.size > 0
chr = str.slice!(0)
if chr == "("
num, mult = "", ""
while (next_chr = str.slice!(0)) != "x"
num << next_chr
end
while (next_chr = str.slice!(0)) != ")"
mult << next_chr
end
num, mult = num.to_i, mult.to_i
consumed = str.slice!(0, num)
size += decompressed_size(consumed) * mult
size += decompressed_size(str)
else
size += 1
end
end
size
end
results.each.with_index do |pair, idx|
decompressed, size = *pair
s = decompressed_size(decompressed.gsub(/[^()x0-9)()A-Z]/, ''))
if s != size
puts "#{idx}: decompressed should be #{uncompressed.size} but was #{size}"
exit
end
end
input = "value 5 goes to bot 2
bot 2 gives low to bot 1 and high to bot 0
value 3 goes to bot 1
bot 1 gives low to output 1 and high to bot 0
bot 0 gives low to output 2 and high to output 0
value 2 goes to bot 2"
class Output
attr_accessor :index, :values
def initialize(index); @values, @index = [], index; end
def visit; end
def inspect; "[##{index}, values: #{values.inspect}]"; end
end
class Bot
attr_accessor :index, :low_dst, :high_dst, :values, :comparisons
def initialize(index)
@values, @index, @comparisons = [], index, []
end
def visit
if values.size == 2 && low_dst && high_dst
low, high = *values.sort
@comparisons << [low, high]
low_dst.values << low
high_dst.values << high
@values = []
low_dst.visit
high_dst.visit
end
end
def inspect; "[##{index}, values: #{values.inspect}, low: #{low_dst.index}, high: #{high_dst.index}, comparisons: #{@comparisons.inspect}]"; end
end
bots = []
outputs = []
input.lines.each do |line|
if match = line.match(/value (\d+) goes to bot (\d+)/)
value, bot = match[1].to_i, match[2].to_i
(bots[bot] ||= Bot.new(bot)).values << value
bots[bot].visit
elsif match = line.match(/bot (\d+) gives low to (output|bot) (\d+) and high to (output|bot) (\d+)/)
bot, low_type, low_dst, high_type, high_dst = match[1].to_i, match[2],match[3].to_i, match[4], match[5].to_i
bots[bot] ||= Bot.new(bot)
bots[bot].low_dst = low_type == "bot" ? (bots[low_dst] ||= Bot.new(low_dst)) : (outputs[low_dst] ||= Output.new(low_dst))
bots[bot].high_dst = high_type == "bot" ? (bots[high_dst] ||= Bot.new(high_dst)) : (outputs[high_dst] ||= Output.new(high_dst))
bots[bot].visit
end
end
require 'pp'
pp bots
pp outputs
puts
puts "Part 1 -- the bot that is responsible for comparing value-5 microchips with value-2 microchips: "
puts bots.find { |b| b.comparisons.include?([2, 5]) }.inspect
puts
puts "Part 2 -- What do you get if you multiply together the values of one chip in each of outputs 0, 1, and 2?"
puts outputs[0..2].map(&:values).map(&:first).reduce(:*)
# Rules:
# * elevator must have 1..2 items, rtg or microchips
# * rtg on a floor must have its microchip or it will fry other microchips
# Sample input
input = "
F4 . . . . .
F3 . . . LG .
F2 . HG . . .
F1 E . HM . LM
".strip
# Part 1
# The first floor contains a thulium generator, a thulium-compatible microchip, a plutonium generator, and a strontium generator.
# The second floor contains a plutonium-compatible microchip and a strontium-compatible microchip.
# The third floor contains a promethium generator, a promethium-compatible microchip, a ruthenium generator, and a ruthenium-compatible microchip.
# The fourth floor contains nothing relevant.
#
# T = Thulium
# P = Plutonium
# S = Strontium
# Pr = Promethium
# R = Ruthenium
input = "
F4 . . . . . . . . . . .
F3 . . . . . . . PrG PrM RG RM
F2 . . . . PM . SM . . . .
F1 E TG TM PG . SG . . . . .
".strip
# Part 2
# Adds to first floor:
# An elerium generator.
# An elerium-compatible microchip.
# A dilithium generator.
# A dilithium-compatible microchip.
#
# T = Thulium
# P = Plutonium
# S = Strontium
# Pr = Promethium
# R = Ruthenium
# E = Elerium
# D = Dilithium
input = "
F4 . . . . . . . . . . . . . . .
F3 . . . . . . . PrG PrM RG RM . . . .
F2 . . . . PM . SM . . . . . . . .
F1 E TG TM PG . SG . . . . . EG EM DG DM
".strip
puts "Input: \n#{input}\n"
State = Struct.new(
:floors, :current_floor, :parent_state, :move
) do
def score
@score ||= floors.
map.with_index.
inject(0) { |floor_score, (floor, index)|
floor_score += (index + 1) * floor.size
floor_score
}
end
def hash
@hash ||= (["E", current_floor] + floors.map { |flr| flr.sort.join('') }).join("-").hash
end
def inspect
padding = (" " * move.last)
floors.map.with_index { |flr, idx|
[idx == current_floor ? "E " : " ", idx + 1] + STATE_TYPES.map { |type|
["#{type}G", "#{type}M"]
}.flatten.map { |obj|
flr.include?(obj) ? obj : "."
}.map { |o| "%03s" % o }
}.map { |flr|
padding + flr.join(' ')
}.
join("\n") + "\n#{padding}Move: #{move}, Move count: #{move.last}, Score: #{score}, Hash: #{hash}\n"
end
def possible_next_directions
[].tap do |directions|
directions << -1 if current_floor > 0
directions << 1 if current_floor < floors.size-1
end
end
def valid?
!invalid?
end
def invalid?(debug=false)
# s = parent_state
# return true if s.hash == hash
# while s = s.parent_state
# return true if s.hash == hash
# end
return true if SEEN_VALID_HASHES.include?(hash)
floors.any? { |flr|
next false if flr.empty?
# Make sure all generators have a corresponding microchip
# valid: HG
# valid: HG HM
# valid: HG HM LM
# invalid: HG LM
microchips, generators = flr.partition { |obj| obj[-1] == "M" }
# No generators = valid
next false if generators.empty?
# No microships where only other generators exist
microchips.any? { |m| !generators.include?("#{m[0..-2]}G") }
}.tap { |result|
SEEN_VALID_HASHES << hash unless result
}
end
def floor
floors[current_floor]
end
def possible_next_states
pairs = (floor.map { |obj| [obj] } + floor.combination(2).to_a)
pairs.map { |pair|
possible_next_directions.map { |direction|
next_current_floor = current_floor + direction
next_floors = floors.map(&:dup)
pair.each do |obj|
next_floors[current_floor].delete(obj)
next_floors[next_current_floor] << obj
end
next_parent_state = self
next_move = [pair, direction, move.last + 1]
state = State.new(
next_floors, next_current_floor, next_parent_state, next_move
)
state
}
}.flatten.select(&:valid?)
end
end
Move = Struct.new(:moves)
current_floor = 0
# :floors, :current_floor, :parent_state, :move
initial_state = State.new(nil, nil, nil, [nil, nil, 0])
initial_state.floors = input.lines.reverse.to_a.map.with_index { |flr,idx|
flr = flr.split(' ')
flr.shift # F1, F2, ...
initial_state.current_floor = idx if flr.shift == "E"
flr.delete('.')
flr
}
STATE_TYPES = initial_state.floors.flatten.map { |o| o[0..-2] }.uniq
SEEN_VALID_HASHES = []
puts "Initial state: \n#{initial_state.inspect}\n"
counter = 1
states = initial_state.possible_next_states
# winning score = types (microchip + generator) * floors
winning_score = (STATE_TYPES.size * 2) * 4
puts "Searching for state with score #{winning_score}..."
until states.any? { |s| s.score >= winning_score }
throw "somethign went wrong" if states.size.zero?
counter += 1
states = states.
flat_map(&:possible_next_states).sort_by(&:score)
puts "(#{states.size} possible states)"
states = states.last(1000) # this is probably terrible, but it makes it faster and gives me a winning solution
puts "Step ##{counter} (testing #{states.size} states)\n"
end
print "Part 1 (or 2, based on input), with winning score #{winning_score} :"
# Example of a winning state
s = states.find { |s| s.score >= winning_score }
puts s.inspect
# while s = s.parent_state
# puts s.inspect
# end
# 8 is too low
# 31 is the answer
# 41 is too high
# Part 2:
# 55 is the answer
# NB this is sort of a brute force method (grabbing top 1000 best possible states each time). A* search algorithm would be better suited.
require 'pp'
inputs = "
cpy 41 a
inc a
inc a
dec a
jnz a 2
dec a
".strip
inputs = "
cpy 1 a
cpy 1 b
cpy 26 d
jnz c 2
jnz 1 5
cpy 7 c
inc d
dec c
jnz c -2
cpy a c
inc a
dec b
jnz b -2
cpy c b
dec d
jnz d -6
cpy 19 c
cpy 14 d
inc a
dec d
jnz d -2
dec c
jnz c -5
".strip
instructions = inputs.lines.to_a.freeze
def run_assembunny(instructions, registers = {a: 0, b: 0, c: 0, d: 0})
puts "Regiser a is #{registers[:a]}"
i = 0
while instructions[i]
# puts instructions[i]
instr, arg1, arg2 = instructions[i].strip.split(' ').map(&:to_sym)
# puts "instr: #{instr}, #{arg1}, #{arg2}"
case instr
when :cpy
registers[arg2] = registers.keys.include?(arg1) ? registers[arg1] : arg1.to_s.to_i
when :inc
registers[arg1] += 1
when :dec
registers[arg1] -= 1
when :jnz
if registers[arg1] != 0
i += arg2.to_s.to_i
next
end
end
i += 1
print "." if i % 1000 == 0
# pp registers
# puts
end
registers
end
registers = run_assembunny(instructions)
puts "Part 1: register a value is #{registers[:a]}"
registers = run_assembunny(instructions, {a: 0, b: 0, c: 1, d: 0})
puts "Part 2: register a value (with c initialized to 1) is #{registers[:a]}"
require 'set'
require 'pp'
SECRET_NUMBER = 10
destination_location = [7,4]
SECRET_NUMBER = 1362
destination_location = [31,39]
Location = Struct.new(:x, :y) do
def wall_or_open
a = (x * x) + (3 * x) + (2 * x * y) + y + (y * y)
b = a + SECRET_NUMBER
c = b.to_s(2)
d = c.delete('0').size
d.even? ? :open : :wall
end
def not_movable?; x < 0 || y < 0 || wall?; end
def wall?; wall_or_open == :wall; end
def open?; wall_or_open == :open; end
def to_s; wall? ? "#" : "."; end
def ==(location); x == location.x && y == location.y; end
end
SEEN = Set.new
DEPTH_LIMIT_MAX = 1000
Step = Struct.new(:location, :parent) do
def inspect
"#<Step steps=#{steps} location=[#{location.x},#{location.y}]>"
end
def hash
"x#{location.x}y#{location.y}".hash
end
def steps
parents.size
end
def destination_steps(destination_location, depth_limit=DEPTH_LIMIT_MAX)
return self if location == destination_location
return nil if depth_limit == 0
SEEN << [location.x, location.y] if (DEPTH_LIMIT_MAX - 50) <= depth_limit
possible_next_steps.map do |step|
step.destination_steps(destination_location, depth_limit - 1)
end
end
def possible_next_steps
[[0,-1],[0,1],[-1,0],[1,0]].
map { |_x,_y|
Location.new(location.x + _x, location.y + _y)
}.
reject { |location|
location.not_movable? || already_visited?(location)
}.map { |location|
Step.new(location, self)
}
end
def already_visited?(location)
p = self
while p
return true if p.location == location
p = p.parent
end
end
def parents
_parents = []
p = self
while p
_parents << p.parent
p = p.parent
end
_parents
end
end
floor = (0..50).to_a.map do |row|
(0..50).to_a.map do |col|
Location.new(col, row)
end.to_a
end
puts " " + floor[0].size.times.map { |i| i.to_s[-1] }.join('')
output = floor.map.with_index do |row, idx|
"#{idx} #{row.map(&:to_s).to_a.join('')}"
end.to_a.join("\n")
puts output
puts "Part 1: shortest path to reach #{destination_location}:"
puts Step.new(floor[1][1]).
destination_steps(Location.new(*destination_location)).
flatten.compact.
sort_by(&:steps).
first.steps - 1 # subtract 1 because size includes initial step
# answer: 82
puts "Part 2: most distinct locations to visit in 50 steps"
puts SEEN.size # answer: 138
require 'digest/md5'
require 'pp'
#SALT = "abc"
SALT = "yjdafjpo"
KEYMAP = []
def get_key(sequence, stretch: false)
KEYMAP[sequence] ||= begin
key = Digest::MD5.hexdigest("#{SALT}#{sequence}")
2016.times { key = Digest::MD5.hexdigest(key) } if stretch
key
end
end
def valid_key?(key, sequence, stretch: false)
return false unless m = key.match(/(\h)\1\1/)
return ((sequence + 1)..(sequence+1001)).to_a.any? do |seq|
get_key(seq, stretch: stretch).match(/(#{m[1]})\1\1\1\1/)
end
end
keys = []
i = 1
while keys.size < 64
key = get_key(i)
if valid_key?(key, i)
keys << [i, key]
puts "#{keys.size} #{i} - #{key}"
end
i += 1
end
puts "Part 1: the index that produced the 64th key was #{keys.last[0]}" # => 25427
KEYMAP.clear
keys = []
i = 0
while keys.size < 65
key = get_key(i, stretch: true)
if valid_key?(key, i, stretch: true)
keys << [i, key]
puts "#{keys.size} #{i} - #{key}"
end
i += 1
end
pp keys.map.with_index.to_a
puts "Part 2: the index that produced the 64th stretched key was #{keys.last[0]}" # => 22045
require 'pp'
# Example input
# input = "
# Disc #1 has 5 positions; at time=0, it is at position 4.
# Disc #2 has 2 positions; at time=0, it is at position 1.
# ".strip
input = "
Disc #1 has 13 positions; at time=0, it is at position 11.
Disc #2 has 5 positions; at time=0, it is at position 0.
Disc #3 has 17 positions; at time=0, it is at position 11.
Disc #4 has 3 positions; at time=0, it is at position 0.
Disc #5 has 7 positions; at time=0, it is at position 2.
Disc #6 has 19 positions; at time=0, it is at position 17.
".strip
build_discs_from_input = -> (txt) do
txt.lines.map do |line|
match = line.match(/Disc #(\d+) has (\d+) positions; at time=0, it is at position (\d+)/)
{ num: match[1].to_i, total_positions: match[2].to_i, initial_position: match[3].to_i }
end
end
valid_time_for_all_positions = -> (time, discs) do
result = discs.map { |disc|
# print "."
cumulative_position = disc[:initial_position] + disc[:num] + time
current_position = cumulative_position % disc[:total_positions]
current_position
}.all?(&:zero?)
end
discs = build_discs_from_input.call(input)
time = 0
time += 1 until valid_time_for_all_positions.call(time, discs)
puts "Part 1: the first time all discs are aligned is throwing the capsule at time: #{time}"
input << "Disc #7 has 11 positions; at time=0, it is at position 0."
discs = build_discs_from_input.call(input)
time = 0
time += 1 until valid_time_for_all_positions.call(time, discs)
puts "Part 2: the first time all discs are aligned with the new disc is throwing the capsule at time: #{time}"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment