Heeft trouwens iemand nog geprobeerd mijn testdata voor dag 16 op te lossen?
Was weer leuk vandaag, als heeft het wat moeite gekost 😅
Oplossing wel cool.
code | video 1 | video 2
Oplossing wel cool.
spoiler:
Ik houd de start move index bij van rock # 0, zoek daarbinnen een herhalend patroon, gebruik dat om gamestate repeats the detecteren en bouw daarmee een skip naar het eind en doe dan het laatste stukje.
In video 2 leg ik m'n oplossing uit
In video 2 leg ik m'n oplossing uit
code | video 1 | video 2
Zal het morgen ff runnenSoultaker schreef op zaterdag 17 december 2022 @ 22:01:
Heeft trouwens iemand nog geprobeerd mijn testdata voor dag 16 op te lossen?
Soultaker schreef op zaterdag 17 december 2022 @ 22:01:
Heeft trouwens iemand nog geprobeerd mijn testdata voor dag 16 op te lossen?
===[ input.txt ]========== Time: 3,987us (load:88us, part1:3,648us, part2:250us) Part 1: 1820 Part 2: 2602 ===[ aoc_2022_day16_large-1.txt ]========== Time: 3,824,898us (load:74us, part1:3,755,070us, part2:69,753us) Part 1: 117949 Part 2: 125937 ===[ aoc_2022_day16_large-2.txt ]========== Time: 1,996,045us (load:134us, part1:1,937,136us, part2:58,775us) Part 1: 113928 Part 2: 130572 ===[ aoc_2022_day16_large-3.txt ]========== Time: 3,497,974us (load:92us, part1:3,433,461us, part2:64,420us) Part 1: 132860 Part 2: 140630 ===[ aoc_2022_day16_large-4.txt ]========== Time: 9,254,944us (load:126us, part1:9,171,140us, part2:83,677us) Part 1: 137838 Part 2: 141648 ===[ aoc_2022_day16_large-7.txt ]========== Time: 506us (load:151us, part1:329us, part2:26us) Part 1: 58361 Part 2: 52131
5 en 6 heb ik afgebroken, die finishte niet binnen 20s en vraten echt enorm veel mem. De snelheid van 7 verbaast me
.edit: heb 5 eens wat langer door laten lopen. 5 Geeft 202s+191s. 6 Runt nu.
.edit2: ik had geen zin om op 6 te wachten en het blokkeerde het linken van een nieuwe executable dus ik heb 'm gestopt. Ziekelijke algoritmische optimize voor part2 dit
[ Voor 25% gewijzigd door .oisyn op 18-12-2022 03:31 ]
Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.
Misschien even naar regel 131 kijkenVarienaja schreef op zondag 18 december 2022 @ 07:19:
Dag 18 in Java. Er zit een WTF in, daar moet ik later nog eens over nadenken.
Hier mijn dag 18 in java
Ken Thompson's famous line from V6 UNIX is equaly applicable to this post:
'You are not expected to understand this'
Ik had 'm al :-)
Het ziet er bij jou veel netter uit, maar we doen exact hetzelfdeHier mijn dag 18 in java
Siditamentis astuentis pactum.
Als je wat meer van de logica in Point3D zet gaat het al een stuk meer op elkaar lijken. Mijn Point3D kon ik hergebruiken van vorig jaar, hoefde er alleen een neighbour functie aan toe te voegen.
Ken Thompson's famous line from V6 UNIX is equaly applicable to this post:
'You are not expected to understand this'
Dag 18 was lekker simpel vond ik voor de verandering
spoiler:
Methode had ik dit jaar voor werk al een keer gebruikt:
- vul een 3d numpy array met 1 waar de obsidian zit
- doe over elke axis een diff (verschil tussen de "rij" en de "rij" 1 opgeschoven).
- elke keer dat de diff niet 0 is is er een rand
- sommeer de hoeveelheid niet 0-en.
Kan in 2 regels (exclusief de input parsing natuurlijk).
Voor deel 2 een flood-fill geimplementeerd, dat kostte iets meer moeite, omdat ik vergat te checken eerst of er al water op de locatie zat.
- vul een 3d numpy array met 1 waar de obsidian zit
- doe over elke axis een diff (verschil tussen de "rij" en de "rij" 1 opgeschoven).
- elke keer dat de diff niet 0 is is er een rand
- sommeer de hoeveelheid niet 0-en.
Kan in 2 regels (exclusief de input parsing natuurlijk).
Voor deel 2 een flood-fill geimplementeerd, dat kostte iets meer moeite, omdat ik vergat te checken eerst of er al water op de locatie zat.
Verandert z'n sig te weinig.
Heb het na dag 15 een beetje opgegeven en ben nu rustig aan nog wat dagen aan het maken om te leren en lekker bezig te zijn. Maar die nummer 1 gast heeft blijkbaar zijn eigen taal geschreven ofzo?Varienaja schreef op vrijdag 16 december 2022 @ 21:49:
Ik heb Floyd-Warshall geïmplementeerd en goed gekeken naar de code van de nummer 1 in het AoC klassement.
Toffe puzzel vandaag! Vooral na de vrij frustrerende van de afgelopen dagen.
Ik vind dit toch de leukere puzzels. Waar het voor de hand ligt wat er moet gebeuren, maar toch uitdagend genoeg om zelf een aanpak te bedenken zonder een of andere recursive network search te hoeven implementeren 😁. Deel 2 nodigt uit om creatief te zijn en je eigen manier te verzinnen. Ik vind het altijd erg leuk als ik in de subreddit een enorm scala aan oplossingen zie van geniale one-liners waar ik zelf nooit aan gedacht had tot aan enorme lappen code van 100+ regels.
Mijn oplossing in Python 3.
Ik vind dit toch de leukere puzzels. Waar het voor de hand ligt wat er moet gebeuren, maar toch uitdagend genoeg om zelf een aanpak te bedenken zonder een of andere recursive network search te hoeven implementeren 😁. Deel 2 nodigt uit om creatief te zijn en je eigen manier te verzinnen. Ik vind het altijd erg leuk als ik in de subreddit een enorm scala aan oplossingen zie van geniale one-liners waar ik zelf nooit aan gedacht had tot aan enorme lappen code van 100+ regels.
Mijn oplossing in Python 3.
Ja, betaveros. Als je zo iets interessant vind, moet je eens kijken naar Tsoding Daily op YouTube, waar hij zijn eigen taal Porth bouwt,Cranzai schreef op zondag 18 december 2022 @ 10:15:
[...]
Heb het na dag 15 een beetje opgegeven en ben nu rustig aan nog wat dagen aan het maken om te leren en lekker bezig te zijn. Maar die nummer 1 gast heeft blijkbaar zijn eigen taal geschreven ofzo?
Pff trage oplossing en zelfs daar veel te lang mee bezig geweest. Maar goed, straks even kijken naar andere oplossingen ter lering en vermaak. Ondertussen snel weer een animatie in elkaar geflanst van mijn input.

