 More e digits trivia.
 Feel free to copy, distribute as long as this header attached so
 original algorithm creators and implementors are known.

 This is an Ada implementation of decimal representation of 'e'
 based on SPIGOT algorithm for \pi by
 S. Rabinowitz & S. Wagon, _The_American_Mathematical_Monthly_, March 1995

 A C implementation of the above was posted on the net by
 Ed Hook
 MRJ Technology Solutions, Inc.
 NAS, NASA Ames Research Center
 Internet: hook@nas.nasa.gov

 This is an Ada implementation of the above using GNAT (gnu Ada compiler),
 with the added feature is that it computes the frequency of each digit in e,
 and computes the largest consecutive sequences of each digit within the
 expression that represents digits of e.

 the following is the result. my PC is still running trying to find the
 frequency for 200,000 digits and more for e, and it's been several days
 and not finished. So this is a partial results. (PC is 200 MHz pentium,
 running Linux 2.0.36, and compiler is GNAT 3.11p

 offcourse as number of digits of e goes very large, each digit is expected
 to show as often as any other digit.

 Nasser Abbasi nabbasi@pacbell.net feb. 20, 1999.

 results:
 this is distribution table for digits in e as function of how many
 digits.
 for example, when looking at 5000 digits of e, we find 497 0's,
 478 1's, etc.. (this is for digits after the decimal point of e)


 #digits in e
 
 500 5,000 20,000 50,000 200,000
 
how many 0's 51 497 1,949 4,948 19,916
how many 1's 43 478 2,010 5,055 20,367
how many 2's 50 492 2,020 4,969 19,794
how many 3's 53 514 2,080 5,026 20,071
how many 4's 52 470 1,989 4,966 20,082
how many 5's 44 478 1,979 5,046 20,038
how many 6's 51 545 2,057 5,133 20,221
how many 7's 60 525 1,977 4,959 19,817
how many 8's 40 509 1,966 4,972 19,939
how many 9's 56 492 1,974 4,926 19,755


most occurring '7' '7' '3' '6' '1'

least occurring '8' '4' '0' '9' '9'

difference
between largest 20 55 131 207 612
and smallest
in frequency

difference
between largest 4% 1.1% 0.655% 0.414% 0.306%
and smallest
frequency in %


consecutive frequencies: under each column, there are 3 values, the first
is the number of digits that occurred next to each others for that digit,
and the start of this sub sequence, and its end, in position values.

for example, for 5,000 digits of e, we see that largest consecutive
sequence of digit '0' had length of 3, and it started at digit position
328 to position 330. Digit positions are counted from left to right at
the decimal point. for example e=2.718, here digit '7' is at position 1,
'1' is at position 2, etc..

 #digits in e
 ++
 5,000  20,000  50,000  100,000
 +++
 0's (3,328,330)  (4,7688,7691)  *no change* (6,89296,89301)
 1's (3,427,429)  (5,12220,12224)  *no change*  *no change*
 2's (2,2744,2746)  (4,17309,17312)  (5,33483,33487)  *no change*
 3's (4,3354,3375)  *no change*  *no change*  *no change*
 4's (3,787,789)  (4,11806,11809)  *no change*  *no change*
 5's (4,3620,3623)  *no change*  *no change*  *no change*
 6's (5,4992,4996)  *no change*  *no change*  *no change*
 7's (4,1071,1074)  *no change*  *no change*  *no change*
 8's (4,723,726)  *no change*  *no change*  *no change*
 9's (3,47,49)  *no change*  (4,29344,29347)  *no change*



Compiler: GNAT 3.11p , see http://www.adahome.com to download
To compile: save this file as dist_e_final.adb and type
 gnatmake dist_e_final.adb
system: Linux 2.0.36
Date: feb. 17, 1999
To Run: ./dist_e_final
 For example, to see e for 70 digits do:

 /home/nabbasi/my_ada $./dist_e_final 70
 2.7182818284590452353602874713526624977572470936999595749669676277240766
 frequency of 0 is 4
 frequency of 1 is 3
 frequency of 2 is 9
 frequency of 3 is 4
 frequency of 4 is 7
 frequency of 5 is 7
 frequency of 6 is 10
 frequency of 7 is 12
 frequency of 8 is 5
 frequency of 9 is 9

 performance note: On Pentium PRO 200 MHZ, using GNAT 3.11p, Linux 2.0.36,
 128 MB RAM. No other activity on PC, and for 1,000,000 digits, this
 program will generate about 50 digits each minutes. So, for 1,000,000
 digits it will take about 13 days. for larger than 1,000,000 you might
 encounter stack overrun, depending on amount of memory you have...

 notice the main algorithm is O(n^2).

with Ada.Text_Io; use Ada.Text_Io;
with ada.command_line; use ada.command_line;
procedure Dist_E_final is
type E_Type is array( Natural range <> ) of Natural;
Distribution : array(0..9) of Natural := (others => 0);
Num_Of_Digits : Natural;
type Sequence_item is record
Starts_At, Ends_At, Length : Natural;
end record;
Sequence: array(0..9) of Sequence_Item := (others=>(0,0,0));
current_Digit, Current_Sequence_Length, Current_Sequence_Start: Natural :=0;
procedure Update_Sequence(Next_Digit_Position, next_digit: Natural) is
begin
if( next_Digit /= Current_Digit) then
if( Sequence( current_Digit ).Length < Current_Sequence_Length) then
Sequence( current_Digit ).Length := Current_Sequence_Length;
Sequence( current_Digit ).Starts_At := Current_Sequence_start;
Sequence( Current_Digit ).Ends_At := Next_Digit_Position 1;
end if;
Current_Digit := Next_Digit;
Current_Sequence_Length := 1;
Current_Sequence_Start := Next_Digit_Position;
else
Current_Sequence_Length := Current_Sequence_Length +1;
end if;
end Update_Sequence;
procedure Done_Sequence( Current_Digit_Position: Natural) is
begin
if( Sequence( current_Digit ).Length < Current_Sequence_Length) then
Sequence( current_Digit ).Length := Current_Sequence_Length;
Sequence( current_Digit ).Starts_At := Current_Sequence_start;
Sequence( Current_Digit ).Ends_At := current_Digit_Position ;
end if;
end Done_Sequence;
begin
if( Argument_Count /= 1 ) then
Put_Line("usage: dist_e "); return;
end if;
begin
Num_Of_Digits := natural'value( Argument(1));
if( Num_Of_Digits = 0 ) then
Put_Line("value for number of digits must be larger than zero");
return;
end if;
exception
when others =>
Put_Line("Exception. invalid value for number of digits"); return;
end;
declare  the algorithm itself is in this block
E: E_Type( 1 .. Num_Of_Digits+2 ) := (others=> 1);
Carry : Natural;
begin
Put("2.");
for I in E'first .. E'Last2 loop
Carry := 0;
for J in reverse E'first .. E'Last loop
E(J) := ( E(J) * 10 ) + Carry;
Carry := E(J)/(J+1);
E(J) := E(J) rem (J+1);
end loop;
Put(Natural'Image(Carry)(2));  print current digit of e
Distribution( Carry ) := Distribution( Carry ) + 1;
Update_Sequence(I,Carry);
end loop;
Done_Sequence(E'Last2);
end;
New_Line;
for I in Distribution'Range loop
Put_line("frequency of " & Natural'Image(I) & " is "
& natural'Image( Distribution(I) ));
end loop;
for I in sequence'Range loop
if( Sequence(I).Length = 0 ) then
Put_Line("Digit "& Natural'Image(I) & " was not seen.");
else
Put_line("largest concecutive seq of " & Natural'Image(I)
&" started at digit "
& natural'Image( sequence(I).Starts_at )
& " and ended at digit "
& natural'Image( sequence(I).ends_at )
& " of length "
& natural'Image( sequence(I).length ));
end if;
end loop;
end Dist_E_final;
