Merge branch 'master' of ssh://git.elnota.space:10222/daviddoji/Advent_of_code

This commit is contained in:
David Doblas Jiménez 2022-04-04 17:13:09 +02:00
commit e52821eee1
7 changed files with 880 additions and 0 deletions

83
src/Year_2015/P8.py Normal file
View File

@ -0,0 +1,83 @@
# --- Day 8: Matchsticks ---
# Space on the sleigh is limited this year, and so Santa will be bringing his
# list as a digital copy. He needs to know how much space it will take up when
# stored.
# It is common in many programming languages to provide a way to escape special
# characters in strings. For example, C, JavaScript, Perl, Python, and even PHP
# handle special characters in very similar ways.
# However, it is important to realize the difference between the number of
# characters in the code representation of the string literal and the number of
# characters in the in-memory string itself.
# For example:
# "" is 2 characters of code (the two double quotes), but the string
# contains zero characters.
# "abc" is 5 characters of code, but 3 characters in the string data.
# "aaa\"aaa" is 10 characters of code, but the string itself contains six
# "a" characters and a single, escaped quote character, for a total of 7 characters in the string data.
# "\x27" is 6 characters of code, but the string itself contains just one
# - an apostrophe ('), escaped using hexadecimal notation.
# Santa's list is a file that contains many double-quoted string literals, one
# on each line. The only escape sequences used are \\ (which represents a
# single backslash), \" (which represents a lone double-quote character), and
# \x plus two hexadecimal characters (which represents a single character with
# that ASCII code).
# Disregarding the whitespace in the file, what is the number of characters of
# code for string literals minus the number of characters in memory for the
# values of the strings in total for the entire file?
# For example, given the four strings above, the total number of characters of
# string code (2 + 5 + 10 + 6 = 23) minus the total number of characters in
# memory for string values (0 + 3 + 7 + 1 = 11) is 23 - 11 = 12.
with open("files/P8.txt") as f:
lines = [line for line in f.read().strip().split()]
# TIL: eval()
def part_1() -> None:
res = sum(len(line) - len(eval(line)) for line in lines)
print(f"There are {res} characters.")
# --- Part Two ---
# Now, let's go the other way. In addition to finding the number of characters
# of code, you should now encode each code representation as a new string and
# find the number of characters of the new encoded representation, including
# the surrounding double quotes.
# For example:
# "" encodes to "\"\"", an increase from 2 characters to 6.
# "abc" encodes to "\"abc\"", an increase from 5 characters to 9.
# "aaa\"aaa" encodes to "\"aaa\\\"aaa\"", an increase from 10 characters to
# 16.
# "\x27" encodes to "\"\\x27\"", an increase from 6 characters to 11.
# Your task is to find the total number of characters to represent the newly
# encoded strings minus the number of characters of code in each original
# string literal. For example, for the strings above, the total encoded length
# (6 + 9 + 16 + 11 = 42) minus the characters in the original code
# representation (23, just like in the first part of this puzzle) is
# 42 - 23 = 19.
def part_2() -> None:
# 2 for the ""
# just count numbers of \\ and new "
res = sum(2 + line.count("\\") + line.count('"') for line in lines)
print(f"There are {res} characters.")
if __name__ == "__main__":
part_1()
part_2()

300
src/Year_2015/files/P8.txt Normal file
View File

