From ea53dbc3acd55ac66cb13af05d5e5c966081dfe3 Mon Sep 17 00:00:00 2001 From: Luc Rubio Date: Mon, 9 Dec 2024 21:37:37 +0100 Subject: [PATCH] AoC 2024 day 9 part 1 --- aoc2024/src/day09/__init__.py | 0 aoc2024/src/day09/python/__init__.py | 0 aoc2024/src/day09/python/solution.py | 70 ++++++++++++++++++++++ aoc2024/test/day09/__init__.py | 0 aoc2024/test/day09/python/__init__.py | 0 aoc2024/test/day09/python/input.txt | 1 + aoc2024/test/day09/python/test_solution.py | 35 +++++++++++ 7 files changed, 106 insertions(+) create mode 100644 aoc2024/src/day09/__init__.py create mode 100644 aoc2024/src/day09/python/__init__.py create mode 100644 aoc2024/src/day09/python/solution.py create mode 100644 aoc2024/test/day09/__init__.py create mode 100644 aoc2024/test/day09/python/__init__.py create mode 100644 aoc2024/test/day09/python/input.txt create mode 100644 aoc2024/test/day09/python/test_solution.py diff --git a/aoc2024/src/day09/__init__.py b/aoc2024/src/day09/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/aoc2024/src/day09/python/__init__.py b/aoc2024/src/day09/python/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/aoc2024/src/day09/python/solution.py b/aoc2024/src/day09/python/solution.py new file mode 100644 index 0000000..22e8408 --- /dev/null +++ b/aoc2024/src/day09/python/solution.py @@ -0,0 +1,70 @@ +# Copyright 2024 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +from typing import Sequence + +_EMPTY_SPACE = '.' + + +def _generate_disk(disk_map: str) -> list[str]: + """Generates actual disk from a disk map. + A disk map alternates between blocks of files and empty space.""" + disk = [] + file_id = 0 + is_file = True + for digit in disk_map: + for i in range(int(digit)): + # Disk layout alternates between files and free space. + value = str(file_id) if is_file else _EMPTY_SPACE + disk.append(value) + if is_file: + file_id += 1 + is_file = not is_file + return disk + + +def _shift_files(disk: list[str]) -> list[str]: + """ + Shift files in a disk starting from the rightmost file to the leftmost empty space. + """ + i = len(disk) - 1 + first_empty = disk.index(_EMPTY_SPACE) + while first_empty < i: + if disk[i] != _EMPTY_SPACE: + # Swap rightmost file and leftmost empty space. + disk[first_empty] = disk[i] + disk[i] = _EMPTY_SPACE + first_empty = disk.index(_EMPTY_SPACE) + i -= 1 + return disk + + +def _checksum(disk: list[str]) -> int: + """Calculates disk checksum as the sum of each position multiplied by its file ID. + Example: checksum(['0','2','2','1','.']) = 0*0 + 1*2 + 2*2 + 3*1 = 9. + + Time complexity: O(n) + Space complexity: O(1) + """ + check_sum = 0 + for index, value in enumerate(disk): + if value == _EMPTY_SPACE: + # Disk is organized so there should not be more files to sum. + return check_sum + check_sum += index * int(value) + return check_sum + + +def checksum(disk_map: str) -> int: + """Calculates the disk checksum given a disk map.""" + return _checksum(_shift_files(_generate_disk(disk_map))) diff --git a/aoc2024/test/day09/__init__.py b/aoc2024/test/day09/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/aoc2024/test/day09/python/__init__.py b/aoc2024/test/day09/python/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/aoc2024/test/day09/python/input.txt b/aoc2024/test/day09/python/input.txt new file mode 100644 index 0000000..8beda73 --- /dev/null +++ b/aoc2024/test/day09/python/input.txt @@ -0,0 +1 @@ +6622774926702567136274121691173983817579825713877722862664878496717554229415989741866544951866797768927645626425928376831961652538912573819520456961332784837114847896582553155167127048213862892166519176836541944049522192105720907435255547169280774197159518657784958641754881409029177352731592571628175564846486629636828363882572277123293449233798304459227930467053736431636065727651181788911772922153975817411193902344466924941561955686133597207650581098161899389645152543264237253658176696534176638026734445286221735922236210762999805069475547437760815525512761386270585676695531643025579033995670361219334692204277879744587185253769147965704615609069277537711136587011753461323229327374186063125189473967103781322886647261986456293981264068454474864619902097826014578169816037613698327511274044695611125232924122624356537091919818906571366078676811587246132164129426137383521117156282565852454055545531308067784639432127214929109017213070308317747735908517145193373534936774823625245347738325796547283485283060283737339078815219198118762571852535481045593432141190398990724377959630943538249920854295337085591698555166553317231761457839171956775121967718733393325127822350196131762488873489915275997345316828565961235825665040848563458397917575909724752993754537679770797328234786731920593230396096757275621097472835754475891383175372899152326465902058527878848799607494463257133313268362864252138745303252546673984711491528561825557223266270449377393396816964768947224980583132125842149494633192739113433619672712483713547070369831608831269714952265983083499128894413176341996788681925873496591764608168367071961375708780966740478282427411199428882157342060705335991246661524805972223965219619692025952959412462255248437042532419661981918999841375202729757219332810175961554756441850978316788974368258545837349019325753377593269243162735663242962237417093615854366039541352234168559427954094339688552018472352232924193525139189122989984545489111893690486998242750174076422849866757849891143025596726871344967952484226992548906767167693826340888146338536217415995353943682317136369893925742883975909235771565549695163344399634456595114593484173717611229098946253412924309651618541278323408737227288924472874317736229133371287515839414191715799894555158771224223570528511816997511845725235302825909016486820207566961869765788694933869349105260248237273338123611843054469137384884835773855898992122742424949874631797479148406312968473183353795521742710346112778130186287669659535759419734137981169725324226105624789526756721389456349349436049887720955720329769421896262928541131326559427522152653209719207989334377659227502030825089622418565734103114528587909247163256557248341037313888987597725596824280172683807264526090414997345099192672879668861257173615556941195729969534162242575222463889445556897141848751638750439263877729318493762892158740671974783096975081905142654153301613232775708425816111252075647474143556416766887814997990377293833323875843494926824912292376625081285083885143336935973076624015104586174134827395773613379055834493502220337783179718747375877525645084571738597615739129475985368111572022886179413363752162939536115199468438173322181030899039141330448311878557985133845439186530653484265247415320734947825591195766219373879071786955379073441915373255786583612698321827518547585039535151274845427689986175177917277261189943959654573970183771754064402072446851784289371964659866592611478619443657259517781473902334491267793566423565696094561610908458363316986474838783889924504273422239525869165264479532596246636572105850613130752112945627483727619335503918739812685334957850701837456810308331917996163490507148999480675465133139604430996829798155219148504347637430106258305384873547909832637746791927652833802293625220127585445824117540231659212381878934783955501658777131561387706379155072111362909755331629396347156784242013761074418899851147442769771955559982825115115990519610546670713129147396731760278161427240204796978597787139849351104348239626687616677273574325229226502741644647754646256347598040313092104234347475405222915974853224671677669581971139936730773894752331828392601040552019503077305334553441709816346942176889243479837716526344103923283069473617539521158118325463947780611456249657461239612111197673455728776156867093111386298142955394145937689592871052695531194372337136476369243144106794612911219784937483904396958641745251341955666676467294731693678628167152716348301661949597566155835889933591886053229976905491217347895981852151307910438194577539142069798675488665979137736642266042985581327179655460132883174662684533776952467196342213678497151756761797229765613260347963301645439436403186863996599944426267332475448071393425256497665310132636299954804139628575425486117633799794418474671916327762327315936521896660434445267974827431221126664241522345528648974141484591867382945460884126708389797447699732865941683659769336264826995234193584482482373584184420973116652977868537815171593450422535381950312894526134657355343566142937314581254624898016584577993994607873643659179447186847791356644075551336216090641150637869979094407642672275391696116221383062525621947716324972694560783963547574722324324824823653982018252391856893976393438678798119602868182219736489946190276632819339311291535911639872664277577025464196164825885150224777529227467124826395356421923264464678321152976320354261897556247182939896423498276634299445942829477731965781804893448117162153746485199475467251915318767636131662681731956523158643834634759328636175546653329349725297868633327158929459612338618414287333123611257215104051159249726312173227576578395666914812747570356142271342863510945427195420797630717124964229413517111556635150695453339976588412805053599479592113513026459090603835575936177813273163529745139939589638307998854559483275986353387460916814759948741094951430274523807075741937777856615263915081314734634317217675423610471428477113479627193392411135397417908426645195951523789972658016636260755251369744296695546110431528316220837180996548489038246137833154304473669280964783716767439745842186557351995737856071261041501941955084621714844651529743595817782229692854594023142241908589635070977829285073864616777721548915697017705784128344413862468288246765121786114634173482622824716345885955471756183990942590316772515022925540275032565828772323821198869628518351865151906460232455846936967778852038747134966428921138892659852991918050827821891566635084872542809876598517693477694575417095464318605890573330919290987265675545364341249796893738938940398966884878456378871457162747336376931080648754321678903435186985349467308948664715593347159866192499502128409439487933268076439856999927287250659419726836796876978651773535993070949817142395433757597179653240975850719190188454586762586314595211985677795948474157582957398784536457301350338944834649425474256589135717748794913352394915614367964650512323467734141018367819301880996223131912433271483552915725569034496481894237985813776591141698393283186554201757924862108365619192639032536575968917229516197336234686597629441071582219601345327199689528287296141090772612499768977467239068266771172185146838759725193131742760568475532136527987333213635366893164295390543359825334803723357779832742275822853242552048397593845616235827912117712111225550647113886933571955182613277610737728426338195453543053562672802322702012513285711788645031308451832224837250462014845637911953551974645610102497183785435499134098438847817126168620382128391860566594168512262191172787839397687151693826764423392760267891752130575980747181496698275342446937401883532912678864999176889119609678412093874869412422458246111247517987235917861819314391258122119348344662185284969665863021197414971210648865148537119962971541264250557377593033351861989263347775395996401672655195501237662862981270669344389942381334506119961048864289793337869265187096903645371818206989652589348423597678383737704576635161629917328478237545307953111170459855928678669569669758231195383062967575975028831320911140628420665513425695931443961567926921166162442973774244486022691569247123101567684643436161742291561828728285834093928616385919141829795947393415373647897562257543941039285768807493171216127385247465159041509793638296344714362217711224844932992698251337491191795198553348596742786450327264835312659633621519841555826616299388809214368139926073888846978868673782311347243142739182807398408157634467359474347938955788391284706114467354525263261377163897637742563866917711463957333187704717568299898026474858179198133126403620263624673145762135977221902842759095699849583998291098553480861731619599405239405869775571694770315762497963123716586895642387515326374958264292429972423331989689629492594595153977238210378984759942673613592039116713781573131269199113906449732546895122949599142864794727189558481087305750946086735632112493529939365095908249404723738553563483944715804339556825417283842427134977372874763984622382773933489882137789198147825422241288509442335358375718658595544719425514235947757459904315768340317434937526878795223115701281772256343548857099584889243220246233338099812067438474123636722424447238605743534893312452908596637396596476285128258491494180849863208147579185676660894394382663306589963842552699166510942192137146287594535832649756697964625062458426167283465481292535652318809112233052529812193750772410901896876362309250985929196852159993316416479911957911557566923668579569288913371486349566344952737852716650359923817011938193891318702072445282981446497355773838753257983634591024122469698074345419408328229757638033158450137178869572299925896139373654376381736613738314744629285839187352705728792794248110479427811745725661382698509152934788572526617719236635177429317619433782398417778085694160639871209532643264217099961649416057851792448490484859271264352340158820837058302085855590254579611234336372543375172715441741705337344729355812365835804943835897865688224513755860642932987125998370774433109968254297856379789872479579906465781460819414947088403680196173426338497828291749629359611370228498622580178227644650731534221330965423231228505394538543757453343612469531847842929422786521793475802893818764232060138947146133859366883619112929803795212245807725737366894166226365265812237410765349265431451830701727976471377087885528645299773217672080992637459131152696486188157175626245388970918010332736341417515516352099958627797710604368867785301213228623964433733796689318547833741619728412712146377882933378262826135772819381433141674833829565812283534628127626715313904788761850588540621221304143146961559614976299146969879394921189426690168979272327234810122246899789997598486355439128184922296595532553279239265252455170958987261829956883756621223712152224951717691990438939431571964084254963956728446433198853518410771356652959264765791245745747621530529136944056212316136364432821407620906547125068302678977743291228274989881225838267353273719475411768917714679989265880392220385486811271271439421326511955669452625257585888813186404258149440463133326055303415691871194942255965115999982956168628633493648796787257553569646790978384601122656952914131668027542437948776951020107964741657938984667153731647626693163979405073583327851457275069363170804767607418471756731271722046121178659251754826635327479954903328312892297133512991467469576480289450403871213136387068896453293129116649164858117883177870926245153450922224617190591461179094771036731863187918946857962686682781212076422345862454796828492830154944153032806250935663653746958367126382547041857716251416156669225643161276613597532428722978968466598012585443347232866215804629809920384467707191595585683463778619359479809643134770749545871430786890645149681017422210321634882089693137202159571328959563306093435873309512913068253983157431865826718339129598836130123872359010223467341239316525807636219175978198676282999084312866409980611132778538451527944274182556163678674169827532355641414546687391547748717718298118273775319554763816168781439425842899173785951266909576198594753120848491602681333226361976899760641062563557281020198126128374815616899627763534979151537225219364542619437969814250769552537839799841746320258080636991948685994139421792443046958949622233252977346853683463311258789570639658687518969381506829169943553580354544692271815850211531509444396751493178577515702357426442735521594688142621445860781726215248289655731882524962222019211685491354262453788133901789434344861317709720146745722616544488856232618781341865668964808683582194695332702615637735826516818717486239507351274140931761762521614280411842463687797826928684447474809042109860173932768338438412108249965828539546527031835152738981532315454844556196532733765436887360151270304757498937475584858160496974906368666445588715858012415667879433206184676576331169878184545999544461839121255012487641146760718258161175995663378392959277818920212796391972563873573487946759315169329046451763735779618524238821317581238742182725734686131334135160783938908633134591631380185122983520765073226830119230659865886252425053503859653584216713943715997245585392202586748818814494136539217225757791107066985973599756885526778439462178647283986199761394634080158472658425313380524799941374493999116523325673842014792780915529534653748071945115271677968926972948889749817475863887133872264097811752986199829991741076686865319345207214171934921328241969897738565530777950525483576818739488484161468721461446542739121562968025691180588961433540645682336652389448904922355215938848349155261083682221145695323796724725795371109844157769776376409640272740725753918658496743314973942344338392641246274321214187675143506735371799866170334542457225917537762466441831542582999250668283181621602657616444348198455641452194774446124419359177369040184789105343466396618081767229355671622114118825868783179383604779455755669924819319222490419334561195457422954174217634489011617547457895909561153747213830457479853216581627264463566794646193875898798020131413536288611674193360762362379944854542196844196666828920622936276914124414635487772219132560207812881862803090997019476572408170943044661630952313164028479216533577215822746426209046953038856354963322495333976177192034308047397661545422447226471097633292262438532473248228233922985893206343174759859921956327584494337326119936429329409787462588628337455162915965733120829665315895439657164010501493936416269311473650168343803294195665767952876760222454186216566663588257408941344568336241177771388848556435781716503936482875238177467744151416143260512959664020745823252876724795914636767986873534206995914374578271988086875875302594455930501712862525638399879475801615193240372080814911198448145516757567606744289756675256432896791271261861165550185114579582348288668857922780789839636719853849619873895649642867657359548942999149874116411456705022735461373563726261738590296310729772984323757223451099456038424067228736911529985131598178287748968433683435359147359382755420264936875915885627687612558636938997626011331653112495564659691210677856587819953539214626923442609358767747251217941350739890975924498213165994513184198817893386342587615838474522163564681254607396639574917128456339791585652055281883839079561386106139562369662661477619197046929576653173828768751280176427665367808132438668427566993430261768686741553325875383862910818395794710508448672153471654566832519657317347955610454389464365928916194773614777488565363285616013977221618735899062958071614698952263159539567675641249764012375648516957262940885426929025329250506122809426664349921468767470768161659486285286342345158910609087765228177574425377889664936395708263172436228491966279495283717478416530251356133568931493433089194898127535975759588939894093845216756981269618333587616095338472297779954743242729198533464759711889437181299794271996729363844644207220482214582754413085343664317154651491736067714084391014642513937434174624429020971275655773789736546121849651554576978271559583904173593954388151495548186346117416425231912885724952339187583445954997959271756831492027717480448596537233384673794821991079249218718066869696907665501172807663102128342410238423658444294771761044257745975787718568919548222632555746306441752877953396144351274621459251334863325555276428535735809446552379816280166961522066257312386993438475362380765454389131623028621664984663832842903843453181516855843644787744464367898593163570469551126098463368469068727548187744446995269496504018746571347381562150184254511349354848282782877996749054183458121088567780161694659529568566742644671478629768563594868046816742528127303382319183145652387530565698132352876985105239974677334229507832628830527110385342569423369536716736233283332420833026984139428418674119723482527626722826353141736089184851835395592136648581319226629143678353745885734935107279569550535331541523626613553395945559767727936488871089224450278073202541704182413664745146824856644569518454975736172774435327404822333181622910508979427193214669161591215222993245909888399358892690915573574727401245193733173137592249795371318571787876628552965486496649391835309289341033752111821045237572898438639750679185339348509141954083641482941636183837822123676951835018118446522716874065109971868130795243148135229878967916559277607538927089906780958534841531417164962068242819288736329788482172295918465692395557143187525651883549949274276391586930705138613671159536704746432481324422942282387463613943384156133349346652909452987756736885554529636025853119137721918047936811213353819651125675501018324053845511356660743322769544501291509262314325958375517554913160446262704437616848396035706014639234181690736797547881157171988435681281155318754314229663492366714779822437934736917090191784839172174491563297811852471176238026999721441924911988634666897788856948546943382246721157738096231217532976897771374650267819866530173495643081874061881479516148302270973575722315236939355043585942133653177927269138251542812774218081654619537982574978799236474494259639536726835453227976965814953395563449247060491071973072508681551993777027124797622097354354556633642562148635681552557433254991785034688665762547268883663079939065275657503744759770728977206847449633568398443475717448527567603371494325188890608935221073556276819999258446819263979037468032648466808065413129462968323814971923321950204599297456314028516564608056741880569247808030422790319419536384783340807391981493336461426952653229629173535896302997204463246897397467601693473796417151319527117570532470694047684816743091358030166922515549649710855325486434315781753150934434287379297819263994548312206079142330545093192946819986787362313678937554676795127285783063825332244572147999257676492189957850677862257597218183335181103810162468991910379056237468926482505521552531526958749052501244926551736928471749251832663577839836324253573830462891328863544428291451202451788667671338746385473293318244793887542464552879788741914636305820927189975435904575375254369389177530386087586146404985327983252399181392132166765458587015662377271355765553244145301857787287176283192473277668949221593024309784697375409473732937493626413167628926155839646829213054402933861037595619804429598767118667208398564123585917388262896177278666202981344878723011777121265298916049358487917991258194414620686992362264217697726791569886525587374456857898239050182853603685476893387658873332341354229846757580531322518338612995608463217896163878729966443743727710401012646180482127452927682497405751214381404389571973757159198962123672478439272631767850264195552247304249684488158889463963858532691993414811738860853999385052956788336470328733627277688546959428333728567419208669333817266641423873953384162794767188813636212489422659209845262351317251353396867679526083766133107970275730347447727426891788478994447418326663746432775296337970498194854523864654658610925861891072279128602261316911747476104412598432365975831499308067325652777561925085878323414097889589418456967282424089162122435425972619122231326051399335883283373035717614518465118568949066919487958547605584337789875656321549567796966231968622383415359562536527611728535939122 \ No newline at end of file diff --git a/aoc2024/test/day09/python/test_solution.py b/aoc2024/test/day09/python/test_solution.py new file mode 100644 index 0000000..17cf26a --- /dev/null +++ b/aoc2024/test/day09/python/test_solution.py @@ -0,0 +1,35 @@ +# Copyright 2024 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +import unittest + +from common.python3.AdventOfCodeTestCase import AdventOfCodeTestCase +from aoc2024.src.day09.python.solution import checksum + + +class TestDay09Solution(AdventOfCodeTestCase): + def __init__(self, *args, **kwargs): + (super(TestDay09Solution, self).__init__(__file__, read_raw=True, *args, **kwargs)) + + def test_part1_withExample_checksums(self): + self.assertEqual(60, checksum('12345')) + + def test_part1_withExample2_checksums(self): + self.assertEqual(1928, checksum('2333133121414131402')) + + def test_part1_withPuzzleInput_checksums(self): + self.assertEqual(6448989155953, checksum(self.input)) + + +if __name__ == '__main__': + unittest.main()