diff --git a/README.md b/README.md index 80f2916..77a8380 100644 --- a/README.md +++ b/README.md @@ -25,8 +25,8 @@ My solutions to [Advent of Code](https://adventofcode.com) puzzles. | 6 | [Guard Gallivant](https://adventofcode.com/2024/day/6) | [day6.rs](aoc2024/src/day6.rs) | 39.48 µs | 6.768 ms | | 7 | [Bridge Repair](https://adventofcode.com/2024/day/7) | [day7.rs](aoc2024/src/day7.rs) | 824.2 µs | 49.06 ms | | 8 | [Resonant Collinearity](https://adventofcode.com/2024/day/8) | [day8.rs](aoc2024/src/day8.rs) | 40.13 µs | 36.43 µs | +| 9 | [Disk Fragmenter](https://adventofcode.com/2024/day/9) | [day9.rs](aoc2024/src/day9.rs) | 186.2 µs | 134.5 ms | - diff --git a/aoc2024/input/2024/day9.txt b/aoc2024/input/2024/day9.txt new file mode 100644 index 0000000..cd63078 --- /dev/null +++ b/aoc2024/input/2024/day9.txt @@ -0,0 +1 @@ +5431847070532496548683598739901860448277147866475038393766447341891019504128283373957976605946436441241236811885153744258354395071637574322351864096571311551468137491833165146849824580464475754760251418232452114431434259695642141245709431459954722698744893399714126740663440275179501517601918806129411288749118168218139469993280814857837114254464734195195312581984488698125727477534117156511558449647991544166549428852446699158325945697464880859478338398358989692786506371298875262629775220733211319536949661409681177899661819133589587837478769915792119798458492485427985488801357232373138732236748853462233448396097281084437925358378424490596177228014974044637170281031411429583021775820273180839559456619452796556872676571556132186797984630934680644481779522232033418913761869766059334561685786914061585846271165837225977234962171539171385066548764879325678073916884925119179078128940908332557416655183248323334358765491852559446282862866349124154590119681586042429512902389444932342329139884998043265179483952358664763341471227294624507498634144468012513455669730253344542554438142798341903946752622894422519240385796399363717319304814181892109738948665244361816480626477334749981979308584646175341164573480549421979318518594936370651431662318398947936837193535164589903222891022332885625080504141242599545644433935715924677964665418679330388028609495768366198370316998746089196271168416567214661857542999179081936071603466413839118250589241209020542762287693592767238247623811266816968276402382293979624192268668637036804913553238444566923090766430739958608386294233277545111832373416143936493751532758733280682014363414117968555347599278345211412189268587111399691082246434754984853280343750316443484873967790503155417985875354106379479357516451925436107072982673394312215523339155295820782375189785144345754763268799346793342314856097703855315398459116995688511766962837349459926842559986423586723942724897226261409562133772359969259862418466838896426851973163817027988413995770144848119225254288424049701995727140737943455214449560656338294728439759809799763425997920276967372080482878507424779452694873427362228081697697985177836773155381675733764259506619722139231248145764987187508975187280418228215517708861937121696383262778212815859213169451298698526612563886932297721459123695633235302241664520895115475321499824565659598696441059363272335349832694891161511441216250455735428875393038226162707338195613887579835648438174479117532744286042476474265937392422189395238882743338903911918571174478959075613513737752812365929031604634571198154518583489648311478180759234109935711785976621932724132957994329794475268026605132326181796042177116298720353424855067585095136516743020811142974945483793498939937644301322215938744669865280191033894695819215193477768848168133163219358376716855991487125725866149302929881931999942465855924986277446491375587968646039634442274364953762114649513686272281165175296277741949969276412876826675288238413427584350795131174936246533427546224472971880525188156967946995612471892837333421346813787195408235144669663817919566509060434235595770635849325288937495822745779459628058204660688974221776926399406658157148716541346183613151106187655651894691184227242674155024867848543518248733155526834036987190526586731111846461158470389516435668793433403843303636626710591756901917271960682788844096558636925272659527193180931568955124917728989323298823884730215727907081776268471195634592442322224749917255769174554580974318672542145684258435813469413454657331533297624961571098274383128826142886178892896249544976501783668999656618538668647427649245173273109879296856838117951162694076988095889976892813789356179113263330286485547976988339435725987217455613809148996029371559673755551164865778172919673553131246865579777031838685665230718288143530352130504667635918445851385520546274251648145730983494767031286316275154738369898657782476611269882092114932377881382117471677308269641034609577675451459673909135686710902448605742824844852396447251184813327923498011253815153549116224376869328657611831245696483849429232628360672338869530144294488472369615254273876654195013263545895498946166529765504417257077403339731368261688225543913199508015835855453738493499706884363165179243835670161917635535454590386649477885568876782550263443936690649136261936517612734965878147419729149361814724812069907061167660244295136648714745792558212553407576435452294783565860592337418941679648722853938298663830662897399473627350178498566954192399692521691490781880599410569351631788576024278298749293113128133936302497841555687342615269922625163352926888784429425338864368475649933262803619656110664834792326735096114311143814172044275432864185582792202877417961473942905140498314968638605678798454107358102617525651132698108560129633886387224458256797158581349380354465524548433159353416849616957939572242353134341479514420511050167317825682911142548297427835607434143149268044997798807982281017936513258518752391722349518631153686875245168026682958393581692515842980854270712384186672355487212831419532101149595519124299607365247366797434499964698874211832812980248426603167274296247872122862519352718217245244493752717783346017458931399278736485964182161259532641671397764094897033317026745451674435156215753752138630722836869394405610254496366388409649862261412399805284145277686535226752122116122767839474665254578914245869939635226613853194766176615640251399949267526447101668701391282857391214324299343781987865309787275174816213548139341867545582265572149374486153645057447465429321122056782781809957832642428762341572468231932697736883199115341415332785455358889719675787912855144691646552619817441869788564973758837281375664716326441558945013361611246518925538654127979454423763425392761252151759138749292749889739304586737120401054519772828367143187555363611441175938973189339919808277886526399775429872681990473255823889804341127553189632688594119141865182986546129158577968161453746654948322733083745621761932594354981440252123484728118615486673829042445945135023561779452933647424106686341536495744311366944487218461185940868215533122953492539720554357507273383560645494241099991834446978507416648557144869117045571079578588752041478126235922426661186856483544499922633585199453902063519787618156687014941353467818514199522218504175888882297877331760569055769938605349402241876764763379232658184021956091159626882997548844291358849280453331457351541385827619557838727085801215291381625633649588895582188577315191489866463164105610957977126933527590435567916152253672274532189916395728637693374121609777673053169914785423299312831424484869627379342023236269524839779275365945137482542974381722269866487037366814539291139086411459699420214480334366884685785772471212538243428131122333796856468164612879981426866512659094108247227015267522715549835217836258923253194315417415453017546920406713761675413932111679356824524536724729571797572725156255472228169580954986296563661246166083942377114546758556125757531273388933769377121130639617229248239196887153124163618315501511222486322930534746346361525799279318447446101965281848911142356964336133535578492268339398699379993354742878356745502027765864908077703918651589807538204210701810772598686478379089858478457158884642821358382184865315481732687776695696463699559552836522162114832160102745186118235073487253473848523280145727852239717218239911567567871649351364811786285052762735589278205485528953107270447920776891175836897938584663927582439513719446537235197026636175195242999765437860387586132086881828419981412171153220435614881951521772467671784643749191467288509468674583471815524372198795976625703121236330505782243316836042267341148494592549423223935396822729106681568726341250758072556647827087231792196430215967654575116286175249947781771380751436633426865445198640987941324252779916166394388922869624341829627063971459552678734611751644251571931270876237882547515143503622626151887141601041755014364143481643607877531370558777745851817098602346822746812945882715636942459665217532809177673560679438715995627048873754723474664633392691227972489290878115727977689474347937749968623215859286936582937393623823459414965135637690237520929318239052191270279668948485346585222684452250662972849397733360246253622698688072644163655036256962566852308677305948788382418735518355103314285397814724299194275245965419331642772255912979776015572581364268398830159554921111957863771446199315267932548927786637172149446776608256581381681950539443691688339712582774109526635076499265795292982934168892652476765344434874937263671478143288832641665347482482285483209584371050674799709863362062892063788921745356217059912326367017289784175456242878193274851654522714784837793120656851219436706831172514746875564240319577236920584420834589232888449349713730888810687276208882858238474749968333716123837887936528651338994440628447748972953646303022458935784286714331331833659613146455921298629384271751625431204831837242464121773138593124963270828014565875209718549645214610592544561762348362265288979219554052149214957073371584649429178317294311606191321361545296228316803211337540106774845548106141681184254330296067841619626084713394279885817948681193752530976058477111106925168545614371578698738234278218902583513723764847688232661291561083529046963056442549493478883691667046972542815848956763528699244423306066552793919728826887674035232141165019793917705920328363153072175059497031391222284345366745992652793794581178629620644173259468841071938470724386307627829074849991122893387277784165303872825459791985552176756541499678471791766228836315584186502452542741428389444059468359514561918073551313631072288370168921177847859255462895331885217012757426868976849568728259485836907386861565338973704239594422423524736448846662911435441053784043453112466084897851439928307412597940202954623945176610674955659346241391488035988422528139786466606088774868132421254026107289834271684410947075942153222937438848944223859953514149597156701624452579153273815651723012878841489991437626287212621626938452549092455997791542838720925129503438921981735074653842582172694493196079376431871828911175727621771283219316809164963942995661516198525813213777881219751736238985262611612658434622783114349369999853586359318282736722734431542442512485962350563469258922704623799249697861273566769947851710115280673778339225465539833882981378492785318263458289851064963527926555884884185197101574589439902325919628519739559986437581769285214735171311844741821680673863556173186642594445545037414324275132177740303456454212222113945624553653207740414662769989163778719692267160386531252189537983291047575814991644745593349942694355546246299851334138342951384380754058222211567091808687635733113168942949149426543761723439761382913521502283106014477173579293472692228779646418527053498131599721301261876175984637884720145616852095149084382688277620409874578855781918881559159752264565618033637551907568997765948889697996136260539953463180474486919530943420964725638757311741836536623973619165224184858173882353138723768772178912119029609641495371102220563448168252364125302116259144543145418077792624272246876012406979559964648896574655832220644699312953154332905185284987925254563370909476514838187255833182281189479845108766201316579561862614772160113396328868579912207094941437665238546318361630992946302362674693589443388084918330218018319379955588709378992766832275622582817558947016312221833526653216918917669942709081412528357967866325148655635551498834863031324077793655823424167573123050276842206028989541609816262237384281738834798636748822683857635938785735566220786893723220969273752969685283224367197496157713884751996685472983211112646887111965733114667524633685405932468421708127733481965268512788692679994595218868814048719510949473743681966476229975261348817488407525201282448429876643466436691931821999954870372789372026443868311361986243965238476328413940451232344628438478424559251865921683112566628220603442868858801181898474573061657486475566544945624677946213921262309623364331212481468041583883492118873226604939487198946073346762531960454442849629882818599161185511576374632682938186342287824325913334809618845946652887786398149676275946915693184114919365549696449157617461308545805916166931676853347424959647698852687967682378663512501052252264353473606016312133139574229774321069504033623623314048335389217752379186822025232564798762531191198147251451885167738810884865751783607746892691183284314014159625162359225995374855294973905875601139953971621356838125288873658513829059228389374112267146524813923696995951951060327335763063627046339613559551394498196733126078166130562675833739662344211586156339637271159755435888369058949243175117123943952521412379998885294943103067231395836136787785658060653260815125907869911826365658888396984041281454992028636972117951151279392776705472374131297311589235743235989821682379585945569692149823887985893357117874302452779615544383259451596565913798436675971210761720141834924686675333948683445614461074624939449746893352546524664286772817109263912322205494771580938955619393219919827714954357637326456321903566188012597138194479919521971045314557684492978447636471393121846732266441127076929623452516469268515317351628916587653659981342524117303834251237803839852555848889253361377523385888536714181952737070557349104427543995206220468098124947165735885399881037441662599849291148828619247425471556775383346452956367907881245461105521535493449371873849398575678737963748105473965877731143931917784438675510391816833918212926191423283193947744615997302247631170475076353034433639647526832483194840657612487422175442682438649468519756889331194188446571101379148474551622164026951155676372462365825337962393944826462553324532734675843069875692998515352629395470319465398696685446846256555739825487858185267130113083709996998944674751374025224866392743298866964633489199398443821877266932608199922665493786878028334675496229138994519344228994381048787918936325311876626788316492888046542231421329814532287484238660819780397322812293676472113115553936307856594873801385746328781850621387995451239347194331873118143956741890317649961053339934384753576873839373818011858962308068359681448187801477714058676777505220214574982396208164807666165465663577513256148131332588451217389060866941629865425474727775594422106344629184884146328247343243942345149242441738157138673148656441659746108697922042559242831428586727636826102477314240597591296994586154382323748697715168543617925131463291175730281711909950313171598913439386313548644112258366426873577370455121271858392822589810897696318271861971688392917271768982498251736437464038884378275090401950266581985720657245911546661988628195404062274023501219958745142910587599786710989528166993146288984074704035181498403498342026189730304114186818154894226128991350261851553634853257717894477792924480308757559153103453391355714177687379841772153859187888991944928974816166394438531288526029429370827118338158373215557653117382902747882350289342573567566591496621125720149010156192333939348577768371276173254839457341579052884855899521455687826219552559353379583287743033373612237922344221398523743885887722145446159091858835326923143598736739776979383162124240376176724756902714422972877386456950359015679783254498665554197313386574946684672440649448928046823952452925875883123474764275683163247982559056783385108478641526541624633941307929665173822474104635274379276669794170231970331184579771981818713214303463802831593179696066521869822420628133599083798358617070787562878410639996794328985566419669725183436737934471487348293520763025987951905770247895541890291192502974213273894629429398517496269934718745472252852785799067413916332610907571353097806547719675572225686585437313706289764926897495283399504894865225947940671578373835792384915864517240451857897837474158666738127882626758926834954212234737347096589835594052622629782514725228801653459682113745362183353647597457236010442151759884878312124331477432807798334447873457868094866830917015754699393346955052658889968069276211835255266477346510198639736226638637348634998789821924918536665568703098683122372819322311298938894359379639133780835641406350463468184916611188867842371777442592313685833473444698689034551998113048234791762027446146727025544042103813784261583650848618484157775543396899383931947511211562491598253548798817799677298815266868175529218241572267174813597458635056447033653576279680728866202215641798761728465765398039702536851465601653688836239621484579886494949445518139504085564648403876616138898496977053705635456441166131237224212132457566818246409089255141604655566937294999779883239684306324139396662378187398583547383351442099886790745214231652707661893686852484253311575649883256286310728911168770135847847942505813249239613554658598458912756751555288445954364137168460381974352139819957517178997591758873416983229795354474556256222931289088956288236930765034996259985143391893819191619668299219457076656449957972739232707651283426189323173271511414963553631022738796229234709891788138421335962389202938472745429665429421449451828085626764373551669023288756897584137125288852204671513465741496258695431468534328534786204128332247938047578049193590876237562413251153815982503377716515745527975074111071683263628779365586288331518624267254838841421857507639557142984366667415719537651198812476439941893225313178772634404228859482432389529689179427561264206830828252847099196970992621215159239039191873638118353095751690804720759335482625874568869589758016947947722134828779851791229873453645154499253778621951665526763263812750673364188063315663685536786662452774668460425338448652267153396698403794958557117715707363427158414910714223613042738143262253545414445189734445315660832126774686261890207990951637852027117940866025941189112113591465909359747259208783322997964321395272386512286648988834728496902721734886267547847471528672747847205387574295736985241696516932844212494268506043999992662783792963516320447644674575318472898870224758505820603968302945492310875523643925961688303462183260763231418028951332213344725539975677345186234844846882656482495455602511518890873842883913163495822973217267608421684631899788622362729088357511278117256797634947232283132985573467816042973454892624277734328412908178282097447928846043263685891259571019642339408836131653632836323611554584763366633141913941913514839123396930803475957244302131978337446772164529446735719434462040324016531972388438518097179281232588371466482375313721177284703522295719881595897528431976558461796918764460253069864598923894166764378191789811405427797728366039795560523235307788142311586556943966573542562778297041212055997021434276525392632292627028243972111236516045344554731635358525661482319167618087669596573080965369323656464519117444929754516615864868623247905514213980949883735267281975164653387557709597488746917291354321839956233319716495715332934056616433602361854259165844846090727098261292975468959076396531881222519084273968952676356676517184209580109527865832358621375142707298585957705594597037138119263760155135724927656715688663178947673197722867479666278737285755951147892235479733939680614837681327436117657554745358946584327728125026319675496256103242646557956076593121132642617859102832225453314322344922816232297078592240951327184982997272807466668041439188581269891715594611336035872923113621737723764275734260183252964896487287778175807776874023883020938542177574348674671731384857458727786498574318365160439216302981267031568420557343643518103231998888608240128736299952507093531952568543364344277955389690521695784333592258666685953773303886807356237197155570385415824262894017205735472558107075984966103557507538768451641875131653916934309186813794405290166210507279741191239829434593938221811876947948319740367520725730977275267584617975723090554087545923817529938752614582655064265520633957992758664213442269404450999660277698162279969594648110484768509395459144512625749275497361337059832341259675242276911271246628238676841296573698947212413442657350581068345095715399782690255967584390922549567242112617131694895561356960275436202317131 diff --git a/aoc2024/src/day9.rs b/aoc2024/src/day9.rs new file mode 100644 index 0000000..5069789 --- /dev/null +++ b/aoc2024/src/day9.rs @@ -0,0 +1,131 @@ +use aoc_runner_derive::aoc; +use itertools::Itertools; + +#[aoc(day9, part1)] +#[must_use] +pub fn part1(input: &str) -> usize { + let mut memory = Vec::with_capacity(51200); + + let input = input.bytes().enumerate(); + let mut digits_rev = input + .clone() + .rev() + .skip_while(|&(_, b)| !b.is_ascii_digit()); + let (mut i_rev, mut i_id_rev, mut b_rev, mut b_remaining_rev); + (i_rev, b_rev) = digits_rev.next().unwrap(); + if i_rev % 2 == 1 { + (i_rev, b_rev) = digits_rev.next().unwrap(); + } + i_id_rev = i_rev / 2; + b_remaining_rev = b_rev - b'0'; + + for (i, b) in input { + if i >= i_rev { + for _ in 0..b_remaining_rev { + memory.push(i_id_rev); + } + break; + } + if i % 2 == 0 { + let i_id = i / 2; + for _ in 0..(b - b'0') { + memory.push(i_id); + } + } else { + for _ in 0..(b - b'0') { + if b_remaining_rev == 0 { + _ = digits_rev.next().unwrap(); + (i_rev, b_rev) = digits_rev.next().unwrap(); + if i >= i_rev { + break; + } + i_id_rev = i_rev / 2; + b_remaining_rev = b_rev - b'0'; + } + b_remaining_rev -= 1; + memory.push(i_id_rev); + } + } + } + memory.into_iter().enumerate().map(|(i, id)| i * id).sum() +} + +#[aoc(day9, part2)] +#[must_use] +pub fn part2(input: &str) -> usize { + let mut files = Vec::with_capacity(10000); + input + .bytes() + .filter(|&b| b.is_ascii_digit()) + .enumerate() + .fold(0, |mut start, (i, b)| { + let len = b - b'0'; + if i % 2 == 0 { + files.push(File { + id: i / 2, + start, + len, + }); + } + start += len as usize; + start + }); + + (0..=files.last().unwrap().id).rev().for_each(|id| { + let file_id = files.iter().position(|file| file.id == id).unwrap(); + if let Some(new_pos) = files + .iter() + .tuple_windows() + .find_map(|(a, b)| { + let end = a.start + a.len as usize; + if end > files[file_id].start { + Some(None) + } else if b.start - end >= files[file_id].len as usize { + Some(Some(end)) + } else { + None + } + }) + .flatten() + { + files[file_id].start = new_pos; + } + files.sort_by_key(|file| file.start); + }); + + files + .into_iter() + .map(|file| { + (file.start..file.start + file.len as usize) + .map(|idx| idx * file.id) + .sum::() + }) + .sum() +} + +#[derive(Clone, Copy)] +struct File { + id: usize, + start: usize, + len: u8, +} + +#[cfg(test)] +mod tests { + use super::*; + use indoc::indoc; + + const SAMPLE: &str = indoc! {" + 2333133121414131402 + "}; + + #[test] + pub fn part1_example() { + assert_eq!(part1(SAMPLE), 1928); + } + + #[test] + pub fn part2_example() { + assert_eq!(part2(SAMPLE), 2858); + } +} diff --git a/aoc2024/src/lib.rs b/aoc2024/src/lib.rs index 29fcc3e..8bd1711 100644 --- a/aoc2024/src/lib.rs +++ b/aoc2024/src/lib.rs @@ -6,7 +6,7 @@ pub mod day5; pub mod day6; pub mod day7; pub mod day8; -// pub mod day9; +pub mod day9; // pub mod day10; // pub mod day11;