@ -0,0 +1,300 @@
"qxfcsmh"
"ffsfyxbyuhqkpwatkjgudo"
"byc\x9dyxuafof\\\xa6uf\\axfozomj\\olh\x6a"
"jtqvz"
"uzezxa\"jgbmojtwyfbfguz"
"vqsremfk\x8fxiknektafj"
"wzntebpxnnt\"vqndz\"i\x47vvjqo\""
"higvez\"k\"riewqk"
"dlkrbhbrlfrp\\damiauyucwhty"
"d\""
"qlz"
"ku"
"yy\"\"uoao\"uripabop"
"saduyrntuswlnlkuppdro\\sicxosted"
"tj"
"zzphopswlwdhebwkxeurvizdv"
"xfoheirjoakrpofles\"nfu"
"q\xb7oh\"p\xce\"n"
"qeendp\"ercwgywdjeylxcv"
"dcmem"
"\"i\x13r\"l"
"ikso\xdcbvqnbrjduh\"uqudzki\xderwk"
"wfdsn"
"pwynglklryhtsqbno"
"hcoj\x63iccz\"v\"ttr"
"zf\x23\\hlj\\kkce\\d\\asy\"yyfestwcdxyfj"
"xs"
"m\"tvltapxdvtrxiy"
"bmud"
"k\"a"
"b\"oas"
"\"yexnjjupoqsxyqnquy\"uzfdvetqrc"
"vdw\xe3olxfgujaj"
"qomcxdnd\"\\cfoe\""
"fpul"
"m\"avamefphkpv"
"vvdnb\\x\\uhnxfw\"dpubfkxfmeuhnxisd"
"hey\\"
"ldaeigghlfey"
"eure\"hoy\xa5iezjp\\tm"
"yygb\"twbj\\r\"\x10gmxuhmp\""
"weirebp\x39mqonbtmfmd"
"ltuz\\hs\"e"
"ysvmpc"
"g\x8amjtt\"megl\"omsaihifwa"
"yimmm"
"iiyqfalh"
"cwknlaaf"
"q\x37feg\xc6s\"xx"
"uayrgeurgyp\\oi"
"xhug\"pt\"axugllbdiggzhvy"
"kdaarqmsjfx\xc3d"
"\"vkwla"
"d\""
"tmroz\"bvfinxoe\\mum\"wmm"
"\"n\"bbswxne\\p\\yr\"qhwpdd"
"skzlkietklkqovjhvj\xfe"
"pbg\\pab\"bubqaf\"obzcwxwywbs\\dhtq"
"xxjidvqh\"lx\\wu\"ij"
"daef\x5fe\x5b\\kbeeb\x13qnydtboof"
"ogvazaqy\"j\x73"
"y"
"n\"tibetedldy\\gsamm\"nwu"
"wldkvgdtqulwkad"
"dpmxnj"
"twybw\"cdvf\"mjdajurokbce"
"ru\"\\lasij\"i"
"roc\\vra\\lhrm"
"pbkt\x60booz\"fjlkc"
"j\x4dytvjwrzt"
"\\uiwjkniumxcs"
"cbhm\"nexccior\"v\"j\"nazxilmfp\x47"
"qdxngevzrlgoq"
"\"lrzxftytpobsdfyrtdqpjbpuwmm\x9e"
"mdag\x0asnck\xc2ggj\"slb\"fjy"
"wyqkhjuazdtcgkcxvjkpnjdae"
"aixfk\xc0iom\x21vueob"
"dkiiakyjpkffqlluhaetires"
"ysspv\"lysgkvnmwbbsy"
"gy\"ryexcjjxdm\"xswssgtr"
"s"
"ddxv"
"qwt\"\x27puilb\"pslmbrsxhrz"
"qdg\xc9e\\qwtknlvkol\x54oqvmchn\\"
"lvo"
"b"
"fk\"aa\"\"yenwch\\\\on"
"srig\x63hpwaavs\\\x80qzk\"xa\"\xe6u\\wr"
"yxjxuj\"ghyhhxfj\"\xa6qvatre"
"yoktqxjxkzrklkoeroil"
"\"jfmik\""
"smgseztzdwldikbqrh\""
"jftahgctf\"hoqy"
"tcnhicr\"znpgckt\"ble"
"vqktnkodh\"lo\"a\\bkmdjqqnsqr"
"ztnirfzqq"
"s"
"xx"
"iqj\"y\\hqgzflwrdsusasekyrxbp\\ad"
"\\xzjhlaiynkioz\"\"bxepzimvgwt"
"s\x36rbw"
"mniieztwrisvdx"
"atyfxioy\x2b\\"
"irde\x85\x5cvbah\\jekw\"ia"
"bdmftlhkwrprmpat\"prfaocvp"
"w\\k"
"umbpausy"
"zfauhpsangy"
"p\"zqyw"
"wtztypyqvnnxzvlvipnq\"zu"
"deicgwq\\oqvajpbov\\or\"kgplwu"
"mbzlfgpi\\\\zqcidjpzqdzxityxa"
"lfkxvhma"
"\xf2yduqzqr\"\\fak\"p\"n"
"mpajacfuxotonpadvng"
"anb\\telzvcdu\\a\xf2flfq"
"lrs\"ebethwpmuuc\"\x86ygr"
"qmvdbhtumzc\"ci"
"meet"
"yopg\x0fdxdq\"h\\ugsu\xffmolxjv"
"uhy"
"fzgidrtzycsireghazscvmwcfmw\\t"
"cqohkhpgvpru"
"bihyigtnvmevx\"xx"
"xz"
"zofomwotzuxsjk\"q\"mc\"js\"dnmalhxd"
"\\ktnddux\\fqvt\"ibnjntjcbn"
"ia"
"htjadnefwetyp\xd5kbrwfycbyy"
"\"\\hkuxqddnao"
"meqqsz\x83luecpgaem"
"cvks\x87frvxo\"svqivqsdpgwhukmju"
"sgmxiai\\o\"riufxwjfigr\xdf"
"fgywdfecqufccpcdn"
"faghjoq\x28abxnpxj"
"zuppgzcfb\"dctvp\"elup\"zxkopx"
"xqs\x45xxdqcihbwghmzoa"
"anbnlp\\cgcvm\"hc"
"xf\"fgrngwzys"
"nrxsjduedcy\x24"
"\x71sxl\"gj\"sds\"ulcruguz\\t\\ssvjcwhi"
"jhj\"msch"
"qpovolktfwyiuyicbfeeju\x01"
"nkyxmb\"qyqultgt\"nmvzvvnxnb"
"ycsrkbstgzqb\"uv\\cisn"
"s"
"ueptjnn\"\"sh"
"lp\"z\"d\"mxtxiy"
"yzjtvockdnvbubqabjourf\"k\"uoxwle"
"\x82\"wqm\""
"\xb5cwtuks\x5fpgh"
"wd"
"tbvf"
"ttbmzdgn"
"vfpiyfdejyrlbgcdtwzbnm"
"uc"
"otdcmhpjagqix"
"\\\xb1qso\"s"
"scowax"
"behpstjdh\xccqlgnqjyz\"eesn"
"r\xe1cbnjwzveoomkzlo\\kxlfouhm"
"jgrl"
"kzqs\\r"
"ctscb\x7fthwkdyko\"\x62pkf\"d\xe6knmhurg"
"tc\"kw\x3ftt"
"bxb\x5ccl"
"jyrmfbphsldwpq"
"jylpvysl\"\"juducjg"
"en\\m\"kxpq\"wpb\\\""
"madouht\"bmdwvnyqvpnawiphgac\""
"vuxpk\"ltucrw"
"aae\x60arr"
"ttitnne\"kilkrgssnr\xfdurzh"
"oalw"
"pc\"\"gktkdykzbdpkwigucqni\"nxiqx"
"dbrsaj"
"bgzsowyxcbrvhtvekhsh\"qgd"
"kudfemvk\"\"\"hkbrbil\"chkqoa"
"zjzgj\\ekbhyfzufy"
"\\acos\"fqekuxqzxbmkbnn\x1ejzwrm"
"elxahvudn\"txtmomotgw"
"\x2eoxmwdhelpr\"cgi\xf7pzvb"
"eapheklx"
"hfvma\"mietvc\"tszbbm\"czex"
"h\"iiockj\\\xc1et"
"d\"rmjjftm"
"qlvhdcbqtyrhlc\\"
"yy\"rsucjtulm\"coryri\"eqjlbmk"
"tv"
"r\"bfuht\\jjgujp\""
"kukxvuauamtdosngdjlkauylttaokaj"
"srgost\"\"rbkcqtlccu\x65ohjptstrjkzy"
"yxwxl\\yjilwwxffrjjuazmzjs"
"dxlw\\fkstu\"hjrtiafhyuoh\"sewabne"
"\x88sj\"v"
"rfzprz\xec\"oxqclu\"krzefp\\q"
"cfmhdbjuhrcymgxpylllyvpni"
"ucrmjvmimmcq\x88\xd9\"lz"
"lujtt\""
"gvbqoixn\"pmledpjmo\"flydnwkfxllf"
"dvxqlbshhmelsk\x8big\"l"
"mx\x54lma\x8bbguxejg"
"\x66jdati\xeceieo"
"\"iyyupixei\x54ff"
"xohzf\"rbxsoksxamiu"
"vlhthspeshzbppa\x4drhqnohjop\"\"mfjd"
"f\"tvxxla\"vurian\"\"idjq\x3aptm\xc3olep"
"gzqz"
"kbq\\wogye\\altvi\\hbvmodny"
"j\xd8"
"ofjozdhkblvndl"
"hbitoupimbawimxlxqze"
"ypeleimnme"
"xfwdrzsc\\oxqamawyizvi\\y"
"enoikppx\xa1ixe\"yo\"gumye"
"fb"
"vzf"
"zxidr"
"cu\x31beirsywtskq"
"lxpjbvqzztafwezd"
"\\jyxeuo\x18bv"
"b\"vawc\"p\\\\giern\"b"
"odizunx\"\"t\\yicdn\"x\"sdiz"
"\"\"tebrtsi"
"ctyzsxv\xa6pegfkwsi\"tgyltaakytccb"
"htxwbofchvmzbppycccliyik\xe5a"
"ggsslefamsklezqkrd"
"rcep\"fnimwvvdx\"l"
"zyrzlqmd\x12egvqs\\llqyie"
"\x07gsqyrr\\rcyhyspsvn"
"butg\""
"gb"
"gywkoxf\"jsg\\wtopxvumirqxlwz"
"rj\"ir\"wldwveair\x2es\"dhjrdehbqnzl"
"ru\"elktnsbxufk\\ejufjfjlevt\\lrzd"
"\"widsvok"
"oy\"\x81nuesvw"
"ay"
"syticfac\x1cfjsivwlmy\"pumsqlqqzx"
"m"
"rjjkfh\x78cf\x2brgceg\"jmdyas\"\\xlv\xb6p"
"tmuvo\"\x3ffdqdovjmdmkgpstotojkv\"as"
"jd\\ojvynhxllfzzxvbn\"wrpphcvx"
"pz"
"\"twr"
"n\\hdzmxe\"mzjjeadlz"
"fb\"rprxuagvahjnri"
"rfmexmjjgh\\xrnmyvnatrvfruflaqjnd"
"obbbde\"co\"qr\"qpiwjgqahqm\\jjp\""
"vpbq\"\"y\"czk\\b\x52ed\"lnzepobp"
"syzeajzfarplydipny\"y\"\xe8ad"
"mpyodwb"
"\x47rakphlqqptd"
"wa\"oj\"aiy"
"a"
"ropozx"
"q\x51nbtlwa"
"etukvgx\\jqxlkq"
"\"tp\"rah\"pg\"s\"bpdtes\\tkasdhqd"
"dn\"qqpkikadowssb\xcah\"dzpsf\\ect\"jdh"
"pxunovbbrrn\\vullyn\"bno\"\"\"myfxlp\""
"qaixyazuryvkmoulhcqaotegfj\\mpzm"
"bvfrbicutzbjwn\\oml\"cf\"d\"ezcpv\"j"
"rmbrdtneudemigdhelmb"
"aq\\aurmbhy"
"wujqvzw"
"gf\"tssmvm\"gm\"hu\x9a\xb7yjawsa"
"hrhqqxow\xe2gsydtdspcfqy\"zw\\ou"
"ianwwf\\yko\\tdujhhqdi"
"xylz\"zpvpab"
"lwuopbeeegp"
"aoop\x49jhhcexdmdtun"
"\\\\mouqqcsgmz"
"tltuvwhveau\x43b\"ymxjlcgiymcynwt"
"gsugerumpyuhtjljbhrdyoj"
"lnjm\xb8wg\"ajh"
"zmspue\"nfttdon\\b\"eww"
"\"w\x67jwaq\x7ernmyvs\\rmdsuwydsd\"th"
"ogtgvtlmcvgllyv"
"z\"fqi\"rvddoehrciyl"
"yustxxtot\"muec\"xvfdbzunzvveq"
"mqslw"
"txqnyvzmibqgjs\xb6xy\x86nfalfyx"
"kzhehlmkholov"
"plpmywcnirrjutjguosh\\"
"pydbnqofv\"dn\\m"
"aegqof"
"eambmxt\\dxagoogl\\zapfwwlmk"
"afbmqitxxqhddlozuxcpjxgh"
"vgts"
"bfdpqtoxzzhmzcilehnflna"
"s\"idpz"
"\xcfhgly\"nlmztwybx\"ecezmsxaqw"
"aackfgndqcqiy"
"\x22unqdlsrvgzfaohoffgxzfpir\"s"
"abh\"ydv\"kbpdhrerl"
"bdzpg"
"ekwgkywtmzp"
"wtoodejqmrrgslhvnk\"pi\"ldnogpth"
"njro\x68qgbx\xe4af\"\\suan"

