"The question of whether a computer can think is no more interesting than the question of whether a submarine can swim" - Edsger Dijkstra
Binnen de for-loop checken of de locatie hoger of lager is dan de huidige lower en updaten als de waarde lager is.
Oplossing in TypeScript: https://github.com/WernerLDev/AOC2023/blob/main/day5/day5.ts
Roses are red, violets are blue, unexpected '{' on line 32.
Wat is hier het praktisch voordeel van t.o.v.Mugwump schreef op dinsdag 5 december 2023 @ 19:21:
spoiler:Geen daadwerkelijke lists maar ranges / progressions gebruiken scheelt al enorm in het geheugen.
Als je dan vervolgens door je ranges heen loopt doe je een reduce operatie waardoor je niet de mapping of het resultaat in het geheugen houdt, maar enkel de tot dan bekende minimale waarde. Je loopt dus wel idioot veel "seeds" door, maar je geheugen klapt er niet uit.
Soultaker schreef op dinsdag 5 december 2023 @ 20:12:
[...]
Wat is hier het praktisch voordeel van t.o.v.spoiler:elk punt 1 voor 1 naar de eindlocatie mappen? Je moet in beide gevallen toch elk punt met alle ranges vergelijken? Dan lijkt het me strict simpeler en net zo snel (of sneller) om punt voor punt te werken.
"The question of whether a computer can think is no more interesting than the question of whether a submarine can swim" - Edsger Dijkstra
Dit kun je nog verder optimaliseren
Zie m'n Python oplossing voor details.
Conceptueel heb ik het wel scherp, maar krijg het niet vertaald
Ik geloof niet dat ik helemaal begrijp wat je bedoelt. Heb je dit idee geïmplementeerd?Mugwump schreef op dinsdag 5 december 2023 @ 20:37:
spoiler:Ook in mijn geval loop je er gewoon 1 voor 1 doorheen. Wat je niet doet is een lijstje opbouwen van alle gemapte eindlocaties en daar aan het einde het minimum van bepalen. Dat betekent namelijk dat het hele lijstje in je geheugen moet.
Joh, maar met <1ms is de noodzaak daarvoor een beetje weg
[ Voor 12% gewijzigd door .oisyn op 05-12-2023 20:54 ]
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.
Soultaker schreef op dinsdag 5 december 2023 @ 20:51:
[...]
Ik geloof niet dat ik helemaal begrijp wat je bedoelt. Heb je dit idee geïmplementeerd?
spoiler:Je kunt niet per map een minimum bijhouden want de seed die uiteindelijk op de minimumlocatie terecht komt kan tussendoor allerlei verschillende tussenwaarden gehad hebben. Je kunt om dezelfde reden niet alleen het minimum van een range bijhouden.
Ik heb het erover dat je één iteratie doet van seed door de hele keten naar een locatie. Dan pak je de volgende seed en doe je hetzelfde, maar aan het eind behoud je de laagste waarde van de twee en zo door.
Als mensen tegen geheugenproblemen aan lopen is dat doorgaans vanwege grote data structuren in je geheugen, dus b.v. het resultaat van elke mapping van seed naar location bijhouden in een lijstje en pas aan het eind de minimale waarde uit dat lijstje selecteren oid
"The question of whether a computer can think is no more interesting than the question of whether a submarine can swim" - Edsger Dijkstra
Aha, dat is precies de oplossing waar ik ook op doelde. Ik had je verkeerd begrepen.Mugwump schreef op dinsdag 5 december 2023 @ 21:10:
spoiler:Ja we praten langs elkaar heen.
Ik heb het erover dat je één iteratie doet van seed door de hele keten naar een locatie. Dan pak je de volgende seed en doe je hetzelfde, maar aan het eind behoud je de laagste waarde van de twee en zo door.
Remcoder schreef op dinsdag 5 december 2023 @ 19:11:
spoiler:Hoe krijgen mensen een runtime met een resultaat in minuten?
Mijn eerste poging vrat in no time al het geheugen op. Alle seeds maken en in het geheugen proppen was blijkbaar niet zo snugger.
Mijn tweede poging zou vast nu nog aan het lopen zijn.
En mijn derde poging was klaar binnen 8 seconden, wat ik al veel vind. Daarbij begin ik met location 0, die reken ik terug naar een seed en dat net zo lang ophogen tot ik een seed in range vond.
Zonder parallelisatie, dus mijn machine stond lekker single threaded te stampen.
Dus, hoe kom je tot een runtime die realistisch in minuten kan tellen?
Een van mijn pogingen was ook om achterstevoren de laagste locatie te berekenen. Dus met 0 begonnen en uiteindelijk op 11 miljoen nog wat uitgekomen. Dat duurt dus iets van 20 minuten.
Latere verfijning zorgde voor een tijd van 2 msec overigens, maar dat was geen brute force meer
... en gaat over tot de orde van de dag
Vandaag begint het wel echt interessant te worden. Deel 1 was na het parsen van de file best eenvoudig om het antwoord te berekenen, maar deel 2 moet ik toch echt even beter m'n best voor doen. Voor deel 2 heb ik in eerste instantie een naieve brute-force oplossing gebouwd, maar die duurt echt vreselijk lang: ruim een kwartier. Aangezien ik hier tijden voorbij zie komen van minder dan een seconde, heb ik ondertussen na zitten denken of ik dit op een andere manier kan oplossen.
Weet niet of anderen dit ook gevonden hebben, maar toen ik ermee bezig was viel me de relatie tussen de drie getallen op en de "beweging" die daarmee gecreëerd word.
Source = range start;
Source + Range lengte = Range einde
Destination - Source = Het verschil dat wordt opgeteld bij de het voortgaande getal. Kan ook negatief zijn.
bv.: 50 98 2
Start: 98
End: 100 (start + lengte)
Diff: -48 (Dst - src)
Zo kun je alle entries van de secties omrekenen.
Vervolgens (beginnend met het seed getal) doorloop je een sectie totdat je een Start en End vind waarbinnen het getal ligt. Bij het voortgaande getal (seed) wordt dan Diff opgeteld.
Met dat getal doe je de volgende sectie.
Dan alleen nog de laagste waarde bijhouden als alle secties doorlopen zijn.
In C#:
Inlezen en voorbereiden van de data ca. 0.3 ms.
Alleen de tijd die wordt besteed aan het zoeken (alle seeds verwerken) naar het laagste nummer gaat in ca. 0.01 ms
Wie du mir, so ich dir.
Mugwump schreef op dinsdag 5 december 2023 @ 21:10:
[...]
spoiler:Als mensen tegen geheugenproblemen aan lopen is dat doorgaans vanwege grote data structuren in je geheugen, dus b.v. het resultaat van elke mapping van seed naar location bijhouden in een lijstje en pas aan het eind de minimale waarde uit dat lijstje selecteren oid
Daarna had ik deze herschreven naar een iterator/stream, waardoor het geheugen drastisch naar beneden ging. Je houdt immer dan niet meer het volledige lijstje in geheugen. Dus ik ging van 20GB naar 5MB.
Alleen de snelheid ging niet omhoog, omdat ik werkte met de losse waardes.
(dat heb ik dus nog wel voor de oplossing van deel 1)
Ik merkte toen ook die "beweging" op en dacht dat ik het op kon lossen door alle secties te comprimeren tot 1 getal. Maar die samenvoeging werd me te complex.
Pas daarna ben ik begonnen om met ranges te werken en die te verwerken (lijst met ranges in -> lijst met bijgewerkte ranges uit).
En daarmee werd de snelheid en geheugenverbruik ook ok.
Enkel met alleen het startgetal van een seed rekening houden heb ik niet gedaan. Het leek me dat het voor kan komen dat ranges gesplitst kunnen worden en het ene deel lager uitkomt dan de andere. Maar mogelijk hebben ze dat scenario niet in de testdata gezet.
let the past be the past.
Dat hield je in het verleden niet tegen.oisyn schreef op dinsdag 5 december 2023 @ 20:53:
Joh, maar met <1ms is de noodzaak daarvoor een beetje weg.
Ik heb het voor de grap nog eens geïmplementeerd in C++ en het lijkt wel iets sneller te zijn op de officiële testdata:En ik vraag me serieus af of het sneller is in dit geval.
Parsing took 141082 ns part1 Solve1() took 4529 ns/run (100000 runs) part1 Solve2() took 3615 ns/run (100000 runs) 240320250 part2 Solve1() took 8948 ns/run (100000 runs) part2 Solve2() took 5634 ns/run (100000 runs) 28580589
Alleen jammer dat de solve-tijd gedomineerd wordt door de parse-tijd.
Hier wat interessantere invoeren (voor 31-bit, 63-bit en 127-bit respectievelijk):
Time: 6074001000 Distance: 9223372036854775807
Antwoord eindigt op ...123.
Time: 2878053387 Distance: 1661589816380250885
Antwoord eindigt op ...366.
Time: 16107645505445695488 Distance: 64856007359523503909674096462042349751
Antwoord eindigt op ...377.
En een grote:
Time: 942 952 879 579 439 716 41 863 672 758 528 535 560 153 302 21 54 825 153 289 705 973 442 333 168 999 367 234 632 435 51 293 69 544 616 628 540 755 620 444 827 50 155 78 745 712 796 554 840 656 753 450 382 188 741 399 700 250 402 835 930 19 994 1000 809 44 305 231 351 20 704 721 814 426 432 902 116 216 738 337 910 178 163 963 211 842 819 659 637 156 608 405 38 135 52 897 609 344 765 552 Distance: 89127 76021 135371 51132 47001 47639 377 176076 973 113909 30127 10947 65832 5791 16326 2 189 62416 1438 4972 6934 158395 19677 5785 5512 93405 20410 5896 91086 14413 111 2355 793 49942 86437 82740 2350 134755 13471 6812 121661 511 408 914 16242 32058 10848 44489 90655 76682 12890 13931 26028 4992 59719 22206 120495 14144 3100 134076 56529 40 164397 211741 143772 439 3742 308 14890 44 29613 87001 116541 7337 36803 42677 1733 1562 52054 25174 76647 5313 1346 27753 263 21555 106686 5562 8227 1231 42203 1039 317 1575 331 76109 47959 7283 14132 24485
Eerste antwoord begint met 233404...
Tweede antwoord eindigt met ...909131
Zeker, geeft me wat tijd om deel 2 van gisteren nog af te maken :-)Mschamp schreef op woensdag 6 december 2023 @ 06:52:
Puzzel van vandaag was wel heel goed te doen
Oplossing voor deel 2 was zelfs heel makkelijk:
Soultaker schreef op woensdag 6 december 2023 @ 06:59:
Dag 6spoiler:was gewoon te bruteforcen
Hier wat interessantere invoeren (voor 31-bit, 63-bit en 127-bit respectievelijk):
Time: 6074001000 Distance: 9223372036854775807
Antwoord eindigt op ...123.
Time: 2878053387 Distance: 1661589816380250885
Antwoord eindigt op ...366.
Time: 16107645505445695488 Distance: 64856007359523503909674096462042349751
Antwoord eindigt op ...377.
En een grote:
Time: 942 952 879 579 439 716 41 863 672 758 528 535 560 153 302 21 54 825 153 289 705 973 442 333 168 999 367 234 632 435 51 293 69 544 616 628 540 755 620 444 827 50 155 78 745 712 796 554 840 656 753 450 382 188 741 399 700 250 402 835 930 19 994 1000 809 44 305 231 351 20 704 721 814 426 432 902 116 216 738 337 910 178 163 963 211 842 819 659 637 156 608 405 38 135 52 897 609 344 765 552 Distance: 89127 76021 135371 51132 47001 47639 377 176076 973 113909 30127 10947 65832 5791 16326 2 189 62416 1438 4972 6934 158395 19677 5785 5512 93405 20410 5896 91086 14413 111 2355 793 49942 86437 82740 2350 134755 13471 6812 121661 511 408 914 16242 32058 10848 44489 90655 76682 12890 13931 26028 4992 59719 22206 120495 14144 3100 134076 56529 40 164397 211741 143772 439 3742 308 14890 44 29613 87001 116541 7337 36803 42677 1733 1562 52054 25174 76647 5313 1346 27753 263 21555 106686 5562 8227 1231 42203 1039 317 1575 331 76109 47959 7283 14132 24485
Eerste antwoord begint met 233404...
Tweede antwoord eindigt met ...909131
Beginnen bij distance / time +1 in plaats van bij 1 als startwaarde voor a schaaft er bij mij nog 2ms vanaf, maar het duurde sowieso maar 20ms. Dat is nog traag, maar ik merk wel dat ik nog wel echt wat 'Kotlin fundamentals' moet leren, want filter(filterexpressie).first() vs firstOrNull(filterexpressie) betekent 1s vs 20ms.
DIt is gewoon ook een heel triviaal wiskundig vraagstuk in de vorm min(a) where a + b = time and a*b > distance.
Daar is vast nog een elegantere wiskundige oplossing voor te verzinnen, maar met 18ms voor deel 2 vind ik het verder wel best.
"The question of whether a computer can think is no more interesting than the question of whether a submarine can swim" - Edsger Dijkstra
rengeltje schreef op woensdag 6 december 2023 @ 07:06:
Oplossing voor deel 2 was zelfs heel makkelijk:
spoiler:Ik heb letterlijk gewoon alle spaties uit de invoer weggehaald en verder precies dezelfde oplossing als deel 1 gebruikt. Moest alleen mijn debug statement om de tussenwaardes af te drukken even weghalen, omdat dat langer duurde dan ik geduld had om op te wachten.
Vanaf 0 proberen hoe lang de distance te laag is, en daarna vanaf de top naar beneden hetzelfde, scheelt toch tientallen miljoenen berekeningen
Ik ga het deel 2 na de koffie misschien nog wel even in een eenvoudige formule gieten zonder loopjes
[ Voor 6% gewijzigd door Dido op 06-12-2023 07:16 ]
Dido schreef op woensdag 6 december 2023 @ 07:14:
[...]
spoiler:Dat had ik ook gedaan om de ster te halen. Maar toch, 330 ms vond ik te lang. Daarom maar even een hele simpele optimalisatie doorgevoerd.
Vanaf 0 proberen hoe lang de distance te laag is, en daarna vanaf de top naar beneden hetzelfde, scheelt toch tientallen miljoenen berekeningen![]()
Ik ga het deel 2 na de koffie misschien nog wel even in een eenvoudige formule gieten zonder loopjes
De stap om vanaf de top naar beneden te gaan is ook zinloos, want door vanaf onder te tellen weet je het antwoord al. vanaf onder krijg je a * b en vanaf boven b * a waarbij a het aantal ms is dat je het knopje ingedrukt houdt en b het aantal ms dat je vaart. Als je weet dat a de ondergrens is, dan is de bovengrens simpelweg time - a.
"The question of whether a computer can think is no more interesting than the question of whether a submarine can swim" - Edsger Dijkstra
Elk algoritme wat tijd proportioneel aan het aan antwoord nodig heeft is wat mij betreft brute force. Prima voor deel 1; voor deel 2 had het wat mij betreft wel iets uitdagender gemogen.Mugwump schreef op woensdag 6 december 2023 @ 07:12:
Nou weet ik niet helemaal hoe je brute forcen interpreteert
Jammer idd, dat brute force nog werkte voor deel 2Soultaker schreef op woensdag 6 december 2023 @ 07:22:
[...]
Elk algoritme wat tijd proportioneel aan het aan antwoord nodig heeft is wat mij betreft brute force. Prima voor deel 1; voor deel 2 had het wat mij betreft wel iets uitdagender gemogen.
Verandert z'n sig te weinig.
MrHaas schreef op woensdag 6 december 2023 @ 07:25:
spoiler:closed form oplossing is triviale middelbare school wiskunde.
FCA schreef op woensdag 6 december 2023 @ 07:35:
spoiler:voor mij zat de moeilijkheid hem in het goed afronden (naar beneden of naar boven), van de gevonden ondergrens en bovengrens. Uiteindelijk na 3 pogingen de juiste gevonden
Met de Android calculator (die gelukkig ook voldoende precisie had voor deel 2) op het handje uitgerekend.
Zo scherp als een voetbal!
Ook ff mee zitten puzzelen, maar ik heb 'm zo: https://github.com/arjand...oc_2023/day06/solution.pySoultaker schreef op woensdag 6 december 2023 @ 07:45:
[...]
spoiler:De kwadratische formule oplossen is inderdaad een standaard probleem maar ik zat te pielen met de afronding. Ik heb het uiteindelijk maar met binary search opgelost, wat simpel genoeg is.
[...]
spoiler:Dit dus precies. Staat je code ergens online? Ben wel benieuwd hoe je 't opgelost hebt.
Soultaker schreef op woensdag 6 december 2023 @ 07:45:
[...]
spoiler:De kwadratische formule oplossen is inderdaad een standaard probleem maar ik zat te pielen met de afronding. Ik heb het uiteindelijk maar met binary search opgelost, wat simpel genoeg is.
Voor nu zoek ik de lowerbound door met een hold van 1 te beginnen en die op te hogen tot ik een winnende distance krijg, en hetzelfde voor de upperbound, maar dan begin ik met een hold van de racetime - 1.
Daarna is het antwoord (upperbound - lowerbound) + 1
Voor nu runt dat al in een acceptabele tijd, en ik vraag me af of een binary search het echt substantieel zal versnellen met deze kleine search space, de meeste tijd wordt toch gespendeerd aan de file I/O bij mij. Maar het is zeker een goede oefening om weer eens een binary search te implementeren
Friits schreef op woensdag 6 december 2023 @ 08:12:
@Soultaker Daar heb ik ook een tijdje mee zitten stoeien, maar volgens mij is dit correct.
Ah ja, dit is de juiste manier inderdaad (jullie hebben feitelijk precies dezelfde formule, wat natuurlijk ook logisch is). Mijn probleem was dat ikMrHaas schreef op woensdag 6 december 2023 @ 08:31:
Ook ff mee zitten puzzelen, maar ik heb 'm zo: https://github.com/arjand...oc_2023/day06/solution.py
Overigens heeft deze aanpak weer als nadeel dat het floating point math gebruikt waardoor 'ie niet correct werkt voor grotere invoer. Dan zou je eigenlijk isqrt() moeten gebruiken. Maakt voor de officiële testdata gelukkig niet uit.
Remcoder schreef op woensdag 6 december 2023 @ 08:50:
spoiler:Voor nu runt dat al in een acceptabele tijd, en ik vraag me af of een binary search het echt substantieel zal versnellen met deze kleine search space, de meeste tijd wordt toch gespendeerd aan de file I/O bij mij. Maar het is zeker een goede oefening om weer eens een binary search te implementeren
En als je de limieten van je huidige aanpak wil ervaren kun je de grotere test inputs hier proberen.
Soultaker schreef op woensdag 6 december 2023 @ 07:45:
[...]
spoiler:De kwadratische formule oplossen is inderdaad een standaard probleem maar ik zat te pielen met de afronding. Ik heb het uiteindelijk maar met binary search opgelost, wat simpel genoeg is.
[...]
spoiler:Dit dus precies. Staat je code ergens online? Ben wel benieuwd hoe je 't opgelost hebt.
[code]
int(math.floor(bovengrens)) - int(math.ceil(ondergrens)) +1[/code]
(De laatste +1 omdat je een een beide zijde inclusieve range bekijkt), maar op 1 of andere manier werden mijn beide grenzen negatief, waardoor je dus moet omdraaien, en ik had er om kwart over 6 even geen zin meer in om dat te debuggen, ontbijt moest nog worden klaargezet.
Verandert z'n sig te weinig.
Brute force FTW in dit geval. Met 1.4 seconde geen onacceptabele tijd
Dag 6 - Kotilin
Tja
:fill(white):strip_exif()/f/image/WvKsTBsfhDY3fA0nSBNIbTbf.png?f=user_large)
Voor de 63 bits variant heeft die 830 ms nodig.Soultaker schreef op woensdag 6 december 2023 @ 09:09:
[...]
[...]
Ah ja, dit is de juiste manier inderdaad (jullie hebben feitelijk precies dezelfde formule, wat natuurlijk ook logisch is). Mijn probleem was dat ikspoiler:de expressie (t**2 - 4*d)**0.5 direct probeerde af te ronden en dat werkt steeds nét niet.
Overigens heeft deze aanpak weer als nadeel dat het floating point math gebruikt waardoor 'ie niet correct werkt voor grotere invoer. Dan zou je eigenlijk isqrt() moeten gebruiken. Maakt voor de officiële testdata gelukkig niet uit.
[...]
spoiler:I/O valt bij dit probleem toch wel mee?
En als je de limieten van je huidige aanpak wil ervaren kun je de grotere test inputs hier proberen.
Voor de 127 bits variant en groter moet ik gaan werken met BigIntegers, en die geven toch wel een riante performance hit in Java...
Anyone who gets in between me and my morning coffee should be insecure.
[ Voor 6% gewijzigd door Diderikdm op 06-12-2023 10:43 ]
MadEgg schreef op woensdag 6 december 2023 @ 09:13:
spoiler:Ze hadden het probleem iets groter moeten maken om mij uit te dagen het algebraïsch op te lossen.
Brute force FTW in dit geval. Met 1.4 seconde geen onacceptabele tijd
Dag 6 - Kotilin
(0..race.first).map { race.first * it - (it * it) }.count { it > race.second }
vervangen door iets als:
(1..time).firstOrNull { it * (time - it) > distance }?.let { (time - it * 2) + 1 } ?: 0
"The question of whether a computer can think is no more interesting than the question of whether a submarine can swim" - Edsger Dijkstra
Mugwump schreef op woensdag 6 december 2023 @ 10:34:
[...]
spoiler:Zelfs "brute force" kan nog veel sneller.
(0..race.first).map { race.first * it - (it * it) }.count { it > race.second }
vervangen door iets als:
(1..time).firstOrNull { it * (time - it) > distance }?.let { (time - it * 2) + 1 } ?: 0
Tja
MadEgg schreef op woensdag 6 december 2023 @ 10:36:
[...]
spoiler:Dat is toch geen brute force meer? Hierbij zoek je de eerste die matched in de wetenschap dat het symmetrisch is en alles tussen die offset en die offset van het einde dus een oplossing is. Hangt een beetje van je definitie van brute force af, maar goed. Wat mij betreft is brute force domweg elke mogelijkheid proberen, dat is wat mijn stukje code doet
Feitelijk zoek je de minimale waarde voor x * (time -x ) > distance en dat kun je oplossen met de kwadratische formule zoals anderen al aangeven. Dan hoef je slechts een berekening te doen waar je beide waarden ingooit. Met mijn oplossing moet je nog steeds vanaf 1 door het lijstje heen lopen totdat je de eerste a tegenkomt waarvoor a * (time - a) > distance geldt.
"The question of whether a computer can think is no more interesting than the question of whether a submarine can swim" - Edsger Dijkstra
Oh cool.Soultaker schreef op woensdag 6 december 2023 @ 00:11:
Ik heb het voor de grap nog eens geïmplementeerd in C++ en het lijkt wel iets sneller te zijn op de officiële testdata:
Parsing took 141082 ns part1 Solve1() took 4529 ns/run (100000 runs) part1 Solve2() took 3615 ns/run (100000 runs) 240320250 part2 Solve1() took 8948 ns/run (100000 runs) part2 Solve2() took 5634 ns/run (100000 runs) 28580589
Alleen jammer dat de solve-tijd gedomineerd wordt door de parse-tijd.
De grap is dat ik meer variantie heb tussen verschillende runs dan dat je wint met die optimalisatie
Vorig jaar gebruikte ik een AVX string to int parser die met een paar instructies een int kon parsen. Ben wel benieuwd hoeveel dat zou schelen.
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.
Hij staat al sinds de post te stampen met BigIntegers en heeft nog geen resultaat, ik vermoed dat het niet helemaal lekker schaalt.Remcoder schreef op woensdag 6 december 2023 @ 09:26:
[...]
Voor de 63 bits variant heeft die 830 ms nodig.
Voor de 127 bits variant en groter moet ik gaan werken met BigIntegers, en die geven toch wel een riante performance hit in Java...
Time spent: 166.9µs
Soultaker schreef op woensdag 6 december 2023 @ 07:45:
[...]
spoiler:De kwadratische formule oplossen is inderdaad een standaard probleem maar ik zat te pielen met de afronding. Ik heb het uiteindelijk maar met binary search opgelost, wat simpel genoeg is.
max = ceil(max) - 1
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.
Reptile209 schreef op woensdag 6 december 2023 @ 08:22:
Hilarisch dit! In een half uurtje met pen en papier aan de ontbijttafel opgelost.
spoiler:Algemene vergelijking opgesteld voor de distance als functie van t en tmax. Die met de abc-formule omgeschreven naar de 2 vergelijkingen voor t. Laagste t naar boven afronden, hoogste naar beneden, verschil plus 1 geeft het aantal opties.
Met de Android calculator (die gelukkig ook voldoende precisie had voor deel 2) op het handje uitgerekend.
FCA schreef op woensdag 6 december 2023 @ 09:12:
[...]
spoiler:door de verschillende mogelijkheden in te vullen![]()
. Volgens mij zou het gewoon goed moeten gaan met:
[code]
int(math.floor(bovengrens)) - int(math.ceil(ondergrens)) +1[/code]
(De laatste +1 omdat je een een beide zijde inclusieve range bekijkt), maar op 1 of andere manier werden mijn beide grenzen negatief, waardoor je dus moet omdraaien, en ik had er om kwart over 6 even geen zin meer in om dat te debuggen, ontbijt moest nog worden klaargezet.
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.
https://github.com/Unreal...n/day6-second/src/main.rs
Ik merk sinds gisteren dat ik eindelijk wat in Rust begin te raken. Minder gestoei, dus dat is fijn
Nu nog even de tijd vinden om naar deel 2 van gisteren kijken. Ik had alleen tijd voor deel 1, en in de wandeling van het station naar huis deel 2 in m'n hoofd opgelost. Nu nog daadwerkelijk implementeren.
PS5 PSN: UnrealKazu
Klopt. Maar die zat bij mij alleen in het voorbeeld, niet in de echte opgave. En met de hand corrigeer je dat makkelijk.oisyn schreef op woensdag 6 december 2023 @ 13:11:
[...]
[...]
spoiler:Die van jullie gaan beide fout wanneer de vergelijking een integer oplevert. Dan zit je precies op het record en die voldoet dus niet.
Zo scherp als een voetbal!
Reptile209 schreef op woensdag 6 december 2023 @ 13:18:
[...]
Klopt. Maar die zat bij mij alleen in het voorbeeld, niet in de echte opgave. En met de hand corrigeer je dat makkelijk. Is wel een leuke edge-case idd.
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.
Mugwump schreef op woensdag 6 december 2023 @ 07:19:
[...]
spoiler:vanaf 0 is zinloos want 0*iets = 0, dus kleiner dan 1 zal de oplossing nooit zijn.
De stap om vanaf de top naar beneden te gaan is ook zinloos, want door vanaf onder te tellen weet je het antwoord al. vanaf onder krijg je a * b en vanaf boven b * a waarbij a het aantal ms is dat je het knopje ingedrukt houdt en b het aantal ms dat je vaart. Als je weet dat a de ondergrens is, dan is de bovengrens simpelweg time - a.
Edit: en nog makkelijker is inzien dat eea symmetrisch is, natuurlijk
Maar goed, uiteindelijk loopt ook deel twee in minder dan 1 ms
[ Voor 5% gewijzigd door Dido op 06-12-2023 16:24 ]
In slechts een kwartiertje dit in elkaar geprutst: https://github.com/WernerLDev/AOC2023/blob/main/day6/day6.ts
Roses are red, violets are blue, unexpected '{' on line 32.
Nu verder prutsen met deel 2 van gisteren..... ik heb een idee maar dat werkt nog niet helemaal.
"I had a problem, I solved it with regular expressions. Now I have two problems". That's shows a lack of appreciation for regular expressions: "I know have _star_ problems" --Kevlin Henney
vs
for mapI := len(maps) - 1; mapI >= 0; mapI-- {
"I had a problem, I solved it with regular expressions. Now I have two problems". That's shows a lack of appreciation for regular expressions: "I know have _star_ problems" --Kevlin Henney
https://github.com/realma...de.Y2023/Solvers/Day06.cs
There's no place like 127.0.0.1
De brute force had nog iets korter gekund door pas vanaf de helft van time te beginnen. En dan te kijken hoeveel er verder komen om vervolgens het aantal × 2 te doen. Moet je voor even tijden nog 1 er van af en klaar ben je.MatHack schreef op woensdag 6 december 2023 @ 20:07:
Na een lange dag op het werk was ik wel blij met hoe simpel deze was, qua tijd benodigd (brute-force met een loop, niet met algebra). Had wel een dag 1 vraag kunnen zijn...
https://github.com/realma...de.Y2023/Solvers/Day06.cs
in mijn functie aanroep gezet met het handje
[ Voor 16% gewijzigd door Visitor.q op 07-12-2023 00:28 ]
Mijn Python code
Maar goed, met onderbreking door ontbijt voor de kantoorganger toch redelijk snel opgelost
en deel 2 was bijna automatisch, moest alleen mijn Counter vervangen door even snel een dict opbouwen, en dan het aantal jokers optellen bij de meest-voorkomende.
Wel grappige edge case, blijkbaar kan 5 jokers ook. Stelletje jokers die elfjes
Verandert z'n sig te weinig.
Leuke puzzel vandaag
Inderdaad. Dag 7 in Java.CrossProd schreef op donderdag 7 december 2023 @ 07:16:
Vandaag gewoon implementeren zonder al te veel nadenken:
Siditamentis astuentis pactum.
Oh, damn! Ik heb het echt vééééél te ingewikkeld gemaakt vandaagFriits schreef op donderdag 7 december 2023 @ 07:38:
Leuk puzzeltje vandaag; deel 1 lekker eenvoudig, deel 2 een leuke twist!
Mijn oplossing (Python)
(Maar toch was ik de eerste op het Tweakers leaderboard, dus misschien is snel maar dom soms toch beter dan slim.)
Zo, dat is lekker compact. Weer wat geleerd vandaag, over Counter. Nu nog wennen aan enumerate, ik ben nog te veel van for i in range(len(xxx)). Dat is wel het leukste aan deze wedstrijd, nieuwe dingen leren uit de taal die je al kent en er mee experimenteren.Friits schreef op donderdag 7 december 2023 @ 07:38:
Leuk puzzeltje vandaag; deel 1 lekker eenvoudig, deel 2 een leuke twist!
Mijn oplossing (Python)
Correcte antwoorden eindigen op 8053 en 5512 voor deel 1 en deel 2 respectievelijk.
Ja, zo weinig code schrijven kost best veel tijdSoultaker schreef op donderdag 7 december 2023 @ 07:41:
(Maar toch was ik de eerste op het Tweakers leaderboard, dus misschien is snel maar dom soms toch beter dan slim.)
0.9 seconden inc parsen (75% van de tijd) met Swift.Soultaker schreef op donderdag 7 december 2023 @ 08:15:
Hier nog een grotere invoer voor dag 7, voor wie z'n oplossing wil benchmarken. M'n python oplossing doet het in 5 seconde en dat is 99% input parsen.
Correcte antwoorden eindigen op 8053 en 5512 voor deel 1 en deel 2 respectievelijk.
De set van @Soultaker doet er bij mij ook circa 5 seconden over in python.
[ Voor 19% gewijzigd door bakkerjangert op 07-12-2023 09:22 ]
https://github.com/mbe81/.../main/2023/day07/day07.go
Wel een redelijk snelle oplossing blijkbaar, ook met de input van @Soultaker is deze met +/- 380 ms klaar (per deel, de input wordt bij mij 2x geparsed)
Bijzonder dat je hand.replace(r, '0') doet in plaats van hand.replace('0', r) wat even kort maar intuïtiever is (joker vervangen door een kaart, i.p.v. kaart door een joker).
Oh, en de list() op de laatste regel is onnodig. Scheelt toch weer 6 karakters.
en dan een switch case met voor de 3 en 2 nog een extra check op respectievelijk de full house en de two pair.
Die had ik uitgebreid met een joker count waardoor je nog meer extra checks kreeg waar ik volgens mij ergens een case over het hoofd had gezien. Wegens tijdgebrek maar even een domme joker replace gedaan voor de bepaling van het type en dat werkte gelijk.
"The question of whether a computer can think is no more interesting than the question of whether a submarine can swim" - Edsger Dijkstra
https://github.com/patric...e/tree/master/2023/Day-07
... en gaat over tot de orde van de dag
... en gaat over tot de orde van de dag
En ook geleerd dat als ik het in de VS Code embedded terminal run, dat er dan ongeveer 70µs bij de tijd bij komt
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.
Even inhalen want was gisteren te druk.
Day 7 in Python
Door dit te doen kan ik nu de resulterende 13-base vertaling converteren naar een 10-based int en hoef ik enkel te sorteren op dat nummer en te vermenigvuldigen met de rang
Beide delen draaien in ~1 seconde per stuk inc parsenSoultaker schreef op donderdag 7 december 2023 @ 08:15:
Hier nog een grotere invoer voor dag 7, voor wie z'n oplossing wil benchmarken. M'n python oplossing doet het in 5 seconde en dat is 99% input parsen.
Correcte antwoorden eindigen op 8053 en 5512 voor deel 1 en deel 2 respectievelijk.
[ Voor 20% gewijzigd door FrankMennink op 07-12-2023 11:47 ]
Time spent: 63023.0µsSoultaker schreef op donderdag 7 december 2023 @ 08:15:
Hier nog een grotere invoer voor dag 7, voor wie z'n oplossing wil benchmarken. M'n python oplossing doet het in 5 seconde en dat is 99% input parsen.
Correcte antwoorden eindigen op 8053 en 5512 voor deel 1 en deel 2 respectievelijk.
FYI: Die set voldoet niet aan het de facto format (hij eindigt op een newline)
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.
Ah ja, dat was nog een overblijfseltje van de opdracht verkeerd lezen. Ik dacht dat alle kaarten van de "joker-waarde" niets waard waren. Heeft me vanochtend wel een paar minuutjes gekostSoultaker schreef op donderdag 7 december 2023 @ 09:56:
[...]
Bijzonder dat je hand.replace(r, '0') doet in plaats van hand.replace('0', r)
Thanks, over het hoofd gezien!Oh, en de list() op de laatste regel is onnodig. Scheelt toch weer 6 karakters.
Na nog wat refactoren kom ik uiteindelijk op deze code.
[ Voor 30% gewijzigd door Friits op 07-12-2023 12:24 ]
Enig idee hoe dat komt? Iets met output flushen naar de terminal, of wordt dat niet meegeteld in de timing?.oisyn schreef op donderdag 7 december 2023 @ 11:28:
En ook geleerd dat als ik het in de VS Code embedded terminal run, dat er dan ongeveer 70µs bij de tijd bij komt.
Volgens mij eindigen alle officiële invoerbestanden ook op een newline? (Zoals het overigens ook hoort!).oisyn schreef op donderdag 7 december 2023 @ 11:43:
FYI: Die set voldoet niet aan het de facto format (hij eindigt op een newline)
Wow, die implementatie van type() is lekker obscuurFriits schreef op donderdag 7 december 2023 @ 12:19:
Na nog wat refactoren kom ik uiteindelijk op deze code.
Ik denk het ja.Soultaker schreef op donderdag 7 december 2023 @ 12:56:
[...]
Enig idee hoe dat komt? Iets met output flushen naar de terminal, of wordt dat niet meegeteld in de timing?
Oh lol je hebt gelijk. Ik save die dingen nooit, want Chrome opent ze gewoon in een tab. En dan doe ik CTRL+A en copy/paste ik 'm naar een file. Maar dan neemt ie de laatste newline dus niet meeVolgens mij eindigen alle officiële invoerbestanden ook op een newline? (Zoals het overigens ook hoort!)
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.
Nog obscuurder, maar ook heel elegant (al zeg ik het zelf):Soultaker schreef op donderdag 7 december 2023 @ 12:56:
Wow, die implementatie van type() is lekker obscuur
Good catch! En ik dacht nog wel dat ik "perfecte" code had geschreven!Eventueel kun je '23456789ABCDE' nog vervangen door hand.
[ Voor 4% gewijzigd door Friits op 07-12-2023 13:18 ]
Mijn implementatie doet er nog geen 500 millisecondes over met zowel deel 1 als deel 2 als ik mijn Stream parallel maak. Zonder parallellisatie doet die het in minder dan een seconde.Soultaker schreef op donderdag 7 december 2023 @ 08:15:
Hier nog een grotere invoer voor dag 7, voor wie z'n oplossing wil benchmarken. M'n python oplossing doet het in 5 seconde en dat is 99% input parsen.
Correcte antwoorden eindigen op 8053 en 5512 voor deel 1 en deel 2 respectievelijk.
Zie hier.
Remcoder schreef op donderdag 7 december 2023 @ 13:23:
[...]
Mijn implementatie doet er nog geen 500 millisecondes over met zowel deel 1 als deel 2 als ik mijn Stream parallel maak. Zonder parallellisatie doet die het in minder dan een seconde.
spoiler:Ik heb mijn objecten Comparable gemaakt en sorteer tijdens het inlezen van de file gelijk de Hands op de juiste volgorde. Daarna moet ik er nog een keer overheen loopen om te bepalen welke positie elke Hand heeft. Helaas kan dat niet tijdens de verwerken van de stream.
Zie hier.
En wat betreft het opnieuw loopen is mapIndexed in Kotlin echt een gigantische verbetering t.o.v. Java. Daarmee doe je gewoon de map methode van een java stream, maar ipv van dat je alleen de value tot je beschikking hebt, heb je dan (index, value) tot je beschikking in de map.
"The question of whether a computer can think is no more interesting than the question of whether a submarine can swim" - Edsger Dijkstra
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.
https://github.com/ysmild...ter/pkg/2023/day7/day7.go
ProAce schreef op donderdag 7 december 2023 @ 15:04:
Ik kom er niet uit, er zit ergens een edge case in die niet in de testdata zit waardoor de uitkomst van deel 2 niet klopt. Vanavond maar eens verder bestuderen![]()
https://github.com/ysmild...ter/pkg/2023/day7/day7.go
ProAce schreef op donderdag 7 december 2023 @ 15:04:
Ik kom er niet uit, er zit ergens een edge case in die niet in de testdata zit waardoor de uitkomst van deel 2 niet klopt. Vanavond maar eens verder bestuderen![]()
https://github.com/ysmild...ter/pkg/2023/day7/day7.go
for _, v := range cards {
if useJokers {
v += jokers
}
switch v {
case 5:
cardStrength = fiveOfAKind
break
case 4:
cardStrength = fourOfAKind
break
case 3:
threeOfAKindFound = true
case 2:
pairs++
}
}
Misschien interpreteer ik het verkeerd, maar gaat dit nu wel goed met pairs?
Als je b.v. J2345 hebt, dan krijg je hier toch 4 pairs in plaats van 1 als ik het goed zie?
"The question of whether a computer can think is no more interesting than the question of whether a submarine can swim" - Edsger Dijkstra
Hé leuk, nog iemand met Go!ProAce schreef op donderdag 7 december 2023 @ 15:04:
Ik kom er niet uit, er zit ergens een edge case in die niet in de testdata zit waardoor de uitkomst van deel 2 niet klopt. Vanavond maar eens verder bestuderen![]()
https://github.com/ysmild...ter/pkg/2023/day7/day7.go
nom vreet 'm in 100ms (inclusief het 2x scoren van de set bedenk ik mij nu, 22ms zonder):Soultaker schreef op donderdag 7 december 2023 @ 08:15:
Hier nog een grotere invoer voor dag 7, voor wie z'n oplossing wil benchmarken. M'n python oplossing doet het in 5 seconde en dat is 99% input parsen.
1
2
3
4
5
| $ ./target/release/aoc2023 --input aoc-2023-day-07-challenge-1.txt run day 7 for aoc-2023-day-07-challenge-1.txt Day 7 parsed (98.747238ms) Day 7 part 1: ****8053 (103.434332ms) Day 7 part 2: ****5512 (110.0438ms) |
[ Voor 4% gewijzigd door veldsla op 07-12-2023 16:06 ]
Mschamp schreef op donderdag 7 december 2023 @ 15:10:
spoiler:toevallig een kaart met 5 keer een joker?
Mugwump schreef op donderdag 7 december 2023 @ 15:15:
spoiler:Ik zat naar dit stukje te kijken:
for _, v := range cards {
if useJokers {
v += jokers
}
switch v {
case 5:
cardStrength = fiveOfAKind
break
case 4:
cardStrength = fourOfAKind
break
case 3:
threeOfAKindFound = true
case 2:
pairs++
}
}
Misschien interpreteer ik het verkeerd, maar gaat dit nu wel goed met pairs?
Als je b.v. J2345 hebt, dan krijg je hier toch 4 pairs in plaats van 1 als ik het goed zie?
Alle drie correct, ik heb nog wat werk te doenmbe81 schreef op donderdag 7 december 2023 @ 15:23:
spoiler:Geef jij je jokers niet dubbel uit? Je telt het aantal jokers op bij het aantal kaarten op de score te bepalen. Als ik snel naar je loop kijk (regel 95) denk ik dat bijvoorbeeld bij een hand als "8822J" twee keer de waarde threeOfAKindFound op true zet maar zie ik niet hoe je het pair telt. (v is in beide gevallen 3 geworden)
Als je de occurrences hebt, deze vermenigvuldigd met zichzelf en dan de som van de hand pakt kun je goed sorteren.
8822A -> 2 2 1 -> 2*2 2*2 1*1 -> 4 4 1 -> 9
18222 -> 1 1 3 -> 1*1 1*1 3*3 -> 1 1 9 -> 11
etc..
BernardV schreef op donderdag 7 december 2023 @ 15:54:
spoiler:Ik geef de hands geen flags als threeOfAKind, FullHouse, pair etc.
Als je de occurrences hebt, deze vermenigvuldigd met zichzelf en dan de som van de hand pakt kun je goed sorteren.
8822A -> 2 2 1 -> 2*2 2*2 1*1 -> 4 4 1 -> 9
18222 -> 1 1 3 -> 1*1 1*1 3*3 -> 1 1 9 -> 11
etc..
.edit: oh wacht, ik dacht even dat je een totale waarde voor elke hand gaf, maar dat getal wat je berekent maakt alleen onderscheid van het soort hand
[ Voor 13% gewijzigd door .oisyn op 07-12-2023 15:59 ]
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.
.oisyn schreef op donderdag 7 december 2023 @ 15:58:
[...]
spoiler:Hoe maak jij het onderscheid tussen 12233 en 12323?
Maar om de mindere Python goden een hart onder de riem te steken mijn oplossing
dag 7 python
Kan duidelijk nog wel wat korter maar heeft wel weer lang genoeg geduurd
Dag 7 - Kotlin
Tja