From ba70b92806fdc2ce7caedaa57c4d196b91bd2890 Mon Sep 17 00:00:00 2001 From: Akumatic Date: Thu, 8 Dec 2022 17:08:46 +0100 Subject: [PATCH] 2022 Day 08 --- 2022/08/README.md | 81 ++++++++++++++++++++++++++++++++++ 2022/08/code.py | 41 +++++++++++++++++ 2022/08/input.txt | 99 ++++++++++++++++++++++++++++++++++++++++++ 2022/08/solution.txt | 2 + 2022/08/test_code.py | 16 +++++++ 2022/08/test_input.txt | 5 +++ 2022/README.md | 2 +- 7 files changed, 245 insertions(+), 1 deletion(-) create mode 100644 2022/08/README.md create mode 100644 2022/08/code.py create mode 100644 2022/08/input.txt create mode 100644 2022/08/solution.txt create mode 100644 2022/08/test_code.py create mode 100644 2022/08/test_input.txt diff --git a/2022/08/README.md b/2022/08/README.md new file mode 100644 index 0000000..f87982d --- /dev/null +++ b/2022/08/README.md @@ -0,0 +1,81 @@ +# 2022 Day 08: Treetop Tree House +Copyright (c) Eric Wastl +#### [Direct Link](https://adventofcode.com/2022/day/8) + +## Part 1 + +The expedition comes across a peculiar patch of tall trees all planted carefully in a grid. The Elves explain that a previous expedition planted these trees as a reforestation effort. Now, they're curious if this would be a good location for a [tree house](https://en.wikipedia.org/wiki/Tree_house). + +First, determine whether there is enough tree cover here to keep a tree house **hidden**. To do this, you need to count the number of trees that are **visible from outside the grid** when looking directly along a row or column. + +The Elves have already launched a [quadcopter](https://en.wikipedia.org/wiki/Quadcopter) to generate a map with the height of each tree (your puzzle input). For example: + +``` +30373 +25512 +65332 +33549 +35390 +``` + +Each tree is represented as a single digit whose value is its height, where `0` is the shortest and `9` is the tallest. + +A tree is **visible** if all of the other trees between it and an edge of the grid are **shorter** than it. Only consider trees in the same row or column; that is, only look up, down, left, or right from any given tree. + +All of the trees around the edge of the grid are **visible** - since they are already on the edge, there are no trees to block the view. In this example, that only leaves the **interior nine trees** to consider: + +- The top-left `5` is **visible** from the left and top. (It isn't visible from the right or bottom since other trees of height `5` are in the way.) +- The top-middle `5` is **visible** from the top and right. +- The top-right `1` is not visible from any direction; for it to be visible, there would need to only be trees of height **0** between it and an edge. +- The left-middle `5` is **visible**, but only from the right. +- The center `3` is not visible from any direction; for it to be visible, there would need to be only trees of at most height `2` between it and an edge. +- The right-middle `3` is **visible** from the right. +- In the bottom row, the middle `5` is **visible**, but the `3` and `4` are not. + +With 16 trees visible on the edge and another 5 visible in the interior, a total of **`21`** trees are visible in this arrangement. + +Consider your map; **how many trees are visible from outside the grid?** + +## Part 2 + +Content with the amount of tree cover available, the Elves just need to know the best spot to build their tree house: they would like to be able to see a lot of **trees**. + +To measure the viewing distance from a given tree, look up, down, left, and right from that tree; stop if you reach an edge or at the first tree that is the same height or taller than the tree under consideration. (If a tree is right on the edge, at least one of its viewing distances will be zero.) + +The Elves don't care about distant trees taller than those found by the rules above; the proposed tree house has large [eaves](https://en.wikipedia.org/wiki/Eaves) to keep it dry, so they wouldn't be able to see higher than the tree house anyway. + +In the example above, consider the middle `5` in the second row: + +``` +30373 +25512 +65332 +33549 +35390 +``` + +- Looking up, its view is not blocked; it can see **`1`** tree (of height `3`). +- Looking left, its view is blocked immediately; it can see only **`1`** tree (of height `5`, right next to it). +- Looking right, its view is not blocked; it can see **`2`** trees. +- Looking down, its view is blocked eventually; it can see **`2`** trees (one of height `3`, then the tree of height `5` that blocks its view). + +A tree's **scenic score** is found by **multiplying together** its viewing distance in each of the four directions. For this tree, this is **`4`** (found by multiplying `1 * 1 * 2 * 2`). + +However, you can do even better: consider the tree of height `5` in the middle of the fourth row: + +``` +30373 +25512 +65332 +33549 +35390 +``` + +- Looking up, its view is blocked at **`2`** trees (by another tree with a height of `5`). +- Looking left, its view is not blocked; it can see **`2`** trees. +- Looking down, its view is also not blocked; it can see **`1`** tree. +- Looking right, its view is blocked at **`2`** trees (by a massive tree of height `9`). + +This tree's scenic score is **`8`** (`2 * 2 * 1 * 2`); this is the ideal spot for the tree house. + +Consider each tree on your map. **What is the highest scenic score possible for any tree?** diff --git a/2022/08/code.py b/2022/08/code.py new file mode 100644 index 0000000..fca13f0 --- /dev/null +++ b/2022/08/code.py @@ -0,0 +1,41 @@ +# SPDX-License-Identifier: MIT +# Copyright (c) 2022 Akumatic +# +# https://adventofcode.com/2022/day/8 + +def read_file(filename: str = "input.txt") -> list: + with open(f"{__file__.rstrip('code.py')}{filename}", "r") as f: + lines = [[int(x) for x in line.strip()] for line in f.readlines()] + return lines + +def calculate_scenic_score(field: list, i: int, j: int) -> int: + dirs = {"u": (0, -1), "d": (0, 1), "l": (1, 0), "r": (-1, 0)} + count = {"u": 0, "d": 0, "l": 0, "r": 0} + for dir, val in dirs.items(): + x, y = i, j + while x + val[0] >= 0 and x + val[0] < len(field[0]) and \ + y + val[1] >= 0 and y + val[1] < len(field): + x += val[0] + y += val[1] + count[dir] += 1 + if field[y][x] >= field[j][i]: + break + return count["u"] * count["d"] * count["l"] * count["r"] + +def part1(vals: list) -> int: + return sum([any(( + not any(vals[j][x] >= vals[j][i] for x in range(0, i)), # left + not any(vals[j][x] >= vals[j][i] for x in range(i+1, len(vals[0]))), # right + not any(vals[y][i] >= vals[j][i] for y in range(0, j)), # down + not any(vals[y][i] >= vals[j][i] for y in range(j+1, len(vals))) # up + )) for j in range(len(vals)) for i in range(len(vals[0]))]) + +def part2(vals: list) -> int: + scenic_scores = [calculate_scenic_score(vals, i, j) for + j in range(len(vals)) for i in range(len(vals[0]))] + return max(scenic_scores) + +if __name__ == "__main__": + vals = read_file() + print(f"Part 1: {part1(vals)}") + print(f"Part 2: {part2(vals)}") diff --git a/2022/08/input.txt b/2022/08/input.txt new file mode 100644 index 0000000..62b77b6 --- /dev/null +++ b/2022/08/input.txt @@ -0,0 +1,99 @@ +323312120104041101003001553044055322145351354433645660555433454202452204412052502421011342410230100 +331223314040220223001130433220004441042006330461143461335633613314213000015223153233240331142300012 +023102231103100342321215533524330225130560305625124623310126454152020030305335002210044012323422232 +033211114433402023241334421151326235424122515414424161565116453111213321055111200550233444040333323 +031320412113341012010242000135046256344463444305066152423440545620430235453525520134521220144043130 +010124340443212543345333321333301441655163125534010352005641320662142112543221425142532404413320002 +032312034332435412243231103121245340611134410006433546515216241603224333504015201503140034044432021 +320200344413202332231554246602660034061050643672316237416266543042042653101335352044243134331323303 +021300102204043340554035441662023251216477627653211774256145300615432406261511620233045011441203023 +214221412130421304035463335360514215534123522725272245137776312134526215216203521523534253001441422 +420043232030231215456256414206036653347362132153333156552344113453564204615313111314105214221003223 +241014245200324505163302204145552154121123441333614641654374366443635062610615660400505253511330311 +231411122124035056146223662646715423323763562152711313214722174623631122416546336265504022423420321 +042134415425335411142551632217112111473327114471514114442336163742155647750445640460531524541203340 +343034551205503142350464162224754743123535251535665351452621461253234473323031250306005520215303040 +410130220425226615062361272722422212213362652886842457443563446376627357725562240530656421332425231 +330405053401450540006525751276462213552438775622853762648444675762737115273314256401440500101434302 +304122334204441123350414175256673644342865574663385723585576354377456151273122601662220161301504112 +422435205014554545365735723436373233832475876524575872268832223848512552555643351604546205341424215 +443115513525431203264315523331217625862645482563537776356753567584283413472356644126410362312334123 +052022430460332345152212254167524466648262435238422282347263726486242532216231573303203326333131543 +404311335435645624675123354136583324744857778885726358668585255832473858653735421124234313332210004 +520111321123045340623442334624735877337545859497694367639273762375345722536177411211020042150153021 +411235141221544066661746224736774624232459373766373495575944484527562783724767432624400142054055522 +024120413051264413175435475422366266524638499844474853789334849464538454233333357361304324422613501 +352214454643240574661363763475756533743797783848433976887696359992333666675226733442545524354500443 +251345503313114376116272866687526585434388584575674356595674465655476743763543124147356110122024044 +133110654322616733231668722725373876835778466784566584387395434396884778345524117356166460636143351 +112230445513242554663324764556586867753674864468343933678664667973977485428425757277634522562064320 +412306136011573262177765432437358738546736839846997485567376574548587838746648241232635661362635551 +311241644325164361477854453554348537943884446578656447795556786443464445568375622146223253430106005 +414462311300441254474772486749467753538794788465984797676648668849664495546568855562445764261642010 +445133603633532623526886852476968663955448979964894644847777557664794864337536578317645124263315442 +021241645421162453132262365348765439348656776856595854754476769757566455663276324366766456305305120 +510244461256441623866724589378887569656684895495456487696769566643875787347426424523647565754401653 +151145124011265333234662229795656686884674575478956878676685556556946338775266677877143733665060552 +131002165277346618257378696764537399445797598957895796889759879556485735764887363865111323236124503 +220611453676274277858565456484455695655979579759955677959885995645474566676772536632553114354340041 +323335253242622148532422868466345564965967686989886957689558546964794339796466254345247754360223316 +112064463545413576425378697983496684567756967695578787779885776765545968768637752578574116433630421 +262635257577314368832689586734395956986977797785985896558768958559955796869794344738811241365425065 +036254031317172762245555787683749657559987756669998856989597798769664563473786885472827134423313506 +112502266652465672888368949558445769459577569797855698786769989985987785676547473444272672141252544 +045215646223371643352336896643689688876655959565996855669678688486694743366369623465327522575042356 +205562422736764236882339845435688999868789977579698799868877976745688897678798344673376264654052604 +640616321667131656568746868646446794765955968978766798777975879944949447436547952777356562624565361 +503133645662433253222235564587874595496598558678699667976697595767948945736786373476844144136233155 +152313252157252347426379766989467986779887556669696688689579876876596876558577966523563177643114061 +015365066657673648536298976339575598578756896788969879767577686654749477584746873347542574227516230 +302516211647152355274343639744655874775669596897686966699876695998787469759645835454545677723745465 +266163561235542776842433383799598975897978899879789767676699785678664666798579564534878747126146153 +634140631567256667662664934564476759588897588797699869877796899585469988739654868456635123523755234 +526164653667775855733559449364494974596968858678799696797985695999575786597999333727844531513343544 +115403464653622458323374663594975966866888697766687979997898875955786785736875844627521437353606304 +640206337252276334632475883969765797699957959997976897898769896775474877959677374487863614742211222 +106034313777637748437776995547694868569869859888896977797665956948986945796495667868436477373160314 +006143515575426735835789383997647997666658866898869877859765667898455643998988843284334411112325061 +060213154573543438565356383379984957565858775655687688855799695465677553374667278462773177353503021 +534112106512613276556555984466559658455977888698665968969989598677796459965554455385335454425613431 +423425206422713575644746337955366575454795967856856876586957554899648773967935667584344176377532425 +315510242114177262757639877363694484999758689789879599886867745964475568777854454352517415741562052 +254415451471443426858387939443978767549948877565555768796577696468685835375388876547331566530141542 +303202343156475546746672434475949695576445897955568899665665785796494455593633835634447131551412543 +530640543251355257253244866999758855497944665987986659888747567449665534577874222676576617430555625 +035226003425623774544664764845838347558577759648579987787884744479479884357976856228167235705641542 +012530303425724762454645575734538738897469478966696978758788679866348589899832555641531652553533310 +431520564223363131574588328444453968694548987546469759466967869587993958848677622834372746605252324 +131024531432663176288887647869436593765656667475894545486664448575468585944778464554223653360402652 +551654340156114412778738226397776454595784788647965555996665676344574743382638772356734133042615443 +024355434261535345548273336774384984477576879774784456784868644637765744738364526332565760044560540 +155113230232747546753685543766476666768567676894864479768956459393759573342483687447324136430444500 +440336611600246742643243587242836576774688377798976584555359856436455842274266466561462502505050311 +015501455202457152271777448623885744575738975738543495886575536689489232583347854551274740450542500 +112355455505514326761438726267648488556885859557845836789874856463364248667756746144136240330222401 +430051415453434173737573386277526293849897978657467838347963744587834677342423717341756610043455255 +444113312134554163124414283335326283887438687965973966654788943867635532444353372724432652622302125 +033012131053460465125111273742768667769675675775436398594585954535426388764627242656605623003420535 +532011006562506121567537614332848223752545648784336666978759658235586323586276363263554554402535155 +225043145666651226342224774572478338454285536637433467599546254373462838314454715765242604264433432 +143342003654424145134151113142525853753886774346442435733753462268623254516141462445566062114320251 +444420540521256141013447675222256426635324487526632736745527642885674235536747737261652463202500555 +222431405032506222504344543644653776575736336844778763733528588764848657567376356150063166013552501 +034510422056636225624747266514456777633233775555386632488454864657717533631241666065420200205052500 +103105455224503224304034177327635111647827276665752827282575886784253656562365122244424151025515301 +101102203425121661104345642122736177478284778325375873527465777421741567742166564045604510141154121 +332242401534421133554041122533563354755216642533436868343877635122146146667706230365422105012153402 +432103353112023141120633555353651647171735573773567775173731563436215115735654456154234331555345240 +311201403135204156305310465662641267265251523134647455137635637621766373241145212506405302221022004 +221411412415305356354132634130374733663416232631657355257255546777623360525504041204002524135430312 +112411441314100543355310054325527735473745551311261276366344472654631261140112663455454513102400244 +013012011123153452314613460031161542746223115713547637621711265172533165260520404042554414322034013 +201330012335124150152314410164151235026663366233372131265564532262110563062500635222224450514021440 +342111222034352424040354160440340405301651622677574134133735403132430514114033551354315433040230114 +112010023301100445223113160555302602635620463156162543530556141321431263425255250524151354433130344 +332330330010343221124140132242255256316545654313060323031636355342510224333220335454325432312040232 +231131200414441021404115411126030522302652306460121060224031660650605423613101532204404042041104211 +110213044340333244505210244013344303254465010502545450101621054023246053340412123410522324133332123 +001010311033004234122205300341243461144265623424563511436115050502162552302441545001031211431213203 +110302001002203213045154432555553533654213115630566633251401333456110344545402251530041323224011221 diff --git a/2022/08/solution.txt b/2022/08/solution.txt new file mode 100644 index 0000000..91f500f --- /dev/null +++ b/2022/08/solution.txt @@ -0,0 +1,2 @@ +Part 1: 1695 +Part 2: 287040 diff --git a/2022/08/test_code.py b/2022/08/test_code.py new file mode 100644 index 0000000..1a5e199 --- /dev/null +++ b/2022/08/test_code.py @@ -0,0 +1,16 @@ +# SPDX-License-Identifier: MIT +# Copyright (c) 2022 Akumatic + +from code import read_file, part1, part2, calculate_scenic_score + +def test(): + vals = read_file("test_input.txt") + assert part1(vals) == 21 + print("Passed Part 1") + assert calculate_scenic_score(vals, 2, 1) == 4 + assert calculate_scenic_score(vals, 2, 3) == 8 + assert part2(vals) == 8 + print("Passed Part 2") + +if __name__ == "__main__": + test() diff --git a/2022/08/test_input.txt b/2022/08/test_input.txt new file mode 100644 index 0000000..16d6fbd --- /dev/null +++ b/2022/08/test_input.txt @@ -0,0 +1,5 @@ +30373 +25512 +65332 +33549 +35390 diff --git a/2022/README.md b/2022/README.md index c766e2e..55bf44d 100644 --- a/2022/README.md +++ b/2022/README.md @@ -22,7 +22,7 @@ Collect stars by solving puzzles. Two puzzles will be made available on each day | 05 | :white_check_mark: | :white_check_mark: | [Solution](05/code.py) | [Day 05](https://adventofcode.com/2022/day/5) | | 06 | :white_check_mark: | :white_check_mark: | [Solution](06/code.py) | [Day 06](https://adventofcode.com/2022/day/6) | | 07 | :white_check_mark: | :white_check_mark: | [Solution](07/code.py) | [Day 07](https://adventofcode.com/2022/day/7) | -| 08 | | | | [Day 08](https://adventofcode.com/2022/day/8) | +| 08 | :white_check_mark: | :white_check_mark: | [Solution](08/code.py) | [Day 08](https://adventofcode.com/2022/day/8) | | 09 | | | | [Day 09](https://adventofcode.com/2022/day/9) | | 10 | | | | [Day 10](https://adventofcode.com/2022/day/10) | | 11 | | | | [Day 11](https://adventofcode.com/2022/day/11) |