133
src/Year_2016/P8.py Normal file
View File

@ -0,0 +1,133 @@
# --- Day 8: Two-Factor Authentication ---
# You come across a door implementing what you can only assume is an
# implementation of two-factor authentication after a long game of
# requirements telephone.
# To get past the door, you first swipe a keycard (no problem; there was one on
# a nearby desk). Then, it displays a code on a little screen, and you type
# that code on a keypad. Then, presumably, the door unlocks.
# Unfortunately, the screen has been smashed. After a few minutes, you've taken
# everything apart and figured out how it works. Now you just have to work out
# what the screen would have displayed.
# The magnetic strip on the card you swiped encodes a series of instructions
# for the screen; these instructions are your puzzle input. The screen is 50
# pixels wide and 6 pixels tall, all of which start off, and is capable of
# three somewhat peculiar operations:
# rect AxB turns on all of the pixels in a rectangle at the top-left of the
# screen which is A wide and B tall.
# rotate row y=A by B shifts all of the pixels in row A (0 is the top row)
# right by B pixels. Pixels that would fall off the right end appear at the
# left end of the row.
# rotate column x=A by B shifts all of the pixels in column A (0 is the
# left column) down by B pixels. Pixels that would fall off the bottom appear
# at the top of the column.
# For example, here is a simple sequence on a smaller screen:
# rect 3x2 creates a small rectangle in the top-left corner:
# ###....
# ###....
# .......
# rotate column x=1 by 1 rotates the second column down by one pixel:
# #.#....
# ###....
# .#.....
# rotate row y=0 by 4 rotates the top row right by four pixels:
# ....#.#
# ###....
# .#.....
# rotate column x=1 by 1 again rotates the second column down by one pixel,
# causing the bottom pixel to wrap back to the top:
# .#..#.#
# #.#....
# .#.....
# As you can see, this display technology is extremely powerful, and will soon
# dominate the tiny-code-displaying-screen market. That's what the
# advertisement on the back of the display tries to convince you, anyway.
# There seems to be an intermediate check of the voltage used by the display:
# after you swipe your card, if the screen did work, how many pixels should be
# lit?
import numpy as np
import numpy.typing as npt
with open("files/P8.txt") as f:
instructions = [line for line in f.read().strip().split("\n")]
def rect(instruction: str, grid: npt.NDArray[int]) -> npt.NDArray[int]:
_, row = instruction.split("x")
_, col = _.split()
grid[: int(row), : int(col)] = 1
def rotate_column(
instruction: str, grid: npt.NDArray[int]
) -> npt.NDArray[int]:
_, cols = instruction.split("=")
x, _, steps = cols.split()
new_col = np.roll(grid[:, int(x) : int(x) + 1], int(steps), axis=0)
grid[:, int(x) : int(x) + 1] = new_col
def rotate_row(instruction: str, grid: npt.NDArray[int]) -> npt.NDArray[int]:
_, rows = instruction.split("=")
y, _, steps = rows.split()
new_row = np.roll(grid[int(y) : int(y) + 1, :], int(steps), axis=1)
grid[int(y) : int(y) + 1, :] = new_row
# dimensions given by the problem
init_grid = np.zeros((6, 50), dtype=int)
def part_1() -> None:
for instruction in instructions:
if instruction.startswith("rect"):
rect(instruction, init_grid)
elif instruction.startswith("rotate row"):
rotate_row(instruction, init_grid)
elif instruction.startswith("rotate column"):
rotate_column(instruction, init_grid)
lit = np.sum(init_grid)
print(f"There should be {lit} pixels lit")
# --- Part Two ---
# You notice that the screen is only capable of displaying capital letters; in
# the font it uses, each letter is 5 pixels wide and 6 tall.
# After you swipe your card, what code is the screen trying to display?
def display(grid: npt.NDArray[int]) -> None:
print(
"\n".join("".join("X" if one else " " for one in row) for row in grid)
)
def part_2() -> None:
print("The code is the following:\n")
display(init_grid)
if __name__ == "__main__":
part_1()
part_2()

