| Bytes | Lang | Time | Link |
|---|---|---|---|
| 132 | APLNARS | 250213T105540Z | Rosario |
| nan | 130626T133719Z | skeevey | |
| 124 | GolfScript | 121128T214006Z | Peter Ta |
| 372 | c | 121126T061203Z | dmckee - |
| 133 | Perl | 121124T165536Z | primo |
| 127 | Mathematica | 121124T194403Z | DavidC |
APL(NARS), 132 chars
a←(0,40⍴1)\[1](0,10⍴1)\[2]40 10⍴{4⍕¯∞{(√2p1)÷⍨*¯2÷⍨⍵*2}∫⍵}¨∊{⍵+{(⍵÷10)+100÷⍨0,⍳9}¨0,⍳9}¨0,⍳3⋄a[1;]←0,0,100÷⍨⍳9⋄a[;1]←' ',0,10÷⍨⍳39⋄a
the function that make the integration is
{4⍕¯∞{(√2p1)÷⍨*¯2÷⍨⍵*2}∫⍵}
the few start and end values of the table are these:
0 0.01 0.02 0.03 0.04 0.05 0.06 0.07 0.08 0.09
0 0.5000 0.5039 0.5079 0.5119 0.5159 0.5199 0.5239 0.5279 0.5318 0.5358
0.1 0.5398 0.5438 0.5477 0.5517 0.5556 0.5596 0.5635 0.5674 0.5714 0.5753
0.2 0.5792 0.5831 0.5870 0.5909 0.5948 0.5987 0.6025 0.6064 0.6102 0.6140
.....................
3.7 0.9998 0.9999 0.9999 0.9999 0.9999 0.9999 0.9999 0.9999 0.9999 0.9999
3.8 0.9999 0.9999 0.9999 0.9999 0.9999 0.9999 0.9999 0.9999 0.9999 0.9999
3.9 0.9999 0.9999 0.9999 0.9999 0.9999 0.9999 0.9999 0.9999 0.9999 0.9999
k
This is based on the Zelen and Severo algorithm here. 162 characters. Can improve the character count significantly by reducing precision.
+`q`p!(q;{abs(x>0)-(exp[-.5*x*x]%sqrt 2*acos -1)*t*.31938153+t*-.356563782+t*1.781477937+t*-1.821255978+1.330274429*t:1%1+.2316419*abs x}(q:0.1*!391)+\:0.01*!100)
Runs in about 15ms on a Pentium E2160.
GolfScript (124 chars)
10:&,~]' 0.0'*40,{n\:I&/'.'I&%&,{' '\I&*+&8?:^*100/:x^54,-2%{:i*x.{*^/}:$~$i).)*/^\-}/$3989423$15000500+`5<(49-'.'@}%}/
Note: the only whitespace in there are two tab characters. MarkDown is turning them into triple-spaces.
The interesting part (i.e. the calculation) is done in x.8 fixpoint using identity 26.2.10 of Abramowitz and Stegun (1972). The program runs in under 2 seconds on my machine.
c -- 372
Just for interest this is an implementation of Peter's Monte Carlo suggestion from the comments
#include "stdio.h"
#include "stdlib.h"
#include "math.h"
#define P printf
#define F(c,n) for(c=0;c<n;++c)
long c=9e9,i,j,k;double a[400],b=.01,t;
double B(){return sqrt(-2*log(drand48()))*cos(2*M_PI*drand48());}main()
{srand48(time(0));F(i,c){t=B();F(k,400)a[k] += t<b*k;}P("%4c",' ');F(j,10)
P("%4.2f ",b*j);F(i,40){P("\n%3.1f ",10*i*b);F(j,10)
P("%6.4f ",a[10*i+j]/c);}}
Lots of repetitive code. A very straight forward implementation, ungolfed it looks like
#include "stdio.h"
#include "stdlib.h"
#include "math.h"
long c=9e9, i, j, k; /* demands longs longer than 32 bits */
double a[400], bw=.01, t;
double B/*oxMuller*/(){
/* normal distribution, centered on 0, std dev 1 */
return sqrt(-2*log(drand48())) * cos(2*M_PI*drand48());
}
main(){
srand48(time(0));
for(i=0; i<c; ++i) { /* compute the probabilities by MC integration */
t=B/*oxMuller*/();
for(k=0; k<400; ++k) a[k] += t<bw*k;
}
/* Print the table */
printf("%4c",' ');
for(j=0; j<10; ++j) printf("%4.2f ",bw*j);
for(i=0; i<40; ++i) {
printf("\n%3.1f ",10*i*bw);
for(j=0; j<10; ++j) printf("%6.4f ",a[10*i+j]/c);
}
printf("\n"); /* make the end pretty */
}
It is slow, about 60 seconds to do 100,000,000 throws with absolutely all the optimization bells and whistles turned on (-m64 -Ofast) on my 2.2 GHz Core 2 Duo laptop. Worse, it needs circa 50 times that many to provide real confidence that you have the right value in each and every bin. As written I'm asking for even more.
That seems too long to me, but I suspect that I underestimate how much work drand48 is doing (and I have sacrificed about a factor of 2 in the random number generation at the alter of small code).
It also demands that long is a bit bigger than 32 bits (thus the -m64 above).
Perl - 137 133 bytes
print"\t0.0$_"for 0..9;for($f=2.506628;$i++<80;$f*=-++$i){printf'
%.1f',$x,s;;+\$x**$i/$i/$f;;printf"\t%.4f",eval,$x+=.01for(.5.$_)x10}
(both \t should be replaced with a literal tab character.)
Uses a Taylor Series expansion[1], adding one term per row, which seems to be good enough. The script produces the output exactly as expected, although each row does have a trailing whitespace. Runs in about 60ms on my lappy.
Edit as per comment by Peter Taylor.
[1] http://mathworld.wolfram.com/NormalDistributionFunction.html (formula 10)
Mathematica 132 136 127
If Erfc is acceptable, here's my attempt, accurate to 6 places:
t=Table;TableForm[Partition[t[0.5 Erfc[-x/Sqrt[2]],{x,0,3.99,.01}],10],
TableHeadings->{t[k,{k,0,3.9,.1}],t[k,{k,0,.09,.01}]}]
