12.5 Ni kompliku iom pli: π kiu generas π.....

Kio estas hazarda entjero? Ĉu hazarde prenita entjero inter 1 kaj 1000000 estas vere reprezentiva de iu ajn hazarda entjero? Oni rimarkas tre rapide ke nia modelado nur proksimiĝas de la ideala modelo. En ordo, ja pri la maniero generi la hazardan nombron ke ni realigos kelkajn ŝanĝojn... Ne ne uzos plu la primitivon hazardon sed uzos la sekvencon de la decimaloj de π. Mi klarigu: la decimaloj de π de ĉiam intrigis la matematikistojn pro ilia manko de reguleco; la ciferoj de 0 ĝis 9 ŝajnas aperi laŭ kvantoj preskaŭ egalaj kaj laŭ hazarda maniero. Ni vidos tuj kiel generi hazaradan nombron per decimaloj de π. Antaŭ ĉio, necesos kolekti la unuajn decimalojn de π (ekzeple unu milionon).

Por krei niajn hazardajn nombrojn, ni prenu pakojn de 8 ciferojn el la sekvenco de decimaloj de π. Por klarigo, la dosiero komenciĝas tiel:

3.1415926
◟  ◝◜   ◞ Unua nombro 53589793
◟   ◝◜   ◞Dua nombro 23846264
◟  ◝◜  ◞Tria nombro338327950288419716939 ktp

Mi forigu la «.» de 3.14... kiu ĝenos kiam oni grupigos la decimalojn. Ĉio en ordo, ni kreu novan proceduron nomatan hazardpi kaj modifu malmulte la proceduron test:

por pgkd :a :b  
se (rest :a :b) = 0 [sendu :b] [sendu pgkd :b rest :a :b]  
fino  
 
por test :provoj  
# Malfermu flukson indikatan de la cifero 1 al la dosiero millionpi.txt  
# (ĉi tie, supozate ke ĝi estas en la kuranta dosierujo;  
# se ne, uzu dosieron_provizu kaj absolutan vojon)  
flukson_malfermu 1 "millionpi.txt  
# Provizu al la variablo linio la unuan linion de la dosiero millionpi.txt  
provizu "linio unuan flukslinion_legu 1  
# Komencu la variablon nombrilo je 0  
provizu "nombrilo 0  
ripetu :provoj  
  [se 1 = pgkd hazardpi 7 hazardpi 7 [provizu "nombrilo :nombrilo + 1]]  
# Kalkulu la frekvencon  
provizu "f :nombrilo / :provoj  
# Skribu la valoron proksimuman al pi  
skribu frazon [proksimumigo de pi:] radiko (6/:f)  
flukson_fermu 1  
fino  
 
por hazardpi :n  
lokp "nombre "  
ripetu :n  
  [# Se estas plu neniu signo sur la linio  
   se 0 = kmpt :linio [provizu "linio unuan flukslinion_legu 1]  
   # Provizu la variablon signo per la valoro de la unua signo de la linio  
   provizu "signo unuan :linio  
   # poste oni forigu tiun unuan signon de la linio  
   provizu "linio senunuan :linio  
   provizu "nombro vorton :nombro :signo]  
sendu :nombro  
fino  
 
test 10  
proksimumigo de pi: 3.4641016151377544  
test 100  
proksimumigo de pi: 3.1108550841912757  
test 1000  
proksimumigo de pi: 3.081180112566604  
test 10000  
proksimumigo de pi: 3.1403714651066386  
test 70000  
proksimumigo de pi: 3.1361767950325627

Oni trovas do proksimumigon de la nombro π per ĝiaj propraj decimaloj!

Ankoraŭ eblas plibonigi tiun programon indikante ekzemple la tempon uzitan por la kalkulo. Aldonu en unua linio de la proceduro test:

provizu "komenco tempon

Aldonu ĝuste antaŭ flukson_fermu 1:

skribu frazon [Tempo uzita: ] tempon - :komenco