Home > Raku > Lazy fishy

## Lazy fishy

AoC day 6 is asking us to simulate a swarm of fish that happily reproduces every 6 days after getting mature at 8 days. My first attempt was to keep track of every single fish. For the requested 80 days, that is no problem at all. Calculating the swarm size after 256 days consumes several GB of RAM and takes halve an hour. According to Larry, laziness is a programmers virtue. All fish of the same age behave the same way. Instead of herding all the cats — I mean fish — we only need to keep track of 8 age-groups.

``````sub day6 {
my @state = 3,4,3,1,2;

my %duegroup := @state.BagHash;
say %duegroup;

my @swarmsize = lazy gather {
take +@state;

for 1..∞ -> \$day {
my \$spawners = %duegroup{0};
%duegroup{0..5} = %duegroup{1..6};
%duegroup{6} = %duegroup{7} + \$spawners;
%duegroup{7..8} = |%duegroup{8}, |\$spawners;

take %duegroup.values.sum;
}
}

say „After 80 days the Lanternfish-swarm is @swarmsize[80] fish strong.“;
say „After 1 year the Lanternfish-swarm is @swarmsize[365] fish strong and fills the entire ocean.“;
}``````

I keep the age groups in a `BagHash` because it does the grouping by days-until-due-for-reproduction automatically. Since I want to use string interpolation at the end of the job, I keep the lazy list in a `@`-sigiled container.

``````say %duegroup; # BagHash(1 2 3(2) 4)
#         ^left side, due in 1 day``````

To avoid filling it (and all RAM) up with fish-counts, I have to modify the `Seq` returned by `gather` with `lazy`. The result for day 0 is the number of fish in the input list. It holds the remainder of the days until reproduction. Each day we shift the not-due fish one group to the “left”. Those which would fall of the table are added to the new number of fish due in 6 days. I also add newly spawned fish at the “right” side of `%duegroup`.