Honda CB750 Hornet :: Yamaha Fazer FZ6 SA (2011 - 2023) | F1Pool.net
spoiler:
Zucht, ik dacht eerst slim te zijn en gewoon per paar van x,y, x,z en y,z coordinaten de min en max van het overige coordinaat bij te houden en dan te kijken of een cube 1 zijde heeft die aan de buitenzijde grenst op basis van die min en max, als een van de coordinaten buiten die range ligt vond ik het een buitengrens.
Alleen zit er waarschijnlijk ergens een tunnel met een bocht in, waardoor dit algoritme de mist in ging.
Toen maar gewoon lomp een bak gemaakt, die gevuld met water, en gekeken welke zijdes aan het water grenzen.
Blijkbaar miste ik 5 zijden waar water aan kon zitten...
Alleen zit er waarschijnlijk ergens een tunnel met een bocht in, waardoor dit algoritme de mist in ging.
Toen maar gewoon lomp een bak gemaakt, die gevuld met water, en gekeken welke zijdes aan het water grenzen.
Blijkbaar miste ik 5 zijden waar water aan kon zitten...
[ Voor 5% gewijzigd door Remcoder op 18-12-2022 15:36 ]
Interessant om te zien hoe je algoritme wel en niet schaalt. Deel 7 heeft vooral veel valves mét positieve flow, wat voor sommige algoritmen problematisch kan zijn (b.v. als je expliciet alle permutaties probeert te enumereren), maar voor de jouwe blijkbaar geen probleem is. Nog steeds frappant dat het veel sneller is dan b.v. aoc_2022_day16_large-1.txt waarvan ik dacht dat het de makkelijkste zou zijn..oisyn schreef op zondag 18 december 2022 @ 01:37:
5 en 6 heb ik afgebroken, die finishte niet binnen 20s en vraten echt enorm veel mem. De snelheid van 7 verbaast me.
De conclusie is dus dat niemand aoc_2022_day16_large-5.txt en aoc_2022_day16_large-6.txt weet op te lossen?
Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.
Toch altijd weer sneaky als je een aanname doet die wel opgaat voor de testdata maar niet voor de echte data.
spoiler:
In de test-input waren alle coördinaten > 0. Onbedoeld maakte mijn code daar gebruik van bij het testen van grenzen.
Het blijkt echter dat mijn echte data wel een druppel met coördinaat x=0 gebruikte. Dat gaf me veel te lang een off-by-one fout.
Het blijkt echter dat mijn echte data wel een druppel met coördinaat x=0 gebruikte. Dat gaf me veel te lang een off-by-one fout.
Ah sorry, dat had ik verkeerd begrepen aangezien je alleen de tijden voor deel 1 t/m 4 en 7 had gepost..oisyn schreef op zondag 18 december 2022 @ 16:19:
@Soultaker Ik heb ze opgost, alleen in een paar minuten.
Maar wat zijn jouw tijden dan?
$ ./solve < ../testdata/16.in 2320 2967 Time: 396,267 us ./solve < ../extradata/aoc_2022_day16_large-1.txt ****49 ****37 Time: 403,909 us ./solve < ../extradata/aoc_2022_day16_large-2.txt ****28 ****72 Time: 421,515 us ./solve < ../extradata/aoc_2022_day16_large-3.txt ****60 ****30 Time: 402,578 us ./solve < ../extradata/aoc_2022_day16_large-4.txt ****38 ****48 Time: 401,840 us ./solve < ../extradata/aoc_2022_day16_large-5.txt ****52 ****98 Time: 4,202,541 us $ ./solve < ../extradata/aoc_2022_day16_large-6.txt ****83 ****85 Time: 44,005,616 us $ ./solve < ../extradata/aoc_2022_day16_large-7.txt ***61 ***31 Time: 17,647,197 us
De runtime hangt grotendeels af van het aantal bereikbare valves af. De complexiteit van mijn algoritme is O(V2 × 2V), worst case (met V het aantal bereikbare valves met flow_rate > 0), en doet praktisch niets om de average case sneller te maken. Dat zie je hier ook terug: ~400 ms voor alle inputs met 15 valves, 4 seconde voor die met 18 valves, en 44 seconde voor die met 21 valves.
(OK, technisch is er ook de Floyd-Warshall preprocessing die O(N3) tijd kost maar dat is niet waar de tijd 'm in zit bij deze invoer.)
[ Voor 3% gewijzigd door Soultaker op 18-12-2022 18:28 ]
Dat duurt zo lang :-P maar goed dan, daar gaan we:Soultaker schreef op zaterdag 17 december 2022 @ 22:01:
Heeft trouwens iemand nog geprobeerd mijn testdata voor dag 16 op te lossen?
Standaard) Solution 16b: 2576 (0,04s) Solution 16a: 1896 (3,4s) 1) Solution 16a: ****49 (4,0s) Solution 16b: ****37 (19,0s) 2) Solution 16a: ****93 (2,5s) !Ander antwoord! Solution 16b: ****95 (9,4s) !Ander antwoord! 3) Solution 16a: ****60 (6,2s) Solution 16b: ****30 (21,7s) 4) Solution 16a: ****38 (0,6s) Solution 16b: ****48 (6,6s) 5+6) Ouf of memory 7) Solution 16a: ***61 (0,1s) Solution 16b: ***31 (0,1s)
Siditamentis astuentis pactum.
Oei! Aangezien .oisyn en ik met compleet andere implementaties op hetzelfde antwoord uitkomen ga ik er vanuit dat dit een bug in jouw solver is.Varienaja schreef op zondag 18 december 2022 @ 19:31:
2) Solution 16a: ****93 (2,5s) !Ander antwoord! Solution 16b: ****95 (9,4s) !Ander antwoord!
Overigens hier nog wat extra test data voor dag 18: aoc_2022_day18_large.zip
Antwoorden en referentie-tijden:
Antwoorden en referentie-tijden:
$ time pypy3 solve.py large-*.txt large-1.txt: ..978 ..126 0.228 s large-2.txt: ..468 ..982 0.078 s large-3.txt: ...384 ...384 1.908 s large-4.txt: ...000 ...424 1.305 s large-5.txt: ...398 ...096 1.546 s large-6.txt: ...944 ...056 0.122 s large-7.txt: ...548 ...382 1.506 s large-8.txt: ...464 ...136 3.816 s real 0m11.051s user 0m10.872s sys 0m0.130s
[ Voor 9% gewijzigd door Soultaker op 18-12-2022 22:40 . Reden: link gefixt, fout in large-6 en large-8 gefixt ]
Mijn programma is geschreven om goed overweg te kunnen met de dataset van AoC en doet waanzinnig lang over testdata met veel verbindingen zoals de sets 1--6. Dataset 7 lukt wel, maar ik heb wel de code een beetje aan moeten passen op de eenrichtingstunnels van @Soultaker.
aoc/2022/dag16$ time ./build-valves-Desktop-Release/valves < aoc_2022_day16_large-7.txt 58361 AA>WL^6748>II^17472>RL^13680>>>AN^9740>>>YK>IP>>>ZS^8544>OD>>IK^1224>>>>>>QH^953 52131 AA>WL^5784>II^14784>RL^11400>>>AN^7792>>>YK>IP>>>ZS^5696>OD>>IK^612 AA>>>>>UF^1560>PU>>>>>>>LS>>>>WB>>NB>NY real 0m0,019s user 0m0,016s sys 0m0,000s
Haha, bastardarnold_m schreef op zondag 18 december 2022 @ 20:06:
Dataset 7 lukt wel, maar ik heb wel de code een beetje aan moeten passen op de eenrichtingstunnels van @Soultaker.
Ik wilde dat nog opschonen omdat ik dacht dubbel werk te doen. Ik wist helemaal niet dat er unidirectional tunnels inzaten. Het is dus meer gewoon luiheid van mijn kant dat ik dat goed doe
Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.
Oei inderdaad. Dat was mijn conclusie ook al. Als je het niet erg vind maak ik er voor de 25e december nog even geen prioriteit van.Soultaker schreef op zondag 18 december 2022 @ 19:57:
Oei! Aangezien .oisyn en ik met compleet andere implementaties op hetzelfde antwoord uitkomen ga ik er vanuit dat dit een bug in jouw solver is.
Siditamentis astuentis pactum.
Kleine optimize
===[ input.txt ]========== Time: 2,856us (load:82us, part1:2,521us, part2:253us) Part 1: 1802 Part 2: 2602 ===[ aoc_2022_day16_large-1.txt ]========== Time: 132,012us (load:72us, part1:65,534us, part2:66,405us) Part 1: 117949 Part 2: 125937 ===[ aoc_2022_day16_large-2.txt ]========== Time: 107,404us (load:140us, part1:52,616us, part2:54,647us) Part 1: 113928 Part 2: 130572 ===[ aoc_2022_day16_large-3.txt ]========== Time: 121,503us (load:97us, part1:60,312us, part2:61,093us) Part 1: 132244 // FOUT Part 2: 140630 ===[ aoc_2022_day16_large-4.txt ]========== Time: 121,857us (load:127us, part1:50,459us, part2:71,269us) Part 1: 137838 Part 2: 141648 ===[ aoc_2022_day16_large-5.txt ]========== Time: 3,998,695us (load:111us, part1:851,937us, part2:3,146,646us) Part 1: 148452 Part 2: 166998 ===[ aoc_2022_day16_large-6.txt ]========== Time: 25,574,942us (load:80us, part1:5,155,388us, part2:20,419,474us) Part 1: 167926 // FOUT Part 2: 194493 // FOUT ===[ aoc_2022_day16_large-7.txt ]========== Time: 591us (load:125us, part1:440us, part2:25us) Part 1: 58361 Part 2: 52131
Klopt alleen niet helemaal. Vreemd, dat betekent dat mijn pruning belangrijke paden afkapt terwijl dat helemaal niet zou moeten kunnen.
Hoe jij zo lang over large-7 doet is me een raadsel...
.edit: aaaah, denkfout.
Ik dacht, als je A->B->C->D vindt en die is "beter" dan A->C->B->D, dan hoef je die laatste nooit verder te expanden. Maar ik dacht iets te makkelijk over wat "beter" is, want er zijn twee criteria: pressure en tijd. In dit geval keek ik louter naar pressure, en prunede ik een stap die qua pressure lager was maar meer tijd overhield. Eens kijken of ik hier een enkele metric voor kan verzinnen die gegarandeerd klopt. Wat we natuurlijk sowieso kunnen stellen is dat als een permutatie slechter is in beide metrics, hij kan stoppen.
[ Voor 20% gewijzigd door .oisyn op 18-12-2022 23:15 ]
Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.
Zo, gefixed
Large-6 part-2 klopt overigens nog steeds niet. De fout was eerst te wijten aan de afhandeling van AA met positieve flowrate (daar hield ik wel rekening mee maar zat een bug in). Ik zie niet helemaal hoe part-2 niet kan kloppen terwijl part-1 wel klopt. Ik krijg voor zowel de pruning als non-pruning dezelfde resultaten. Wat is jouw volledige antwoord, @Soultaker?
===[ input.txt ]========== Time: 6,158us (load:3,512us, part1:2,380us, part2:265us) Part 1: 1820 Part 2: 2602 ===[ aoc_2022_day16_large-1.txt ]========== Time: 126,909us (load:3,011us, part1:65,463us, part2:58,434us) Part 1: 117949 Part 2: 125937 ===[ aoc_2022_day16_large-2.txt ]========== Time: 108,163us (load:4,282us, part1:56,397us, part2:47,483us) Part 1: 113928 Part 2: 130572 ===[ aoc_2022_day16_large-3.txt ]========== Time: 119,333us (load:91us, part1:61,370us, part2:57,871us) Part 1: 132860 Part 2: 140630 ===[ aoc_2022_day16_large-4.txt ]========== Time: 126,642us (load:4,047us, part1:50,645us, part2:71,950us) Part 1: 137838 Part 2: 141648 ===[ aoc_2022_day16_large-5.txt ]========== Time: 3,863,103us (load:241us, part1:949,716us, part2:2,913,145us) Part 1: 148452 Part 2: 166998 ===[ aoc_2022_day16_large-6.txt ]========== Time: 40,588,194us (load:77us, part1:3,943,448us, part2:36,644,668us) Part 1: 158683 Part 2: 184097 // Komt niet overeen met Soultaker. ===[ aoc_2022_day16_large-7.txt ]========== Time: 436us (load:77us, part1:330us, part2:27us) Part 1: 58361 Part 2: 52131
Large-6 part-2 klopt overigens nog steeds niet. De fout was eerst te wijten aan de afhandeling van AA met positieve flowrate (daar hield ik wel rekening mee maar zat een bug in). Ik zie niet helemaal hoe part-2 niet kan kloppen terwijl part-1 wel klopt. Ik krijg voor zowel de pruning als non-pruning dezelfde resultaten. Wat is jouw volledige antwoord, @Soultaker?
Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.
Ik kom hier op 181585, iets minder dus. Had je 'm niet eerder al opgelost met een andere versie van je solver? Kreeg je toen hetzelfde antwoord of is dat niet meer te achterhalen?.oisyn schreef op maandag 19 december 2022 @ 00:02:
===[ aoc_2022_day16_large-6.txt ]==========
Time: 40,588,194us (load:77us, part1:3,943,448us, part2:36,644,668us)
Part 1: 158683
Part 2: 184097 // Komt niet overeen met Soultaker.
Large-6 part-2 klopt overigens nog steeds niet. De fout was eerst te wijten aan de afhandeling van AA met positieve flowrate (daar hield ik wel rekening mee maar zat een bug in). Ik zie niet helemaal hoe part-2 niet kan kloppen terwijl part-1 wel klopt. Ik krijg voor zowel de pruning als non-pruning dezelfde resultaten. Wat is jouw volledige antwoord, @Soultaker?
Ik had dus een bug met AA met positieve flowrate. Toen hij gisteren met een resultaat kwam na een paar minuten heb ik niet gecontroleerd of het antwoord wel klopte, maar ik verwacht niet dat dat anders was dan wat ik daarnet kreeg.Soultaker schreef op maandag 19 december 2022 @ 00:08:
[...]
Ik kom hier op 181585, iets minder dus. Had je 'm niet eerder al opgelost met een andere versie van je solver? Kreeg je toen hetzelfde antwoord of is dat niet meer te achterhalen?
Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.
Kun je proberen het optimale pad te reconstrueren? Ik kan hetzelfde doen maar aangezien jouw antwoord hoger is het voor jouw eenvoudiger te bewijzen dat jouw antwoord klopt dan voor mij om het te ontkrachten..oisyn schreef op maandag 19 december 2022 @ 00:10:
Ik had dus een bug met AA met positieve flowrate. Toen hij gisteren met een resultaat kwam na een paar minuten heb ik niet gecontroleerd of het antwoord wel klopte, maar ik verwacht niet dat dat anders was dan wat ik daarnet kreeg.
@Soultaker Ik zie het al. Het gevonden pad klopt, het getal wat ie print alleen niet
. Het verschil tussen onze antwoorden is exact 4x de flowrate van AA. Ik doe tijdens part1 al voorwerk voor part2, maar omdat de tijd bij part2 4 seconden minder is moet ik de score aanpassen. Ik track de totale flowrate van de oplossing en vermenigvuldig dat met 4 en trek dat van de pressure af voor de score van part2.
Alleen AA met positieve flowrate is een special case queue entry, alleen daar vergeet ik de waarde van de totale flowrate in te vullen, dus die wordt er aan het eind ook niet afgetrokken, en eindig ik 4xAA te hoog. Heeft verder geen invloed op de timings.
Alleen AA met positieve flowrate is een special case queue entry, alleen daar vergeet ik de waarde van de totale flowrate in te vullen, dus die wordt er aan het eind ook niet afgetrokken, en eindig ik 4xAA te hoog. Heeft verder geen invloed op de timings.
[ Voor 7% gewijzigd door .oisyn op 19-12-2022 00:17 ]
Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.
Eindelijk heb ik ook dag 16 opgelost. Ik zat zaterdag helemaal vast, heb wel 2 uur zitten debuggen en testen en het resultaat klopte! Maar:
Deze oplossing lijkt volgens mij heel erg op die van .oisyn, maar bij mij runt hij in 320ms in Kotlin.
De grote bestanden gaan ongeveer zo:
- large-1: 862ms
- large-2: meer dan 64 items, wordt nog niet ondersteund
- large-3: 759ms
- large-4: 1710ms
- large-5: veeeeel te lang
- large-6: veeeeel te lang
- large-7: meer dan 64 items, wordt nog niet ondersteund
Heb duidelijk nog best wel wat werk te doen
spoiler:
Ik had eroverheen gelezen dat we bij AA moesten starten, ik startte bij de eerste in de lijst 
Deze oplossing lijkt volgens mij heel erg op die van .oisyn, maar bij mij runt hij in 320ms in Kotlin.
De grote bestanden gaan ongeveer zo:
- large-1: 862ms
- large-2: meer dan 64 items, wordt nog niet ondersteund
- large-3: 759ms
- large-4: 1710ms
- large-5: veeeeel te lang
- large-6: veeeeel te lang
- large-7: meer dan 64 items, wordt nog niet ondersteund
Heb duidelijk nog best wel wat werk te doen
[ Voor 25% gewijzigd door Marcj op 19-12-2022 11:00 ]
Veels te lang vast gezeten op dag 19:
spoiler:
ik kwam er pas heel laat achter dat je maximaal 1 robot per minuut kan produceren ...
Daarna oplossing met dynamic programming gebouwd die 20s doet over voor deel 1 en 2. Wel de aanname gedaan dat als je Geode robot kan produceren je dat ook doet en hetzelfde voor Obsidian. Volgens mij zijn er inputs te verzinnen waarvoor dat niet werkt.
Daarna oplossing met dynamic programming gebouwd die 20s doet over voor deel 1 en 2. Wel de aanname gedaan dat als je Geode robot kan produceren je dat ook doet en hetzelfde voor Obsidian. Volgens mij zijn er inputs te verzinnen waarvoor dat niet werkt.
Heel lang veel te moeilijk lopen doen en constant tegen off by one error's aangekeken.MrHaas schreef op maandag 19 december 2022 @ 12:34:
Veels te lang vast gezeten op dag 19:
spoiler:ik kwam er pas heel laat achter dat je maximaal 1 robot per minuut kan produceren ...
Daarna oplossing met dynamic programming gebouwd die 20s doet over voor deel 1 en 2. Wel de aanname gedaan dat als je Geode robot kan produceren je dat ook doet en hetzelfde voor Obsidian. Volgens mij zijn er inputs te verzinnen waarvoor dat niet werkt.
Uiteindelijk 1 prune conditie gevonden die ontiegelijk veel gevallen uitsloot waardoor alles wel snel klaar was.
spoiler:
Als ik in beurt N genoeg had om robot X te bouwen, maar dit niet gedaan had, dan had het geen zin om dat de beurt erna wel te doen
Moeilijke meuk verder maar laten zitten. Deel 1 doet ie hier in 336ms en deel 2 in 566ms.
spoiler:
Ik had al dat ik altijd geode ging bouwen, maar je hebt een punt met obsidian. Dat ook maar even toegevoegd. Het werkt voor de gegeven inputs, maar dat komt denk ik omdat de hoeveelheid benodigde clay erg hoog ligt en de benodigde ore bijna gelijk. Zou dat niet zo zijn dan vermoed ik dat je ore gaat wegkapen voor obsidian die je eigenlijk voor geode zou moeten gebruiken
Na die aanpassing is het 152ms voor deel 1 en 92ms voor deel 2 geworden.
Code
Ken Thompson's famous line from V6 UNIX is equaly applicable to this post:
'You are not expected to understand this'
Wel een leuk probleem vandaag! Vreemd genoeg gaat de officiële invoer (bij deel 2) voor mij veel sneller dan de voorbeeldinvoer, waardoor ik behoorlijk lang heb zitten optimaliseren terwijl dat eigenlijk niet nodig was.
Ook heb ik helaas een verkeerd antwoord gegeven bij deel 1; dat was de eerste keer dit jaar (daar gaat m'n streak).
Uiteindelijk heb ik het zo opgelost:
Ook heb ik helaas een verkeerd antwoord gegeven bij deel 1; dat was de eerste keer dit jaar (daar gaat m'n streak).
Uiteindelijk heb ik het zo opgelost:
spoiler:
Per dag hou ik een lijst van mogelijke states bij, waarbij een state bestaat uit het aantal robots en grondstoffen ik van elk type heb. Elke dag kun je natuurlijk kiezen om te sparen of 1 van de mogelijke robots te bouwen. Daardoor genereer je wel erg veel mogelijkheden.
Om het aantal mogelijkheden in te perken doe ik twee dingen: ten eerste verwijder ik per dag de inferieure states (i.e. die waarbij je voor alle robots en grondstoffen ofwel minder of het gelijke aantal hebt dan een andere state), maar dan blijven er nog steeds vrij veel states over: b.v. je kunt 3 ore en 1 clay hebben, 2 ore en 2 clay, 1 ore en 3 clay, etc. en geen van die drie is inferieur aan de ander. En dat dan voor 8 velden.
Het tweede wat ik doe is het het maximeren van het aantal robots en grondstoffen. Voor robots is het makkelijk: je hoeft nooit meer te bouwen van het robot-type dat een grondstof produceert dan de duurste robot kost, aangezien je toch maar 1 robot per minuut kan bouwen (voor de voorbeeldinvoer is dat bijvoorbeeld 4 ore, 14 clay, 7 obsidian). Voor grondstoffen is het lastiger. In eerste instantie had ik het aantal grondstoffen simpelweg gelimiteerd op 100; de intuïtie is dat als je een heleboel van een grondstof op voorraad hebt dat je ze waarschijnlijk nooit meer op gaat gebruiken, maar formeel is dat natuurlijk niet helemaal goed onderbouwd.
In de uiteindelijke versie heb ik dat veranderd naar het maximum dat je nodig hebt voor een andere robot × het aantal minuten dat nog resteert. Dat is duidelijk correct en ook snel genoeg; m'n Python code loopt in 1 seconde.
Om het aantal mogelijkheden in te perken doe ik twee dingen: ten eerste verwijder ik per dag de inferieure states (i.e. die waarbij je voor alle robots en grondstoffen ofwel minder of het gelijke aantal hebt dan een andere state), maar dan blijven er nog steeds vrij veel states over: b.v. je kunt 3 ore en 1 clay hebben, 2 ore en 2 clay, 1 ore en 3 clay, etc. en geen van die drie is inferieur aan de ander. En dat dan voor 8 velden.
Het tweede wat ik doe is het het maximeren van het aantal robots en grondstoffen. Voor robots is het makkelijk: je hoeft nooit meer te bouwen van het robot-type dat een grondstof produceert dan de duurste robot kost, aangezien je toch maar 1 robot per minuut kan bouwen (voor de voorbeeldinvoer is dat bijvoorbeeld 4 ore, 14 clay, 7 obsidian). Voor grondstoffen is het lastiger. In eerste instantie had ik het aantal grondstoffen simpelweg gelimiteerd op 100; de intuïtie is dat als je een heleboel van een grondstof op voorraad hebt dat je ze waarschijnlijk nooit meer op gaat gebruiken, maar formeel is dat natuurlijk niet helemaal goed onderbouwd.
In de uiteindelijke versie heb ik dat veranderd naar het maximum dat je nodig hebt voor een andere robot × het aantal minuten dat nog resteert. Dat is duidelijk correct en ook snel genoeg; m'n Python code loopt in 1 seconde.
Druk weekend gehad, vandaag wat tijd gehad om het e.e.a. op te poetsen.
Dag 17 - Python
Dag 18 - Python
Moet nog heel wat sleutelen aan vandaag, 16s op part1 en een uur ofzo op part2
Dag 19 - Python
Dag 17 - Python
Dag 18 - Python
Moet nog heel wat sleutelen aan vandaag, 16s op part1 en een uur ofzo op part2

Dag 19 - Python
Niet heel veel activiteit in dit topic vanavond. Als iemand zich verveeld: mijn testdata voor dag 18 is nog niet opgelost!
Iedereen is bijna burned out denk ik en blij als ze weer een dag zijn doorgekomenSoultaker schreef op maandag 19 december 2022 @ 20:05:
Niet heel veel activiteit in dit topic vanavond. Als iemand zich verveeld: mijn testdata voor dag 18 is nog niet opgelost!
Ik heb er al redelijk wat tijd in gestoken, maar heb de rare situatie te pakken dat mijn programma wel de goede output geeft voor part 1, maar
spoiler:
als ik het tijdslimiet verhoog naar 32 ik niet meer de goede output krijg bij de voorbeelden. Waarschijnlijk prune ik te snel/te veel, waardoor dit gebeurd, maar ik zie door de ores de geodes niet meer
Waarschijnlijk heel erg kort door de bocht gevlogen maar runt nu beide delen in 3sDiderikdm schreef op maandag 19 december 2022 @ 19:33:
Druk weekend gehad, vandaag wat tijd gehad om het e.e.a. op te poetsen.
Dag 17 - Python
Dag 18 - Python
Moet nog heel wat sleutelen aan vandaag, 16s op part1 en een uur ofzo op part2![]()
Dag 19 - Python
spoiler:
makeshift berekening waarvan ik vrij zeker ben dat die te kort door de bocht is om vanaf end - 10 een evaluatie te maken of het hoogste aantal geodes nog te halen is (regel 14 - 17)
De laatste dagen eindelijk wat tijd aan het vinden om een inhaalbeweging te starten. Zonet tot en met dag 12 opgelost in Rust:Volgende dagen heb ik wat vakantie, dan kan ik eens verder doen om mijn achterstand in te halen
Without nipples, boobs are pointless - 365 project - In mijn hoofd is het alle dagen Kerstmis - What type of bees make milk? Boobies! - What type of bees are scary? BoooOOOOOooobeees! - Cactusliefhebster
Hey @.oisyn ! Heb je toevallig wat meer uitleg over hoe jij het voor elkaar krijgt om zo snel combinaties van niet-overlappende paden kan vinden voor dag 16? Ik zit naar jouw code te kijken, maar ik zie niet in hoe dit zo snel gaat. Mijn huidige algoritme is O(n^2), maar ik weet misschien een O(n log(n)) manier (maar dit kost wat werk)..oisyn schreef op maandag 19 december 2022 @ 00:16:
@Soultaker Ik zie het al. Het gevonden pad klopt, het getal wat ie print alleen niet. Het verschil tussen onze antwoorden is exact 4x de flowrate van AA. Ik doe tijdens part1 al voorwerk voor part2, maar omdat de tijd bij part2 4 seconden minder is moet ik de score aanpassen. Ik track de totale flowrate van de oplossing en vermenigvuldig dat met 4 en trek dat van de pressure af voor de score van part2.
Alleen AA met positieve flowrate is een special case queue entry, alleen daar vergeet ik de waarde van de totale flowrate in te vullen, dus die wordt er aan het eind ook niet afgetrokken, en eindig ik 4xAA te hoog. Heeft verder geen invloed op de timings.
Voor mij, in deel 2 is dit hetgeen wat veruit het langste duurt!
Het verkennen van alle paden heb ik wel een aantal leuke optimalisaties gevonden:
spoiler:
- Depth-first search bleek bij mij 2x sneller (en verkent 2x minder nodes) dan bread-first search
- Ik heb de heuristic (van maximaal mogelijke score) vervangen door het opslaan van de meest optimale tussen-paden. Dit bleek een factor 10 te schelen voor deel 1. Hier kwam ik per ongeluk doordat ik voor deel 2 de meest optimale tussenpaden wilde bewaren.
- Sorteren van uitgaande paden gebaseerd op de flowrate van die valve bleek ook nog behoorlijk te helpen.
- Ik heb de heuristic (van maximaal mogelijke score) vervangen door het opslaan van de meest optimale tussen-paden. Dit bleek een factor 10 te schelen voor deel 1. Hier kwam ik per ongeluk doordat ik voor deel 2 de meest optimale tussenpaden wilde bewaren.
- Sorteren van uitgaande paden gebaseerd op de flowrate van die valve bleek ook nog behoorlijk te helpen.
Op zich een prima dag vandaag vergeleken met de vorige dagen
Dag 20 - Python
spoiler:
Wel lang vastgezeten op dubbele getallen in de input waardoor indexering niet lekker ging
Dag 20 - Python
Voor dag 16 heb ik zelf een andere implementatie gevonden om sneller te kunnen doorzoeken. Op zich wel mooie resultaten voor op de JVM (zal altijd langzamer zijn dan C++):
Alleen nu viel het me op dat voor large-2 en large-6 het niet helemaal klopt. @Soultaker heb jij een hint wat er speciaal aan deze zijn?
large-1: Loaded in 0,049 seconds Day 16: Part 1: 117859 Part 2: 125937 Calculated in 0,290 seconds large-2: Loaded in 0,060 seconds Day 16: Part 1: 111201 Part 2: 127836 Calculated in 0,161 seconds large-3: Loaded in 0,046 seconds Day 16: Part 1: 132666 Part 2: 140630 Calculated in 0,256 seconds large-4: Loaded in 0,053 seconds Day 16: Part 1: 137838 Part 2: 141648 Calculated in 0,220 seconds large-5: Loaded in 0,049 seconds Day 16: Part 1: 148452 Part 2: 166998 Calculated in 6,679 seconds large-6: Loaded in 0,045 seconds Day 16: Part 1: 151682 Part 2: 175671 Calculated in 29,732 seconds large-7: Loaded in 0,076 seconds Day 16: Part 1: 58361 Part 2: 52131 Calculated in 0,012 seconds
Alleen nu viel het me op dat voor large-2 en large-6 het niet helemaal klopt. @Soultaker heb jij een hint wat er speciaal aan deze zijn?
@Marj Er kloppen er wel meer niet
1a, 2a, 2b, 3a, 6a, 6b
.
Het is een lookup op de onderste N ongebruikte bits. Bij mijn vorige oplossing N=1, nu N=2.
Part1 genereert een set van gebruikte valves en hun maximale score (met t<=26). Voor part2 moet je dan idd een paar zoeken zonder dat die dezelfde valves gebruiken (zo ver was jij natuurlijk ook).
Ik groepeer dan alle oplossingen op hun onderste gebruikte valve(s). Ik stel even dat N=1 voor het gemak van de uitleg. Oftewel, als je ze encodeerd als bits, dan groepeer je ze op de index van de kleinste bit die 1. De groepen kunnen niet overlappen: een oplossing uit de groep met bit-0 kan wellicht ook de valve op bit-1 gebruiken, maar die oplossing zit dan niet in de bit-1 groep want dan is bit-1 niet de kleinste gezette bit.
Al die groepen sorteer je op score, van hoog naar laag, zodat je een early out hebt. Hetzelfde doe je overigens bij de totale set.
Dan loop je over de totale set, voor elke oplossing bereken je het complement van de valves van de oplossing, en dan pak je per gezette bit de betreffende groepen van hierboven erbij. Die loop je ook allemaal af, maar je kunt stoppen als de score van de buitenste oplossing + de score van de gecomplementeerde oplossing kleiner is dan de huidige maximale score. Evenzo kun je in de buitenste loop ook stoppen als 2x de score van de buitenste oplossing kleiner is dan de maximale score (immers, om een betere score te halen zou betekenen dat er een binnenste oplossing is met een score groter dan de buitenste oplossing, maar die heb je dan al gehad als buitenste oplossing, dus dit scheelt de helft van het werk).
Voor grotere N maak je een betere voorselectie maar wordt je binnenste loop wel gecompliceerder. Waar je bij N=1 simpelweg over de bits loopt, moet je bij N=2 over alle paren van bits lopen, etc.
@Soultaker Die stomme bug die ik had bij 6b zorgt trouwens wel voor hoofdpijn. Als ik de bug fix dan prunet hij teveel mogelijkheden en krijg ik het goede antwoord er niet uit. Ik was er al bang voor dat mijn heuristiek om een pad af te kappen een beetje te kort door de bocht is.
1a, 2a, 2b, 3a, 6a, 6b
Ik heb 6b inmiddels in 4,5sMarcj schreef op dinsdag 20 december 2022 @ 09:03:
[...]
Hey @.oisyn ! Heb je toevallig wat meer uitleg over hoe jij het voor elkaar krijgt om zo snel combinaties van niet-overlappende paden kan vinden voor dag 16? Ik zit naar jouw code te kijken, maar ik zie niet in hoe dit zo snel gaat. Mijn huidige algoritme is O(n^2), maar ik weet misschien een O(n log(n)) manier (maar dit kost wat werk).
Het is een lookup op de onderste N ongebruikte bits. Bij mijn vorige oplossing N=1, nu N=2.
Part1 genereert een set van gebruikte valves en hun maximale score (met t<=26). Voor part2 moet je dan idd een paar zoeken zonder dat die dezelfde valves gebruiken (zo ver was jij natuurlijk ook).
Ik groepeer dan alle oplossingen op hun onderste gebruikte valve(s). Ik stel even dat N=1 voor het gemak van de uitleg. Oftewel, als je ze encodeerd als bits, dan groepeer je ze op de index van de kleinste bit die 1. De groepen kunnen niet overlappen: een oplossing uit de groep met bit-0 kan wellicht ook de valve op bit-1 gebruiken, maar die oplossing zit dan niet in de bit-1 groep want dan is bit-1 niet de kleinste gezette bit.
Al die groepen sorteer je op score, van hoog naar laag, zodat je een early out hebt. Hetzelfde doe je overigens bij de totale set.
Dan loop je over de totale set, voor elke oplossing bereken je het complement van de valves van de oplossing, en dan pak je per gezette bit de betreffende groepen van hierboven erbij. Die loop je ook allemaal af, maar je kunt stoppen als de score van de buitenste oplossing + de score van de gecomplementeerde oplossing kleiner is dan de huidige maximale score. Evenzo kun je in de buitenste loop ook stoppen als 2x de score van de buitenste oplossing kleiner is dan de maximale score (immers, om een betere score te halen zou betekenen dat er een binnenste oplossing is met een score groter dan de buitenste oplossing, maar die heb je dan al gehad als buitenste oplossing, dus dit scheelt de helft van het werk).
Voor grotere N maak je een betere voorselectie maar wordt je binnenste loop wel gecompliceerder. Waar je bij N=1 simpelweg over de bits loopt, moet je bij N=2 over alle paren van bits lopen, etc.
@Soultaker Die stomme bug die ik had bij 6b zorgt trouwens wel voor hoofdpijn. Als ik de bug fix dan prunet hij teveel mogelijkheden en krijg ik het goede antwoord er niet uit. Ik was er al bang voor dat mijn heuristiek om een pad af te kappen een beetje te kort door de bocht is.
[ Voor 100% gewijzigd door .oisyn op 20-12-2022 14:42 ]
Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.
large-2 is simpelweg een grotere versie van 1 (meer nodes), large-6 heeft asymmetrische paden (b.v. wel AA->BB maar niet BB->AA). Maar zoals .oisyn al opmerkte gaat het bij 1a al mis, dus ik zou daar beginnen.Marcj schreef op dinsdag 20 december 2022 @ 13:48:
Alleen nu viel het me op dat voor large-2 en large-6 het niet helemaal klopt. @Soultaker heb jij een hint wat er speciaal aan deze zijn?
Als je je code post kan ik je misschien een tip geven (maar ik beloof niets
Wat mij betreft tellen alleen geldige optimalisaties, niet cut-offs die toevallig op de beschikbare invoer werken@Soultaker Die stomme bug die ik had bij 6b zorgt trouwens wel voor hoofdpijn. Als ik de bug fix dan prunet hij teveel mogelijkheden en krijg ik het goede antwoord er niet uit. Ik was er al bang voor dat mijn heuristiek om een pad af te kappen een beetje te kort door de bocht is.
DuhSoultaker schreef op dinsdag 20 december 2022 @ 15:39:
Wat mij betreft tellen alleen geldige optimalisaties, niet cut-offs die toevallig op de beschikbare invoer werkenAnders is natuurlijk het hek van de dam, dan kun je het optimale pad bij wijze van spreke wel hardcoden.
Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.
Ik zie het nu, op een of andere manier mis ik het meeste optimale pad. Ik zou verwachten dat dit alleen kan liggen aan te agressief afkappen van paden. Zou iemand het beste pad voor large-1a met me kunnen delen (eventueel via DM)? Dan kan ik debuggen waarom die niet doorzocht wordt.
Het rare is dat voor de testinvoer en mijn opdracht op de site het prima werkt.
Het rare is dat voor de testinvoer en mijn opdracht op de site het prima werkt.
@Marcj AA -> EY -> WD -> BH -> FB -> VZ -> VI -> AD -> LY -> YC -> HY -> OQ -> IF -> JY -> FL
.edit: dit is trouwens niet per se hét beste pad, he. Er kunnen er meerdere zijn met dezelfde score.
.edit: dit is trouwens niet per se hét beste pad, he. Er kunnen er meerdere zijn met dezelfde score.
[ Voor 35% gewijzigd door .oisyn op 20-12-2022 17:27 ]
Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.
Heel erg bedankt voor deze input @.oisyn ! Ik heb het kunnen vinden. Het uiteindelijke probleem zat eigenlijk in het inlezen, waar een foutje in zat. Daardoor vielen er in een paar gevallen een enkele edge weg. En dit kwam niet voor in de kleinere sets. Helaas was dat ook een groot deel van de reden waarom het zo snel was 
Nou ja, wel weer een hoop geleerd in ieder geval. Voor degene die de code willen bekijken, Day16 is de oplossing, met hier de hulpfuncties voor BFS, DFS en combinaties maken.
Day 16 from day16.txt: Part 1: 1923 in 0,027 seconds Part 2: 2594 in 0,045 seconds Full run in 0,111 seconds Day 16 from day16_big-1.txt: Part 1: 117949 in 0,230 seconds Part 2: 125937 in 0,357 seconds Full run in 0,631 seconds Day 16 from day16_big-2.txt: Part 1: 113928 in 0,267 seconds Part 2: 130572 in 0,348 seconds Full run in 0,678 seconds Day 16 from day16_big-3.txt: Part 1: 132860 in 0,166 seconds Part 2: 140630 in 0,294 seconds Full run in 0,507 seconds Day 16 from day16_big-4.txt: Part 1: 137838 in 0,403 seconds Part 2: 141648 in 0,443 seconds Full run in 0,894 seconds Day 16 from day16_big-5.txt: Part 1: 148452 in 5,716 seconds Part 2: 166998 in 7,024 seconds Full run in 12,787 seconds Day 16 from day16_big-6.txt: Part 1: 158683 in 6,397 seconds Part 2: 181585 in 63,713 seconds Full run in 70,157 seconds Day 16 from day16_big-7.txt: Part 1: 58361 in 0,004 seconds Part 2: 52131 in 0,003 seconds Full run in 0,097 seconds
Nou ja, wel weer een hoop geleerd in ieder geval. Voor degene die de code willen bekijken, Day16 is de oplossing, met hier de hulpfuncties voor BFS, DFS en combinaties maken.
Omdat ik het niet kan laten, hier nog wat extra testdata voor dag 20: aoc_2022_day20_large.zip.
Oplossingen en referentie-tijden:
Oplossingen en referentie-tijden:
$ time pypy3 -O solve.py < large-1.txt ...037 ...357 2.149s $ time pypy3 -O solve.py < large-2.txt ...329 ...383 9.982s $ time pypy3 -O solve.py < large-3.txt ...878 ...634 1m14.715s
poeh, mijn simpele oplossing (linked list + array) doet al 17 sec over de eerste. de 2e heb ik na 5 min maar gestopt 
code:
1
2
3
4
| $ go run main.go Part 1: ...037 Part 2: ...357 Time: 17.88357825s |
spoiler:
De pragmatische oplossingsrichting is om ook next100, next1000, next10000, next100000, prev100, etc. toe te voegen aan de nodes van de LL. Dan is het 1x iets meer werk met parsen, daarna veel sneller heen en weer springen.
Grappig, dat was ook mijn eerste gedachte, maar ik vond het erg lastig om de details correct te implementeren. Het lastigste is dat jeHectorMalot schreef op dinsdag 20 december 2022 @ 23:48:
spoiler:De pragmatische oplossingsrichting is om ook next100, next1000, next10000, next100000, prev100, etc. toe te voegen aan de nodes van de LL. Dan is het 1x iets meer werk met parsen, daarna veel sneller heen en weer springen.
spoiler:
niet eenmalig die extra pointers kunt toevoegen, je moet ze ook (efficiënt!) updaten wanneer je nodes verplaatst.
Ik denk dat het wel moet kunnen, maar ik vond het persoonlijk lastig om het correct te implementeren, dus ik heb het uiteindelijk met een andere datastructuur opgelost. Misschien dat ik het later alsnog probeer; het is wel een elegante aanpak namelijk.
edit:
Hm, nu ik er wat langer over nagedacht heb weet ik niet of die aanpak wel haalbaar is. Als je b.v. een linkedlist hebt met elk tiende element, en je verwijdert 1 node, dan moet je alle volgende items in de linked list updaten wat nog steeds ongeveer lineair tijd kost. Dat is dus niet echt winst.
[ Voor 17% gewijzigd door Soultaker op 21-12-2022 12:55 ]
Python 3
Goed te doen vandaag, leuke puzzel!
Goed te doen vandaag, leuke puzzel!
spoiler:
Deel 1 zat ik vrijwel direct goed met een resursieve oplossing. Voor deel 2 dacht ik in eerste instantie dat dit weer een enorm gedoe zou worden, maar bleek vrij makkelijk aangezien de rechter aap altijd hetzelfde antwoord geeft. Het was voor mij logisch dat het antwoord sowieso een integer moest zijn en er zat een duidelijk patroon in. Toen heb ik in eerste instantie met de hand uitgerekend wat het andwoord moest zijn. Dit heb ik daarna maar geimplementeerd in de code 😅.
Dag 21 is een leuke en niet al te moeilijk.
spoiler:
Deel 2 initieel opgelost met een binary search, maar daarna nog even omgeschreven naar een lineaire vegelijking met wat operator overloading magic om hem direct in mn bestaande evaluate functie te kunnen gooien.
Leuke opdracht vandaag, aapjes kijken is altijd leuk
.
spoiler:
Deel twee heb ik numeriek opgelast; ik merkte dat de ene aap altijd hetzelfde antwoord terug gaf en dat de andere aap voor een delta +1 ok circa hetzelfde verschil aan antwoord terug gaf (in mijn geval circa +2,83... per verhoging van 1). Een loop geschreven die het verschil / delta bij mijn initiële antwoord gooit om een nieuwe guess te doen. Werkte vrij goed voor mijn input; oplossing gevonden binnen 3 iteraties, maar geen idee of het ook voor andere input werkt. Code in python.
bakkerjangert schreef op woensdag 21 december 2022 @ 10:07:
Leuke opdracht vandaag, aapjes kijken is altijd leuk.
spoiler:Deel twee heb ik numeriek opgelast; ik merkte dat de ene aap altijd hetzelfde antwoord terug gaf en dat de andere aap voor een delta +1 ok circa hetzelfde verschil aan antwoord terug gaf (in mijn geval circa +2,83... per verhoging van 1). Een loop geschreven die het verschil / delta bij mijn initiële antwoord gooit om een nieuwe guess te doen. Werkte vrij goed voor mijn input; oplossing gevonden binnen 3 iteraties, maar geen idee of het ook voor andere input werkt. Code in python.
spoiler:
Je kunt het antwoord ook volledig recursief beredeneren, je weet steeds van 1 branch wat het antwoord is, vervolgens kun je de omgekeerde operatie uitvoeren en voor de andere branch weer niveau dieper kijken. Zo heb ik het in ieder geval opgelost (< 1 s in python).
Python code dag 21 deel 1 en 2
spoiler:
Het zat me toch niet helemaal lekker dat ik niet direct het juiste antwoord kan berekenen voor part 2. Zou niet zo moeilijk moeten zijn aangezien het om een lineare functie gaat. Het is me nu gelukt om met redelijke precisie op het juiste antwoord te komen door de delta x (1e12) groot genoeg te maken.Linkje naar code.
Leuk die advent of code. De oplossing vandaag snel in elkaar geklopt, met behulp van de fantastische exec functie van python:
spoiler:
monkeys = [x.replace(":", " = ") for x in open("input.txt", "r").read().split("\n")]
while (len(monkeys) > 0):
for i, monkey in enumerate(monkeys):
try:
exec(monkey)
del monkeys[i]
except: pass
print(int(root))
En deel 2 met 'het handje' gedaan in excel, na het uitrekenen na 2 waardes voor humn :-)
while (len(monkeys) > 0):
for i, monkey in enumerate(monkeys):
try:
exec(monkey)
del monkeys[i]
except: pass
print(int(root))
En deel 2 met 'het handje' gedaan in excel, na het uitrekenen na 2 waardes voor humn :-)
[ Voor 10% gewijzigd door IWriteCode op 21-12-2022 11:49 ]
Less = more
Leuke dag vandaag!
Dag 21 - Python
spoiler:
Liep in eerste instantie meerdere keren door de monkeys en wanneer bekend, zette ik hun waarde in een dict. Deel twee eerst met de hand gedaan.
Daarna geoptimaliseerd door elke monkey een lambda te geven naar ofwel hun int, ofwel op metaniveau de berekening.
Deel twee opgelost met een lineaire vergelijking
Daarna geoptimaliseerd door elke monkey een lambda te geven naar ofwel hun int, ofwel op metaniveau de berekening.
Deel twee opgelost met een lineaire vergelijking
Dag 21 - Python
[ Voor 12% gewijzigd door Diderikdm op 21-12-2022 17:30 ]
En nu ik dan toch in de draad ben aangehaakt, wil ik graag nog mijn oplossing voor dag 19 delen.
Ik gebruik een genetisch algoritme om de oplossing te vinden. Nadat ik eerst zelf bedacht had hoe zo'n algoritme zou moeten werken, tot een oplossing gekomen, maar dat kostte wel een x aantal pogingen.
Daarna ingelezen hoe zo'n genetisch algoritme echt zou moeten werken en daar m'n code mee verbeterd. Nu vindt ie sneller (en vaker
) het juiste antwoord:
https://topaz.github.io/p...BkKO0LQ7IlIuv7br/+ARlnA==
Ik gebruik een genetisch algoritme om de oplossing te vinden. Nadat ik eerst zelf bedacht had hoe zo'n algoritme zou moeten werken, tot een oplossing gekomen, maar dat kostte wel een x aantal pogingen.
Daarna ingelezen hoe zo'n genetisch algoritme echt zou moeten werken en daar m'n code mee verbeterd. Nu vindt ie sneller (en vaker
https://topaz.github.io/p...BkKO0LQ7IlIuv7br/+ARlnA==
Less = more
Uuugh, al de zoveelste dag waarbij part 2 niet werkt met de echte input 
Oké, gevonden! Oef... rust in het hoofd opnieuw
Blijkbaar moest ik dus...
spoiler:
Mijn idee was soortgelijk aan dat van @RefleXion. Ik zoek eerst een pad van 'root' naar 'humn'. Daarna begin ik opnieuw bij root, en kijk ik welke branch ik kan/moet aanpassen, namelijk die waarin 'humn' zit.
Aangezien beide branches dezelfde waarde moeten geven, reken je dan uit wat de branch, waarin 'humn' zit, eigenlijk zou moeten teruggeven. Ga een niveautje lager en rinse en repeat.
Maar door die delingen kom ik soms een kommagetal uit. Ik had verwacht dat alles altijd netjes deelbaar zou zijn
En als ik hier dan naar sommige mensen hun (Python-)oplossingen kijk, zie ik ook dat jullie int division doen (door die // operator). Waar staat er gespecifieerd dat dit mag?
Of wat mis ik nu net?
Aangezien beide branches dezelfde waarde moeten geven, reken je dan uit wat de branch, waarin 'humn' zit, eigenlijk zou moeten teruggeven. Ga een niveautje lager en rinse en repeat.
Maar door die delingen kom ik soms een kommagetal uit. Ik had verwacht dat alles altijd netjes deelbaar zou zijn
Oké, gevonden! Oef... rust in het hoofd opnieuw
spoiler:
... in het geval dat de tweede branch de 'humn'-branch is, de volgorde van m'n termen omdraaien. Best 'n domme fout wel.
[ Voor 12% gewijzigd door RangedNeedles op 21-12-2022 12:29 ]
Je hebt gelijk!RangedNeedles schreef op woensdag 21 december 2022 @ 12:19:
Uuugh, al de zoveelste dag waarbij part 2 niet werkt met de echte input
spoiler:Mijn idee was soortgelijk aan dat van @RefleXion. Ik zoek eerst een pad van 'root' naar 'humn'. Daarna begin ik opnieuw bij root, en kijk ik welke branch ik kan/moet aanpassen, namelijk die waarin 'humn' zit.
Aangezien beide branches dezelfde waarde moeten geven, reken je dan uit wat de branch, waarin 'humn' zit, eigenlijk zou moeten teruggeven. Ga een niveautje lager en rinse en repeat.
Maar door die delingen kom ik soms een kommagetal uit. Ik had verwacht dat alles altijd netjes deelbaar zou zijnEn als ik hier dan naar sommige mensen hun (Python-)oplossingen kijk, zie ik ook dat jullie int division doen (door die // operator). Waar staat er gespecifieerd dat dit mag?
Of wat mis ik nu net?
spoiler:
Had bij de division monkeys gekeken naar de uitkomst, welke altijd x.0 was voor mijn input en daarom een int() eromheen gegooid, of intdiv. In theorie kan het inderdaad wel dat er kommagetallen voorkomen.. Ik heb mn code aangepast, thanks 
Ik heb het mezelf gemakkeljik gemaakt en gebruik 'teveel' .indexOf operaties op LinkedList.Soultaker schreef op dinsdag 20 december 2022 @ 21:41:
Omdat ik het niet kan laten, hier nog wat extra testdata voor dag 20: aoc_2022_day20_large.zip.
Bij de eerste reken ik al 90 seconden. De rest heb ik maar niet uitgeprobeerd.
Siditamentis astuentis pactum.
Dag 21 was een leuk concept. Zelfde aanpak als de anderen hierboven; volgens mij is er ook niet veel anders mogelijk. Niet super moeilijk maar wel de meeste code die ik heb moeten schrijven door het implementeren van alle operators etc.
RangedNeedles schreef op woensdag 21 december 2022 @ 12:19:
spoiler:Maar door die delingen kom ik soms een kommagetal uit. Ik had verwacht dat alles altijd netjes deelbaar zou zijnEn als ik hier dan naar sommige mensen hun (Python-)oplossingen kijk, zie ik ook dat jullie int division doen (door die // operator). Waar staat er gespecifieerd dat dit mag?
spoiler:
Ik zou er nooit vanuit gaan dat het mag. Ik probeer eventuele aannamen altijd te checken in de code. Bijvoorbeeld in plaats van direct te delen kun je dit doen:
assert a % b == 0
return a // b
Het voordeel daarvan is dat als je aanname niet klopt, je een duidelijk foutmelding krijgt, in plaats van dat je domweg het verkeerde antwoord krijgt.
Als er niet-geheeltallige delingen zouden voorkomen dan zou je in Python vrij makkelijk kunnen overschakelen op Fractions, maar daar zou ik in eerste instantie niet vanuit gaan; het is vrij waarschijnlijk dat de invoer zo geconstrueerd is dat het op te lossen is met alleen gehele getallen, en dat was hier dus ook het geval.
assert a % b == 0
return a // b
Het voordeel daarvan is dat als je aanname niet klopt, je een duidelijk foutmelding krijgt, in plaats van dat je domweg het verkeerde antwoord krijgt.
Als er niet-geheeltallige delingen zouden voorkomen dan zou je in Python vrij makkelijk kunnen overschakelen op Fractions, maar daar zou ik in eerste instantie niet vanuit gaan; het is vrij waarschijnlijk dat de invoer zo geconstrueerd is dat het op te lossen is met alleen gehele getallen, en dat was hier dus ook het geval.
[ Voor 3% gewijzigd door Soultaker op 21-12-2022 14:27 ]
spoiler:
Ik dacht eerst deel 2 met z3 te doen maar uiteindelijk een domme brute-force gedaan richting "root: a - b == 0". Getal humn gaat omhoog zolang ik onder 0 zit en weer omlaag als ik erboven zit. Initieel met stapjes van 10 miljard en dan steeds kleiner richting de 0.
Geen idee of alle inputs een lineare correlatie hebben tussen humn en root maar in mijn geval wel (anders zou ik niet hoger-lager kunnen doen?)
Geen idee of alle inputs een lineare correlatie hebben tussen humn en root maar in mijn geval wel (anders zou ik niet hoger-lager kunnen doen?)
Inderdaad, gewoon met // geprobeerd en het werkte, niet verder over nagedacht. Als je in mijn code de // door / vervangt werkt hij ook voor floats.RangedNeedles schreef op woensdag 21 december 2022 @ 12:19:
En als ik hier dan naar sommige mensen hun (Python-)oplossingen kijk, zie ik ook dat jullie int division doen (door die // operator). Waar staat er gespecifieerd dat dit mag?Of wat mis ik nu net?
Deel 1 van vandaag was zo af, maar voor deel 2 ben ik een rabbit hole ingedoken met een complete polynoom implementatie, totdat ik doorhad dat het antwoord van een monkey maar door 1 andere monkey werd gebruikt. Dat maakte alles heel simpel.
Code
spoiler:
itt de eerdere oplossingen in dit topic heb ik gewoon mijn boom laten berekenen zoals bij part 1, alleen liet ik de kant van de operatie leeg waar humn in zat. Vervolgens zit in root 1 antwoord en ben ik gewoon weer naar beneden de boom in gegaan waarbij ik inverse van de operaties gebruikte icm het antwoord wat ik moest hebben en de waarde uit de andere tak.
Code
Ken Thompson's famous line from V6 UNIX is equaly applicable to this post:
'You are not expected to understand this'
Aha, dat is feitelijk een exponential search gecombineerd met een binary search, behalve dat je het niet in binaire stappen doet.Ghehe schreef op woensdag 21 december 2022 @ 14:43:
[spoiler]
Ik dacht eerst deel 2 met z3 te doen maar uiteindelijk een domme brute-force gedaan richting "root: a - b == 0". Getal humn gaat omhoog zolang ik onder 0 zit en weer omlaag als ik erboven zit. Initieel met stapjes van 10 miljard en dan steeds kleiner richting de 0.
In z'n algemeenheid niet, denk bijvoorbeeld aanGeen idee of alle inputs een lineare correlatie hebben tussen humn en root maar in mijn geval wel (anders zou ik niet hoger-lager kunnen doen?)
spoiler:
1/(10 - x), die discontinu is rond x=10.
Maar het lijkt er op dat in de gegenereerde invoer
spoiler:
geen berekeningen met negatieve getallen voorkomen. Dan is het vrij eenvoudig te concluderen dat de uitkomst ofwel strict stijgt ofwel strict daalt, immers geldt dat voor alle operaties afzonderlijk: voor a + b en a * b geldt dat de uitkomst stijgt met a en b, en voor a - b en a / b geldt dat de uitkomst stijgt met a en daalt met b.
Sterker nog, er lijkt een strict lineair verband te zijn tussen de waarde van humn en het resultaat van de expressie waar die in voorkomt (laten we zeggen, x en f(x)). Dat betekent dat je zelfs geen binary search nodig hebt.
Als je de invoer omzet naar een expressie (met x voor de humn variabele) dan kun je het zo uitrekenen met de Python interpreter. Voor de voorbeeldinvoer is de expressie b.v. ((4+(2*(x-3)))/4) == 150.
En voor mijn testinvoer:
(5*(40172078470474-((427+(87+(((((2*((((11*(((399+((((((356+(2*((10*(610+(((((2*(516+((((((((((3*(((611+(((((((((((((857+((425+((((7*((((9*(x+446))-308)/11)-306))+797)/2)-910))/3))*14)+759)+984)/7)-910)*14)-937)+180)+345)/2)+907)*2))/9)-185))-539)*3)+872)/11)-404)+467)/10)+362)*85)))-655)/7)-783)/2)))-159)))/2)-137)*2)+818)/2))/10)-479))-339)/10)+289))-155)/9)+677)*19)))/2))) == 90565407195785
Als ik dan even experimenteer met Python:
>>> f = lambda x: (5*(40172078470474-((427+(87+(((((2*((((11*(((399+((((((356+(2*((10*(610+(((((2*(516+((((((((((3*(((611+(((((((((((((857+((425+((((7*((((9*(x+446))-308)/11)-306))+797)/2)-910))/3))*14)+759)+984)/7)-910)*14)-937)+180)+345)/2)+907)*2))/9)-185))-539)*3)+872)/11)-404)+467)/10)+362)*85)))-655)/7)-783)/2)))-159)))/2)-137)*2)+818)/2))/10)-479))-339)/10)+289))-155)/9)+677)*19)))/2)))
>>> ff = lambda x: f(Fraction(x))
>>> ff(1) - ff(0)
Fraction(-2261, 66)
>>> ff(2) - ff(1)
Fraction(-2261, 66)
>>> ff(100) - ff(99)
Fraction(-2261, 66)
>>> ff(123456789) - ff(123456788)
Fraction(-2261, 66)
Hmmmm!!! Het verschil is altijd hetzelfde!
>>> (90565407195785 - ff(0)) / (ff(1) - ff(0))
Fraction(3219579395609, 1)
Tadaa! 3219579395609 is mijn antwoord.
Concluderend: voor de gegeven testinvoer hoef je alleen maar de expressie te evalueren voor humn=0 en humn=1 (met breuken) en dan kun je het correcte antwoord zo uitlezen. Maar pas op: floating point getallen hebben niet genoeg precisie!
Sterker nog, er lijkt een strict lineair verband te zijn tussen de waarde van humn en het resultaat van de expressie waar die in voorkomt (laten we zeggen, x en f(x)). Dat betekent dat je zelfs geen binary search nodig hebt.
Als je de invoer omzet naar een expressie (met x voor de humn variabele) dan kun je het zo uitrekenen met de Python interpreter. Voor de voorbeeldinvoer is de expressie b.v. ((4+(2*(x-3)))/4) == 150.
En voor mijn testinvoer:
(5*(40172078470474-((427+(87+(((((2*((((11*(((399+((((((356+(2*((10*(610+(((((2*(516+((((((((((3*(((611+(((((((((((((857+((425+((((7*((((9*(x+446))-308)/11)-306))+797)/2)-910))/3))*14)+759)+984)/7)-910)*14)-937)+180)+345)/2)+907)*2))/9)-185))-539)*3)+872)/11)-404)+467)/10)+362)*85)))-655)/7)-783)/2)))-159)))/2)-137)*2)+818)/2))/10)-479))-339)/10)+289))-155)/9)+677)*19)))/2))) == 90565407195785
Als ik dan even experimenteer met Python:
>>> f = lambda x: (5*(40172078470474-((427+(87+(((((2*((((11*(((399+((((((356+(2*((10*(610+(((((2*(516+((((((((((3*(((611+(((((((((((((857+((425+((((7*((((9*(x+446))-308)/11)-306))+797)/2)-910))/3))*14)+759)+984)/7)-910)*14)-937)+180)+345)/2)+907)*2))/9)-185))-539)*3)+872)/11)-404)+467)/10)+362)*85)))-655)/7)-783)/2)))-159)))/2)-137)*2)+818)/2))/10)-479))-339)/10)+289))-155)/9)+677)*19)))/2)))
>>> ff = lambda x: f(Fraction(x))
>>> ff(1) - ff(0)
Fraction(-2261, 66)
>>> ff(2) - ff(1)
Fraction(-2261, 66)
>>> ff(100) - ff(99)
Fraction(-2261, 66)
>>> ff(123456789) - ff(123456788)
Fraction(-2261, 66)
Hmmmm!!! Het verschil is altijd hetzelfde!
>>> (90565407195785 - ff(0)) / (ff(1) - ff(0))
Fraction(3219579395609, 1)
Tadaa! 3219579395609 is mijn antwoord.
Concluderend: voor de gegeven testinvoer hoef je alleen maar de expressie te evalueren voor humn=0 en humn=1 (met breuken) en dan kun je het correcte antwoord zo uitlezen. Maar pas op: floating point getallen hebben niet genoeg precisie!
dag 21 runtime 5ms
https://github.com/Jeroen...22/blob/main/src/day21.rs
Ik heb deel 2 opgelost door telkens als ik een variabele nodig had die niet voorkwam in de rechterlid van een vergelijking, de vergelijking om te draaien en verder te rekenen.
Totdat uiteindelijk (na 72 aanpassingen voor mijn input) alle variabelen die ik nodig heb om "humn" te berekenen in het rechterlid staan.
Ben benieuwd welke alternatieve aanpakken er zijn die eleganter zijn, want mijn oplossing is niet meteen de meest compacte naar mijn aanvoelen.
EDIT: indien ik de variabelen gewoon zou representeren met een index ipv een string kan de rekentijd zeker nog heel veel naar beneden... maar had weinig tijd vandaag
https://github.com/Jeroen...22/blob/main/src/day21.rs
Ik heb deel 2 opgelost door telkens als ik een variabele nodig had die niet voorkwam in de rechterlid van een vergelijking, de vergelijking om te draaien en verder te rekenen.
Totdat uiteindelijk (na 72 aanpassingen voor mijn input) alle variabelen die ik nodig heb om "humn" te berekenen in het rechterlid staan.
Ben benieuwd welke alternatieve aanpakken er zijn die eleganter zijn, want mijn oplossing is niet meteen de meest compacte naar mijn aanvoelen.
EDIT: indien ik de variabelen gewoon zou representeren met een index ipv een string kan de rekentijd zeker nog heel veel naar beneden... maar had weinig tijd vandaag
[ Voor 13% gewijzigd door Jern_97 op 21-12-2022 20:25 ]
Soultaker schreef op woensdag 21 december 2022 @ 14:24:
Dag 21 was een leuk concept. Zelfde aanpak als de anderen hierboven; volgens mij is er ook niet veel anders mogelijk. Niet super moeilijk maar wel de meeste code die ik heb moeten schrijven door het implementeren van alle operators etc.
[...]
spoiler:
Newton's approximation was ook een optie vandaag!
Varienaja schreef op donderdag 22 december 2022 @ 08:41:
Wat een slachtveld vandaag. Temeer daar de layout van het voorbeeld anders is dan de echte input. Ik heb hier een bos if-elsen waar je eng van wordt. (niks generiek geïmplementeerd, gewoon een vouwsel gemaakt en nageprogrammeerd.)
spoiler:
Ik hard-code voor de voorbeeld kubus en mijn input kubus een "cubeInfo" struct met daarin de size van de kubus en voor elke kant de (x, y) van de top-left corner (in de input) + de 4 edges (per edge de target face + direction).
Daarmee kun je de 'echte' code generiek implementeren. Ik vond part 2 wel de minst leuke puzzel dit jaar omdat het veel handmatig uitzoeken vereist - het is vast mogelijk om te automatiseren, maar dat wordt me te tijdrovend...
edit: nu ik er over nadenk.. het is misschien niet eens zo moeilijk om de input te transformeren naar mijn representatie, misschien als ik vanavond tijd heb
[ Voor 13% gewijzigd door user109731 op 22-12-2022 13:11 ]
Was een leuke dag
Wel veel gepriegel..
Dag 22 - Python
spoiler:
Wil als ik nog tijd over hou ergens deze maand een 3d grid aan 2d coords koppelen (en vice versa). Dan zou in theorie elke variant van een uitgevouwde kubus moeten werken /denk/ ik.
Voor nu semi-hardcoded variant op basis van de vorm van de kubus uit mijn input (zie code) -> wel schaalbaar op formaat (nu 50 per kant).
Voor nu semi-hardcoded variant op basis van de vorm van de kubus uit mijn input (zie code) -> wel schaalbaar op formaat (nu 50 per kant).
Dag 22 - Python
Fijn om te zien dat ik niet de enige ben die met papier en schaar aan de slag is gegaan!Varienaja schreef op donderdag 22 december 2022 @ 08:41:
Wat een slachtveld vandaag. Temeer daar de layout van het voorbeeld anders is dan de echte input. Ik heb hier een bos if-elsen waar je eng van wordt. (niks generiek geïmplementeerd, gewoon een vouwsel gemaakt en nageprogrammeerd.)
[Afbeelding]
Erg lastig debuggen. Heeft even geduurd voordat ik door had dat ik mijn lokale coördinaten moest corrigeren naar totale uitgevouwen kaart.
Heb hem inmiddels af:
Dag 22 - deel 2 (Python)
Was weer een hele lastige vandaag. Ben benieuwd wat vrijdag en zaterdag nog in petto hebben. Ik gok morgen wel te doen en zaterdag nog een kraker?
Zo, dag 22 ook af (Python code). Ik zou mensen die nog achter lopen met de opdrachten wel aanraden om dag 22 voorlopig over te slaan; dat is echt een tijdrovend klusje.
Zoals anderen heb ik de topologie van de invoer min of meer gehardcode, wat niet heel elegant is. Ik zal nog eens proberen dat te verbeteren.
Overigens lijkt het erop dat bij iedereen de testinvoer dezelfde vorm heeft.
Zoals anderen heb ik de topologie van de invoer min of meer gehardcode, wat niet heel elegant is. Ik zal nog eens proberen dat te verbeteren.
Overigens lijkt het erop dat bij iedereen de testinvoer dezelfde vorm heeft.
Ik denk dat je gelijk hebt qua gelijke invoer: https://www.reddit.com/r/...tm_medium=web2x&context=3Soultaker schreef op donderdag 22 december 2022 @ 19:57:
Zo, dag 22 ook af (Python code). Ik zou mensen die nog achter lopen met de opdrachten wel aanraden om dag 22 voorlopig over te slaan; dat is echt een tijdrovend klusje.
Zoals anderen heb ik de topologie van de invoer min of meer gehardcode, wat niet heel elegant is. Ik zal nog eens proberen dat te verbeteren.
Overigens lijkt het erop dat bij iedereen de testinvoer dezelfde vorm heeft.
Zeker! Vermoed stiekem dat ze beiden nog flink pittig zullen zijn, wellicht nog iets VM/reverse engineering/simuation - igs?Asgardian28 schreef op donderdag 22 december 2022 @ 18:51:
Was weer een hele lastige vandaag. Ben benieuwd wat vrijdag en zaterdag nog in petto hebben. Ik gok morgen wel te doen en zaterdag nog een kraker?
spoiler:
Ik ben veel te lang bezig geweest om erachter te komen dat mijn edge detection ook rekening moest houden met de richting waarin ik aan het lopen was.
Ik kwam met mijn input blijkbaar op een hoekpunt uit waarbij ik daarna een verkeerde edge terug gaf, en daarna ging uiteraard de rest compleet de mist ging.
Nadat ik een paar stukken code van anderen vergeleken had en tijdens verschillende debug sessies niet duidelijk zag waar het nu precies mis ging viel het kwartje dat rekening houden met de richting nodig is voor de juiste edge te bepalen in een hoek.
Ik kwam met mijn input blijkbaar op een hoekpunt uit waarbij ik daarna een verkeerde edge terug gaf, en daarna ging uiteraard de rest compleet de mist ging.
Nadat ik een paar stukken code van anderen vergeleken had en tijdens verschillende debug sessies niet duidelijk zag waar het nu precies mis ging viel het kwartje dat rekening houden met de richting nodig is voor de juiste edge te bepalen in een hoek.

Held, ik snapte maar niet waarom mijn code niet het juiste antwoord gaf. Straks maar even implementeren.RefleXion schreef op donderdag 22 december 2022 @ 15:38:
[...]
Fijn om te zien dat ik niet de enige ben die met papier en schaar aan de slag is gegaan!
Erg lastig debuggen. Heeft even geduurd voordat ik door had dat ik mijn lokale coördinaten moest corrigeren naar totale uitgevouwen kaart.
Heb hem inmiddels af:
Dag 22 - deel 2 (Python)
Ik heb dag 22 ook nog generiek geïmplementeerd, dus zonder de grootte of de configuratie van de kubus te hardcoden.
Het is niet eens meer code (al is mijn implementatie verre van compact). Het idee erachter is dit:
Het is niet eens meer code (al is mijn implementatie verre van compact). Het idee erachter is dit:
spoiler:
je kunt de ruimte modelleren als een graaf. De punten van de graaf corresponderen met de '.' en '#' karakters in de invoer. Voor deel 1 zijn de punten verbonden met edges in de vier richtingen met wraparound.
Voor deel 2 kun je een kubus bouwen en vervolgens het grid erop projecteren.
Voor deel 2 kun je een kubus bouwen en vervolgens het grid erop projecteren.
Nice work!Soultaker schreef op donderdag 22 december 2022 @ 22:51:
Ik heb dag 22 ook nog generiek geïmplementeerd, dus zonder de grootte of de configuratie van de kubus te hardcoden.
Het is niet eens meer code (al is mijn implementatie verre van compact). Het idee erachter is dit:
spoiler:je kunt de ruimte modelleren als een graaf. De punten van de graaf corresponderen met de '.' en '#' karakters in de invoer. Voor deel 1 zijn de punten verbonden met edges in de vier richtingen met wraparound.
Voor deel 2 kun je een kubus bouwen en vervolgens het grid erop projecteren.
Zo, veel te lang mee bezig geweest, en eigenlijk pas opgelost toen ik daadwerkelijk een kartonnen doosje gepakt had om te zien hoe welke edge aan welke edge geknoopt werd.
Qua oplossing had ik gelijk aan het begin al de oplossingsrichting gekozen die @Soultaker ook al noemde, alhoewel ik het stitchen van de edges nog wel hardcoded heb. Ik ging heel erg de mist in met de verandering van de draaiing waardoor ik het gewoon maar uitgetekend heb, en ook dat hardcoded gedaan heb.
Code
Qua oplossing had ik gelijk aan het begin al de oplossingsrichting gekozen die @Soultaker ook al noemde, alhoewel ik het stitchen van de edges nog wel hardcoded heb. Ik ging heel erg de mist in met de verandering van de draaiing waardoor ik het gewoon maar uitgetekend heb, en ook dat hardcoded gedaan heb.
Code
Ken Thompson's famous line from V6 UNIX is equaly applicable to this post:
'You are not expected to understand this'
Was prima te doen vandaag vergeleken met gisteren. Code runt in ~10s dus daar valt vast nog iets aan te doen.
Dag 23 - Python
Dag 23 - Python
Ken Thompson's famous line from V6 UNIX is equaly applicable to this post:
'You are not expected to understand this'
Best wel tevreden met vandaag na het slachtveld van gisteren. In eerste instantie ging ik volledig de mist in, want ik had de opdracht niet goed gelezen.
Python code
spoiler:
Blijkbaar schaalt de grootte met het veld mee met de elven. Hier had ik natuurlijk volledig overheen gelezen en mijn numpy implementatie werkte prima met de test input waar dit niet in voorkwam. Toen maar even herschreven naar een implementatie met sets zoals gebruikelijk is bij dit soort puzzels en dat ging eigenlijk direct goed.
Python code
spoiler:
Vandaag was mijn vermoeden over deel 2 juist. We hadden nog geen "game of life" achtige opdracht gehad waarbij je een end state moet bepalen.
Mijn deel 1 oplossing was dus met een paar kleine wijzigingen geschikt te maken voor deel 2.
Het is niet de meest efficiente oplossing, het duurt ~1,5 seconde om ~1000 iteraties te simuleren om deel 2 op te lossen.
Mijn deel 1 oplossing was dus met een paar kleine wijzigingen geschikt te maken voor deel 2.
Het is niet de meest efficiente oplossing, het duurt ~1,5 seconde om ~1000 iteraties te simuleren om deel 2 op te lossen.
Siditamentis astuentis pactum.
Dag 23 kan je ook zo oplossen:
Nu even mentaal voorbereiden op morgen
spoiler:
Alleen de elfjes tracken in een set van coordinaten.
Werkt vaak gemakkelijker dan een lijst van lijsten of np array bijhouden met padding enzo.
Nog niet opgeschoonde code Denk dat ik vooral wat meer op het goed benoemen van m'n variabelen moet gaan letten
Werkt vaak gemakkelijker dan een lijst van lijsten of np array bijhouden met padding enzo.
Nog niet opgeschoonde code Denk dat ik vooral wat meer op het goed benoemen van m'n variabelen moet gaan letten
Nu even mentaal voorbereiden op morgen

Ik denk dat de meeste mensen het juist op die manier hebben opgelostAsgardian28 schreef op vrijdag 23 december 2022 @ 13:58:
Dag 23 kan je ook zo oplossen:
spoiler:Alleen de elfjes tracken in een set van coordinaten.
Dag 23 ging prima, dus ik ben nog maar even voor dag 22 gaan zitten. Gister was echt zwaar frustrerend voor mij met debuggen. Ik zat er echt volledig naast met mijn eerste implementatie. Dus ik had het even gelaten voor wat het was. Vandaag was goed te doen, dus ik had wat tijd over om er nog eens in te duiken. Opnieuw begonnen en toen viel het eigelijk allemaal wel mee. Een dag te laat, maar wilde toch graag mijn oplossing delen.
Dag 22 deel 2
spoiler:
Net als iedereen heb ik ook gewoon alle regeltjes ge-handcode, veel simpeler. 😅
Dag 22 deel 2
Soultaker schreef op vrijdag 23 december 2022 @ 14:07:
[...]
Ik denk dat de meeste mensen het juist op die manier hebben opgelost
spoiler:
Zoiets heb ik dus ook gedaan, en dan gecombineerd met mijn Grid.
De lijst van elfjes gebruik ik om het volgende gewenste coördinaat te bepalen, op basis van de huidige beschikbaarheid op de Grid. Daardoor hoef ik niet voor elk elfje aan alle andere elfjes te vragen of die plek beschikbaar is, maar vraag ik dat aan mijn Grid die onderwater een HashMap gebruikt.
Per coördinaat houd ik dan een telling bij van hoeveel elfjes daarheen willen gaan. Weer gebaseerd op een HashMap.
In de move fase kijkt elk elfje dan of die de enige is die naar dat coördinaat wil en gaat erheen.
De lijst van elfjes gebruik ik om het volgende gewenste coördinaat te bepalen, op basis van de huidige beschikbaarheid op de Grid. Daardoor hoef ik niet voor elk elfje aan alle andere elfjes te vragen of die plek beschikbaar is, maar vraag ik dat aan mijn Grid die onderwater een HashMap gebruikt.
Per coördinaat houd ik dan een telling bij van hoeveel elfjes daarheen willen gaan. Weer gebaseerd op een HashMap.
In de move fase kijkt elk elfje dan of die de enige is die naar dat coördinaat wil en gaat erheen.
De testinvoer is toch altijd voor iedereen identiek?Soultaker schreef op donderdag 22 december 2022 @ 19:57:
Zoals anderen heb ik de topologie van de invoer min of meer gehardcode, wat niet heel elegant is. Ik zal nog eens proberen dat te verbeteren.
Overigens lijkt het erop dat bij iedereen de testinvoer dezelfde vorm heeft.
Je moet altijd oppassen met aannames. Deze is fout. En ik schrijf te vlug. Ja de testinvoer is volgens mij voor iedereen gelijk. De echte invoer verschilt doorgaans.joppybt schreef op vrijdag 23 december 2022 @ 16:46:
De testinvoer is toch altijd voor iedereen identiek?
[ Voor 22% gewijzigd door Varienaja op 23-12-2022 16:59 ]
Siditamentis astuentis pactum.
Dat wist ik ook niet, ik nam ook aan dat enkel de 'echte' input gebruikersafhankelijk was.Varienaja schreef op vrijdag 23 december 2022 @ 16:47:
[...]
Je moet altijd oppassen met aannames. Deze is fout.
De test-input kan je ook zien zonder ingelogd te zijn en die was altijd hetzelfde.
Ik ging er dus ook van uit dat die voor iedereen hetzelfde was.
Even gecontroleerd en mijn test-input is bijvoorbeeld altijd gelijk aan die van een anonieme gebruiker. Volgens mij is dat gewoon altijd zo.Mschamp schreef op vrijdag 23 december 2022 @ 16:50:
[...]
Dat wist ik ook niet, ik nam ook aan dat enkel de 'echte' input gebruikersafhankelijk was.
De test-input kan je ook zien zonder ingelogd te zijn en die was altijd hetzelfde.
Ik ging er dus ook van uit dat die voor iedereen hetzelfde was.
De voorbeeld-invoer die in de tekst genoemd wordt is inderdaad voor iedereen gelijk, maar ik bedoelde de officiële invoer die je alleen kunt zien als je inlogt. Die kan veranderen van persoon tot persoon (v.z.i.w. is er een pool van mogelijke invoeren, dus niet iedereen heeft een unieke invoer) maar voor deze dag leek het erop dat de uitgevouwen kubussen in ieder geval allemaal dezelfde vorm hadden (waarschijnlijk waren de muren/instructies wel verschillend).
Ik vond vandaag toch best een lastige, maar vooral begrijpend lezen dan. Ik heb 4 verschillende implementaties van "Finally, at the end of the round, the first direction the Elves considered is moved to the end of the list of directions." geimplementeerd.
spoiler:
Eerst genegeerd
, daarna per elf gekeken of ze uberhaupt probeerden te bewegen en dan de move-check order updaten, daarna per elf of ze daadwerkelijk bewogen en dan de move-check updaten, en daarna pas gerealiseerd dat ik te moeilijk dacht en dus de move-check order voor alle elven altijd hetzelfde was, maar per stap verschilde.
Ondertussen zat ik 4 dicts/hashmaps de hele tijd te updaten, wat de foutloosheid ook niet ten goede kwa

Ondertussen zat ik 4 dicts/hashmaps de hele tijd te updaten, wat de foutloosheid ook niet ten goede kwa
Verandert z'n sig te weinig.
Erg goed te doen na enkele wat lastigere van de laatste dagen.
Oplossing in Swift.
spoiler:
Ik heb ook een set gebruikt voor de posities van de elven ipv een grid, maakt alles zoveel makkelijker.
Oplossing in Swift.
Ik heb voor de grap dag 23 ook nog met numpy geïmplementeerd (valt nog van alles aan te optimaliseren). Het is conceptueel wel leuk, aangezien je elke simulatie-stap met een constant aantal array-operaties kunt uitvoeren, maar voor de officiële invoer niet heel veel sneller.
Het valt me trouwens tegen dat we nog niet van @.oisyn of andere figuren die ervaring hebben met graphics programming gehoord hebben; de bitmap-aanpak is behoorlijk goed te optimaliseren. B.v. het tellen van buren kan met een convolutie-matrix.
Het valt me trouwens tegen dat we nog niet van @.oisyn of andere figuren die ervaring hebben met graphics programming gehoord hebben; de bitmap-aanpak is behoorlijk goed te optimaliseren. B.v. het tellen van buren kan met een convolutie-matrix.
[ Voor 14% gewijzigd door Soultaker op 23-12-2022 21:36 ]