Engineering is like Tetris. Succes disappears and errors accumulate.
Poeh, part 2 was even puzzelen. Ik ben blij dat ik al wat Project Euler ervaring heb, dus uiteindelijk ben ik eruit gekomen. De code ga ik later nog wel even wat duidelijker maken.
Stel niet uit tot morgen wat je vandaag nog tot morgen kunt uitstellen...
https://github.com/rverst.../blob/main/Y2020/Day13.cs
“Build a man a fire, and he'll be warm for a day. Set a man on fire, and he'll be warm for the rest of his life.”
Mooi, met die LINQ expressie in part 1!Woy schreef op zondag 13 december 2020 @ 09:34:
Part2 had ik inderdaad ook iets meer tijd voor nodig om er over na te denken, eerst even rustig douchen en toen had ik redelijk vlot een oplossing.
https://github.com/rverst...de2020/blob/main/Day13.cs
Stel niet uit tot morgen wat je vandaag nog tot morgen kunt uitstellen...
Voorbeeld in part 2 (17,x,13,19) had ik vrij snel opgelost. Maar ja, die oplossing werkte niet meer echt snel met meerdere buslijnen.vliegnerd schreef op zondag 13 december 2020 @ 08:44:
Dag 13 deel 2 is voor mij de eerste puzzel waarbij ik denk... Uhh...
Omdat ik eerdere edities heb meegedaan, herken ik het getaltheorie dingetje wel. Maar vervolgens weet ik niet hoe ik het moet oplossen.
spoiler:Bus ID zijn priemgetallen, dus het zal wel Chinese Remainder Theorem zijn...
Ik ga eerst maar eens met 3 getallen op papier proberen... Er komt de laatste jaren altijd zo'n moment dat de puzzel meer tijd kost dan ik eraan kan besteden... En vandaag is waarschijnlijk die dag ;-)
(Mijn Python oplossingen: https://github.com/tomkooij/adventofcode)
EDIT: Eehmm.. tip: als je vastzit, lees de opdracht in plaats van bovenstaande. Ik had (niet voor het eerst) een heel andere opdracht in gedachten
Ik las op reddit een hint en vond daarna desbetreffende getaltheorie. Dan is het opeens simpel.
Dan gevonden dat de huidige situatie zich maar voordoet bij veelvouden van het kleinste gemeen veelvoud van alle reeds geplande bussen. Zie nu dat jullie spreken dat het allemaal priemgetallen zijn, dan had ik dus eigenlijk gewoon kunne vermenigvuldigen
https://github.com/mscham...blob/master/2020/Day13.cs
Duurde even, mijn hersenen wilden niet meewerken. Uiteindelijk een snelle oplossing gevonden en in heel weinig code nog wel.
Belangrijk is hier wel dat je niet een nieuwe sequence maakt door te filteren op de oude, maar echt een nieuwe op basis van f[0] = init, f[n] = f[n-1] + step. De routine rekent dus init en step uit en genereert daar een nieuwe sequence mee. Die stepsize is natuurlijk gewoon de vermenigvuldiging van de primes, maar ik was lui.
[ Voor 23% gewijzigd door armageddon_2k1 op 13-12-2020 10:37 ]
Engineering is like Tetris. Succes disappears and errors accumulate.
Dat was omdat er in de tekst dit stondDricus schreef op zondag 13 december 2020 @ 09:50:
[...]
Mooi, met die LINQ expressie in part 1!
spoiler:Vanwaar die startwaarde voor timestamp bij part 2? Het lijkt optimalisatie te zijn, maar dan had je ook wel hoger kunnen gaan zitten, gegeven de informatie in de opdracht. En het is wel nano-optimalisatie, want ik begin gewoon bij 1 en mijn oplossing (die hetzelfde werkt als de jouwe) heeft in 110 microsecondes het antwoord.
Maar ik zie dat ik nog een factor 1000 te laag begonnen benHowever, with so many bus IDs in your list, surely the actual earliest timestamp will be larger than 100000000000000!
“Build a man a fire, and he'll be warm for a day. Set a man on fire, and he'll be warm for the rest of his life.”
Volgens mij is het prima met hand uit te rekenen als je de truc eenmaal door hebt (afgezien van de onhandig grote getallen).
Siditamentis astuentis pactum.
Het is grappig om te zien dat hoewel ik vandaag met een schone lei was begonnen, de code van vandaag ook nagenoeg hetzelfde is als de code uit 2016 (op namen van variabelen na).
In 2016 heb ik de code / het algoritme van jou afgekeken, denk ik. En vandaag heb ik dat indirect weer gedaan omdat ik mij de puzzel herinnerde (en pas na goed lezen zag dat het gewoon hetzelfde was).Soultaker schreef op zondag 13 december 2020 @ 12:15:
Dag 13 deel 2 is exact hetzelfde probleem als dag 15 van 2016.
4,8kW ZO-NW PVOutput 8x300Wp ZO 12 graden. 8x300Wp NW 12 graden.
... en gaat over tot de orde van de dag
Fuck man, deel 2 van dag 10 ben ik echt uren mee bezig geweest! DP is echt m'n ding niet
https://niels.nu
YouTube: Chinese Remainder Theorem
Mijn code in c#
[ Voor 13% gewijzigd door Daos op 13-12-2020 15:09 ]
Uit de lappenmand dus en weer inhalenHydra schreef op zondag 13 december 2020 @ 14:17:
Nou, ben weer wat beter dus maar aan de slag gegaan.
Fuck man, deel 2 van dag 10 ben ik echt uren mee bezig geweest! DP is echt m'n ding nietOp naar dag 11
DP heb je in feite niet nodig, je kan ook gewoon een fold doen over de waardes (oplopend) en in de accumulator een lookup bijhouden. Effectief natuurlijk DP maar dan waar de waardes al op volgorde liggen. Sortering is ook O(n) te doen omdat je weet wat het maximum kan zijn (3*n).
Engineering is like Tetris. Succes disappears and errors accumulate.
P_Tingen schreef op zondag 13 december 2020 @ 13:33:
Pff, eerste deel was beschamend makkelijk, maar zo moeilijk is deel 2. Ik ben nog aan het puzzelen, maar dit is wat teveel wiskunde voor mijn smaak
https://github.com/evanraalte/aoc2020/tree/master/day13
[/spoiler]
Aanzienlijk makkelijker
https://niels.nu
Had ik ok last van, ik had east/west omgedraaid, maar dat kwam niet voor in het voorbeeldHydra schreef op zondag 13 december 2020 @ 15:46:
Meh. Scheit. 12 moet een eitje zijn, en ik krijg op deel 1 op de voorbeeld input het juiste antwoord maar niet op de echte... Now what...
“Build a man a fire, and he'll be warm for a day. Set a man on fire, and he'll be warm for the rest of his life.”
Hydra schreef op zondag 13 december 2020 @ 15:46:
Meh. Scheit. 12 moet een eitje zijn, en ik krijg op deel 1 op de voorbeeld input het juiste antwoord maar niet op de echte... Now what...
[ Voor 4% gewijzigd door Mschamp op 13-12-2020 15:49 ]
Fuck me... Wat een kutvoorbeeld dan dat het daar niet op misgaat...Mschamp schreef op zondag 13 december 2020 @ 15:48:
spoiler:Misschien vergeten dat bij R en L meer dan 90 kan staan (ook 180 en denk ook 270 komen voor) in het voorbeeld is het enkel 90
https://niels.nu
Jup. ging bij mij ook fout. denkfoutje met tijdelijke variable die overschreven werd ipv opgeteld bij meerdere 90 graden bochten.Hydra schreef op zondag 13 december 2020 @ 15:50:
[...]
Fuck me... Wat een kutvoorbeeld dan dat het daar niet op misgaat...
Wel merk ik dat ik nodeloos defensief programeer. getallen zijn ook altijd getallen.
En ik had wel iets sneakys als een r0 verwacht. om ergens een divide by zero error te triggeren.
Heuveltjes CPU geschiedenis door de jaren heen : AMD 486dx4 100, Cyrix PR166+, Intel P233MMX, Intel Celeron 366Mhz, AMD K6-450, AMD duron 600, AMD Thunderbird 1200mhz, AMD Athlon 64 x2 5600, AMD Phenom X3 720, Intel i5 4460, AMD Ryzen 5 3600 5800x3d
Dat gebeurt heel vaak expres. Een opgave met lelijke corner cases verzinnen en daar dan die corner cases bij weglaten, of alleen sommige corner cases weglaten. Soms wordt in de opgave wel eens uitgelegd waarom een van de corner cases misgaat, dat is soms een hint dat er meer is en soms een rottigheidje om je minder oplettend te maken. Ik kijk zelf het liefst helemaal niet naar de voorbeeld-input, ik implementeer de opgave zoals ik denk dat 'ie zou moeten en verzin tijdens het implementeren al corner cases. Meestal gaat het dan op de voorbeeldinput wel direct goed en op de opgave ook. Ik heb dit jaar nog geen fout antwoord ingestuurd in ieder gevalHydra schreef op zondag 13 december 2020 @ 15:50:
[...]
Fuck me... Wat een kutvoorbeeld dan dat het daar niet op misgaat...
Vandaag was wel de eerste keer dat ik de daadwerkelijke puzzel-input had bekeken.
Nja, ik vind dat een beetje irritant.DataGhost schreef op zondag 13 december 2020 @ 16:29:
Dat gebeurt heel vaak expres. Een opgave met lelijke corner cases verzinnen en daar dan die corner cases bij weglaten, of alleen sommige corner cases weglaten.
Pas trouwens op met spoilers. Ik was volgens mij wel duidelijk dat ik nog niet aan 13 begonnen was en ik verwachtte dus niet dat in je spoiler vandaag gespoild zou staan.
https://niels.nu
Gebeurt bij alle software die je wilt ontwikkelen, de specificaties zijn altijd ruk en je zal toch echt zelf alle corner cases moeten verzinnen en testen.
Nja er staat letterlijk "vandaag" boven, en het is een spoiler. Daarom staat 'ie in een spoilerPas trouwens op met spoilers. Ik was volgens mij wel duidelijk dat ik nog niet aan 13 begonnen was en ik verwachtte dus niet dat in je spoiler vandaag gespoild zou staan.

Een goeie richtlijn is om op geen enkele spoiler te klikken als er "X december" boven de post staat en X > hoe ver jij bent met oplossen.
[ Voor 24% gewijzigd door DataGhost op 13-12-2020 16:51 ]
Je reageert op mijn post waarin ik het over dag 12 heb dan is het wel wat logisch te bedenken dat ik nog niet bij 13 ben en misschien voordat ik 't goed en wel gelezen heb die spoiler openklik. Lijkt me niet zo raar dat ik je vraag om daar wat voorzichtig mee te zijn.DataGhost schreef op zondag 13 december 2020 @ 16:48:
Nja er staat letterlijk "vandaag" boven, en het is een spoiler.
Sorry hoor, je kunt ook even meedenken.Een goeie richtlijn is om op geen enkele spoiler te klikken als er "X december" boven de post staat en X > hoe ver jij bent met oplossen.
[ Voor 18% gewijzigd door Hydra op 13-12-2020 16:54 ]
https://niels.nu
Volgens mij doe ik dat, door je een tip te geven. Moet ik volgende keer m'n spoiler in een spoiler nesten dan?
[ Voor 12% gewijzigd door DataGhost op 13-12-2020 16:59 ]
De rekentijd voor mijn oplossing voor deel 2 kwam daarmee uit op iets minder dan 2ms, waarmee dit interessant genoeg mijn snelste oplossing tot zover is.
[ Voor 3% gewijzigd door dcm360 op 13-12-2020 17:22 ]
Verwijderd
(wou het perse niet brute force doen)
382 ms
Geen eindeloze for loops dus...
[ Voor 89% gewijzigd door Verwijderd op 13-12-2020 20:20 ]
Kan je die code alsjeblieft ergens anders posten (op Github ofzo, of desnoods op pastebin.com)? Een lange lap code draagt niet veel bij aan de discussie en is niet fijn om langs te moeten scrollen.
Met bijkomend voordeel dat de code dan tenminste leesbaar is.Soultaker schreef op zondag 13 december 2020 @ 18:20:
Kan je die code alsjeblieft ergens anders posten (op Github ofzo, of desnoods op pastebin.com)? Een lange lap code draagt niet veel bij aan de discussie en is niet fijn om langs te moeten scrollen.
https://niels.nu
Deel 1 was simpel, deel 2 heb ik enorm op vastgezeten. Uiteindelijk een hint online moeten opzoeken.
Wel jammer dat 't niet 100% m'n eigen oplossing was, maargoed.
https://niels.nu
DieHydra schreef op zondag 13 december 2020 @ 18:41:
En tenslotte Day 13.
Deel 1 was simpel, deel 2 heb ik enorm op vastgezeten. Uiteindelijk een hint online moeten opzoeken.
1
| var increment = 7L |
[ Voor 16% gewijzigd door Varienaja op 13-12-2020 18:55 ]
Siditamentis astuentis pactum.
Vervolgens de hele middag zitten puzzelen en het uiteindelijk maar opgegeven. Ik heb nu een werkende oplossing in python gejat en die omgezet naar 4GL. Aan de hand van deze code heb ik met een simpel voorbeeld (buslijnen 2,3,5 -> goede tijd = 8 ) geprobeerd te snappen wat er nou precies gebeurt. Helaas. Wiskunde is niet mijn ding....
... en gaat over tot de orde van de dag
Ah, thanks. Vergeten te generaliseren. Het is gewoon de ID van de eerste bus van de voorbeeldcode. Ik heb de code ff aangepast.Varienaja schreef op zondag 13 december 2020 @ 18:48:
Diecode:is wel heel nasty. Met mijn input (eerste bus is 19) zou je code al een fout antwoord geven.
1 var increment = 7L
Normaal doe ik nog een refactoringslag over de code maar daar had ik nu geen zin meer in
https://niels.nu
Zo, rustige zondag gehad dusHydra schreef op zondag 13 december 2020 @ 18:41:
En tenslotte Day 13.
spoiler:Ik had wel meteen door dat ik cycle detection moest gaan doen, maar uiteindelijk had ik de incrementen verkeerd gekozen. Het was uiteindelijk een kwestie van een steeds langere lijst te pakken en van die sublijst dan de IDs te vermenigvuldigen als volgende increment grootte. Daar zat ik met m'n eigen implementatie dus naast waardoor ik wel een oplossing kreeg, maar met een veel te groot getal.
Wel jammer dat 't niet 100% m'n eigen oplossing was, maargoed.
Engineering is like Tetris. Succes disappears and errors accumulate.
Siditamentis astuentis pactum.
Sorry hoor, je kunt ook even gewoon lezenHydra schreef op zondag 13 december 2020 @ 16:53:
[...]
[...]
Sorry hoor, je kunt ook even meedenken.
To be fair, er staat letterlijk “vandaag” boven z’n spoiler. Weet niet helemaal wat ie anders kan doen. Elke dag is er een puzzel en het is vrij normaal spoilers over de lopende dag te plaatsen.
Engineering is like Tetris. Succes disappears and errors accumulate.
Heb 't gerefactored. Stuk minder codeVarienaja schreef op zondag 13 december 2020 @ 18:57:
Begrijpelijk @Hydra. Soms bekijk ik mijn eigen code een halfuur later nog eens en gruw dan van wat er soms nog voor onhandige kronkels in zitten.![]()
https://niels.nu
Gewoon geen spoiler poste in een rechtstreekse reactie op iemand die nog niet op die dag is? Je kunt dat zinnetje heel simpel op 2 manieren interpreteren. Als je reageert op een post over dag 12, in de tekst ingaat op die issues over dag 12, en dan aan het eind even een spoiler zet voor dag 13, dan ben je vind ik gewoon onhandig bezig.armageddon_2k1 schreef op zondag 13 december 2020 @ 18:59:
To be fair, er staat letterlijk “vandaag” boven z’n spoiler. Weet niet helemaal wat ie anders kan doen.
En als ik dan gewoon vraag daar een beetje mee op te passen krijg ik een betweterige reactie. Ja sorry hoor, maar dat vind ik gewoon kinderachtig. Ik had gewoon geluk dat ik als eerste "13" in die spoiler zag staan en dus de tekst niet gelezen had.
https://niels.nu
Ik weet niet precies hoe het heet. Heb dit probleem wel in een andere vorm eerder gezien.armageddon_2k1 schreef op zondag 13 december 2020 @ 18:56:
spoiler:Cycle detection snap ik niet. Het is toch gewoon een reeks?
https://niels.nu
De puzzels worden moeilijker, gelukkig hoef ik nog maar twee dagen te werken en heb ik daarna lekker tijd de puzzels te doen.
Naast schuur opruimen, zolder schilderen, plintjes plaatsen, tuin nog wat opruimen, kelder opruimen, stellingkast bij schoonmoeder bouwen, lampen plaatsen... maar verder genoeg tijd
Engineering is like Tetris. Succes disappears and errors accumulate.
Verwijderd
Geen probleem, dacht dat het de bedoeling was...Soultaker schreef op zondag 13 december 2020 @ 18:20:
[...]
Kan je die code alsjeblieft ergens anders posten (op Github ofzo, of desnoods op pastebin.com)? Een lange lap code draagt niet veel bij aan de discussie en is niet fijn om langs te moeten scrollen.
Euh, als je je post dan ook ff edit...Verwijderd schreef op zondag 13 december 2020 @ 19:19:
Geen probleem, dacht dat het de bedoeling was...
https://niels.nu
Paar regels is prima. bij langere posts liever link naar oplossing.Verwijderd schreef op zondag 13 december 2020 @ 19:19:
[...]
Geen probleem, dacht dat het de bedoeling was...
Ik heb de handdoek er maar inggegooid bij opdracht 2 van vandaag.
Hiervoor heb je volgens mij toch iets meer wiskundige achtergrond nodig, dan ik heb
Heuveltjes CPU geschiedenis door de jaren heen : AMD 486dx4 100, Cyrix PR166+, Intel P233MMX, Intel Celeron 366Mhz, AMD K6-450, AMD duron 600, AMD Thunderbird 1200mhz, AMD Athlon 64 x2 5600, AMD Phenom X3 720, Intel i5 4460, AMD Ryzen 5 3600 5800x3d
Bedankt! Zonder hint had ik de computer waarschijnlijk 24u moeten laten draaien voordat ik een antwoord had gekregendcm360 schreef op zondag 13 december 2020 @ 17:22:
Deel 2 van vandaag duurde inderdaad wel even, en dat bedoelde ik niet alle mogelijkheden nalopen (wel geprobeerd overigens, tijdens het bedenken van een efficiënte oplossing). Uiteindelijk wel met een oplossing weten te komen die het correcte antwoord weet te geven op enkele van de testcases en de gegeven input, maar ik ben er nog niet echt van overtuigd dat ik daadwerkelijk correct alle edge-cases te pakken heb.
spoiler:De truc voor een snelle oplossing is vaak dat het probleem in deeloplossingen op te splitsen is. In dit geval: los het op voor 1 bus (t=0 voldoet). Voeg vervolgens een bus toe, en zoek de oplossing voor beide bussen. Vervolgens is het de kunst om door te zoeken naar een oplossing die blijft voldoen voor de al berekende bussen, en ook voldoet voor de volgende. Dat trucje kan je dan blijven herhalen voor alle resterende bussen.
De rekentijd voor mijn oplossing voor deel 2 kwam daarmee uit op iets minder dan 2ms, waarmee dit interessant genoeg mijn snelste oplossing tot zover is.
Met de hulp lukte het me dan eindelijk nadat ik een keer heel goed keek naar het eerste voorbeeld.
[ Voor 3% gewijzigd door Sharkware op 13-12-2020 22:17 ]
Ik ben er ook een groot deel van de dag mee bezig geweest. De post van Woy heeft mij geholpen - even afstand nemen. Hint.heuveltje schreef op zondag 13 december 2020 @ 21:55:
Ik heb de handdoek er maar inggegooid bij opdracht 2 van vandaag.
Hiervoor heb je volgens mij toch iets meer wiskundige achtergrond nodig, dan ik heb
Dag 13 in C# (LINQPad).
Nadeel van LINQ is dat het nogal lastig debugt. Ik was lange tijd met ParallelEnumerable bezig en kreeg arithmetic overflow errors. Blijkt dat deze 'maar' int.MaxValue elementen kan verwerken.
[ Voor 24% gewijzigd door nescafe op 13-12-2020 23:09 ]
* Barca zweert ook bij fixedsys... althans bij mIRC de rest is comic sans
Er zijn wel scenarios voor de te stellen waarbij deze niet de beste oplossing vind. Al zijn er wel methods om dan terug te rekenen.
Code in C#
https://pastebin.com/B9gWrRuY
Verwijderd
heuveltje schreef op zondag 13 december 2020 @ 21:55:
[...]
Paar regels is prima. bij langere posts liever link naar oplossing.
Ik heb de handdoek er maar inggegooid bij opdracht 2 van vandaag.
Hiervoor heb je volgens mij toch iets meer wiskundige achtergrond nodig, dan ik heb
Hint: zoek voor iedere buslijn eens los het veelvoud waarop de bus op het juiste moment vertrekt:
Hiervoor geldt dat het verschil van de rest van de deling gelijk is aan het wegrijmoment - de busperiode.
In principe (het zijn allemaal priemgetallen) hoef je alleen maar te zoeken in de rij 1..nxm, waar n 19 en m een van de andere busnummers is.
Je moet verder opletten als het verschil in aanrijtijd groter wordt als een geheel maal de cyclustijd van de eerste bus (19). Dan moet je je zoekveld vergroten met 19*m, en het geheel aantal 19 van de tussenoplossing aftrekken.
ZO krijg je 8 'gemene delers' die je met elkaar moet vermenigvuldigen:
114 209 15580 228 304 532 8284 456
Nu nog ff een onlinecalculator vinden die arbitrair grote getallen aankan...
Ik was begonnen met een slimme manier van bruteforcen.P_Tingen schreef op zondag 13 december 2020 @ 18:51:
Ik had voor deel 2 een werkend algoritme, redelijk recht-toe, recht-aan, maar werkte voor alle testcases. Dat ging met ongeveer een miljoen timestamps per seconde, maar gezien de hint in de opgave dat de uitkomst wel eens heul groot zou kunnen zijn had ik al snel door dat hem dat niet zou gaan worden. En gezien de uiteindelijke uitkomst had ik dat goed ingeschat omdat ik anders mijn pc nog wel een paar jaar aan had moeten laten staan.
Vervolgens de hele middag zitten puzzelen en het uiteindelijk maar opgegeven. Ik heb nu een werkende oplossing in python gejat en die omgezet naar 4GL. Aan de hand van deze code heb ik met een simpel voorbeeld (buslijnen 2,3,5 -> goede tijd = 8 ) geprobeerd te snappen wat er nou precies gebeurt. Helaas. Wiskunde is niet mijn ding....
pak 1 x de hoogste bus, probeer die te vergelijken met de hoogste bus daaronder. Als dat lukt dan de volgende kijken of die klopt. Mocht dat lniet lukken probeer dan 2 keer de hoogste bus etc.
Ging nog wel in de test, maar werd onmogelijk in de 2e ronde
Grappig. an de hand van die opmerking (buslijnen 2,3,5 -> goede tijd =
En toen ik die ging uitschrijven op een stuk papier, werd het me wel een stuk duidelijker.
pak 2,3,5 als voorbeeld
de 1e keer dat *2 1 kleiner is dan *3 is bij 1x3 (2-3)
de 2e keer dat *2 1 kleiner is dan *3 is bij 3x3 (8-9)
de 3e keer dat *2 1 kleiner is dan *3 is bij 5x3 (14-15)
En je ziet een patroon ontstaan, het herhaalt zich in dit geval elke keer met 2
nu ga je 3 en 5 zoeken, waarbij je alleen nog maar in stappen van +2*3 te checken
de 1e keer dat *3 ook 1 kleiner is dan *5 is bij 2x5 (8,9,10)
de 2e keer dat *3 ook 1 kleiner is dan *5 is bij 8x5 (38,39,40
de 3e keer dat *3 ook 1 kleiner is dan *5 is bij 14x5 (68,69,70)
Het herhaald zich om de 6 stappen, nu kun je de volgende zoeken
En vanaf nu hoef je alleen nog maar in stappen van +(6x5) te checken.
ik had al een routine geschreven, die prima die stappen kon bereken door een for loopje.
Zijn nog geen 70 cycles nodig om de 1e 2 waarden te vinden.
Kan je uitleg niet helemaal volgen, maar geloof wel dat we op dezeflde weg zittenVerwijderd schreef op maandag 14 december 2020 @ 00:06:
[...]
spoiler:Je moet verder opletten als het verschil in aanrijtijd groter wordt als een geheel maal de cyclustijd van de eerste bus (19). Dan moet je je zoekveld vergroten met 19*m, en het geheel aantal 19 van de tussenoplossing aftrekken.
ZO krijg je 8 'gemene delers' die je met elkaar moet vermenigvuldigen:
..
[ Voor 19% gewijzigd door heuveltje op 14-12-2020 01:16 ]
Heuveltjes CPU geschiedenis door de jaren heen : AMD 486dx4 100, Cyrix PR166+, Intel P233MMX, Intel Celeron 366Mhz, AMD K6-450, AMD duron 600, AMD Thunderbird 1200mhz, AMD Athlon 64 x2 5600, AMD Phenom X3 720, Intel i5 4460, AMD Ryzen 5 3600 5800x3d
Siditamentis astuentis pactum.
CongratsVarienaja schreef op maandag 14 december 2020 @ 06:35:
HA! In plaats van zenuwachtig proberen snel te zijn heb ik nu meer geprobeerd netjes te werken. Beide sterren binnen. Niet te lang bezig geweest. Beide keren bij de eerste 1000. Dat heb ik nog niet eerder bereikt. :-D
Ik heb het dus meer traditioneel aangepakt (ijverig gaan tikken terwijl je voorzichtig aan je eerste koffie nipt) en vandaag bij stap 1 ben ik in zo ongeveer elke valkuil gestapt die maar kon
Deel twee ging wel in 1 keer goed, na een vierde koffie en 5 minuten pauze
Grappig om te zien dat het dit jaar beter vol te houden lijkt. Bijna 2 keer zo veel mensen die goud hebben op dag 13 versus 33% meer op dag 1. Er blijven dus relatief meer mensen doorgaan.
[ Voor 13% gewijzigd door Dido op 14-12-2020 07:48 ]
https://github.com/evanra...lob/master/day14/day14.py
Uurtje bezig geweest, niet veel fouten gemaakt. Toch bijna 10 keer (snelste had een oplossing in 6 min!) zo traag als de snelste vandaag
[ Voor 8% gewijzigd door evanraalte op 14-12-2020 11:38 ]
Zo een eenvoudige puzzel als vandaag voelt dan wel even heel erg fijn
Dit was wel een leuke. Wel veel werk!
Verder ben ik gewoon 'dom' integers naar binary strings aan het omzetten geweest en vice versa. If it works, it ain't stupid. Ga misschien nog wel ff kijken of ik 't korter op kan schrijven. "Feelin' cute, might refactor later"
Edit: FF snel de loops in part 1 en part 2 omgebouwd naar een fold-left. Da's nu typisch iets wat je in 'productie' relatief weinig gebruikt (ook vanwege de "wat is deze?" reacties van sommige collega's) dus ik vind het wel cool om daar nu een beetje mee te oefenen
[ Voor 19% gewijzigd door Hydra op 14-12-2020 10:19 ]
https://niels.nu
Na de hint gelezen te hebben dat het allemaal priem getallen zijn ben is gaan nadenken over hoe het op te lossen.
t % priem 1 = 0
t + x % priem 2 = 0
enz...
Volgens mij doet die voorwaarde zich ieder stapgrootte priem 1 * priem 2 zich een keer voor.
Vervolgens ga je opzoek naar een punt waar je aan t + x % priem_n = 0 en verminigvuldig je weer je stap groote met priem_n
enz.. tot je tot het einde bent
At dawn on the fifth day look to the east
Deel 1, fout. Oh, niet goed gelezen dat de mask kon veranderen.

Deel 2, fout. Oh, als de mask 0 is overschrijft hij niet.

Uiteindelijk wel de juiste antwoorden gekregen.
[ Voor 16% gewijzigd door coop op 06-12-2021 13:48 ]
Als het langzaam is gebruikt je niet genoeg bitmasks. Mijn oplossing (ook in Python) runt in 100 ms ofzo.evanraalte schreef op maandag 14 december 2020 @ 08:26:
Uurtje bezig geweest, niet veel fouten gemaakt. Toch bijna 10 keer zo traag als de snelste vandaag
Je ziet bij deze opdracht ook gelijk wie de old-school programmeurs zijn.
Haha, ik wilde niet dubbelzinnig zijn. Ik bedoel dat het mij 60 minuten kostte om de code te schrijven, tov de kennelijk 6 minuten die het iemand anders kostteSoultaker schreef op maandag 14 december 2020 @ 10:56:
[...]
Als het langzaam is gebruikt je niet genoeg bitmasks. Mijn oplossing (ook in Python) runt in 100 ms ofzo.
Je ziet bij deze opdracht ook gelijk wie de old-school programmeurs zijn.
https://github.com/rverst.../blob/main/Y2020/Day14.cs
“Build a man a fire, and he'll be warm for a day. Set a man on fire, and he'll be warm for the rest of his life.”
Deel 2 kwam ik op dezelfde manier niet uit:
java: https://github.com/Moofnor/AoC2020/tree/main/day14
- 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
Challenge accepted! Bij het fatsoeneren van de code heb ik gepoogd zoveel mogelijk her te gebruiken. Day 14.Hydra schreef op maandag 14 december 2020 @ 10:00:
Day 14
spoiler:Wat je voor deel 1 en 2 nodig hebt verschilt enorm, afgezien van het parsen van de input kun je niet zo veel hergebruiken.
Ik geloof niet dat het er lees- en /of begrijpbaarder door geworden is.
Siditamentis astuentis pactum.
Ik wil het niet helemaal spoilen, dus hier wat hints (een voor een openen).Moofnor schreef op maandag 14 december 2020 @ 12:06:
Deel 2 kwam ik op dezelfde manier niet uit
for (int submask = 0; submask <= mask; ++submask) {
// doe iets met submask
}
int submask = mask;
while (true) {
// doe iets met submask
if (submask == 0) break;
submask = submask - 1;
}
Dit heeft hetzelfde effect, maar dan lopen we de submasks van hoog naar laag door. In dit geval is het niet veel beter maar het helpt als de mask ook nullen bevat. Waarom?
Hoe kun je het volgende getal in de reeks berekenen? Bijvoorbeeld van 1101 naar 1100? Of van 1100, 1001? Welke integer operaties kun je gebruiken?
Bedenk zelf waarom dat werkt. En probeer de while-lus te schrijven om over alle masks te itereren.
Volledige oplossing
Dank voor de uitgebreide uitleg!Soultaker schreef op maandag 14 december 2020 @ 13:27:
[...]
Ik wil het niet helemaal spoilen, dus hier wat hints (een voor een openen).
spoiler:De hoofdvraag is hoe je voor een bitmask van X'en makkelijk alle subbitmasks kunt genereren, waarbij een subbitmask een bitmask is waar een deel van de 1'en vervangen zijn door 0'en. Bijvoorbeeld 101 heeft subbitmasks: 000, 001, 100, 101. In z'n algemeenheid heeft een bitmask met N 1-bits, 2N subbitmasks.
spoiler:Hoe zou je het oplossen als je bitmask alleen de laagste bits gebruikt? e.g. 11 = 3, 111 = 7, 1111 = 15.
spoiler:Die voorbeelden zijn eenvoudig: je kunt gewoon van 0 tot mask itereren:
for (int submask = 0; submask <= mask; ++submask) {
// doe iets met submask
}
spoiler:Stel dat ik de lus als volgt herschrijf:
int submask = mask;
while (true) {
// doe iets met submask
if (submask == 0) break;
submask = submask - 1;
}
Dit heeft hetzelfde effect, maar dan lopen we de submasks van hoog naar laag door. In dit geval is het niet veel beter maar het helpt als de mask ook nullen bevat. Waarom?
spoiler:Neem een voorbeeld als 1101. Van hoog naar laag zijn de submasks dan 1101, 1100, 1001, 1000, 0101, 0100, 0001, 0000.
Hoe kun je het volgende getal in de reeks berekenen? Bijvoorbeeld van 1101 naar 1100? Of van 1100, 1001? Welke integer operaties kun je gebruiken?
spoiler:Hint: de enige operatoren die je nodig hebt zijn - en &.
spoiler:De formule is: submask = (submask - 1) & mask.
Bedenk zelf waarom dat werkt. En probeer de while-lus te schrijven om over alle masks te itereren.
Volledige oplossing
Zeer helder, nu onthouden voor de volgende keer.
- 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

Nou, fijn, opdracht klaar, antwoord ingeleverd, maar het antwoord wat mijn "moeilijke" methode gaf ligt maar 0,3% van het uiteindelijke antwoord vandaan, dus dat is wel frustrerend, het *voelt* alsof ik in de goede richting zit. Ik heb er nog behoorlijk over nagedacht maar ik denk dat ik een fout in mijn idee heb en dat het best wel eens zou kunnen zijn dat de veranderingen die ik moet maken alsnog voor een worst-case looptijd zorgen die niet beter is dan simulatie, maar hopelijk wel met een beter geheugengebruik.
Nou dus de vraag om te zien of het überhaupt kan: wie heeft een algoritme wat deel 2 correct oplost, en bovendien zonder aanpassingen de testinput van deel 1 kan oplossen binnen een seconde en met minder dan zeg, iets royaals als 16GB geheugengebruik?
Hint 1:DataGhost schreef op maandag 14 december 2020 @ 14:04:
Hm, ik was begonnen aan een "moeilijke" oplossing voor deel 2. Ging prima op de testinput in de opdracht maar vervolgens was het antwoord op de volledige invoer fout. Dus extra testcases maken om te kijken waar mijn denkfout precies zat,
spoiler:en een simulator gemaakt die het gewoon simuleerde (zoals schijnbaar elke oplossing die hier is langsgekomen), zodat ik kon zien in hoeverre mijn antwoord fout was. Voor de gein heb ik deze ook even op de volledige input gedraaid en tot mijn verbazing kwam daar bijna instant het correcte antwoord uitwat ik niet verwacht had als je kijkt naar de testinput voor deel 1, ik ging ervan uit dat de volledige input daar genoeg op zou lijken om simuleren lekker te kunnen vergeten.
Nou, fijn, opdracht klaar, antwoord ingeleverd, maar het antwoord wat mijn "moeilijke" methode gaf ligt maar 0,3% van het uiteindelijke antwoord vandaan, dus dat is wel frustrerend, het *voelt* alsof ik in de goede richting zit. Ik heb er nog behoorlijk over nagedacht maar ik denk dat ik een fout in mijn idee heb en dat het best wel eens zou kunnen zijn dat de veranderingen die ik moet maken alsnog voor een worst-case looptijd zorgen die niet beter is dan simulatie, maar hopelijk wel met een beter geheugengebruik.
Nou dus de vraag om te zien of het überhaupt kan: wie heeft een algoritme wat deel 2 correct oplost, en bovendien zonder aanpassingen de testinput van deel 1 kan oplossen binnen een seconde en met minder dan zeg, iets royaals als 16GB geheugengebruik?
Hint 2:
Nja ik ben niet helemaal van gisterenevanraalte schreef op maandag 14 december 2020 @ 14:17:
[...]
Hint 1:
spoiler:Je bent alleen geinteresseerd in de elementen die je aanpast in memory. Dus de secties in je geheugen die "0" zijn hoef je niet op te slaan.
Hint 2:
spoiler:Kijk of je taal iets als een dictionary support (het heet dictionary in Python althans)
1
2
3
4
| mask = XXXXXXXXXXXXXXXXXXXXXXXXXXXXX1XXXX0X mem[8] = 11 mem[7] = 101 mem[8] = 0 |
DataGhost schreef op maandag 14 december 2020 @ 15:44:
[...]
Nja ik ben niet helemaal van gisterenDat gebruik ik ook al gewoon. Maar kijk eens naar de voorbeeldinput bij deel 1:
code:
1 2 3 4 mask = XXXXXXXXXXXXXXXXXXXXXXXXXXXXX1XXXX0X mem[8] = 11 mem[7] = 101 mem[8] = 0
spoiler:Ik wens je heel veel succes met een dictionary, map, of wat dan ook. Mijn simulatie gebruikt ook gewoon een dict maar dit "kleine" voorbeeldje past daar niet in
spoiler:Bij een mask met allemaal X (bijna het voorbeeld dus) heb je 236 = 68 miljard adressen. Met 32 bits inhoud per geheugencel (maximale waarde zo'n 4 miljard) kost dat minimaal 256GB. En in alle simulatie-voorbeelden hier ben je elke toewijzing dus die 68 miljard adressen opnieuw aan het genereren.
spoiler:Een dict zal in dit geval alleen maar slechter zijn dan een statische array, of hoogstens even goed.
[ Voor 4% gewijzigd door dcm360 op 14-12-2020 16:05 ]
Daarnaast wel regex aangeleerd om eens te gebruiken, toch wel fijn
https://github.com/rj-cod...rjcoding/aoc2020/Day14.kt
Hij is wel wat traag (~1,5s), dus later eens refactoren om die addresses wat slimmer te genereren......
Engineering is like Tetris. Succes disappears and errors accumulate.
dcm360 schreef op maandag 14 december 2020 @ 16:01:
[...]
spoiler:Maar het voorbeeld bij deel 2 gebruikt ruim minder dan dat. En jouw input file ook naar alle waarschijnlijkheid. Dus gewoon deel 2 niet testen met de test-invoer van deel 1 dus.
Volgens mij is het antwoord op de testinvoer 1735166787584 en dat zou ik er graag binnen afzienbare tijd uit krijgen met een algoritme wat voor deel 2 gebruikt is.
Edit: ondertussen heb ik iemand gevonden die het voor elkaar heeft gekregen op bijna dezelfde manier die ik in gedachten had, en met het correcte antwoord voor de invoer van deel 1. Hij vertelde me binnen een paar seconden het antwoord in m'n spoiler, dus het kan. Dus ik ga verder puzzelen
Edit2: ondertussen gelukt trouwens.
[ Voor 14% gewijzigd door DataGhost op 14-12-2020 18:50 ]
Er vallen wel veel mensen af elke dag. Dag 1 nog 130.000 gouden sterren, gisteren nog maar 24.000. Al 80% afvallers. Onder de tweakers lijker er minder afvallers te zijn dan gemiddeld. Daar zijn er pak 'm beet 100 helemaal bij tot en met gisteren. Dus maar ongeveer 50% afvallers. Dat is mooi.
Siditamentis astuentis pactum.
Lekker niks bitmasken. Ik zou toch al lineair door de string heen moeten lopen om de mask op te bouwen, dan is nog een paar keer erdoorheen om te vergelijken niet zo'n probleem. Het draait nog altijd in 300ms
Is dit jaar ook de 1e keer dat ik mee doe. Spreekt me wel echt aan. Ga de komende weken proberen de vorige jaren ook te doen. Is leuk om op deze manier bij te leren.Soultaker schreef op maandag 14 december 2020 @ 16:48:
Ik zie trouwens dat we 200 deelnemers op het Tweakers leaderbord hebben staan (waarvan er ruim 150 daadwerkelijk een probleem hebben opgelost)! Dat is best veel.
MrHaas schreef op maandag 14 december 2020 @ 18:24:
spoiler:Iemand opgelost zonder alle adressen van elke memory mask te berekenen? Ik heb het nu ook op de "naieve" manier gedaan maar zat te denken aan een oplossing waarbij je een lijst bijhoudt van elke memorymask + value, dan ga je voor elke volgende memorymask terugkijken naar elke vorige memorymask om te kijken hoe je die memorymask zo kan opsplitsen in 0 - n memorymasks zodat die geen overlap meer hebben met de huidige. Voorbeeld: je huidige memorymask is XX11XX en je wilt de overlap uit 11XXXX halen. De overlappende adressen zijn 111100, 111101, 111110 en 111111. Dan kan je 11XXXX dus opsplitsen in 110XXX en 1110XX. Aan het einde doe je dan per entry 2 ^ (aantal X) * value en dat sommeer je.
Logica klopte van geen kant. Laat maar.DataGhost schreef op maandag 14 december 2020 @ 16:44:
[...]
spoiler:Mag een deel van de uitdaging nog wel zijn om iets met een algoritmisch leuke looptijd te krijgen?Ik heb het probleem allang opgelost en het antwoord allang ingestuurd maar ik ben gewoon op zoek naar een algoritme wat alle invoer in een acceptabele tijd op kan lossen. Sterker nog, ik verwacht eigenlijk dat dit probleem in de komende dagen nog een vervolg krijgt waarin dit weer belangrijk wordt, tenzij er geen goed algoritme voor bestaat.
Volgens mij is het antwoord op de testinvoer 1735166787584 en dat zou ik er graag binnen afzienbare tijd uit krijgen met een algoritme wat voor deel 2 gebruikt is.
Edit: ondertussen heb ik iemand gevonden die het voor elkaar heeft gekregen op bijna dezelfde manier die ik in gedachten had, en met het correcte antwoord voor de invoer van deel 1. Hij vertelde me binnen een paar seconden het antwoord in m'n spoiler, dus het kan. Dus ik ga verder puzzelen
[ Voor 34% gewijzigd door coop op 14-12-2020 18:37 ]
mask = 0000000000000000000000000000X1XXXX0X
mem[8] = 11
mem[7] = 101
mem[8] = 0
mask = 000000000000000000000000000XX1XXXX0X
mem[8] = 11
mem[7] = 101
mem[8] = 0
mask = 00000000000000000000000000XXX1XXXX0X
mem[8] = 11
mem[7] = 101
mem[8] = 0
Dan zie je gauw genoeg waar het heen gaat.
Edit: ah, dat zag je al.
[ Voor 21% gewijzigd door DataGhost op 14-12-2020 18:38 ]
Hoe voorkom je een exponentiële groei van het aantal bitmasks na splitsen? Bijvoorbeeld, stel de invoer is:DataGhost schreef op maandag 14 december 2020 @ 18:34:
spoiler:Dat is dus bijna de aanpak die ik eerst had verzonnen (en niet werkte) en precies de aanpak die ik daarna van iemand anders hoorde (en wel werkt). Qua geheugen is dat dan grofweg O(a * b) waarbij a het aantal assignments is en b het aantal bits (36), terwijl de simulatie-oplossing O(2b) is.
11XXXXXX = 2
XX11XXXX = 3
XXXX11XX = 4
Stap 1:
XXXXXXXX = 1
Stap 2:
0XXXXXXX = 1
10XXXXXX = 1
11XXXXXX = 2
Stap 3:
0X0XXXXX = 1
0X10XXXX = 1
100XXXXX = 1
1010XXXX = 1
110XXXXX = 2
1110XXXX = 2
XX11XXXX = 3
enzovoorts. Je verdubbelt dus steeds het aantal bitmasks en dan kom je op 2N/2 + 2 - 1 bitmasks uit, wat nog steeds exponentiële groei is. Voor N = 36 is dat ongeveer een miljoen, wat toevallig net in het geheugen past.
https://niels.nu
Hydra schreef op maandag 14 december 2020 @ 20:03:
Ik volg het niet helemaal; er is niks exponentieels aan vandaag? Het is millisecondenwerk.
[ Voor 3% gewijzigd door DataGhost op 14-12-2020 20:06 ]
Waarom zou je? Er wordt nogal expliciet een andere genomen. De voorbeeldinvoer van deel 1 is niet geschikt voor deel 2.DataGhost schreef op maandag 14 december 2020 @ 20:05:
Dat is een heftig verkeerde aanname. Probeer de voorbeeldinvoer van deel 1 maar eens op deel 2.
https://niels.nu
Stel niet uit tot morgen wat je vandaag nog tot morgen kunt uitstellen...
Ja snap ik, maar dat is geen issue met de voorbeelden in deel 2 of je echte invoer. Deel 1 moet je los zien; daar moet je inderdaad 17179869184 adressen gaan maken, en dat werkt natuurlijk niet.Dricus schreef op maandag 14 december 2020 @ 20:09:
Ja, maar het aantal adrespermutaties groeit exponentieel met het aantal X-bits in het mask. Ik denk dat dat bedoeld wordt.
https://niels.nu
Je schreef dat er niks exponentieels aan is vandaag. Dat is feitelijk onjuist. Het is inderdaad zo dat dat, gezien de input, geen factor (Hydra schreef op maandag 14 december 2020 @ 20:11:
Ja snap ik, maar dat is geen issue met de voorbeelden in deel 2 of je echte invoer. Deel 1 moet je los zien; daar moet je inderdaad 17179869184 adressen gaan maken, en dat werkt natuurlijk niet.
Stel niet uit tot morgen wat je vandaag nog tot morgen kunt uitstellen...
Je begrijpt wel wat ik bedoel denk ikDricus schreef op maandag 14 december 2020 @ 20:12:
Je schreef dat er niks exponentieels aan is vandaag. Dat is feitelijk onjuist.
https://niels.nu
Soms gaat het niet zoals het moet, maar moet het maar zoals het gaat
Oh, zeker. Mijn bijdrage was een goed bedoelde poging om te laten zien dat je tekst door @DataGhost waarschijnlijk iets te letterlijk geïnterpreteerd was

Stel niet uit tot morgen wat je vandaag nog tot morgen kunt uitstellen...
Moet niet, maar mag wel hoorDricus schreef op maandag 14 december 2020 @ 20:17:
Oh, zeker. Mijn bijdrage was een goed bedoelde poging om te laten zien dat je tekst door @DataGhost waarschijnlijk iets te letterlijk geïnterpreteerd was. Ik moet me ook niet overal mee bemoeien
.
https://niels.nu
Waarom niet?Hydra schreef op maandag 14 december 2020 @ 20:08:
[...]
Waarom zou je? Er wordt nogal expliciet een andere genomen. De voorbeeldinvoer van deel 1 is niet geschikt voor deel 2.
2^34 is een groot getal. Het is niet voor niets dat deze dag, itt tot de meeste anderen, niet naar het voorbeeld in deel 1 verwijst maar een nieuw voorbeeld geeft. Proberen dat voorbeeld voor deel 2 werkend te krijgen is een dood spoor.DataGhost schreef op maandag 14 december 2020 @ 20:19:
Waarom niet?
Leef je verder uit hoor
[ Voor 14% gewijzigd door Hydra op 14-12-2020 20:21 ]
https://niels.nu
Vanochtend had ik al een snel in elkaar geflanste functioneel-opgezette oplossing met veel te veel code, die ook nog eens bizar slecht performde (100 secondes voor deel 2). Nu heb ik maar even een imperatieve oplossing gemaakt, en die heeft maar 32 millisecondes nodig...
In Kotlin kun je collections helaas nog niet gebruiken zoals in een écht functionele programmeertaal. Je kunt geen nieuwe List/Map aanmaken op basis van een bestaande met een nieuw of gewijzigd element, zonder dat je daar performancetechnisch de prijs voor betaalt. De overhead heeft hem denk ik vooral gezeten in het feit dat ik dat wel deed.
Stel niet uit tot morgen wat je vandaag nog tot morgen kunt uitstellen...
Soultaker schreef op maandag 14 december 2020 @ 19:48:
[...]
Hoe voorkom je een exponentiële groei van het aantal bitmasks na splitsen? Bijvoorbeeld, stel de invoer is:
spoiler:XXXXXXXX = 1
11XXXXXX = 2
XX11XXXX = 3
XXXX11XX = 4
Stap 1:
XXXXXXXX = 1
Stap 2:
0XXXXXXX = 1
10XXXXXX = 1
11XXXXXX = 2
Stap 3:
0X0XXXXX = 1
0X10XXXX = 1
100XXXXX = 1
1010XXXX = 1
110XXXXX = 2
1110XXXX = 2
XX11XXXX = 3
enzovoorts. Je verdubbelt dus steeds het aantal bitmasks en dan kom je op 2N/2 + 2 - 1 bitmasks uit, wat nog steeds exponentiële groei is. Voor N = 36 is dat ongeveer een miljoen, wat toevallig net in het geheugen past.
Hm, het doorgestreepte stuk klopt niet helemaal, er kunnen maximaal b nieuwe voor in de plaats komen maar dan wel voor elke die al in het geheugen stond en niet onafhankelijk daarvan. Ik denk dat je tegenvoorbeeld en berekening valide is. Ik weet niet of er een betere mogelijkheid is. Bij weinig assignments en simulatie-onvriendelijke masks blijft deze oplossing wel beter, maar het kan vast nog beter