This is quite fast. Calculating the 666463873541831246973426535180081306051344332419496097574607054518520839712550000594802691141564100111292720331357073290882244225192714184089169346685964671516187813951096262775287721663915276037319968883789316173563712342011586035522467448600678459412817531237893966744548230642659801567798572516443076828073809628951485686367299329173252460181111652453921794109579961493750750734265060027862319480301195721313855543368780410508489633987968914281286844276398056626056500195554449381491834369426013823615252815425543249358779614574848646041262235325074419121599566115743353840105721990147263874748266408772032316595776612139275667150427915327686811729436199173446975271203992586398293131887618521011755271899166531953123757885268369102417404559972744230868418598748655243343869986766661655042037984488812438348695753685017592648702268683994214491364317393963000241098774900860353154350255976660612825403755954259350777693373207214861611583733971247573753279647135857625981918122186224389736913154106660544150165044497782195798322467474545414359975280416021441868622819428265244124896732471132319475701297098131677160490677788279224281506375689792156083261660239743059289383954114360045274214222447181262304526133273574533858979412601139808464840312101529514180385599430255955781457713151780397881537813797741641230260021041504757528558567274708288004546316057088994331798567783285763677777142122893528306103449281714510452991482789242022142994359648845815232477126859520823649474552988312877187921416635399339769955646489084732858557082288490783224894412739826318984292580566158052826330786018382319598588584819781525838565470572832599454876144624825685404140533646123043106524436362093177570751086786992684152833820485100470478462777156051559248632339883918620198736118866635553334340968766645368916095695325353449774328446440853029129756875723991564302091757886533273523038336595218155455847720671360296311456615511534013669909215005974655727411796937809475695407372366543688858553164927186176284319696215869840409175116790478421050877644744904836567400465071060826920730779993325487654843921279330137019941534562291371379739094205792954311994261599649404889922657935181190550846909442988980801810457765018578868168346363395719520126080693090513623794846310221314002540928562091544035735325038582779915950068599810881238838540448661640810736257932409239805606726993593971797657644383607714015131260878806196971337351189307132698177407972017000201825640472058109196425617780979614274139677245275326428802749811532165738249568357364288460055317791819187069807360720201014895008424122335796058656382694269027483373897038315879369712516175302775491130230060194100099770983797730029371076098600606612606504496540435861780431593005821164544353917534438370844599828015624171035152767618278502384395318480104807923622283443228345020744327514580863359757880740620565938348095639936790616537599389440870787580722382958374157045847403580250327710279742970965217530007567847487846429484345115975936089086457712364194335781795515213707375354638264749379637149285715302499699088845270788017375200781914651624886714042032631270469044847919416882757592998910768135740421382562919303214988217260004008757603083768569310849111601378668903711883637090353302532077564619529097226962909371328794773406990184575492574816382339282338269302833194041280013723295140495812294249892861526693716554130318513200838212285332707704499327803950532136817920788685464177684231882161475412158613980694356704252223485876770828303281339998270153017398653147421948177553993722391032011790555781475682485164990790796034888331872104119994060864766641589486019776451094668437290051663716036351804363561485132861888879574332105755746153309513037221378820879329573100621979109181602108382778687920007027623414831325355922936046968957227262772531473235744575569740514039285285079980036544832094265112377855497790912673262704852676592069446938153092444838196960689253870134387550557038873034718392173556998819875192064045117445575414318403644736200616976079570351581324439468616174728711252055735149140658285911276621119118732662217544015753511023622959240241260159058502957488628401113683752318710676758503695635066625468822413388076887811531732302500858604790123295291538975651419944639646087856174350263884179672051458673053727846741852940783409835954103271242036038353321394729469974885235979650051711963599818288978055126149102294122957690031497952217393672252034107303994335475246886610393935909711275770573986970854143317950284989356715086562230590990839662529967681272012701505798117971299799673234803156367016061677454703877721642007114534983433005793420903432912243015821072394360443476630711401955759956596477921259921197706822024842706184998910663864226283398436784178963976789932203898475822109125115822415490069379877953461916500641360785172808758119764443455742650172841311795874542342105299546764202358136285062614258090851832551635187962587820503810490289553470001551935217902197256402696601078401640235964011992837767132544306689962788840045977817796846871328731122938775504758466277366002412258932993666859399845672862117595717765477084418344974513339885386063619148967760485644569723254386502614599760138260597586913326592541522848983986438880452374164216429025751686557474365199522842488300216635033117150699388311553631871523304932368513183793460587360209998943010954435528289373335985043693053046434862949189611789904404003996815754992741168257864648722507852978319713865174461022833619615861427774300761688047803529375954505687612634211974798691951830710730289116602338015712571919713442740921101207870031487262857757224763770493982861280180603699869281254386149365595141503324500597971840838925444811519173746205453585901612000096078377983693216681932761735871382240485236129666942296837602516410628534674249139340936564072588858508662014518396032670642171566567771092610926600132205438873264132169671839186033389009379212165494532865224738228272982628415238069291858853204890673332880170473586404742119046305516995821325630692191761607383013664301194995569003288388503364517918373684336120978256237183864578616282607689412551049174006645430791960802835367975524722469944875023083997434516051965324062562062442752116848975771006421529560299607198682335508788021748824834632380555640603831398812935629742121752733051617067038539404438447484910824885029216904840603378133010150718632314196549910940069982462107378900141797555250249935208997397711315528593375548049421047048207638162260994766052843933057072429081984043595382668008048815441886172552323834194611025394425207398796061655113529875766770335862295433937836310790356151504721463830935974879920537435613958346775599338978427292432231783451675146229944198725258442285056096897643424026441622229366580337496992870774916559942664143218462435883056138313243966685145911608280044630183828743286830275241001375308435058876588315394558530369931268118528336420931812712916773937710863132947830591511365516095582265199154128356467750260531926118525066675003071739260309498814109697189063963885209401818145157660757802363003040514869809402584304387485680818578184439487976464280610699595673895597604947155761931451857026119481521989593940428110457669252083455024257132120074023930581161863487809678476816678436527159186156678756992425278664261263708484749418357954362156298366169569952858156319404498178302520729199899572253728399089327226902089224984752734795690279882470693252940552757819062460127046586815772344470484790253458472803165221028960275008692355763601919703557459324036872353025549748290921483516876610531395817429047761411697904862224464212531048933689503710953109442732759237356189014125558693485176472400652479673164432317040092383048015713215512740516304979316443942228161330426132203218492568652429844498726935561264929505127040159441733670469017273769559892857515811651970232842902910750966526190087199111410520935729735696689765846703413417162958695721018396373977842934203382304174669594558675787121040712019812712637199564803807379998750042443634573161317032814654063703050313745228800256069546872721055397472849971261055167179148093797923385453790218673892818823567739343110029248690913982030310372481582634843912806744923808043007181815800649169469673070351509475681317040362080079281312224119391626505976590681654036842848901857111705024868826560558936251253859583929011265828395689945327820197228833561384392456298313561747748394718483542037615552580248500271438063011789566281595470199853023198605236455144377113950002829956885749726910859970467453792552668635995216864206218596950021302760671686860948660709098573433002174990465358653937153029463224102021507578668602684150574870330045407826281962883214840079596799276490894750533219984415623098428666873188029374708547890337468187414157979648817501413641552787994758913710746800642864628337671539154374549083325827751519622507300647675596156687313927874984679290918334751557320148851174268648748501598460423236243361175276493299700932350967611304127144863529443814326050641613997036999124651655030638507037387145077891922768079837374493772434405033883503075509855261373190585532568183734429126636609566437113208049191934178757873767996237864137030898595297764852947278503137535654458605086469339191811000608091947271420968592805443940823737551389579814508299891882450889085371376080695820603935358334989016914765326067944139312755088780873497628147215539231161256746277969813244329537295987450414498891042368211888806848015647664192838074523692506916539749616425352934092641915767614631974106789002780829259370945153878209885580118528965359521919939822564430178365165774801326445119698160605794516715313781273522505061346800085177272425594654595195871297893714444484654019369230684383865521835716565191711011225703873328690113338741589006004434605591923717311969482396225232141424607533639489729752857061366998628370189292803862359460211210097047097656785799422841468511247218250748712137270072150217376845512716579835863424124266409969323997884912125894710274417892440097212151006601864964501715587498027228291821527214891597929763067858211813183757227618746949153003067548837587385641297152433994877288147478924408708574787735392027870749748046058647481086754228856101011366212709560274468780106805925245692447193482596542371766911950533561804337941557402124280610123795070613547672025879877827460785101263145383763820589221812599680793379972139164978282434256491687426685791963210897737564390119822184172424646736690737001296189907293372002794718794343859271805116725046891389626435528472595260800584941078380832327387177955258248778327681468071971827524880496086353713584741373924249622400717299750258850422909328819339559616577726969888285499265108274415782048123220789084199913497296557007403128779553093784717845918745445922290732789635313425161159032772703674611865792209093078143315637983839062583178927604885804176901890074139431024521992946790674264598456993382894873782585589232909351337252085909914987029391625209523662798912738575387325882697093630889584806342086729953269904180963241778840784728451687149681183128287044178404559876211705493978607993217578576595627309177560138258393251229199363344608600791943289536916669977633214113363571738151766646583136944036255700361005501752780457860088797135268322742487795589796175524357222548619105448650889563122822300557069722234511223992337592422006595019241835160237357792597623226264796156436525000444919271143365054736760621783169117928864481337560330379337932871519758802364131406533840184638722778523503513161237577707839869894469301356642468409908038779903549303814329129368082877601350597015101443573569786660293070026290612678398529969549771340240049619685204641651940533388963319505779753820775106675393993440746877919137663894627710484952951370533558417848334983399118573772254814592641503109595203052266576628217982665280419682884629826433563359175909783893066680247809189684737319679794810962417304587378927029630140010025294071206254272147536956464176571120496356346058921327170718943074661003103039095915152587583902674312312092101412991709057528461788275313322023157444923961515073490629080814033737775390515724908613770868592505552627071392493431908003184245362798129644814275247365465174219093675867063908906790309087484038360355448865944433826848902249323340769551921362344300902654849989228061990570470320344406773081761525973310281281615015380247003600136192752901263014086146704494718707845916463576554858823406717928933268940127994564908810162906532920920224071766152344686212414339704259239442393373659788070205050074953421106903523777932561660319404315618286334884494752810138279280394839953523775430495636405722647736806105023313467826798305889070300688292676577425317590296248572229516029571842028122586867322197535500120877596981160658274166184430633768752767078804119527472092104099830927628974599431655369376640668429730717615832450226685074005759908848629013070780369003601994294137555213073407824546267230564379446839152125019696541355555784059875677483047688836017349363987435005707550300562941097489361280394538124621172777424335297196186189142985139997339712153248035313265906268750184715536312835386428661584074713111362111257299033685041830246384893597396787107620258243945962742675775172752828336415533038684107921898451917374241277659939338207690545527751158390355107462788415060406672197712718081242621431094055357466672139382347530564727892260750730970200840864797632462812548794461694757284402212145015656804330958957193444620379159129815905928250504737659678 fish strong swarm after 1000 years takes 40.345 seconds.

### UPDATE:

The following version is 12.5x faster and inspired by a Haskellist.

``````sub day6_2 {
my @state = 3,4,3,1,2;

my (\$a1, \$a2, \$a3, \$a4, \$a5, \$a6, \$a7, \$a8, \$a9) = @state.Bag{0..8};

for 1..(365*1000) -> \$day {
(\$a1, \$a2, \$a3, \$a4, \$a5, \$a6, \$a7, \$a8, \$a9) = (\$a2, \$a3, \$a4, \$a5, \$a6, \$a7, \$a8 + \$a1, \$a9, \$a1)
}

say [+] (\$a1, \$a2, \$a3, \$a4, \$a5, \$a6, \$a7, \$a8, \$a9);
}``````

No wonder one can travel faster without baggage!

Categories: Raku
1. No comments yet.
1. December 13, 2021 at 21:57