173
src/Year_2016/files/P8.txt Normal file
View File

@ -0,0 +1,173 @@
rect 1x1
rotate row y=0 by 20
rect 1x1
rotate row y=0 by 2
rect 1x1
rotate row y=0 by 3
rect 2x1
rotate row y=0 by 2
rect 1x1
rotate row y=0 by 3
rect 2x1
rotate row y=0 by 2
rect 1x1
rotate row y=0 by 4
rect 2x1
rotate row y=0 by 2
rect 1x1
rotate row y=0 by 2
rect 1x1
rotate row y=0 by 2
rect 1x1
rotate row y=0 by 3
rect 2x1
rotate row y=0 by 2
rect 1x1
rotate row y=0 by 5
rect 1x1
rotate row y=0 by 2
rect 1x1
rotate row y=0 by 6
rect 5x1
rotate row y=0 by 2
rect 1x3
rotate row y=2 by 8
rotate row y=0 by 8
rotate column x=0 by 1
rect 7x1
rotate row y=2 by 24
rotate row y=0 by 20
rotate column x=5 by 1
rotate column x=4 by 2
rotate column x=2 by 2
rotate column x=0 by 1
rect 7x1
rotate column x=34 by 2
rotate column x=22 by 1
rotate column x=15 by 1
rotate row y=2 by 18
rotate row y=0 by 12
rotate column x=8 by 2
rotate column x=7 by 1
rotate column x=5 by 2
rotate column x=2 by 1
rotate column x=0 by 1
rect 9x1
rotate row y=3 by 28
rotate row y=1 by 28
rotate row y=0 by 20
rotate column x=18 by 1
rotate column x=15 by 1
rotate column x=14 by 1
rotate column x=13 by 1
rotate column x=12 by 2
rotate column x=10 by 3
rotate column x=8 by 1
rotate column x=7 by 2
rotate column x=6 by 1
rotate column x=5 by 1
rotate column x=3 by 1
rotate column x=2 by 2
rotate column x=0 by 1
rect 19x1
rotate column x=34 by 2
rotate column x=24 by 1
rotate column x=23 by 1
rotate column x=14 by 1
rotate column x=9 by 2
rotate column x=4 by 2
rotate row y=3 by 5
rotate row y=2 by 3
rotate row y=1 by 7
rotate row y=0 by 5
rotate column x=0 by 2
rect 3x2
rotate column x=16 by 2
rotate row y=3 by 27
rotate row y=2 by 5
rotate row y=0 by 20
rotate column x=8 by 2
rotate column x=7 by 1
rotate column x=5 by 1
rotate column x=3 by 3
rotate column x=2 by 1
rotate column x=1 by 2
rotate column x=0 by 1
rect 9x1
rotate row y=4 by 42
rotate row y=3 by 40
rotate row y=1 by 30
rotate row y=0 by 40
rotate column x=37 by 2
rotate column x=36 by 3
rotate column x=35 by 1
rotate column x=33 by 1
rotate column x=32 by 1
rotate column x=31 by 3
rotate column x=30 by 1
rotate column x=28 by 1
rotate column x=27 by 1
rotate column x=25 by 1
rotate column x=23 by 3
rotate column x=22 by 1
rotate column x=21 by 1
rotate column x=20 by 1
rotate column x=18 by 1
rotate column x=17 by 1
rotate column x=16 by 3
rotate column x=15 by 1
rotate column x=13 by 1
rotate column x=12 by 1
rotate column x=11 by 2
rotate column x=10 by 1
rotate column x=8 by 1
rotate column x=7 by 2
rotate column x=5 by 1
rotate column x=3 by 3
rotate column x=2 by 1
rotate column x=1 by 1
rotate column x=0 by 1
rect 39x1
rotate column x=44 by 2
rotate column x=42 by 2
rotate column x=35 by 5
rotate column x=34 by 2
rotate column x=32 by 2
rotate column x=29 by 2
rotate column x=25 by 5
rotate column x=24 by 2
rotate column x=19 by 2
rotate column x=15 by 4
rotate column x=14 by 2
rotate column x=12 by 3
rotate column x=9 by 2
rotate column x=5 by 5
rotate column x=4 by 2
rotate row y=5 by 5
rotate row y=4 by 38
rotate row y=3 by 10
rotate row y=2 by 46
rotate row y=1 by 10
rotate column x=48 by 4
rotate column x=47 by 3
rotate column x=46 by 3
rotate column x=45 by 1
rotate column x=43 by 1
rotate column x=37 by 5
rotate column x=36 by 5
rotate column x=35 by 4
rotate column x=33 by 1
rotate column x=32 by 5
rotate column x=31 by 5
rotate column x=28 by 5
rotate column x=27 by 5
rotate column x=26 by 3
rotate column x=25 by 4
rotate column x=23 by 1
rotate column x=17 by 5
rotate column x=16 by 5
rotate column x=13 by 1
rotate column x=12 by 5
rotate column x=11 by 5
rotate column x=3 by 1
rotate column x=0 by 1

