Powered by AppSignal & Oban Pro
Would you like to see your link here? Contact us

Day 8

2022/day08.livemd

Day 8

Mix.install([
  {:nx, "~> 0.2"}
])

input = """
012210012213303320303222443113334342210313303454311331225110130030424212142031302213330002110012202
102111010213210021001022332202430004242253521151233435512412354104014404443413310323011012023201021
222111003103212333013134434140410034543551441115323331241513231234431132024442112441221030323222201
211012231012012302200321204210044513144154225545213542132254151144432412133213041300331330203232021
002201312313222001411332000110432522431232314331333333341453144254551331133403204411302212311202222
110230032313312322243243202152533544354355433511352253222235253151343332220121001410340302222303310
101313222321043104033302002124412142331115412425545541414142413325115451211012344223412413001132312
000110031333220133042312354442315421411124331555452354542212112435551414455113414040333101101113323
231131102314203003210255344412121351334525335562222234363342225331324441223135530430044214323110010
001302013334343042232523555451355144155463632254526622543325633542143241412224323141041332210112123
232133223421212244014135242143544562436253323552332245442342453545311122352325114433041240033123210
313311013443004432534112223421323522535632525344622566243626643556352132422325121121143043201001112
312131000031042414412233131132546464466645663456625633662464326243345423442331115145421104131132032
011313124102221132213332554444454462552663453222636663423523253543344325351111113251500031040140333
131210242234103445444313116435342654435436424324537553522235434226423435624312521322541433210110300
202104212221122341315153563325425645423454444673474357636565332462233326223625251414331404301010320
010242333200311221125541336654235564266376534545434743476476346546644556545321145252442104103430030
123333033333445552541136546354365266546335747553764544376335347754554432326234113551545230341122122
111132120023444352452333426232535276677646555634363636373466436473655322366362634415114243210313120
213200032234314354122644243422227457747776356365644735433734455435673526323365322422555531242442231
221422333211235525365463423444744353746765464667353567655366755663537575264345266534345331230013324
033412323511535124544563324333377354535477745733737354753353536336573757542436456241122223533000033
240304415122421153355563542457436543756544576457865577876334567346736766732362524435122433213011404
011211402432221454523535324337776747776587685748855567444784577637555433533536663633143332154204440
423240022155524264343553343746666763475576845467864765764587587677754336346645643264512245534444134
133414333521342436652322666463456436668687785675678858768577664863663755734764364264263525114242130
241402355253143246562535745533633575558656588765647785777458888544764747566733233663264213451332133
032333551141315355366435333675567764455765648777745586456574555878456477447543422633334525124452220
443022215443326244322465745545476885648844464676774464664455545448774664554746334262332344111154340
103305251343224345526445765577667564485778867678558957997488484647887746765364343543254345242322403
110043441441443262567747674335676674655844587575577866678585648565746476554643474632233355434343442
001044325213325543343734347538774478875456578998996977586879764484468567537574434323663562331543123
120512432215425546364374473575488687466956956666987685597778996654684857735443354726463462445443221
304354134424524455546463367846758455678898977855779898575555556744756468487535777333454423344155320
011353212543542246543767576745688674595889976679665955986577659697778465787765757745642666242411421
035113413122424246634347354647557557975958889798985567857985768857456555686446556733245245522225141
025153324533365623646535757766476555597869768568779896597576865777744747767565353456342433231341352
245544523544266655766436477887688957595955898689898679788685578679586544487665667573264356465251422
033224433342434445465635878464545765577688878699896876696866556657877488746575367477436555241525221
315141122265642667755375685566447659789976989866988676997796565888696746776856433447532225622243351
313314116365233565753337575488658556986998877797986698778699959978579967888578576464625434636312451
342233333566233676563337864766686879797978677887676977798777685969895746856458447377363344325335322
433545132565326757334568475578655585957666879898967679868767677796556574467858566457346366663411141
345324234446263476454766668858898589558667968778997799996866696899667576476558435735432563663332541
312141353442544546634587484687667669699899878889978787889876998656977896854586536533433532334434521
421311244624332566556345756478555565896968687987998898897896789888878556656685833563774626536531144
424222425365265773564457865886659885699879998988998977988768896877988655576765765543662442622645454
432441323556523363464657758447767865968787678879787879987776788699979988576754636367543325444245154
123431445555544436575556444769685767679998687877788778778699966787557865544844456347473666445531523
141345455355664436455478476746966898888798889777798788779789687967978579448686864357535554235412445
323432535325536337645674444657767665788796688977779898787967796687756757884544657334343235564253135
155524266324543757346355847785966878888776777978777987878796699896976678584466874354476526234422452
155113453542247554674774656588686895698799999777899778989667779786879589567555663644655633426355342
324425534552525433775686547887987786666869898797879878889696899998758576477476534547756426363325444
321245142432525757435666584569856585696966989787878898787996668696878978556846654476363565345314512
551524523654624757363567765568975585589787796978979978979997896658879895544684833663556646642244334
121522443453235435577465888546759769679867986687898889898888767655597875445686737473743335645125321
121254456654356775475757547554586695776987777877778968976799989889677576677677735543432463624412141
315112344343554673333478574475899696969998666688769896776687668777587976748675566476662646226255121
142143445624462657343477675856758699868889977987787669966779887697978885555757655565454666224515442
034232413435464564355434766688567675659569867678867868676997786787778547566444576466755623434334145
433254133644634345673646688868756577699669767979788997869877596596987546756753555754764434362342411
453523241444264455356636664578767556898896696688768979977777589765586745558477344365434245223422542
304125245622252556736355686646455975868699869688668889667567866589668657854465753477263355354251125
315141233336436425435755686655767876557668658998888666696755856675677857887673573353344234225143433
142221555135333525544776565678587568765575558585885689897988658868554567576457556656446554342142345
333452515435533552356647768446787845656899758895665976775555697958546647854356456633363323254151222
344245154226666464373466666578555765476887885977776666688699968664547644473634646542623643535115324
130453141334524632544577733564585445458765598559958679677696776586546565466375534666363444155352423
314034311325644552263675467548788477478856977777856788986979555884685548374573646344225224423324132
443124113334245635225654646536458844757458967685869655766894684858667443665437436355654533244451213
430315431125424333554676647365587855567445477856899969876656878874645737765557644664332641251544403
033245124123256643265256444735354488454467664748584488686587888568885663446653443333463441421414031
300130145452213655555257655737563646464886564457844477657565585655577536556477254533465521135322212
132304552221234236346364447477743567848464675477685485775886475546547347666444653565236445512251302
340330314521213336632436566555374753447674844446876454847778554547574764673664462654645421434502242
121444124232153243633223444767675443456644476845644566474556785655455333376232435445343555555542313
221204445334324345463325435743666444676755675586554587775467764447455474446443635342153521532230041
433432023331552513536424443244457766436735446475464586555575535644474366735363432542511535543010003
032241200312124213245452452226334647455667737756675446663633477356455457565644225632353414424130114
102444132053311412163535553534753534634333436357663565766355454776665764245533435413243435224144400
024123302224552155342666566235246336465665655666634457367677744553657456352665552433135424243312002
311331142321221224355246526246556473357543473764353576633343356777344254622222661224121212043301012
132122023023323354543344245635322326747445745474546537574647374552524662663466433354424314142403130
302243323343222423342154264623354324646435745333535475464637363442623452625542351441533110034202410
203314222113402413153513335344264452432253443554553346753553534333333246526254423311554442233333000
020103121204342211435131256362565655363223625653355544326352524342323465526244435311124113342120211
002232322230123333221533522425264655455245535436562466322543256236236263653224321242232412211143200
233112334413432221231114241151223525225546246465652364424433435443662663345545125433230103320432100
313000003424020140324343523153152644355645263562425566545355355552245413452314553421142141243211223
203313011330042021445221111514415562552545335255436326646353424363451524225252123000432200020010200
201300220330103443020432122551342512422456442236525255564524654622552433313111211310124043400310001
033312220120311243202222252313125514414236234532624552562342253352425325255353141232242222111211032
203011221000301201412231422352342451452113435145535446312151551345524532555513001023014311113123022
121021113230041341014134031242325532325435534252442123134323445313341451214204043304321002112120120
002031331230112330122421141451253231511332232321234152123254342154421311343320113140341230300030301
001123300300201101244344424301215351355125424322331125121255541444431130023330000344430012000003021
212022123023002021024004011330024441114255452255343132452423554322214043030000330401030022311221212
110120102133312201323320402242014144252524113245144224553241354421310224142233233422001111212321010
"""

