https://niels.nu
Deel 1 meteen uit bed gedaan, werkte in 1 keer. Toen las ik deel 2. "Shit... Koffie".armageddon_2k1 schreef op maandag 6 december 2021 @ 08:37:
Okee dan, ik laat deel 2 even rusten voor vanmiddag denk ik ;-)
Ik weet wel hoe ik het moet doen, maar ik ben niet scherp genoeg op het moment.
https://niels.nu
Zoals gewoonlijk bouw ik tegenwoordig data-classes om de data te modelleren. Dat werkt toch een stuk beter voor me om het probleem voor mezelf te beschrijven. Uiteindelijk blij met de oplossing, maar niet blij dat ik niet eerder aan de andere manier naar het probleem kijken had gedacht.
Ach ja, maandag.
Engineering is like Tetris. Succes disappears and errors accumulate.
Puzzel spoiler:
Voor deel 2 alleen de recursie even moeten cachen, dat kostte een minuut werk. Ik was nog even bang last te krijgen van overflows, maar blijkbaar is een int in python stiekem een long. En de diepte van de recursie gaf gelukkig ook geen problemen. Kortom,
Draaitijd deel 2 bij 256 dagen: 10ms.
Draaitijd deel 2 bij 2048 dagen: 80ms.
Draaitijd deel 2 bij 4048 dagen: 192ms.
Draaitijd deel 2 bij 4049 dagen: "RESTART: Shell".
When life gives you lemons, start a battery factory
't Het nog nooit, nog nooit zo donker west, of 't wer altied wel weer licht
- I can accurately say I was born on Earth, but it's not very precise. I can precisely say I was born at latitude 37.229N, longitude 115.811W, but that is not at all accurate - Matt Parker
MrHaas schreef op maandag 6 december 2021 @ 09:42:
@KabouterSuper ik had zelfde aanpak idd: https://github.com/arjand...ain/python/06/solution.py
[ Voor 22% gewijzigd door evanraalte op 06-12-2021 10:01 ]
When life gives you lemons, start a battery factory
Verwijderd
circshift was nog compacter geweestZieglerNichols schreef op maandag 6 december 2021 @ 07:20:
Dag 6 in MATLAB
spoiler:Ik hou alleen het aantal van elke 'soort' bij
[ Voor 11% gewijzigd door Creepy op 06-12-2021 10:36 ]
"I had a problem, I solved it with regular expressions. Now I have two problems". That's shows a lack of appreciation for regular expressions: "I know have _star_ problems" --Kevlin Henney
Was alleen wel ff puzzelen om de timing juist te krijgen, uiteindelijk moest ik mijn extra visjes wel spawnen op 7 maar doordat ik daarna een roll doe is dat effectief 6. Eigenlijk heb ik nu de logic een beetje aangepast, ipv de nieuwe visjes een penalty te geven van 2 geef ik de oude die als het ware, vraag me nu ik dit schrijf wel af of er dan inputs zijn waarmee ik pech heb?
as always:
https://github.com/Cranza.../2021/day6/python/day6.py
[ Voor 34% gewijzigd door Cranzai op 06-12-2021 10:21 ]
4049 dagen is geen probleem hiermee: (3ms) wat dat betreft voelt Python idd wel een beetje als valsspelen.. Er komt een enorm groot getal uit. Dat had ik in Java toch anders moeten doen denk ik.
https://github.com/YoToP/AoC-2021/blob/main/6/p2.py
Me think, why waste time say lot word, when few word do trick.
TrailBlazer schreef op maandag 6 december 2021 @ 10:26:
Ik had deel 2 moeilijker verwacht ergens iets met sterfte er in oid.
spoiler:Gelukkig al snel bedacht dat het aantal van elke vis bijhouden makkelijker was dan elke individuele vis. Was denk ik mijn snelste deel 2 ooit.
Alternatief zou je ook een soort tweede histogram bij kunnen houden waarin je bijhoudt wanneer wat te killen.
https://github.com/CodeEn...eer/aoc/aoc2021/Day6.java
"I had a problem, I solved it with regular expressions. Now I have two problems". That's shows a lack of appreciation for regular expressions: "I know have _star_ problems" --Kevlin Henney
Je hoeft geen numpy te gebruiken voorcoop schreef op maandag 6 december 2021 @ 08:38:
Dag 6 in Python
spoiler:Het lijkt wel een virus die visjes.
[ Voor 1% gewijzigd door DataGhost op 06-12-2021 10:52 . Reden: oja spoilers oeps ]
"Gelukkig" is het een gevalletje out of memory dus nog een poging met aangepaste JVM settings. Duurt "maar" 10 seconde om een nieuwe dag te berekenen dus het zou ooit moeten lukken
ShitHappens schreef op maandag 6 december 2021 @ 10:48:
Part 1 was zo gelukt, maar uiteraard
spoiler:Werkt dezelfde oplossing niet meer voor part 2
"Gelukkig" is het een gevalletje out of memory dus nog een poging met aangepaste JVM settings. Duurt "maar" 10 seconde om een nieuwe dag te berekenen dus het zou ooit moeten lukken
domme speedup gevonden
[ Voor 4% gewijzigd door DataGhost op 06-12-2021 10:57 ]
[ Voor 3% gewijzigd door Patriot op 06-12-2021 11:03 ]
Oh ja, je moet natuurlijk niet je code op de test input draaien...
[ Voor 3% gewijzigd door NickThissen op 06-12-2021 11:03 ]
Het kan zonder numpy, met nóg minder regels codePatriot schreef op maandag 6 december 2021 @ 10:55:
... uiteindelijk numpy maar gebruikt om mijn implementatie te vervangen van sommige kleine dingen. Gewoon omdat het dan minder regels code zijn
Haha, dat geloof ik, maar ik vind het zo prima eerlijk gezegd. Nog minder regels code heeft imo nu ook niet zo heel veel zin meerDataGhost schreef op maandag 6 december 2021 @ 11:10:
[...]
Het kan zonder numpy, met nóg minder regels code
https://github.com/Synthe.../blob/master/day6/day6.py
[ Voor 31% gewijzigd door iThinkSo op 06-12-2021 11:19 . Reden: url toevoegen ]
Dat is waar, maar het kan interessant zijn om uit te zoeken welk deel van je code eigenlijk letterlijk nutteloos is en alleen maar tijd kost zonder dat het iets verandert aan de uitkomstPatriot schreef op maandag 6 december 2021 @ 11:11:
[...]
Haha, dat geloof ik, maar ik vind het zo prima eerlijk gezegd. Nog minder regels code heeft imo nu ook niet zo heel veel zin meer
Was uiteraard eerst begonnen met een fish class, maar met deel 2 moest ik die omschrijven en toen heb ik een uur zitten staren naar een off-by-one error.
[ Voor 6% gewijzigd door EfBe op 06-12-2021 11:28 ]
Creator of: LLBLGen Pro | Camera mods for games
Photography portfolio: https://fransbouma.com
Is het niet een 9*9 matrix waar je een macht van neemt?KabouterSuper schreef op maandag 6 december 2021 @ 10:02:
Iemand nog zin om een algemene oplossing te vinden voor dag 6 zonder te programmeren? Ik claim dat ik het kan met alleen pen en papier (maar ben niet zo dol op het vinden van nulpunten van een 9e graads polynoom).
Edit2:DataGhost schreef op maandag 6 december 2021 @ 10:53:
[...]
spoiler:1048576 dagen uitrekenen duurt bij mij 22 seconden 5 seconden in totaal
domme speedup gevonden
EDIT:@DataGhost
[ Voor 20% gewijzigd door YoToP op 06-12-2021 12:00 . Reden: update code :) ]
Me think, why waste time say lot word, when few word do trick.
Ja ik draai het dus in een VM op een oude laptop, ging me er meer om dat er een paar ordes van grootte verschil zit tussen 40 minuten en 5 seconden (voor een input die 4096 keer zo groot is). Ondertussen nog maar 3 seconden trouwens, sneller gaat het volgens mij niet worden op deze hardware/software.
[ Voor 7% gewijzigd door DataGhost op 06-12-2021 11:39 ]
Weet je het zeker?DataGhost schreef op maandag 6 december 2021 @ 10:44:
[...]
Je hoeft geen numpy te gebruiken voorspoiler:, die uitkomst isbig ints. If anything, heb je het jezelf daarmee mogelijk lastiger gemaakt, aangezien je expliciet Int64s gebruikt. Probeer maar eens met 1048576 dagen
spoiler:een getal van zo'n 39000 cijfers wat ik eerst in deze spoiler wilde zetten maar toch maar niet heb gedaan. Het eindigt in ieder geval op 28573496239894039695745723808288682175668852848906644415654274469955462501827062337915214000466450439329
Bij mij eindigd hij op 9316. Het getal heeft iig 39676 digits. Mijn oplossing had ongeveer 2 en een halve seconde nodig om het te berekenen.
Ken Thompson's famous line from V6 UNIX is equaly applicable to this post:
'You are not expected to understand this'
Lang op het tweede deel zitten staren waarom het zo lang duurt
[ Voor 21% gewijzigd door FrankMennink op 06-12-2021 11:44 ]
Doe je dit op de testinput uit de probleemomschrijving, of op jouw eigen volledige input? 39674 digits hier trouwens.Janoz schreef op maandag 6 december 2021 @ 11:37:
[...]
Weet je het zeker?
Bij mij eindigd hij op 9316. Het getal heeft iig 39676 digits. Mijn oplossing had ongeveer 2 en een halve seconde nodig om het te berekenen.
[ Voor 3% gewijzigd door DataGhost op 06-12-2021 11:42 ]
Janoz schreef op maandag 6 december 2021 @ 11:37:
[...]
Weet je het zeker?
Bij mij eindigd hij op 9316. Het getal heeft iig 39676 digits. Mijn oplossing had ongeveer 2 en een halve seconde nodig om het te berekenen.
Oh, dat is het verschil. Bij input "3,4,3,1,2" komt er inderdaad wel 39675 digits lang getal uit eindigend op 9329.DataGhost schreef op maandag 6 december 2021 @ 11:41:
[...]
Doe je dit op de testinput uit de probleemomschrijving, of op jouw eigen volledige input? 39674 digits hier trouwens.
Maakt qua doorloop niet uit natuurlijk. Alleen de vulling van het start histogram is anders.
Ken Thompson's famous line from V6 UNIX is equaly applicable to this post:
'You are not expected to understand this'
Nou ja afhankelijk van je algoritme kan het zomaar een factor 10 aan totale tijd schelenJanoz schreef op maandag 6 december 2021 @ 11:44:
[...]
Oh, dat is het verschil. Bij input "3,4,3,1,2" komt er inderdaad wel 39675 digits lang getal uit eindigend op 9329.
Maakt qua doorloop niet uit natuurlijk. Alleen de vulling van het start histogram is anders.
Klopt! En als je die met de hand wilt uitrekenen, zoek de de eigenwaarden/vectoren (wat de nulpunten van de 9e graads polynoom zijn). Maar als je de matrix hebt, kan je het ook in python gooien. Als je je heel erg verveelt, kom je op een oplossing met twee regels code:iThinkSo schreef op maandag 6 december 2021 @ 11:33:
[...]
Is het niet een 9*9 matrix waar je een macht van neemt?
print('total after 256 day(s) is '+str(np.sum(np.linalg.matrix_power (np.array([[0,1,0,0,0,0,0,0,0],[0,0,1,0,0,0,0,0,0],[0,0,0,1,0,0,0,0,0],[0,0,0,0,1,0,0,0,0],[0,0,0,0,0,1,0,0,0],[0,0,0,0,0,0,1,0,0],[1,0,0,0,0,0,0,1,0],[0,0,0,0,0,0,0,0,1],[1,0,0,0,0,0,0,0,0]],dtype=np.object), 256).dot(np.array([[int(int(d)) for d in io.open("C:\\Users\\xxxx\\Advent of Code\\2021\\day 06 input.txt", "r", encoding="utf-8").readline().split(',')].count(d) for d in range(9)],dtype=np.object)))))
Edit: ja, ik verveel me stierlijk.
Edit2: vanwege numpy krijg je waarschijnlijk een overflow zodra je boven int64 een bepaalde waarde komt.. Ik heb het geprobeerd met 1048576 dagen. Het goede antwoord was er in 5 seconden...niet slecht voor python.
[ Voor 14% gewijzigd door KabouterSuper op 06-12-2021 12:20 ]
When life gives you lemons, start a battery factory
Bedankt voor de tip. Het kan met circshift inderdaad compacter. Ik heb de initialisatie van N ook nog watcompacter gekregen:
N = sum(x==[0:8]',2)';
for i=1:256
N = circshift(N,-1) + [0,0,0,0,0,0,N(1),0,0];
end
disp(sum(N))
Ken Thompson's famous line from V6 UNIX is equaly applicable to this post:
'You are not expected to understand this'
ZIPper: Zelfstandig Interim Professional
We staan al een paar dagen in de leaderboard bij elkaar in de buurt (gisteren stond jij direct boven mij, vandaag direct onder mij, ik ben anonymous user #1535341). Dus ik weet niet of ik het leuk vind dat jij al een matrix-module klaar hebt liggenJanoz schreef op maandag 6 december 2021 @ 12:39:
@KabouterSuper goh, alle matrix meuk was bij mij eigenlijk al best ver weggevallen. Bij de Bingo vraag had ik al een paar matrix functies gebruikt (en dus geschreven). Maar nu heb die util nog even verder uitgewerkt om de oplossing van vandaag ook met matrices op te kunnen lossen. Altijd handig die functies alvast in mijn project te hebben. Zal de komende dagen vast nog wel eens nodig zijn.
Overigens, de matlab-oplossing van @ZieglerNichols is nog eleganter qua opbouw; hier wordt mooi gebruik gemaakt dat de matrix-multiplicatie eigenlijk helemaal niet nodig is.
[ Voor 8% gewijzigd door KabouterSuper op 06-12-2021 19:43 ]
When life gives you lemons, start a battery factory
Erg gaaf!KabouterSuper schreef op maandag 6 december 2021 @ 11:54:
[...]
Klopt! En als je die met de hand wilt uitrekenen, zoek de de eigenwaarden/vectoren (wat de nulpunten van de 9e graads polynoom zijn). Maar als je de matrix hebt, kan je het ook in python gooien. Als je je heel erg verveelt, kom je op een oplossing met twee regels code:
spoiler:import io,numpy as np
print('total after 256 day(s) is '+str(np.sum(np.linalg.matrix_power (np.array([[0,1,0,0,0,0,0,0,0],[0,0,1,0,0,0,0,0,0],[0,0,0,1,0,0,0,0,0],[0,0,0,0,1,0,0,0,0],[0,0,0,0,0,1,0,0,0],[0,0,0,0,0,0,1,0,0],[1,0,0,0,0,0,0,1,0],[0,0,0,0,0,0,0,0,1],[1,0,0,0,0,0,0,0,0]],dtype=np.object), 256).dot(np.array([[int(int(d)) for d in io.open("C:\\Users\\xxxx\\Advent of Code\\2021\\day 06 input.txt", "r", encoding="utf-8").readline().split(',')].count(d) for d in range(9)],dtype=np.object)))))
Edit: ja, ik verveel me stierlijk.
Edit2: vanwege numpy krijg je waarschijnlijk een overflow zodra je boven int64 een bepaalde waarde komt.. Ik heb het geprobeerd met 1048576 dagen. Het goede antwoord was er in 5 seconden...niet slecht voor python.
Heb je hier ook een Jip en Janneke uitleg van? Het klein beetje lineaire algebra dat ik als scheikundige ken is niet genoeg haha.
Ik heb zelf trouwens ook wiskunde gedaan (of eigenlijk informatica, maar dat was eind vorige eeuw nog bijna hetzelfde als wiskunde)
Ben trouwens wel ff aan het rekenen geslagen en de matrix oplossing is wel de efficiëntste. De normale histogram doorreken variant is O(N) waarbij N het aantal dagen is, terwijl de matrix variant het kan doen in O(logN) mits je een recursieve matrix vermenigvuldiging gebruikt (wat in numpy vast het geval is)
Oh, en de ranking heeft voornamelijk te maken met hoe vroeg je opstaat lijkt me. Als ik pas 's avonds tijd heb om de puzzel te maken dan is mijn score een stuk lager
[ Voor 13% gewijzigd door Janoz op 06-12-2021 12:57 ]
Ken Thompson's famous line from V6 UNIX is equaly applicable to this post:
'You are not expected to understand this'
@Cranzai
"Doubt—the concern that my views may not be entirely correct—is the true friend of wisdom and (along with empathy, to which it’s related) the greatest enemy of polarization." -- Václav Havel
Zelfs als ik al het geheugen van te voren reserveer en ik de kleinste aantal bits reserveer dan heb ik voor elke vis 4 bits nodig en op de laatste dag heb ik dan 811.266.672.163 bytes nodig (eigenlijk is de laatste byte 0,5, maar ja dat bestaat niet). Dat is dan weer 792.252.609,5 KiB en dat is dan weer 773684,2 MiB en dat komt uit op 755,6 GiB aan RAM.
In andere woorden onze computers zijn waarschijnlijk kleiner dan de ocean.
[ Voor 4% gewijzigd door DevWouter op 06-12-2021 13:10 ]
"Doubt—the concern that my views may not be entirely correct—is the true friend of wisdom and (along with empathy, to which it’s related) the greatest enemy of polarization." -- Václav Havel
numpy.transpose?Janoz schreef op maandag 6 december 2021 @ 12:55:
Nou, de matrix module had ik nog niet. Heb alleen snel een traspose geschreven bij de Bingo.
Dat kan ik beamen. Het enige verschil tussen wiskunde en informatica in mijn tijd (in '93 begonnen) was dat de informatici nog veel slechter waren in mechanica dan de wiskundigen. Ik heb mijn dosis ouderwetsche programmeertalen toen wel gehad (pascal, pdp11, fortran). Tegenwoordig alleen nog bezig met (PL-)SQL, python en php/html/css/js.Janoz schreef op maandag 6 december 2021 @ 12:55:
Ik heb zelf trouwens ook wiskunde gedaan (of eigenlijk informatica, maar dat was eind vorige eeuw nog bijna hetzelfde als wiskunde)
Oh, dat is wel verrassend. Ik zat nog te denken of een sparse matrix-aanpak de boel nog versnelt, aangezien de matrix vrij simpel van vorm is. Dat zal de orde-performance niet veranderen neem ik aan.Janoz schreef op maandag 6 december 2021 @ 12:55:Ben trouwens wel ff aan het rekenen geslagen en de matrix oplossing is wel de efficiëntste. De normale histogram doorreken variant is O(N) waarbij N het aantal dagen is, terwijl de matrix variant het kan doen in O(logN) mits je een recursieve matrix vermenigvuldiging gebruikt (wat in numpy vast het geval is)
Cranzai schreef op maandag 6 december 2021 @ 12:54:
[...]
Erg gaaf!
Heb je hier ook een Jip en Janneke uitleg van? Het klein beetje lineaire algebra dat ik als scheikundige ken is niet genoeg haha.
vis(bevalt over 0 dagen,tijdstip t+1)=vis(bevalt over 1 dag ,tijdstip t)
vis(bevalt over 1 dag ,tijdstip t+1)=vis(bevalt over 2 dagen,tijdstip t)
vis(bevalt over 2 dagen,tijdstip t+1)=vis(bevalt over 3 dagen,tijdstip t)
vis(bevalt over 3 dagen,tijdstip t+1)=vis(bevalt over 4 dagen,tijdstip t)
vis(bevalt over 4 dagen,tijdstip t+1)=vis(bevalt over 5 dagen,tijdstip t)
vis(bevalt over 5 dagen,tijdstip t+1)=vis(bevalt over 6 dagen,tijdstip t)
vis(bevalt over 6 dagen,tijdstip t+1)=vis(bevalt over 7 dagen,tijdstip t)+vis(bevalt over 0 dagen,tijdstip t)
vis(bevalt over 7 dagen,tijdstip t+1)=vis(bevalt over 8 dage,tijdstip tn)
vis(bevalt over 8 dagen,tijdstip t+1)=vis(bevalt over 0 dagen,tijdstip t)
In matrix vorm wordt dit:
vissen(tijdstap t+1)= [
[0,1,0,0,0,0,0,0,0],
[0,0,1,0,0,0,0,0,0],
[0,0,0,1,0,0,0,0,0],
[0,0,0,0,1,0,0,0,0],
[0,0,0,0,0,1,0,0,0],
[0,0,0,0,0,0,1,0,0],
[1,0,0,0,0,0,0,1,0],
[0,0,0,0,0,0,0,0,1],
[1,0,0,0,0,0,0,0,0]
]*vissen(tijdstap t)
waarbij vissen een vector is ter grootte 9 met alle stadia van zwangerschap.
Als je dit herhaaldelijk toepast, krijg je een matrixvermenigvuldiging (np.linalg.matrix_power operatie)
tenslotte laat je deze matrix los op de begin-vector van vissen (.dot operatie)
When life gives you lemons, start a battery factory
Eigenlijk komt het er in het kort op neer dat je een matrix hebt waarmee je de totalen van vandaag vermenigvuldigd om de totalen van morgen te krijgen.
Je hebt dus een matrix P met je populatie visjes en een matrix R die de reproductie voorstelt
Dit zijn bv de eerste 2 stappen in het voorbeeld uitgeschreven (hoe de berekening exact gaat moet je maar ff opzoeken).
P1 = P0 x R
1
2
3
4
5
6
7
8
9
| {0,0,0,0,0,0,1,0,1}
{1,0,0,0,0,0,0,0,0}
{0,1,0,0,0,0,0,0,0}
{0,0,1,0,0,0,0,0,0}
{0,1,1,2,1,0,0,0,0} X {0,0,0,1,0,0,0,0,0} = {1,1,2,1,0,0,0,0}
{0,0,0,0,1,0,0,0,0}
{0,0,0,0,0,1,0,0,0}
{0,0,0,0,0,0,1,0,0}
{0,0,0,0,0,0,0,1,0} |
P2 = P1 x R
1
2
3
4
5
6
7
8
9
| {0,0,0,0,0,0,1,0,1}
{1,0,0,0,0,0,0,0,0}
{0,1,0,0,0,0,0,0,0}
{0,0,1,0,0,0,0,0,0}
{1,1,2,1,0,0,0,0,0} X {0,0,0,1,0,0,0,0,0} = {1,2,1,0,0,1,0,1}
{0,0,0,0,1,0,0,0,0}
{0,0,0,0,0,1,0,0,0}
{0,0,0,0,0,0,1,0,0}
{0,0,0,0,0,0,0,1,0} |
Door dit nu 80 keer te herhalen kom je op het antwoord uit.
De truuk is echter dat de vermenigvuldigingen transitief zijn.
P2 = P0 x R x R
of
P2 = P0 x R2
Het uiteindelijke antwoord kun je dus ook krijgen door:
P80 = P0 x R80
Die R80 kun je middels een truukje* in O(log '80' ) berekenen waardoor je uiteindelijk op een complexiteit uitkomt van O(Log N).
* Het truukje:
R1 = R
Rx = Rceil(x/2) x Rfloor(x/2)
Ken Thompson's famous line from V6 UNIX is equaly applicable to this post:
'You are not expected to understand this'
Ah, dus je hebt gewoon wel een matrix lib tot je beschikkingKabouterSuper schreef op maandag 6 december 2021 @ 13:20:
numpy.transpose?
Ik vind het voornamelijk leuk om het nog even zelf uit te schrijven. Fijne afwisseling met het normale bedrijfsproces automatiseren
Ken Thompson's famous line from V6 UNIX is equaly applicable to this post:
'You are not expected to understand this'
Bedankt voor de uitleg heren, zo is die mij duidelijk.
Kon in de two-liner van KabouterSuper de loop over de vermenigvuldiging zo snel niet herkennen.
Pn = P0 x Rn is toch wel een pracht oplossing
edit:
Zo mooi dat ik hem gwn eventjes moet uitvoeren
[ Voor 10% gewijzigd door Cranzai op 06-12-2021 13:25 ]
Call took 35 milliseconds
[ Voor 50% gewijzigd door luukvr op 06-12-2021 13:51 ]
Mooi.Janoz schreef op maandag 6 december 2021 @ 13:21:
@Cranzai
P80 = P0 x R80
Die R80 kun je middels een truukje* in O(log '80' ) berekenen waardoor je uiteindelijk op een complexiteit uitkomt van O(Log N).
* Het truukje:
R1 = R
Rx = Rceil(x/2) x Rfloor(x/2)
Bij Janoz' aanpak zou je dit doen:
R2,
R3=R2*R,
R5=R2*R3,
R10=(R5)2,
R20=(R10)2,
R40=(R20)2,
R80=(R40)2,
Dus met 7 operaties ben je er. Vandaar dus de O(logN).
In dit geval is 80 toevallig ook 64+16, dus je kunt dit ook doen:
R2,
R4=(R2)2,
R8=(R4)2,
R16=(R8)2,
R32=(R16)2,
R64=(R32)2,
En dan doe je R64 * R16
Maar misschien worden we een beetje te enthousiast en dwalen we teveel af.
When life gives you lemons, start a battery factory
Part 1 was 0.0182 ms
Part 2 was 0.0246 ms
{
//store the data
var gens = new long[9];
var NextGens = new long[9];
//prepare data for the start situation
foreach(var start in lines[0].Split(',').Select(x => int.Parse(x)))
{
gens[start]++;
}
//each day
for (int day = 0; day < daysToDo; day++)
{
NextGens[7] = gens[8];
NextGens[6] = gens[7];
NextGens[5] = gens[6];
NextGens[4] = gens[5];
NextGens[3] = gens[4];
NextGens[2] = gens[3];
NextGens[1] = gens[2];
NextGens[0] = gens[1];
NextGens[8] = gens[0]; //new
NextGens[6] += gens[0]; //existing
//rotate arrsys
var tmp = gens;
gens = NextGens;
NextGens = tmp;
}
//done
return gens.Sum();
}
[ Voor 8% gewijzigd door DRaakje op 06-12-2021 13:50 ]
Om even pedant te doen: beide methoden zijn minimaal O(N) omdat de lengte van de uitvoer O(N) is. Print maar de antwoorden voor N=100, N=1000, N=10000 etc., dan zul je zien dat het aantal cijfers in de uitvoer ook steeds 10 keer zo groot is (ongeveer).Janoz schreef op maandag 6 december 2021 @ 12:55:
Ben trouwens wel ff aan het rekenen geslagen en de matrix oplossing is wel de efficiëntste. De normale histogram doorreken variant is O(N) waarbij N het aantal dagen is, terwijl de matrix variant het kan doen in O(logN)
Daardoor is de aanpak met machtsverheffen niet O(log N), omdat grote getallen optellen en vermenigvuldigen niet in O(1) tijd kan. Optellen alleen is al O(N). Toch zijn beide methoden O(N), of dicht daarbij in de buurt: hoewel de lineaire aanpak O(N) optellingen doet, kun je bewijzen dat het totaal aantal bits over alle optellingen ook O(N) is. Het bewijs is een oefening aan de lezer (steekwoord: amortized analysis).
De matrixmethode wordt pas sneller als je de uitvoer afkapt (b.v. alleen de laatste 10 cijfers, of modulo een of ander groot priemgetal).
Deel 2 van dag 6 deed er wel zo'n 430 seconde over, maar kreeg zo snel geen formule oid voor elkaar.
Dus maar iets opgelost met een "slimme" brute force.
En daarna mijn input bekeken en de eerder berekende totalen opgeteld zodat is niet meerdere keren dezelfde berekening hoef te doen.
Tevens maar iets recursive ingevoerd maar dat gaf nog geen acceptabele executie tijd.
Vanavond maar een rustig kijken welke slimme oplossingen jullie bedacht hebben...
[ Voor 2% gewijzigd door ydderf op 06-12-2021 19:02 . Reden: Fixed link ]
Soms gaat het niet zoals het moet, maar moet het maar zoals het gaat
Ja, dat kan (hierboven zijn al wat reacties hierover). De basis van een exponentiele formule is de ontbinding van de matrix in eigenwaarden en eigenvectoren (een diagonaalmatrix en een orthogonale matrix). Vervolgens neem je de gewenste macht van de diagonaalmatrix en vermenigvuldig je deze op de juiste manier met de eigenvector-matrix. Als je dit netjes uitschrijft, krijg je een lineaire combinatie van de machten van de eigenwaarden; kortom een exponentiele formule.Daanoz schreef op maandag 6 december 2021 @ 13:57:
Hmm, niet de juiste strategie gekozen.
spoiler:Ik dacht dat het wel mogelijk zou zijn om tot een exponentiële formule te komen waarbij het gewoon een kwestie is van de berekening uitvoeren voor een bepaald aantal dagen (en dat dan voor elke start dag). Helaas na veel kladblaadjes proberen is het gewoon een hashmap per vis leeftijd geworden. Vraag me toch af of het mogelijk is.
When life gives you lemons, start a battery factory
Ik zou nog eens goed kijken naar wat je nou eigenlijk precies doet op regels 24 t/m 30. Conceptueel gezien dus.ydderf schreef op maandag 6 december 2021 @ 14:06:
Hier ook Dag 5 en Dag 6 in C# afgerond.
Deel 2 van dag 6 deed er wel zo'n 430 seconde over, maar kreeg zo snel geen formule oid voor elkaar.
Dus maar iets opgelost met een "slimme" brute force.
spoiler:Eerst heb ik voor elke begin waarde het eindtotaal van 256 dagen uitgerekend. Bij mij waren dat de getallen 1 t/m 5.
En daarna mijn input bekeken en de eerder berekende totalen opgeteld zodat is niet meerdere keren dezelfde berekening hoef te doen.
Tevens maar iets recursive ingevoerd maar dat gaf nog geen acceptabele executie tijd.
Vanavond maar een rustig kijken welke slimme oplossingen jullie bedacht hebben...
Daar heb je wel een punt. Ik had inderdaad de vermenigvuldiging als O(1) genomen. Moet wel zeggen dat hij toch echt lekker vlot is. De @DataGhost set doet er bij mijn nog maar 833ms over.Soultaker schreef op maandag 6 december 2021 @ 14:00:
[...]
Om even pedant te doen: beide methoden zijn minimaal O(N) omdat de lengte van de uitvoer O(N) is. Print maar de antwoorden voor N=100, N=1000, N=10000 etc., dan zul je zien dat het aantal cijfers in de uitvoer ook steeds 10 keer zo groot is (ongeveer).
Daardoor is de aanpak met machtsverheffen niet O(log N), omdat grote getallen optellen en vermenigvuldigen niet in O(1) tijd kan. Optellen alleen is al O(N). Toch zijn beide methoden O(N), of dicht daarbij in de buurt: hoewel de lineaire aanpak O(N) optellingen doet, kun je bewijzen dat het totaal aantal bits over alle optellingen ook O(N) is. Het bewijs is een oefening aan de lezer (steekwoord: amortized analysis).
De matrixmethode wordt pas sneller als je de uitvoer afkapt (b.v. alleen de laatste 10 cijfers, of modulo een of ander groot priemgetal).
Ken Thompson's famous line from V6 UNIX is equaly applicable to this post:
'You are not expected to understand this'
Anyone who gets in between me and my morning coffee should be insecure.
Die "lompe" aanpak had ik ook in F#, maar vervolgens de array eruit gewerkt.Verwijderd schreef op zondag 5 december 2021 @ 19:58:
Wow nice oplossingen zie ik voor bij komen.
Ik had zelf maar de lompe aanpak gedaan:spoiler:"diagram" (2D list) op bouwen en muteren ("lijnen toevoegen") dan weer flattenen en filteren op >= 2 instersections en daarvan de lengte nemen, beetje te letterlijk genomen hoe het in de beschrijving stond.
De tweede oplossing zonder array gebruikt dan wel minder geheugen, maar is ook een factor 4 langzamer dan de eerste oplossing. Zal vast te maken hebben met het onderwater alloceren van extra objecten enz. in F#.
[ Voor 5% gewijzigd door Moonsugar op 26-03-2024 15:05 . Reden: URL verwijderd op verzoek van gebruiker ]
"Doubt—the concern that my views may not be entirely correct—is the true friend of wisdom and (along with empathy, to which it’s related) the greatest enemy of polarization." -- Václav Havel
Wat ik probeerde te maken:DataGhost schreef op maandag 6 december 2021 @ 14:14:
[...]
Ik zou nog eens goed kijken naar wat je nou eigenlijk precies doet op regels 24 t/m 30. Conceptueel gezien dus.
Elke dag de teller met 1 verlagen. Zodra je onder nul komt, betekend dat de vis een nieuwe vis gemaakt heeft (met teller 8 ) en zelf verder gaat met teller 6).
Hierna verwijder ik de vis met de teller onder nul.
Het zou sowieso mooier zijn om niet die vis te verwijderen en er één toe te voegen, maar de actuele teller van die vis aan te passen. Maar dat lukte mij niet (met mijn hobby c# kennis). En de count had nog direct in de for() kunnen staan ipv via een tussen geheugen.
Hopelijk bedoelde je dat met je opmerking, anders moet ik nog dieper gaan nadenken...
[ Voor 0% gewijzigd door ydderf op 06-12-2021 15:40 . Reden: 8 haakje sluiten werd smiley ]
Soms gaat het niet zoals het moet, maar moet het maar zoals het gaat
Misschien wordt het lastig zonder de hele oplossing te spoilen, maar probeer je eigen code eens als normaal engels te lezen. Dat is heel lastig omdat je het zelf geschreven hebt en het lastig loslaten is van je eerder bedachte concepten, maar misschien geeft het toch nieuwe inzichten. Op regels 26 t/m 30ydderf schreef op maandag 6 december 2021 @ 15:31:
[...]
Wat ik probeerde te maken:
Elke dag de teller met 1 verlagen. Zodra je onder nul komt, betekend dat de vis een nieuwe vis gemaakt heeft (met teller 8 ) en zelf verder gaat met teller 6).
Hierna verwijder ik de vis met de teller onder nul.
Het zou sowieso mooier zijn om niet die vis te verwijderen en er één toe te voegen, maar de actuele teller van die vis aan te passen. Maar dat lukte mij niet (met mijn hobby c# kennis). En de count had nog direct in de for() kunnen staan ipv via een tussen geheugen.
Hopelijk bedoelde je dat met je opmerking, anders moet ik nog dieper gaan nadenken...
Wat je op regel 24 doet
Ook kan je met die spoiler in het achterhoofd
[ Voor 4% gewijzigd door DataGhost op 06-12-2021 15:50 ]
Eerste deel had ik inderdaad hardcoded gedaan en daarna de diverse suggesties en hints van diverse mensen toegepast en daarna tot een best mooie oplossing gekomen
Het werkt allemaal prima maar dan zie ik van die scripts waarbij alles veel beknopter wordt gedaan. Misschien is het mijn onervarenheid maar desondanks vind ik het werken met classes ook voor dit soort kleine dingen wel makkelijk om het overzicht te bewaren.
Ik zou je adviseren om vooral gestructureerd te blijven werken. Duidelijke code leest lekkerder (zeker voor anderen), bevat vaak minder fouten en is fijn bij (unit-)testen. Compacte code is leuk om te showen, maar een hel om te debuggen of aan iemand anders uit te leggen. Wat overigens niet betekent dat je niet kunt leren van andermans code....en dat is precies waarom Advent of Code zo leuk is. Iedereen heeft andere oplossingen voor hetzelfde probleem, en zo leer je van elkaar!TrailBlazer schreef op maandag 6 december 2021 @ 18:56:
Ik merk dat ik vaak heel erg veel overbodige code schrijf. Vandaag heb ik ook weer een class Fishes geschreven. Hierin heb ik dan een functie add_fish geschreven om vissen toe te voegen en een functie om de vissen allemaal een dag ouder te laten worden. Ii
Het werkt allemaal prima maar dan zie ik van die scripts waarbij alles veel beknopter wordt gedaan. Misschien is het mijn onervarenheid maar desondanks vind ik het werken met classes ook voor dit soort kleine dingen wel makkelijk om het overzicht te bewaren.
When life gives you lemons, start a battery factory
Ik denk dat ik je feedback grotendeels begrijp. Al zegt de term "method-call" me niet direct wat. Maar misschien moet ik ook eerst de basis cursus C# nog een keer doen ipv direct beginnen.DataGhost schreef op maandag 6 december 2021 @ 15:49:
[...]
Misschien wordt het lastig zonder de hele oplossing te spoilen, maar probeer je eigen code eens als normaal engels te lezen. Dat is heel lastig omdat je het zelf geschreven hebt en het lastig loslaten is van je eerder bedachte concepten, maar misschien geeft het toch nieuwe inzichten. Op regels 26 t/m 30spoiler:heb je een loop over i, terwijl i helemaal niet gebruikt wordt in de loop. Vaak betekent zoiets dat die loop helemaal niet nodig is en er andere manieren zijn voor hetzelfde. Misschien moet je dan nog wat andere dingen aanpassen, zoals:
Wat je op regel 24 doetspoiler:kan je zien als een soort array access ipv een method-call op een list. Heb je alleen nog een concept nodig om het resultaat in een array bij te houden ipv dat dat elke keer berekend moet worden dmv die method-call.
Ook kan je met die spoiler in het achterhoofdspoiler:de "Add" in die loop ook als iets conceptueel anders zien dan hoe het nu gebruikt is.
Na wat inspiratie op te hebben gedaan bij de mede tweakers, heb ik een tweede versie gemaakt. Is wel een heel stukje korter qua code en executie tijd.
Soms gaat het niet zoals het moet, maar moet het maar zoals het gaat
Dat hoeft geen slechte eigenschap te zijn. Ik doe het zelf ook vaak. Zeker als ik twijfel over wat we er met dat specifieke data gedaan moet worden. In dit geval zag ik aan de vraag al dat het niet ging werken.TrailBlazer schreef op maandag 6 december 2021 @ 18:56:
Ik merk dat ik vaak heel erg veel overbodige code schrijf. Vandaag heb ik ook weer een class Fishes geschreven. Hierin heb ik dan een functie add_fish geschreven om vissen toe te voegen en een functie om de vissen allemaal een dag ouder te laten worden. Ii
Het werkt allemaal prima maar dan zie ik van die scripts waarbij alles veel beknopter wordt gedaan. Misschien is het mijn onervarenheid maar desondanks vind ik het werken met classes ook voor dit soort kleine dingen wel makkelijk om het overzicht te bewaren.
En ervarenheid helpt vooral om in te schatten wat wel/niet nodig is. Voor mij is het vooral een spel om het tweede gedeelte te raden. Tot dus ver heb ik alleen te complex gedacht.
En inderdaad zou ik het advies van KabouterSuper in "Advent of Code 2021" volgen.
"Doubt—the concern that my views may not be entirely correct—is the true friend of wisdom and (along with empathy, to which it’s related) the greatest enemy of polarization." -- Václav Havel
Overzicht bewaren en duidelijke code schrijven is belangrijker dan zo beknopt mogelijk. Eventuele optimalisatie komt daarna.
"I had a problem, I solved it with regular expressions. Now I have two problems". That's shows a lack of appreciation for regular expressions: "I know have _star_ problems" --Kevlin Henney
In ieder geval bij mijn code kan alles wel eens heel beknopt worden. Zoals meerderen hier is AoC niet mijn eerste programmeerwedstrijd en heb ik ook aan wedstrijden meegedaan die een paar uur duren voordat ze voorbij zijn. Daardoor zit er al een werkwijze in van "snel coden", gecombineerd met redelijk wat kennis over algoritmische problemen zorgt ervoor dat het van een AoC-probleem gauw genoeg duidelijk is wat voor "standaardprobleem" het is, evt met welke variaties eraan gedaan worden. Een heleboel gebeurt alvast in mijn hoofd voordat ik het uitschrijf naar code, en zo heb ik van anderen hier ook code gezien. Dat levert dan iets op wat niet direct leesbaar of begrijpbaar is, maar wel snel werkt en snel geschreven is.TrailBlazer schreef op maandag 6 december 2021 @ 18:56:
Ik merk dat ik vaak heel erg veel overbodige code schrijf. Vandaag heb ik ook weer een class Fishes geschreven. Hierin heb ik dan een functie add_fish geschreven om vissen toe te voegen en een functie om de vissen allemaal een dag ouder te laten worden. Ii
Het werkt allemaal prima maar dan zie ik van die scripts waarbij alles veel beknopter wordt gedaan. Misschien is het mijn onervarenheid maar desondanks vind ik het werken met classes ook voor dit soort kleine dingen wel makkelijk om het overzicht te bewaren.
Omdat de tijdsdruk hier wat minder is probeer ik wel iets leesbaardere of intuïtievere code te maken, zeker voordat ik het publiek maak. Ook ben ik met andere programmeerprojecten bezig waarin leesbaarheid belangrijk is voor de volgende die eraan gaat werken. Dit is zeker geen verkeerd iets om te doen, het levert alleen vaak wat extra "nutteloze" code op. Dat helpt wel enorm als er ooit een foutje in je algoritme zit omdat je dan veel makkelijker kan zien wat er verkeerd is. Dus gewoon doorgaan met uitgebreide code maken. Op den duur kan je in je uitgebreidere code bepaalde patronen gaan herkennen die je kan vervangen door iets wat veel korter is maar hetzelfde doet en hoef je ook minder lang na te denken over hoe alles nou in elkaar zit en in elkaar zou moeten zitten. Dat is puur ervaring, dat komt vanzelf maar dat duurt wel eventjes. Niks om je zorgen over te maken.
Het kan wel heel erg helpen om inderdaad goed de andere oplossingen in dit topic te bekijken en dan vooral proberen te begrijpen waarom die werken en daarna hoe ze werken. Je hoeft jouw eigen inzendingen dan niet op dezelfde manier te doen, maar het kan wel als een idee in je hoofd schieten als je ergens op stukloopt.
Als ik er zo heel kort naar kijk is dat inderdaad precies wat ik bedoelde. Je weet hopelijk ook waarom het werktydderf schreef op maandag 6 december 2021 @ 19:10:
[...]
Ik denk dat ik je feedback grotendeels begrijp. Al zegt de term "method-call" me niet direct wat. Maar misschien moet ik ook eerst de basis cursus C# nog een keer doen ipv direct beginnen.
Na wat inspiratie op te hebben gedaan bij de mede tweakers, heb ik een tweede versie gemaakt. Is wel een heel stukje korter qua code en executie tijd.
Wat betreft een method call... een klasse heeft functies, die worden in de context van een klasse methods genoemd. Een object is een instantie van een klasse.
Direct beginnen is prima, een cursus doet ook maar beperkt wat voor je kennis. Uiteindelijk moet je het heel veel doen. Terminologie is natuurlijk wel belangrijk om te begrijpen waar jij of een ander het over heeft, dus daar is een cursus vaak wel nuttig voor.
Het schaven van een oplossing vind ik ook wel erg leuk moet ik zeggen.
Net als met dag 5, waarin eigenlijk het hele grid geen rol speelt, en de individuele lijnen zelfs in mindere mate - eigenlijk draait alles enkel om de snijpunten.
Dag 4: "bingo spelen" is eigenlijk helemaal niet nodig, enkel per kaart berekenen na hoeveel beurten deze zou winnen
Maar ja, ik ben nou eenmaal erg slecht in abstract denken en absoluut geen held in wiskunde, dus juist het zo concreet mogelijk schrijven van code (zo "dicht bij" het verhaal als mogelijk) helpt me het juiste resultaat te behalen... En ja ach, soms zorgt dat ervoor dat de gekozen oplossing niet helemaal ideaal blijkt. Ik doe dan juist ook mee om een beetje uitgedaagd te worden, en wat anders te programmeren dan werk. Valt altijd wat van te leren
We zitten nog maar op dag 6TrailBlazer schreef op maandag 6 december 2021 @ 21:48:
Ik stel met voor dat de maker bij de 2e task een enorme evil laugh had.
Caelorum schreef op maandag 6 december 2021 @ 21:20:
spoiler:"maybe exponentially quickly" was bij mij de trigger om het meteen per dag te doen dan "dom" simuleren. Vaak zie je ook wel een hint in het eerste stuk over hoe het tweede deel gaat zijn.
[ Voor 34% gewijzigd door Varienaja op 07-12-2021 06:26 ]
Siditamentis astuentis pactum.
Inderdaad erg makkelijk vandaag.Varienaja schreef op dinsdag 7 december 2021 @ 06:16:
Nou.. vandaag was erg gemakkelijk. Helemaal als ik het vergelijk met vorig jaar.
When life gives you lemons, start a battery factory
Eigenlijk verwacht ik ook wel dat het de bedoeling was om iets slims te bouwen, maar dat bleek niet per se nodig. Lomp alles doorrekenen lukt bij mij binnen een halve seconde.
[ Voor 38% gewijzigd door dcm360 op 07-12-2021 06:22 ]
Deze was heel erg makkelijk.
Ik raakte alleen enorm in de war omdat het eerste antwoord heel erg leek op het antwoord van dag 6 voor part 1. Daardoor dacht ik dat ik de verkeerde functie aanriep:
- 373378
- 337833
Engineering is like Tetris. Succes disappears and errors accumulate.
Ik denk oprecht dat als ik om 6 uur was opgestaan ik op het leaderboard was gekomen haha. Het is niet de snelste code, maar beide parts in 1 regel en in 1x goed. Jammer dat ze zo vroeg online komen.
De scripts die veel beknopter zijn zijn in mijn geval nadat ik het antwoord heb en het opschoont heb. Ik werk in den beginne ook erg verbose.TrailBlazer schreef op maandag 6 december 2021 @ 18:56:
Ik merk dat ik vaak heel erg veel overbodige code schrijf. Vandaag heb ik ook weer een class Fishes geschreven. Hierin heb ik dan een functie add_fish geschreven om vissen toe te voegen en een functie om de vissen allemaal een dag ouder te laten worden. Ii
Het werkt allemaal prima maar dan zie ik van die scripts waarbij alles veel beknopter wordt gedaan. Misschien is het mijn onervarenheid maar desondanks vind ik het werken met classes ook voor dit soort kleine dingen wel makkelijk om het overzicht te bewaren.
Engineering is like Tetris. Succes disappears and errors accumulate.
Github.
-- Edit -- Bedenk net dat je als je eerst je positie bepaalt en dan de fuel berekent ik niet steeds de fuel hoef up te daten en dus nog net iets sneller is.
[ Voor 8% gewijzigd door bakkerjangert op 07-12-2021 07:50 ]
Hier ook. Het is een beetje afhankelijk van de oplossing maar voor complexere zaken waar ik moet debuggen e.d. schrijf ik het ook eerst vaak meer procedureel op, en bouw het daarna om.armageddon_2k1 schreef op dinsdag 7 december 2021 @ 07:24:
De scripts die veel beknopter zijn zijn in mijn geval nadat ik het antwoord heb en het opschoont heb. Ik werk in den beginne ook erg verbose.
https://niels.nu
Het is btw geen exponentiële groeiarmageddon_2k1 schreef op dinsdag 7 december 2021 @ 07:19:
Dag 7 in Kotlin.
Deze was heel erg makkelijk.
Ik raakte alleen enorm in de war omdat het eerste antwoord heel erg leek op het antwoord van dag 6 voor part 1. Daardoor dacht ik dat ik de verkeerde functie aanriep:
- 373378
- 337833
Neem je whisky mee, is het te weinig... *zucht*