View File

@ -88,5 +88,78 @@ def part_1() -> None:
print(f"The name of the bottom program is {root_program}")
# --- Part Two ---
# The programs explain the situation: they can't get down. Rather, they could
# get down, if they weren't expending all of their energy trying to keep the
# tower balanced. Apparently, one program has the wrong weight, and until it's
# fixed, they're stuck here.
# For any program holding a disc, each program standing on that disc forms a
# sub-tower. Each of those sub-towers are supposed to be the same weight, or
# the disc itself isn't balanced. The weight of a tower is the sum of the
# weights of the programs in that tower.
# In the example above, this means that for ugml's disc to be balanced, gyxo,
# ebii, and jptl must all have the same weight, and they do: 61.
# However, for tknk to be balanced, each of the programs standing on its disc
# and all programs above it must each match. This means that the following sums
# must all be the same:
# ugml + (gyxo + ebii + jptl) = 68 + (61 + 61 + 61) = 251
# padx + (pbga + havc + qoyq) = 45 + (66 + 66 + 66) = 243
# fwft + (ktlj + cntj + xhth) = 72 + (57 + 57 + 57) = 243
# As you can see, tknk's disc is unbalanced: ugml's stack is heavier than the
# other two. Even though the nodes above ugml are balanced, ugml itself is too
# heavy: it needs to be 8 units lighter for its stack to weigh 243 and keep the
# towers balanced. If this change were made, its weight would be 60.
# Given that exactly one program is the wrong weight, what would its weight
# need to be to balance the entire tower?
def child_values(node, node_map, node_values):
weights, unbalanced = [], []
children = node_map[node]
for child in children:
if child in node_map.keys():
child_weight, child_balance = child_values(
child, node_map, node_values
)
value = sum(child_weight) + node_values[child]
unbalanced.append(child_balance)
else:
value = node_values[child]
weights.append(value)
if len(set(weights)) != 1:
unbalanced.append((node_map[node], weights))
return weights, unbalanced
def part_2() -> None:
node_map, node_values = {}, {}
for line in towers:
if "->" in line:
lhs, rhs = line.split(" -> ")
parent, value = lhs.split()
node_values[parent] = int(value[1:-1])
_childs = rhs.split(", ")
node_map[parent] = [child for child in _childs]
else:
child, value = line.split()
node_values[child] = int(value[1:-1])
_, unbalance = child_values("rqwgj", node_map, node_values)
heavier_child_idx = unbalance[0][0][5][1].index(max(unbalance[0][0][5][1]))
heavier_child = unbalance[0][0][5][0][heavier_child_idx]
unbalanced_child = node_values[heavier_child]
print(f"To balance the tower, the weight must be {unbalanced_child - 8}")
if __name__ == "__main__":
part_1()
part_2()

