Kirjautuminen

Haku

Tehtävät

Keskustelu: Ohjelmointiputka: Putkaposti 32: Noppakonsti

Sivun loppuun

Antti Laaksonen [16.07.2009 19:20:00]

#

Tässä tulee uusi putkaposti:

https://www.ohjelmointiputka.net/postit/tehtava.php?tunnus=noppak

Metabolix [19.07.2009 11:23:03]

#

Pythonilla optimoimaton ratkaisu vei kolmisenkymmentä riviä ja laski kaikki tapaukset yhteensä 2,5 sekunnissa.

Javalla kokeilin hieman erilaista, pikaisesti ajatellen lähes yhtä tehokasta lähestymistapaa, ja pisimmät sarjat ratkesivat tälläkin kolmessa sekunnissa. Nyt en kuitenkaan saanut laskettua lyhyempiä sarjoja samalla kertaa, joten kaikkien ratkaisujen laskeminen vei lähes puoli minuuttia.

Antti Laaksonen [19.07.2009 11:42:23]

#

Minun Python-ohjelmani laskee tapaukset 6–27 0,5 sekunnissa ja tapaukset 6–100 18 sekunnissa (3 GHz:n suorittimella).

jlaire [19.07.2009 12:29:17]

#

Lievästi optimoidun C-toteutuksen ajoaika on suunnilleen 0,008s, vaihtelee välillä 0ms-16ms. Sama Haskellilla ilman optimointeja vie 0,12s jos käyttää 64-bittisiä kokonaislukuja ja 0,67s jos rajattoman tarkkuuden lukuja. Tapaukset 6-100 vievät n. 4,3s ja tapaukset 6-1000 n. 71s, prosessori 2,2GHz.

1000 29580231144628040438389565097236942235178032131546871576023
2952717079868743640225488283395999197176343372890052779965329425
8714503588551265742851164297330621261880415994523715885784096463
5198837057653218811420380536156196434138394011754579168945616876
0538948580462533890632667325897407431078841380742758907194119977
4829566781668503173960620747181347378022240140343787386643033045
5914210667620659691799070937170619660756859861232539680028993953
6031939942434573212155077904177086922236868479326822973212026183
8534260840018699615280267493325405878261943112327074153227678605
3553919785674829373019606603193348885936719082117587699770212614
5023563254012690104429719046391014247373142443502154601109685950
8182459147194017844364766537833460649165980197202327859225176652
944835245058317

Metabolix [19.07.2009 13:24:44]

#

Toteutin saman C:llä, ja sillä nopeus on mainittua muutaman millisekunnin luokkaa. Alkuperäinen Python-koodini käsitteli lukuja tekstinä, mutta jostain syystä oikeiden lukujen käyttökään ei nopeuttanut koodia. Olisi mielenkiintoista tietää, millainen pikku optimointi minulta on jäänyt huomaamatta, kun Antin ratkaisu on noin paljon nopeampi. Tapauksen 1000 laskemiseen meni Pythonilla 130 sekuntia, prosessori on 32-bittinen ja kellotaajuus 1,73 GHz.

Teuro [19.07.2009 13:33:00]

#

Voisiko Antin prosessori käsitellä lukuja nopeammin, koska 3 GHz on kuitenkin nopeanpi kuin 1,73 GHz. En jostain syystä jaksa uskoa, että sinulta olisi jäänyt huomaamatta jotakin.

Antti Laaksonen [19.07.2009 14:26:06]

#

Metabolix kirjoitti:

Olisi mielenkiintoista tietää, millainen pikku optimointi minulta on jäänyt huomaamatta, kun Antin ratkaisu on noin paljon nopeampi.

Vai onkohan ratkaisutapa erilainen? Lähetin sinulle sähköpostia.

Metabolix [19.07.2009 14:59:46]

#

Ratkaisutapa on näköjään hyvinkin erilainen ja selvästi mutkikkaampi. Uudempi versio omasta ratkaisustani on hyvin selkeä alle 20-rivisenäkin.

Chiman [19.07.2009 20:14:58]

#

Oma ratkaisu: 22 (merkitsevää) Python-riviä, yhteensä 3 min 37 s. Hidas mutta selkeä algoritmi.

jlaire [20.07.2009 00:29:38]

#

Koodasin uuden algoritmin Haskellilla. Se voi ratkaista isoja tapauksia ilman kaikkien pienempien tuloksia. Tuhannen nopan heittosarja vie sekunnin, ja koska tulos on sama kuin tuo jonka pastesin aiemmin, se on melko varmasti oikein. Kymmenen tuhannen sarja vie 3,5s, sadan tuhannen minuutin, miljoonan 20min. Viimeisen tarkka arvo on 1779850986...9205325019, jossa pisteiden kohdalla on 778132 numeroa.

Wikipediassa on monta hyvää artikkelia tähän liittyen. Jos jotain kiinnostaa, näistä on hyvä aloittaa:
http://en.wikipedia.org/wiki/Markov_chain
http://en.wikipedia.org/wiki/Stochastic_matrix

User137 [20.07.2009 02:18:05]

#

Miten te käsittelette noin valtavia lukuja? Valmiilla kirjastolla vai jollain omalla ratkaisulla?

jlaire [20.07.2009 02:36:06]

#

Haskellissa ja Pythonissa on valmiina tuki. Yleensä se on toteutettu GMP:llä, ja sitä voi käyttää myös monilla muilla kielillä. Omat ratkaisut tuskin olisivat läheskään yhtä hyviä.

os [22.07.2009 00:48:59]

#

Itse pääsin 1,3 GHz kellotaajuudella tällaiseen tulokseen

$ time python noppa.py 10000
10000 294504624606303899806625...5490470235656924931097

real	0m32.527s
user	0m29.954s
sys	0m0.048s

missä pisteiden välissä on noin 7700 numeroa. Tuhannen heiton käsittelemiseen menee 1,7s. Ainakin linkeistä päätellen algoritmi lienee samantapainen kuin funktiolla.


Sivun alkuun

Vastaus

Aihe on jo aika vanha, joten et voi enää vastata siihen.

Tietoa sivustosta