Part 1

forest =
  input
  |> String.split("\n", trim: true)
  |> Enum.map(fn line ->
    line
    |> String.split("", trim: true)
    |> Enum.map(&String.to_integer/1)
  end)
  |> Nx.tensor()

{l, h} = Nx.shape(forest)

{_, count} =
  for x <- 0..(l - 1), y <- 0..(h - 1), reduce: {forest, 0} do
    {forest, count} ->
      curr_tree = forest[x][y]

      visible? =
        x == 0 or x == l - 1 or y == 0 or y == h - 1 or
          Enum.all?(0..(x - 1), fn x_val -> curr_tree > forest[x_val][y] end) or
          Enum.all?((x + 1)..(l - 1), fn x_val -> curr_tree > forest[x_val][y] end) or
          Enum.all?(0..(y - 1), fn y_val -> curr_tree > forest[x][y_val] end) or
          Enum.all?((y + 1)..(h - 1), fn y_val -> curr_tree > forest[x][y_val] end)

      count = if visible?, do: count + 1, else: count
      {forest, count}
  end

count

Part 2

{_, view_scores} =
  for x <- 0..(l - 1), y <- 0..(h - 1), reduce: {forest, Nx.iota({99, 99})} do
    {forest, view_scores} ->
      curr_tree = forest[x][y]

      left =
        Enum.reduce_while((x - 1)..0//-1, 0, fn x_val, l_count ->
          if forest[x_val][y] < curr_tree do
            {:cont, l_count + 1}
          else
            {:halt, l_count + 1}
          end
        end)

      right =
        Enum.reduce_while((x + 1)..(l - 1)//1, 0, fn x_val, r_count ->
          if forest[x_val][y] < curr_tree do
            {:cont, r_count + 1}
          else
            {:halt, r_count + 1}
          end
        end)

      up =
        Enum.reduce_while((y - 1)..0//-1, 0, fn y_val, u_count ->
          if forest[x][y_val] < curr_tree do
            {:cont, u_count + 1}
          else
            {:halt, u_count + 1}
          end
        end)

      down =
        Enum.reduce_while((y + 1)..(h - 1)//1, 0, fn y_val, d_count ->
          if forest[x][y_val] < curr_tree do
            {:cont, d_count + 1}
          else
            {:halt, d_count + 1}
          end
        end)

      view_score = left * right * up * down

      view_scores = Nx.indexed_put(view_scores, Nx.tensor([[x, y]]), Nx.tensor([view_score]))
      {forest, view_scores}
  end

view_scores
|> Nx.to_flat_list()
|> Enum.max()