117
src/Year_2021/P7.py Normal file
View File

@ -0,0 +1,117 @@
# --- Day 7: The Treachery of Whales ---
# A giant whale has decided your submarine is its next meal, and it's much
# faster than you are. There's nowhere to run!
# Suddenly, a swarm of crabs (each in its own tiny submarine - it's too deep
# for them otherwise) zooms in to rescue you! They seem to be preparing to
# blast a hole in the ocean floor; sensors indicate a massive underground cave
# system just beyond where they're aiming!
# The crab submarines all need to be aligned before they'll have enough power
# to blast a large enough hole for your submarine to get through. However, it
# doesn't look like they'll be aligned before the whale catches you! Maybe you
# can help?
# There's one major catch - crab submarines can only move horizontally.
# You quickly make a list of the horizontal position of each crab (your puzzle
# input). Crab submarines have limited fuel, so you need to find a way to make
# all of their horizontal positions match while requiring them to spend as
# little fuel as possible.
# For example, consider the following horizontal positions:
# 16,1,2,0,4,2,7,1,2,14
# This means there's a crab with horizontal position 16, a crab with horizontal
# position 1, and so on.
# Each change of 1 step in horizontal position of a single crab costs 1 fuel.
# You could choose any horizontal position to align them all on, but the one
# that costs the least fuel is horizontal position 2:
# Move from 16 to 2: 14 fuel
# Move from 1 to 2: 1 fuel
# Move from 2 to 2: 0 fuel
# Move from 0 to 2: 2 fuel
# Move from 4 to 2: 2 fuel
# Move from 2 to 2: 0 fuel
# Move from 7 to 2: 5 fuel
# Move from 1 to 2: 1 fuel
# Move from 2 to 2: 0 fuel
# Move from 14 to 2: 12 fuel
# This costs a total of 37 fuel. This is the cheapest possible outcome; more
# expensive outcomes include aligning at position 1 (41 fuel), position 3 (39
# fuel), or position 10 (71 fuel).
# Determine the horizontal position that the crabs can align to using the least
# fuel possible. How much fuel must they spend to align to that position?
with open("files/P7.txt") as f:
positions = [int(num) for num in f.read().strip().split(",")]
def part_1() -> None:
fuel = []
for pos in positions:
sum = 0
for elem in positions:
sum += abs(elem - pos)
fuel.append(sum)
print(f"It is needed {min(fuel)} units of fuel")
# --- Part Two ---
# The crabs don't seem interested in your proposed solution. Perhaps you
# misunderstand crab engineering?
# As it turns out, crab submarine engines don't burn fuel at a constant rate.
# Instead, each change of 1 step in horizontal position costs 1 more unit of
# fuel than the last: the first step costs 1, the second step costs 2, the
# third step costs 3, and so on.
# As each crab moves, moving further becomes more expensive. This changes the
# best horizontal position to align them all on; in the example above, this
# becomes 5:
# Move from 16 to 5: 66 fuel
# Move from 1 to 5: 10 fuel
# Move from 2 to 5: 6 fuel
# Move from 0 to 5: 15 fuel
# Move from 4 to 5: 1 fuel
# Move from 2 to 5: 6 fuel
# Move from 7 to 5: 3 fuel
# Move from 1 to 5: 10 fuel
# Move from 2 to 5: 6 fuel
# Move from 14 to 5: 45 fuel
# This costs a total of 168 fuel. This is the new cheapest possible outcome;
# the old alignment position (2) now costs 206 fuel instead.
# Determine the horizontal position that the crabs can align to using the least
# fuel possible so they can make you an escape route! How much fuel must they
# spend to align to that position?
# TIL :D
def triangular_cost(steps: int) -> int:
return steps * (steps + 1) // 2
def part_2() -> None:
fuel = []
for pos in positions:
sum = 0
for elem in positions:
sum += triangular_cost(abs(elem - pos))
fuel.append(sum)
print(f"It is needed {min(fuel)} units of fuel")
if __name__ == "__main__":
part_1()
part_2()

