Count the occurrence of each digit in e
It is conjectured that each decimal digit will occur with the same frequency in the mathematical constant e, see: the Wikipedia page on e.
This task is to count and display (here on this page) how many times each digit occurs, up to some "large" number of fractional digits.
- Notes
A B program to calculate the first 4000 fractional digits is on the Wikipedia here: B (programming language)
The algorithm shown is from Ken Thompson's Users' Reference to B manual and does not require big-integers.
This Redit article draws a graph of the first 100 digits.
ALGOL 68
This is a tranlation of the algorithm from Ken Thompson's User's Reference to B manual, as shown on the B page of the Wikipedia.
The source of rows.incl.a68 is on another page on Rosetta Code, see the above link.
Note, ALGOL 68Genie will warn that the loop counter, col is unused - I've left it as it would be used in the currently commented-out code that displays the actual fractional digit was uncommented.
BEGIN # calculate the decimal digits of e and count how many times each #
# digit occurs - based on the B code on the Wikipedia page: #
# https://en.wikipedia.org/wiki/B_(programming_language) #
PR include "rows.incl.a68" PR # include row (array) utilities #
# this counts the digits in the fractional part of e so the initial #
# count for 2 is 1, to include the non-fractional digit #
[ 0 : 9 ]INT dcount := []INT( 0, 0, 1, 0, 0, 0, 0, 0, 0, 0 )[ AT 0 ];
[ 0 : 1999 ]INT v;
INT n = UPB v + 1;
INT c, a;
FOR i FROM LWB v TO UPB v DO v[i] := 1 OD;
FOR col FROM 0 TO 2*n DO
a := n+1;
c := 0;
FOR i FROM LWB v TO UPB v DO
c +:= v[i]*10;
v[i] := c MOD a;
c OVERAB a;
a -:= 1
OD;
dcount[ c ] +:= 1
CO ; # uncomment this to show the actual digits #
print( ( REPR ( c + ABS "0" ) ) );
IF ( col + 1 ) MOD 5 = 0 THEN
print( ( IF ( col + 1 ) MOD 50 /= 0 THEN space ELSE newline FI ) )
FI
CO
OD;
SHOW dcount
END
- Output:
396 395 391 403 387 390 422 409 397 412
Asymptote
import math;
int MaxIDx = 2000;
int[] v = new int[MaxIDx];
int[] dcount = {0, 0, 1, 0, 0, 0, 0, 0, 0, 0};
int i, c, a, col;
for(i = 0; i < MaxIDx; ++i) {
v[i] = 1;
}
for(col = 0; col <= 2 * MaxIDx; ++col) {
a = MaxIDx + 1;
c = 0;
for(i = 0; i < MaxIDx; ++i) {
c += v[i] * 10;
v[i] = c % a;
c = floor(c / a);
a -= 1;
}
dcount[c] += 1;
}
string result = "";
for(i = 0; i <= 9; ++i) {
result += string(dcount[i]) + " ";
}
write(result);
- Output:
396 395 391 403 387 390 422 409 397 412
BASIC
BASIC256
arraybase 0
MaxIDx = 2000
dim v(MaxIDx) fill 1
dim dcount = {0, 0, 1, 0, 0, 0, 0, 0, 0, 0}
for col = 0 to 2 * MaxIDx
a = MaxIDx + 1
c = 0
for i = 0 to MaxIDx-1
c += v[i] * 10
v[i] = c mod a
c = int(c / a)
a -= 1
next
dcount[c] += 1
next
for i = 0 to 9
print " "; dcount[i];
next
- Output:
Similar to FreeBASIC entry.
Chipmunk Basic
100 cls
110 maxidx = 2000
120 dim v(maxidx-1)
130 for i = 0 to maxidx-1
140 v(i) = 1
150 next
160 dim dcount(9)
170 for i = 0 to 9
180 dcount(i) = 0
190 next
200 dcount(2) = 1
210 for col = 0 to 2*maxidx
220 a = maxidx+1
230 c = 0
240 for i = 0 to maxidx-1
250 c = c+v(i)*10
260 v(i) = c mod a
270 c = int(c/a)
280 a = a-1
290 next
300 dcount(c) = dcount(c)+1
310 next
320 for i = 0 to 9
330 print dcount(i);
340 next
350 print
360 end
- Output:
Same as FreeBASIC entry.
FreeBASIC
Nearly copy&paste of Algol version
' calculate the decimal digits of e and count how many times each
' digit occurs - based On the B code On the Wikipedia page:
' https://en.wikipedia.org/wiki/B_(programming_language)
Const MaxIDx As Integer = 2000
Dim As Integer i, c, a, col
Dim v(MaxIDx-1) As Integer
For i = Lbound(v) To Ubound(v)
v(i) = 1
Next
Dim dcount(9) As Integer = {0, 0, 1, 0, 0, 0, 0, 0, 0, 0}
For col = 0 To 2 * MaxIDx
a = MaxIDx + 1
c = 0
For i = 0 To MaxIDx-1
c += v(i) * 10
v(i) = c Mod a
c \= a
a -= 1
Next
dcount(c) += 1
Next
For i = Lbound(dcount) To Ubound(dcount)
Print dcount(i);
Next
Sleep
- Output:
396 395 391 403 387 390 422 409 397 412
Gambas
Private Const MaxIDx As Integer = 2000
Private v As New Integer[MaxIDx]
Private dcount As New Integer[10]
Public Sub Main()
Dim i As Integer, c As Integer, a As Integer, col As Integer
For i = 0 To 9
dcount[i] = 0
Next
dcount[2] = 1
For i = 0 To MaxIDx - 1
v[i] = 1
Next
For col = 0 To 2 * MaxIDx
a = MaxIDx + 1
c = 0
For i = 0 To MaxIDx - 1
c += v[i] * 10
v[i] = c Mod a
c \= a
a -= 1
Next
dcount[c] += 1
Next
For i = 0 To 9
Print " "; dcount[i];
Next
End
- Output:
Same as FreeBASIC entry.
Minimal BASIC
110 LET N = 2000
120 DIM V(2000)
130 FOR I = 1 TO N
140 LET V(I) = 1
150 NEXT I
160 DIM D(10)
170 FOR I = 1 TO 10
180 LET D(I) = 0
190 NEXT I
200 LET D(3) = 1
210 FOR K = 1 TO 2*N
220 LET A = N+1
230 LET C = 0
240 FOR I = 1 TO N
250 LET C = C+V(I)*10
260 LET V(I) = C-INT(C/A)*A
270 LET C = INT(C/A)
280 LET A = A-1
290 NEXT I
300 LET D(C+1) = D(C+1)+1
310 NEXT K
320 FOR I = 1 TO 10
330 PRINT D(I);
340 NEXT I
350 PRINT
360 END
OxygenBasic
uses console
const MaxIDx as integer = 2000
dim as integer i, c, a, col
dim v(MaxIDx-1) as integer
for i = lbound(v) to ubound(v)
v(i) = 1
next
dim dcount(9) as integer = {0, 0, 1, 0, 0, 0, 0, 0, 0, 0}
for col = 0 to 2 * MaxIDx
a = MaxIDx + 1
c = 0
for i = 0 to MaxIDx-1
c += v(i) * 10
v(i) = c mod a
c \= a
a -= 1
next
dcount(c) += 1
next
for i = lbound(dcount) to ubound(dcount)
print " " dcount(i);
next
printl cr "Enter ..."
waitkey
- Output:
Same as FreeBASIC entry.
PureBasic
OpenConsole()
#N = 2000
Dim v(#N-1)
Dim dcount(9)
For i = 0 To 9
dcount(i) = 0
Next i
dcount(2) = 1
For i = 0 To #N-1
v(i) = 1
Next i
; Main calculation loop
For col = 0 To 2 * #N
a = #N + 1
c = 0
For i = 0 To #N-1
c + v(i) * 10
v(i) = c % a
c = c / a
a - 1
Next i
dcount(c) + 1
Next col
For i = 0 To 9
Print(" " + Str(dcount(i)))
Next i
PrintN(#CRLF$ + "Press ENTER to exit"): Input()
CloseConsole()
- Output:
Similar to FreeBASIC entry.
QBasic
The QB64 solution works without any changes.
QB64
Const MaxIDx = 2000
Dim i As Integer, c As Integer, a As Integer, col As Integer
Dim v(MaxIDx - 1) As Integer
For i = LBound(v) To UBound(v) - 1
v(i) = 1
Next
Dim dcount(9)
For i = 0 To 9
dcount(i) = 0
Next
dcount(2) = 1
For col = 0 To 2 * MaxIDx
a = MaxIDx + 1
c = 0
For i = 0 To MaxIDx - 1
c = c + v(i) * 10
v(i) = c Mod a
c = c \ a
a = a - 1
Next
dcount(c) = dcount(c) + 1
Next
For i = LBound(dcount) To UBound(dcount)
Print dcount(i); '" ";
Next
- Output:
Same as FreeBASIC entry.
Run BASIC
MaxIDx = 2000
dim v(MaxIDx-1)
for i = 0 To MaxIDx -1
v(i) = 1
next
dim dcount(9)
for i = 0 To 9
dcount(i) = 0
next
dcount(2) = 1
for col = 0 to 2 * MaxIDx
a = MaxIDx +1
c = 0
for i = 0 to MaxIDx -1
c = c + v(i) * 10
v(i) = c mod a
c = int(c / a)
a = a -1
next
dcount(c) = dcount(c) +1
next
for i = 0 to 9
print " "; dcount(i);
next
- Output:
Same as FreeBASIC entry.
True BASIC
OPTION BASE 0
LET maxidx = 2000
DIM v(0)
MAT REDIM v(maxidx-1)
FOR i = LBOUND(v) TO UBOUND(v)-1
LET v(i) = 1
NEXT i
DIM dcount(9)
FOR i = 0 TO 9
LET dcount(i) = 0
NEXT i
LET dcount(2) = 1
FOR col = 0 TO 2*maxidx
LET a = maxidx+1
LET c = 0
FOR i = 0 TO maxidx-1
LET c = c+v(i)*10
LET v(i) = REMAINDER(c,a)
LET c = IP(c/a)
LET a = a-1
NEXT i
LET dcount(c) = dcount(c)+1
NEXT col
FOR i = LBOUND(dcount) TO UBOUND(dcount)
PRINT dcount(i);
NEXT i
END
XBasic
PROGRAM "Count the occurrence of each digit in e"
VERSION "0.0000"
DECLARE FUNCTION Entry ()
FUNCTION Entry ()
MaxIDx = 2000
DIM v[MaxIDx-1]
FOR i = 0 TO MaxIDx-1
v[i] = 1
NEXT
DIM dcount[9]
FOR i = 0 TO 9
dcount[i] = 0
NEXT
dcount[2] = 1
FOR col = 0 TO 2 * MaxIDx
a = MaxIDx + 1
c = 0
FOR i = 0 TO MaxIDx-1
c = c + v[i] * 10
v[i] = c MOD a
c = INT(c / a)
DEC a
NEXT
INC dcount[c]
NEXT
FOR i = 0 TO 9
PRINT " "; dcount[i];
NEXT
END FUNCTION
END PROGRAM
- Output:
396 395 391 403 387 390 422 409 397 412
Yabasic
MaxIDx = 2000
dim v(MaxIDx-1)
for i = 0 to arraysize(v(), 1)
v(i) = 1
next
dim dcount(9)
for i = 0 to 9
dcount(i) = 0
next
dcount(2) = 1
for col = 0 to 2 * MaxIDx
a = MaxIDx + 1
c = 0
for i = 0 to MaxIDx-1
c = c + v(i) * 10
v(i) = mod (c, a)
c = int(c / a)
a = a - 1
next
dcount(c) = dcount(c) + 1
next
for i = 0 to 9
print " ", dcount(i);
next
print
- Output:
Same as FreeBASIC entry.
C
#include <stdio.h>
#include <stdlib.h>
void countDigitsInE(int n) {
int i, a, c, col, td = 1;
int *v = malloc(n * sizeof(int));
for (i = 0; i < n; ++i) v[i] = 1;
int dc[10] = {0};
dc[2] = 1; /* to count the non-fractional digit */
for (col = 1; col < 2 * n; ++col) {
a = n + 1;
c = 0;
for (i = 0; i < n; ++i) {
c += v[i] * 10;
v[i] = c % a;
c /= a--;
}
dc[c]++;
td++;
}
free(v);
for (i = 0; i < 10; ++i) printf("%d: %d\n", i, dc[i]);
printf("Total digits: %d\n", td);
}
int main() {
countDigitsInE(2000);
printf("\n");
countDigitsInE(3000);
return 0;
}
- Output:
Same as Wren.
C++
#include <iostream>
#include <vector>
#include <string>
int main() {
const int n = 2000;
std::vector<int> dcount(10, 0); // Initialize all to 0
dcount[2] = 1; // Set digit 2 count to 1
std::vector<int> v(n, 1);
// Main calculation loop
for (int col = 0; col <= 2 * n; col++) {
int a = n + 1;
int c = 0;
for (int i = 0; i < n; i++) {
c += v[i] * 10;
v[i] = c % a;
c = c / a;
a -= 1;
}
dcount[c]++;
}
for (int i = 0; i < dcount.size(); i++) {
std::cout << " " << dcount[i];
}
std::cout << std::endl;
return 0;
}
- Output:
Same as Dart entry.
COBOL
IDENTIFICATION DIVISION.
PROGRAM-ID. DIGITS-CALCULATION.
DATA DIVISION.
WORKING-STORAGE SECTION.
01 MAX-IDX PIC 9(4) VALUE 2000.
01 I PIC 9(4).
01 C PIC 9(8).
01 A PIC 9(4).
01 CLM PIC 9(8).
01 TMP-CALC PIC 9(8).
01 MOD-VAL PIC 9(8).
01 V-ARRAY.
02 V OCCURS 2000 TIMES PIC 9(8).
01 DCOUNT-ARRAY.
02 DCOUNT OCCURS 10 TIMES PIC 9(8).
01 OUTPUT-LINE PIC X(100).
PROCEDURE DIVISION.
MAIN-PROCEDURE.
PERFORM INITIALIZE-ARRAYS
PERFORM MAIN-CALCULATION
PERFORM DISPLAY-RESULTS
STOP RUN.
INITIALIZE-ARRAYS.
PERFORM VARYING I FROM 1 BY 1 UNTIL I > MAX-IDX
MOVE 1 TO V(I)
END-PERFORM
PERFORM VARYING I FROM 1 BY 1 UNTIL I > 10
MOVE 0 TO DCOUNT(I)
END-PERFORM
MOVE 1 TO DCOUNT(3).
MAIN-CALCULATION.
PERFORM VARYING CLM FROM 0 BY 1
UNTIL CLM > FUNCTION NUMVAL(MAX-IDX) * 2
COMPUTE A = MAX-IDX + 1
MOVE 0 TO C
PERFORM VARYING I FROM 1 BY 1 UNTIL I > MAX-IDX
COMPUTE C = C + (V(I) * 10)
DIVIDE C BY A GIVING TMP-CALC REMAINDER MOD-VAL
MOVE MOD-VAL TO V(I)
MOVE TMP-CALC TO C
COMPUTE A = A - 1
END-PERFORM
ADD 1 TO DCOUNT(C + 1)
END-PERFORM.
DISPLAY-RESULTS.
MOVE SPACES TO OUTPUT-LINE
PERFORM VARYING I FROM 1 BY 1 UNTIL I > 10
MOVE DCOUNT(I) TO TMP-CALC
DISPLAY TMP-CALC WITH NO ADVANCING
DISPLAY " " WITH NO ADVANCING
END-PERFORM
STOP RUN.
- Output:
00000396 00000395 00000391 00000403 00000387 00000390 00000422 00000409 00000397 00000412
Dart
void main() {
const int n = 2000;
List<int> dcount = [0, 0, 1, 0, 0, 0, 0, 0, 0, 0];
List<int> v = List<int>.filled(n, 1);
// Main calculation loop
for (int col = 0; col <= 2 * n; col++) {
int a = n + 1;
int c = 0;
for (int i = 0; i < n; i++) {
c += v[i] * 10;
v[i] = c % a;
c = c ~/ a;
a -= 1;
}
dcount[c]++;
}
print(dcount.join(' '));
}
- Output:
396 395 391 403 387 390 422 409 397 412
EasyLang
n = 2000
len dcount[] 10
arrbase dcount[] 0
dcount[2] = 1
for i to n : v[] &= 1
for col = 0 to 2 * n
a = n + 1
c = 0
for i to n
c += v[i] * 10
v[i] = c mod a
c = c div a
a -= 1
.
dcount[c] += 1
.
print dcount[]
- Output:
[ 396 395 391 403 387 390 422 409 397 412 ]
Java
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.stream.IntStream;
public final class CountTheOccurrencesOfEachDigitInE {
public static void main(String[] args) {
// Counting the occurrences of the first 4,000 digits of Euler's number e.
// That is, the initial digit '2' before the decimal point and the first 3,999 digits after the decimal point.
final int maxIndex = 2_000;
List<Integer> values = new ArrayList<Integer>(Collections.nCopies(maxIndex, 1));
List<Integer> digitCounts = new ArrayList<Integer>(List.of( 0, 0, 1, 0, 0, 0, 0, 0, 0, 0 ));
IntStream.range(0, 2 * maxIndex - 1).forEach( _ -> {
int a = maxIndex + 1;
int c = 0;
for ( int i = 0; i < maxIndex; i++ ) {
c += values.get(i) * 10;
values.set(i, c % a);
c /= a;
a -= 1;
}
digitCounts.set(c, digitCounts.get(c) + 1);
} );
System.out.println("The counts for the digits 0, 1, 2, ... , 9 are:");
System.out.println(digitCounts + System.lineSeparator());
System.out.print("The number of digits counted is " + digitCounts.stream().mapToInt(Integer::intValue).sum());
}
}
- Output:
The counts for the digits 0, 1, 2, ... , 9 are: [396, 395, 390, 403, 387, 390, 422, 408, 397, 412] The number of digits counted is 4000
Julia
Nearly copy&paste of Algol version
const MaxIDx = 2000
v = ones(Int, MaxIDx) # Initialize array v with all 1s
dcount = [0, 0, 1, 0, 0, 0, 0, 0, 0, 0]
# Main calculation
for col = 0:(2 * MaxIDx)
a = MaxIDx + 1
c = 0
for i = 1:MaxIDx
c += v[i] * 10
v[i] = c % a # Modulo operation
c = div(c, a) # Integer division
a -= 1
end
dcount[c + 1] += 1 # Julia arrays are 1-indexed
end
println(join(dcount, " "))
- Output:
396 395 391 403 387 390 422 409 397 412
Pascal
Free Pascal
Nearly copy&paste of Algol version
//calculate the decimal digits of e and count how many times each #
//digit occurs - based on the B code on the Wikipedia page: #
//https://en.wikipedia.org/wiki/B_(programming_language) #
program DigitCntOfE;
uses
sysutils;
const
MaxIDx = 2000;
base = 10;
var
dcount : array[0..Base-1] of integer = ( 0, 0, 1, 0, 0, 0, 0, 0, 0, 0 );
v : array[0..MaxIdx-1] of integer;
n : integer = MaxIdx;
i,col,
c, a : Integer;
BEGIN
//# this counts the digits in the fractional part of e so the initial #
// # count for 2 is 1, to include the non-fractional digit #
FOR i := Low(v) to High(v) do
v[i] := 1;
FOR col := 0 to 2*n do
Begin
a := n+1;
c := 0;
FOR i := Low(v) to High(v) do
Begin
c += v[i]*10;
v[i] := c MOD a;
c := c DIV a;
a -= 1
end;
dcount[ c ] += 1
end;
For i := low(dcount) to High(dCount) do
write(dcount[i]:5);
writeln;
END.
- Output:
396 395 391 403 387 390 422 409 397 412
Python
#!/usr/bin/python3
# calculate the decimal digits of e and count how many times each
# digit occurs - based On the B code On the Wikipedia page:
# https://en.wikipedia.org/wiki/B_(programming_language)
dcount = [0, 0, 1, 0, 0, 0, 0, 0, 0, 0]
MaxIDx = 2000
v = [1] * MaxIDx
for col in range(2 * MaxIDx + 1):
a = MaxIDx + 1
c = 0
for i in range(MaxIDx):
c += v[i] * 10
v[i] = c % a
c //= a
a -= 1
dcount[c] += 1
output = ' '.join(str(count) for count in dcount)
print(output)
- Output:
396 395 391 403 387 390 422 409 397 412
Raku
constant 𝑒 = [\+] flat 1, [\/] 1.FatRat..*;
sub e-count ($n) {
my @digits = 𝑒[$n / 2.7].substr(0,$n+1).comb.classify(*).sort.skip(1).map: {.key => .value.elems};
.say for @digits;
say 'Total digits: ', @digits».value.sum;
say '';
}
.&e-count for 4000, 6000;
- Output:
0 => 396 1 => 395 2 => 390 3 => 403 4 => 387 5 => 390 6 => 422 7 => 408 8 => 397 9 => 412 Total digits: 4000 0 => 602 1 => 592 2 => 604 3 => 625 4 => 559 5 => 586 6 => 644 7 => 600 8 => 597 9 => 591 Total digits: 6000
Verilog
module main;
parameter MaxIDx = 2000;
reg [31:0] v [0:MaxIDx-1];
reg [31:0] dcount [0:9];
integer i, c, a, col;
integer outfile;
initial begin
for(i = 0; i <= 9; i = i + 1) begin
dcount[i] = 0;
end
dcount[2] = 1;
for(i = 0; i < MaxIDx; i = i + 1) begin
v[i] = 1;
end
for(col = 0; col <= 2 * MaxIDx; col = col + 1) begin
a = MaxIDx + 1;
c = 0;
for(i = 0; i < MaxIDx; i = i + 1) begin
c = c + v[i] * 10;
v[i] = c % a;
c = c / a;
a = a - 1;
end
dcount[c] = dcount[c] + 1;
end
outfile = $fopen("digits_result.txt", "w");
for(i = 0; i <= 9; i = i + 1) begin
$fwrite(outfile, "%0d ", dcount[i]);
$display("%0d ", dcount[i]);
end
$fclose(outfile);
$finish;
end
endmodule
- Output:
396 395 391 403 387 390 422 409 397 412
Wren
This is based on the B code in its Wikipedia article.
var countDigitsInE = Fn.new { |n|
var v = List.filled(n, 1)
var dc = List.filled(10, 0)
dc[2] = 1 // to count the non-fractional digit
for (col in 1...2 * n) {
var a = n + 1
var c = 0
for (i in 0...n) {
c = c + v[i] * 10
v[i] = c % a
c = (c/a).floor
a = a - 1
}
dc[c] = dc[c] + 1
}
for (d in 0..9) System.print("%(d): %(dc[d])")
var t = dc.reduce { |acc, d| acc + d }
System.print("Total digits: %(t)")
}
countDigitsInE.call(2000)
System.print()
countDigitsInE.call(3000)
- Output:
0: 396 1: 395 2: 390 3: 403 4: 387 5: 390 6: 422 7: 408 8: 397 9: 412 Total digits: 4000 0: 602 1: 592 2: 604 3: 625 4: 559 5: 586 6: 644 7: 600 8: 597 9: 591 Total digits: 6000
XPL0
def N = 2000;
int Ans(10), V(N);
int I, C, Col, A, Sum;
[for I:= 0 to 9 do Ans(I):= 0;
Ans(2):= 1;
I:= 0; Col:= 0;
while I < N do
[V(I):= 1; I:= I+1];
while Col < 2*N do
[A:= N+1;
C:= 0; I:= 0;
while I < N do
[C:= C + V(I)*10;
V(I):= rem(C/A); I:= I+1;
C:= C/A; A:= A-1;
];
Ans(C):= Ans(C)+1;
Col:= Col+1;
];
for I:= 0 to 9 do
[IntOut(0, Ans(I)); ChOut(0, ^ )];
Crlf(0);
Sum:= 0;
for I:= 0 to 9 do
Sum:= Sum + Ans(I);
IntOut(0, Sum);
Crlf(0);
]
- Output:
396 395 390 403 387 390 422 409 397 412 4001