View File

@ -0,0 +1 @@
1101,1,29,67,1102,0,1,65,1008,65,35,66,1005,66,28,1,67,65,20,4,0,1001,65,1,65,1106,0,8,99,35,67,101,99,105,32,110,39,101,115,116,32,112,97,115,32,117,110,101,32,105,110,116,99,111,100,101,32,112,114,111,103,114,97,109,10,20,1091,861,228,628,186,980,996,710,541,354,1611,69,1331,91,1220,447,523,38,1286,244,643,1069,566,70,155,1710,1266,120,302,72,232,387,1086,278,1122,605,1559,98,111,1816,795,543,1217,304,356,129,839,704,49,523,370,74,13,232,179,101,664,892,266,622,197,404,147,882,435,504,48,766,684,1362,136,830,1393,1259,925,68,879,251,43,1339,61,98,403,51,1008,197,659,195,1823,233,121,731,82,141,580,18,427,774,13,685,496,752,63,132,39,237,18,167,51,299,22,19,1442,305,1283,253,159,731,302,76,115,185,136,447,821,307,207,30,1427,251,589,0,1096,1240,261,442,757,5,172,847,858,382,425,79,402,166,1058,186,35,21,324,183,1293,95,410,321,12,155,88,409,40,428,1180,199,1444,487,148,57,1187,15,100,983,77,0,1667,359,513,659,339,142,968,994,787,0,443,183,133,538,4,332,1459,204,1156,710,1654,20,36,407,890,1265,1090,743,36,78,1033,781,608,476,103,1401,24,4,875,414,799,305,1047,842,72,497,362,270,73,12,9,0,21,11,51,1357,455,505,483,552,199,1108,214,238,686,1496,116,154,1403,35,272,738,1024,50,50,934,564,19,395,324,447,794,1326,14,407,1694,452,439,455,442,86,1515,588,809,224,112,156,21,1405,610,187,23,370,112,397,995,777,75,1281,32,60,284,388,916,555,200,675,20,320,32,398,104,113,447,113,351,396,322,36,1674,1708,232,1004,514,95,859,382,116,277,239,343,3,433,11,55,699,513,1465,319,44,306,224,615,482,695,421,300,321,283,579,323,102,275,17,723,632,713,277,801,222,130,189,1549,49,784,690,136,444,1315,259,1334,472,711,1109,276,70,315,838,35,328,766,1100,460,4,178,630,571,5,106,429,368,547,1210,840,162,166,10,403,880,287,44,1001,316,402,1054,174,7,1194,105,58,268,667,86,588,166,547,238,1586,77,112,244,107,63,873,1152,16,407,198,26,587,20,1449,775,653,1369,732,262,566,222,10,102,22,573,233,297,1238,789,291,93,206,1274,177,58,841,672,37,16,262,201,241,938,133,774,978,631,511,0,263,498,799,51,330,11,206,325,173,676,15,457,364,46,373,34,1475,530,672,295,55,4,297,274,1519,15,688,555,96,160,185,583,646,41,378,1572,67,219,572,143,16,286,65,788,886,243,883,1012,109,90,742,464,1099,388,1855,731,62,6,415,66,232,542,98,1123,11,414,1262,4,440,8,691,130,164,773,992,423,115,1807,1618,153,168,1213,719,291,316,311,110,24,608,0,127,131,142,196,232,75,248,412,275,1295,239,86,967,133,422,415,894,280,807,345,446,250,979,231,713,201,1009,208,444,43,1400,434,8,221,141,235,909,1018,340,0,178,1144,353,662,491,294,6,440,446,824,1392,379,269,1427,911,671,231,424,102,718,86,54,130,206,514,137,1075,1573,248,472,602,249,974,8,372,59,2,940,165,1132,327,1424,63,6,97,140,1302,439,1237,59,324,733,397,477,426,278,274,1636,745,41,269,257,51,173,503,88,1223,754,228,584,72,632,645,323,156,7,337,192,375,583,613,370,172,528,1282,360,208,17,208,802,22,67,290,242,458,809,6,1388,49,14,327,911,121,475,101,617,284,91,1,35,421,293,1419,602,143,142,168,657,472,219,345,411,115,387,5,494,383,348,85,1070,154,42,63,586,953,563,12,1263,788,762,222,351,730,42,643,877,522,775,698,564,604,155,191,430,5,386,787,120,470,433,564,955,411,1090,210,1096,933,109,70,279,287,736,390,1075,30,194,30,1318,473,727,100,584,1227,89,432,120,393,1080,185,500,847,117,319,54,160,32,114,700,12,36,681,53,1063,113,82,1625,1426,53,658,80,253,36,16,810,560,602,177,275,147,335,1237,1447,176,55,366,721,471,501,217,67,899,914,168,981,1177,898,1,9,704,602,787,1280,305,57,786,1696,211,63,55,351,14,151,932,757,810,1748,169,1018,125,849,234,102,823,300,127,6,849,1163,229,726,397,656,135,466,137,1247,811,807,366,209,1703,24,1219,45,161,353,274,572,397,899,646,32,137,439,1048,2,391,8,214,736,518,409,414,567,1262,155,102,178,1247,526,10,94,759,781,18,14,1518,68,295,905,478,1581,89,429,937,438,915,1110,659,615,1128,8,125,89,289,1084,905,254,1227,184,883,983,110,1,24,748,1408,828,1187,63,264,481,214