Update all new Tasks
This commit is contained in:
parent
00a190b0a6
commit
91df62d461
5697 changed files with 93386 additions and 804 deletions
18
Task/Benfords-law/00DESCRIPTION
Normal file
18
Task/Benfords-law/00DESCRIPTION
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
{{Wikipedia|Benford's_law}}
|
||||
'''Benford's law''', also called the '''first-digit law''', refers to the frequency distribution of digits in many (but not all) real-life sources of data. In this distribution, the number 1 occurs as the first digit about 30% of the time, while larger numbers occur in that position less frequently: 9 as the first digit less than 5% of the time. This distribution of first digits is the same as the widths of gridlines on a logarithmic scale. Benford's law also concerns the expected distribution for digits beyond the first, which approach a uniform distribution.
|
||||
|
||||
This result has been found to apply to a wide variety of data sets, including electricity bills, street addresses, stock prices, population numbers, death rates, lengths of rivers, physical and mathematical constants, and processes described by power laws (which are very common in nature). It tends to be most accurate when values are distributed across multiple orders of magnitude.
|
||||
|
||||
A set of numbers is said to satisfy Benford's law if the leading digit <math>d</math> (<math>d \in \{1, \ldots, 9\}</math>) occurs with probability
|
||||
|
||||
:<math>P(d) = \log_{10}(d+1)-\log_{10}(d) = \log_{10}\left(1+\frac{1}{d}\right)</math>
|
||||
|
||||
For this task, write (a) routine(s) to calculate the distribution of first significant (non-zero) digits in a collection of numbers, then display the actual vs. expected distribution in the way most convenient for your language (table / graph / histogram / whatever).
|
||||
|
||||
Use the first 1000 numbers from the Fibonacci sequence as your data set. No need to show how the Fibonacci numbers are obtained. You can [[Fibonacci sequence|generate]] them or load them [http://www.ibiblio.org/pub/docs/books/gutenberg/etext01/fbncc10.txt from a file]; whichever is easiest. Display your actual vs expected distribution.
|
||||
|
||||
''For extra credit:'' Show the distribution for one other set of numbers from a page on Wikipedia. State which Wikipedia page it can be obtained from and what the set enumerates. Again, no need to display the actual list of numbers or the code to load them.
|
||||
|
||||
;<nowiki>See also:</nowiki>
|
||||
* [http://www.numberphile.com/videos/benfords_law.html numberphile.com].
|
||||
* A starting page on Wolfram Mathworld is {{Wolfram|Benfords|Law}}.
|
||||
27
Task/Benfords-law/AWK/benfords-law.awk
Normal file
27
Task/Benfords-law/AWK/benfords-law.awk
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
# syntax: GAWK -f BENFORDS_LAW.AWK
|
||||
BEGIN {
|
||||
n = 1000
|
||||
for (i=1; i<=n; i++) {
|
||||
arr[substr(fibonacci(i),1,1)]++
|
||||
}
|
||||
print("digit expected observed deviation")
|
||||
for (i=1; i<=9; i++) {
|
||||
expected = log10(i+1) - log10(i)
|
||||
actual = arr[i] / n
|
||||
deviation = expected - actual
|
||||
printf("%5d %8.4f %8.4f %9.4f\n",i,expected*100,actual*100,abs(deviation*100))
|
||||
}
|
||||
exit(0)
|
||||
}
|
||||
function fibonacci(n, a,b,c,i) {
|
||||
a = 0
|
||||
b = 1
|
||||
for (i=1; i<=n; i++) {
|
||||
c = a + b
|
||||
a = b
|
||||
b = c
|
||||
}
|
||||
return(c)
|
||||
}
|
||||
function abs(x) { if (x >= 0) { return x } else { return -x } }
|
||||
function log10(x) { return log(x)/log(10) }
|
||||
49
Task/Benfords-law/Ada/benfords-law-1.ada
Normal file
49
Task/Benfords-law/Ada/benfords-law-1.ada
Normal file
|
|
@ -0,0 +1,49 @@
|
|||
with Ada.Text_IO, Ada.Numerics.Generic_Elementary_Functions;
|
||||
|
||||
procedure Benford is
|
||||
|
||||
subtype Nonzero_Digit is Natural range 1 .. 9;
|
||||
function First_Digit(S: String) return Nonzero_Digit is
|
||||
(if S(S'First) in '1' .. '9'
|
||||
then Nonzero_Digit'Value(S(S'First .. S'First))
|
||||
else First_Digit(S(S'First+1 .. S'Last)));
|
||||
|
||||
package N_IO is new Ada.Text_IO.Integer_IO(Natural);
|
||||
|
||||
procedure Print(D: Nonzero_Digit; Counted, Sum: Natural) is
|
||||
package Math is new Ada.Numerics.Generic_Elementary_Functions(Float);
|
||||
package F_IO is new Ada.Text_IO.Float_IO(Float);
|
||||
Actual: constant Float := Float(Counted) / Float(Sum);
|
||||
Expected: constant Float := Math.Log(1.0 + 1.0 / Float(D), Base => 10.0);
|
||||
Deviation: constant Float := abs(Expected-Actual);
|
||||
begin
|
||||
N_IO.Put(D, 5);
|
||||
N_IO.Put(Counted, 14);
|
||||
F_IO.Put(Float(Sum)*Expected, Fore => 16, Aft => 1, Exp => 0);
|
||||
F_IO.Put(100.0*Actual, Fore => 9, Aft => 2, Exp => 0);
|
||||
F_IO.Put(100.0*Expected, Fore => 11, Aft => 2, Exp => 0);
|
||||
F_IO.Put(100.0*Deviation, Fore => 13, Aft => 2, Exp => 0);
|
||||
end Print;
|
||||
|
||||
Cnt: array(Nonzero_Digit) of Natural := (1 .. 9 => 0);
|
||||
D: Nonzero_Digit;
|
||||
Sum: Natural := 0;
|
||||
Counter: Positive;
|
||||
|
||||
begin
|
||||
while not Ada.Text_IO.End_Of_File loop
|
||||
-- each line in the input file holds Counter, followed by Fib(Counter)
|
||||
N_IO.Get(Counter);
|
||||
-- Counter and skip it, we just don't need it
|
||||
D := First_Digit(Ada.Text_IO.Get_Line);
|
||||
-- read the rest of the line and extract the first digit
|
||||
Cnt(D) := Cnt(D)+1;
|
||||
Sum := Sum + 1;
|
||||
end loop;
|
||||
Ada.Text_IO.Put_Line(" Digit Found[total] Expected[total] Found[%]"
|
||||
& " Expected[%] Difference[%]");
|
||||
for I in Nonzero_Digit loop
|
||||
Print(I, Cnt(I), Sum);
|
||||
Ada.Text_IO.New_Line;
|
||||
end loop;
|
||||
end Benford;
|
||||
1
Task/Benfords-law/Ada/benfords-law-2.ada
Normal file
1
Task/Benfords-law/Ada/benfords-law-2.ada
Normal file
|
|
@ -0,0 +1 @@
|
|||
-- N_IO.Get(Counter);
|
||||
95
Task/Benfords-law/Aime/benfords-law.aime
Normal file
95
Task/Benfords-law/Aime/benfords-law.aime
Normal file
|
|
@ -0,0 +1,95 @@
|
|||
text
|
||||
sum(text a, text b)
|
||||
{
|
||||
data d;
|
||||
integer e, f, n, r;
|
||||
|
||||
e = length(a);
|
||||
f = length(b);
|
||||
|
||||
r = 0;
|
||||
|
||||
n = min(e, f);
|
||||
while (n) {
|
||||
n -= 1;
|
||||
e -= 1;
|
||||
f -= 1;
|
||||
r += a[e] - '0';
|
||||
r += b[f] - '0';
|
||||
b_insert(d, 0, r % 10 + '0');
|
||||
r /= 10;
|
||||
}
|
||||
|
||||
if (f) {
|
||||
e = f;
|
||||
a = b;
|
||||
}
|
||||
|
||||
while (e) {
|
||||
e -= 1;
|
||||
r += a[e] - '0';
|
||||
b_insert(d, 0, r % 10 + '0');
|
||||
r /= 10;
|
||||
}
|
||||
|
||||
if (r) {
|
||||
b_insert(d, 0, r + '0');
|
||||
}
|
||||
|
||||
return b_string(d);
|
||||
}
|
||||
|
||||
text
|
||||
fibs(list l, integer n)
|
||||
{
|
||||
integer c, i;
|
||||
text a, b, w;
|
||||
|
||||
l_r_integer(l, 1, 1);
|
||||
|
||||
a = "0";
|
||||
b = "1";
|
||||
i = 1;
|
||||
while (i < n) {
|
||||
w = sum(a, b);
|
||||
a = b;
|
||||
b = w;
|
||||
c = w[0] - '0';
|
||||
l_r_integer(l, c, 1 + l_q_integer(l, c));
|
||||
i += 1;
|
||||
}
|
||||
|
||||
return w;
|
||||
}
|
||||
|
||||
integer
|
||||
main(void)
|
||||
{
|
||||
integer i, n;
|
||||
list f;
|
||||
real m;
|
||||
|
||||
n = 1000;
|
||||
|
||||
i = 10;
|
||||
while (i) {
|
||||
i -= 1;
|
||||
lb_p_integer(f, 0);
|
||||
}
|
||||
|
||||
fibs(f, n);
|
||||
|
||||
m = 100r / n;
|
||||
|
||||
o_text("\t\texpected\t found\n");
|
||||
i = 0;
|
||||
while (i < 9) {
|
||||
i += 1;
|
||||
o_winteger(8, i);
|
||||
o_wpreal(16, 3, 3, 100 * log10(1 + 1r / i));
|
||||
o_wpreal(16, 3, 3, l_q_integer(f, i) * m);
|
||||
o_text("\n");
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
43
Task/Benfords-law/AutoHotkey/benfords-law.ahk
Normal file
43
Task/Benfords-law/AutoHotkey/benfords-law.ahk
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
SetBatchLines, -1
|
||||
fib := NStepSequence(1, 1, 2, 1000)
|
||||
Out := "Digit`tExpected`tObserved`tDeviation`n"
|
||||
n := []
|
||||
for k, v in fib
|
||||
d := SubStr(v, 1, 1)
|
||||
, n[d] := n[d] ? n[d] + 1 : 1
|
||||
for k, v in n
|
||||
Exppected := 100 * Log(1+ (1 / k))
|
||||
, Observed := (v / fib.MaxIndex()) * 100
|
||||
, Out .= k "`t" Exppected "`t" Observed "`t" Abs(Exppected - Observed) "`n"
|
||||
MsgBox, % Out
|
||||
|
||||
NStepSequence(v1, v2, n, k) {
|
||||
a := [v1, v2]
|
||||
Loop, % k - 2 {
|
||||
a[j := A_Index + 2] := 0
|
||||
Loop, % j < n + 2 ? j - 1 : n
|
||||
a[j] := BigAdd(a[j - A_Index], a[j])
|
||||
}
|
||||
return, a
|
||||
}
|
||||
|
||||
BigAdd(a, b) {
|
||||
if (StrLen(b) > StrLen(a))
|
||||
t := a, a := b, b := t
|
||||
LenA := StrLen(a) + 1, LenB := StrLen(B) + 1, Carry := 0
|
||||
Loop, % LenB - 1
|
||||
Sum := SubStr(a, LenA - A_Index, 1) + SubStr(B, LenB - A_Index, 1) + Carry
|
||||
, Carry := Sum // 10
|
||||
, Result := Mod(Sum, 10) . Result
|
||||
Loop, % I := LenA - LenB {
|
||||
if (!Carry) {
|
||||
Result := SubStr(a, 1, I) . Result
|
||||
break
|
||||
}
|
||||
Sum := SubStr(a, I, 1) + Carry
|
||||
, Carry := Sum // 10
|
||||
, Result := Mod(Sum, 10) . Result
|
||||
, I--
|
||||
}
|
||||
return, (Carry ? Carry : "") . Result
|
||||
}
|
||||
62
Task/Benfords-law/C++/benfords-law.cpp
Normal file
62
Task/Benfords-law/C++/benfords-law.cpp
Normal file
|
|
@ -0,0 +1,62 @@
|
|||
//to cope with the big numbers , I used the Class Library for Numbers( CLN )
|
||||
//if used prepackaged you can compile writing "g++ -std=c++11 -lcln yourprogram.cpp -o yourprogram"
|
||||
#include <cln/integer.h>
|
||||
#include <cln/integer_io.h>
|
||||
#include <iostream>
|
||||
#include <algorithm>
|
||||
#include <vector>
|
||||
#include <iomanip>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <cstdlib>
|
||||
#include <cmath>
|
||||
#include <map>
|
||||
using namespace cln ;
|
||||
|
||||
class NextNum {
|
||||
public :
|
||||
NextNum ( cl_I & a , cl_I & b ) : first( a ) , second ( b ) { }
|
||||
cl_I operator( )( ) {
|
||||
cl_I result = first + second ;
|
||||
first = second ;
|
||||
second = result ;
|
||||
return result ;
|
||||
}
|
||||
private :
|
||||
cl_I first ;
|
||||
cl_I second ;
|
||||
} ;
|
||||
|
||||
void findFrequencies( const std::vector<cl_I> & fibos , std::map<int , int> &numberfrequencies ) {
|
||||
for ( cl_I bignumber : fibos ) {
|
||||
std::ostringstream os ;
|
||||
fprintdecimal ( os , bignumber ) ;//from header file cln/integer_io.h
|
||||
int firstdigit = std::atoi( os.str( ).substr( 0 , 1 ).c_str( )) ;
|
||||
auto result = numberfrequencies.insert( std::make_pair( firstdigit , 1 ) ) ;
|
||||
if ( ! result.second )
|
||||
numberfrequencies[ firstdigit ]++ ;
|
||||
}
|
||||
}
|
||||
|
||||
int main( ) {
|
||||
std::vector<cl_I> fibonaccis( 1000 ) ;
|
||||
fibonaccis[ 0 ] = 0 ;
|
||||
fibonaccis[ 1 ] = 1 ;
|
||||
cl_I a = 0 ;
|
||||
cl_I b = 1 ;
|
||||
//since a and b are passed as references to the generator's constructor
|
||||
//they are constantly changed !
|
||||
std::generate_n( fibonaccis.begin( ) + 2 , 998 , NextNum( a , b ) ) ;
|
||||
std::cout << std::endl ;
|
||||
std::map<int , int> frequencies ;
|
||||
findFrequencies( fibonaccis , frequencies ) ;
|
||||
std::cout << " found expected\n" ;
|
||||
for ( int i = 1 ; i < 10 ; i++ ) {
|
||||
double found = static_cast<double>( frequencies[ i ] ) / 1000 ;
|
||||
double expected = std::log10( 1 + 1 / static_cast<double>( i )) ;
|
||||
std::cout << i << " :" << std::setw( 16 ) << std::right << found * 100 << " %" ;
|
||||
std::cout.precision( 3 ) ;
|
||||
std::cout << std::setw( 26 ) << std::right << expected * 100 << " %\n" ;
|
||||
}
|
||||
return 0 ;
|
||||
}
|
||||
64
Task/Benfords-law/C/benfords-law.c
Normal file
64
Task/Benfords-law/C/benfords-law.c
Normal file
|
|
@ -0,0 +1,64 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <math.h>
|
||||
|
||||
float *benford_distribution(void)
|
||||
{
|
||||
static float prob[9];
|
||||
for (int i = 1; i < 10; i++)
|
||||
prob[i - 1] = log10f(1 + 1.0 / i);
|
||||
|
||||
return prob;
|
||||
}
|
||||
|
||||
float *get_actual_distribution(char *fn)
|
||||
{
|
||||
FILE *input = fopen(fn, "r");
|
||||
if (!input)
|
||||
{
|
||||
perror("Can't open file");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
int tally[9] = { 0 };
|
||||
char c;
|
||||
int total = 0;
|
||||
while ((c = getc(input)) != EOF)
|
||||
{
|
||||
/* get the first nonzero digit on the current line */
|
||||
while (c < '1' || c > '9')
|
||||
c = getc(input);
|
||||
|
||||
tally[c - '1']++;
|
||||
total++;
|
||||
|
||||
/* discard rest of line */
|
||||
while ((c = getc(input)) != '\n' && c != EOF)
|
||||
;
|
||||
}
|
||||
fclose(input);
|
||||
|
||||
static float freq[9];
|
||||
for (int i = 0; i < 9; i++)
|
||||
freq[i] = tally[i] / (float) total;
|
||||
|
||||
return freq;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
if (argc != 2)
|
||||
{
|
||||
printf("Usage: benford <file>\n");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
float *actual = get_actual_distribution(argv[1]);
|
||||
float *expected = benford_distribution();
|
||||
|
||||
puts("digit\tactual\texpected");
|
||||
for (int i = 0; i < 9; i++)
|
||||
printf("%d\t%.3f\t%.3f\n", i + 1, actual[i], expected[i]);
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
21
Task/Benfords-law/CoffeeScript/benfords-law.coffee
Normal file
21
Task/Benfords-law/CoffeeScript/benfords-law.coffee
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
fibgen = () ->
|
||||
a = 1; b = 0
|
||||
return () ->
|
||||
([a, b] = [b, a+b])[1]
|
||||
|
||||
leading = (x) -> x.toString().charCodeAt(0) - 0x30
|
||||
|
||||
f = fibgen()
|
||||
|
||||
benford = (0 for i in [1..9])
|
||||
benford[leading(f()) - 1] += 1 for i in [1..1000]
|
||||
|
||||
log10 = (x) -> Math.log(x) * Math.LOG10E
|
||||
|
||||
actual = benford.map (x) -> x * 0.001
|
||||
expected = (log10(1 + 1/x) for x in [1..9])
|
||||
|
||||
console.log "Leading digital distribution of the first 1,000 Fibonacci numbers"
|
||||
console.log "Digit\tActual\tExpected"
|
||||
for i in [1..9]
|
||||
console.log i + "\t" + actual[i - 1].toFixed(3) + '\t' + expected[i - 1].toFixed(3)
|
||||
43
Task/Benfords-law/Common-Lisp/benfords-law.lisp
Normal file
43
Task/Benfords-law/Common-Lisp/benfords-law.lisp
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
(defun calculate-distribution (numbers)
|
||||
"Return the frequency distribution of the most significant nonzero
|
||||
digits in the given list of numbers. The first element of the list
|
||||
is the frequency for digit 1, the second for digit 2, and so on."
|
||||
|
||||
(defun nonzero-digit-p (c)
|
||||
"Check whether the character is a nonzero digit"
|
||||
(and (digit-char-p c) (char/= c #\0)))
|
||||
|
||||
(defun first-digit (n)
|
||||
"Return the most significant nonzero digit of the number or NIL if
|
||||
there is none."
|
||||
(let* ((s (write-to-string n))
|
||||
(c (find-if #'nonzero-digit-p s)))
|
||||
(when c
|
||||
(digit-char-p c))))
|
||||
|
||||
(let ((tally (make-array 9 :element-type 'integer :initial-element 0)))
|
||||
(loop for n in numbers
|
||||
for digit = (first-digit n)
|
||||
when digit
|
||||
do (incf (aref tally (1- digit))))
|
||||
(loop with total = (length numbers)
|
||||
for digit-count across tally
|
||||
collect (/ digit-count total))))
|
||||
|
||||
(defun calculate-benford-distribution ()
|
||||
"Return the frequency distribution according to Benford's law.
|
||||
The first element of the list is the probability for digit 1, the second
|
||||
element the probability for digit 2, and so on."
|
||||
(loop for i from 1 to 9
|
||||
collect (log (1+ (/ i)) 10)))
|
||||
|
||||
(defun benford (numbers)
|
||||
"Print a table of the actual and expected distributions for the given
|
||||
list of numbers."
|
||||
(let ((actual-distribution (calculate-distribution numbers))
|
||||
(expected-distribution (calculate-benford-distribution)))
|
||||
(write-line "digit actual expected")
|
||||
(format T "~:{~3D~9,3F~8,3F~%~}"
|
||||
(map 'list #'list '(1 2 3 4 5 6 7 8 9)
|
||||
actual-distribution
|
||||
expected-distribution))))
|
||||
24
Task/Benfords-law/D/benfords-law-1.d
Normal file
24
Task/Benfords-law/D/benfords-law-1.d
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
import std.stdio, std.range, std.math, std.conv, std.bigint;
|
||||
|
||||
double[2][9] benford(R)(R seq) if (isForwardRange!R && !isInfinite!R) {
|
||||
typeof(return) freqs = 0;
|
||||
uint seqLen = 0;
|
||||
foreach (d; seq)
|
||||
if (d != 0) {
|
||||
freqs[d.text[0] - '1'][1]++;
|
||||
seqLen++;
|
||||
}
|
||||
|
||||
foreach (immutable i, ref p; freqs)
|
||||
p = [log10(1.0 + 1.0 / (i + 1)), p[1] / seqLen];
|
||||
return freqs;
|
||||
}
|
||||
|
||||
void main() {
|
||||
auto fibs = recurrence!q{a[n - 1] + a[n - 2]}(1.BigInt, 1.BigInt);
|
||||
|
||||
writefln("%9s %9s %9s", "Actual", "Expected", "Deviation");
|
||||
foreach (immutable i, immutable p; fibs.take(1000).benford)
|
||||
writefln("%d: %5.2f%% | %5.2f%% | %5.4f%%",
|
||||
i+1, p[1] * 100, p[0] * 100, abs(p[1] - p[0]) * 100);
|
||||
}
|
||||
18
Task/Benfords-law/D/benfords-law-2.d
Normal file
18
Task/Benfords-law/D/benfords-law-2.d
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
import std.stdio, std.range, std.math, std.conv, std.bigint,
|
||||
std.algorithm, std.array;
|
||||
|
||||
auto benford(R)(R seq) if (isForwardRange!R && !isInfinite!R) {
|
||||
return seq.filter!q{a != 0}.map!q{a.text[0]-'1'}.array.sort().group;
|
||||
}
|
||||
|
||||
void main() {
|
||||
auto fibs = recurrence!q{a[n - 1] + a[n - 2]}(1.BigInt, 1.BigInt);
|
||||
auto expected = iota(1, 10).map!(d => log10(1.0 + 1.0 / d));
|
||||
|
||||
enum N = 1_000;
|
||||
writefln("%9s %9s %9s", "Actual", "Expected", "Deviation");
|
||||
foreach (immutable i, immutable f; fibs.take(N).benford)
|
||||
writefln("%d: %5.2f%% | %5.2f%% | %5.4f%%", i + 1,
|
||||
f * 100.0 / N, expected[i] * 100,
|
||||
abs((f / double(N)) - expected[i]) * 100);
|
||||
}
|
||||
25
Task/Benfords-law/Erlang/benfords-law.erl
Normal file
25
Task/Benfords-law/Erlang/benfords-law.erl
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
-module( benfords_law ).
|
||||
-export( [actual_distribution/1, distribution/1, task/0] ).
|
||||
|
||||
actual_distribution( Ns ) -> lists:foldl( fun first_digit_count/2, dict:new(), Ns ).
|
||||
|
||||
distribution( N ) -> math:log10( 1 + (1 / N) ).
|
||||
|
||||
task() ->
|
||||
Total = 1000,
|
||||
Fibonaccis = fib( Total ),
|
||||
Actual_dict = actual_distribution( Fibonaccis ),
|
||||
Keys = lists:sort( dict:fetch_keys( Actual_dict) ),
|
||||
io:fwrite( "Digit Actual Benfords expected~n" ),
|
||||
[io:fwrite("~p ~p ~p~n", [X, dict:fetch(X, Actual_dict) / Total, distribution(X)]) || X <- Keys].
|
||||
|
||||
|
||||
|
||||
fib( N ) -> fib( N, 0, 1, [] ).
|
||||
fib( 0, Current, _, Acc ) -> lists:reverse( [Current | Acc] );
|
||||
fib( N, Current, Next, Acc ) -> fib( N-1, Next, Current+Next, [Current | Acc] ).
|
||||
|
||||
first_digit_count( 0, Dict ) -> Dict;
|
||||
first_digit_count( N, Dict ) ->
|
||||
[Key | _] = erlang:integer_to_list( N ),
|
||||
dict:update_counter( Key - 48, 1, Dict ).
|
||||
44
Task/Benfords-law/Forth/benfords-law.fth
Normal file
44
Task/Benfords-law/Forth/benfords-law.fth
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
: 3drop drop 2drop ;
|
||||
: f2drop fdrop fdrop ;
|
||||
|
||||
: int-array create cells allot does> swap cells + ;
|
||||
|
||||
: 1st-fib 0e 1e ;
|
||||
: next-fib ftuck f+ ;
|
||||
|
||||
: 1st-digit ( fp -- n )
|
||||
pad 6 represent 3drop pad c@ [char] 0 - ;
|
||||
|
||||
10 int-array counts
|
||||
|
||||
: tally
|
||||
0 counts 10 cells erase
|
||||
1st-fib
|
||||
1000 0 DO
|
||||
1 fdup 1st-digit counts +!
|
||||
next-fib
|
||||
LOOP f2drop ;
|
||||
|
||||
: benford ( d -- fp )
|
||||
s>f 1/f 1e f+ flog ;
|
||||
|
||||
: tab 9 emit ;
|
||||
|
||||
: heading ( -- )
|
||||
cr ." Leading digital distribution of the first 1,000 Fibonacci numbers:"
|
||||
cr ." Digit" tab ." Actual" tab ." Expected" ;
|
||||
|
||||
: .fixed ( n -- ) \ print count as decimal fraction
|
||||
s>d <# # # # [char] . hold #s #> type space ;
|
||||
|
||||
: report ( -- )
|
||||
precision 3 set-precision
|
||||
heading
|
||||
10 1 DO
|
||||
cr i 3 .r
|
||||
tab i counts @ .fixed
|
||||
tab i benford f.
|
||||
LOOP
|
||||
set-precision ;
|
||||
|
||||
: compute-benford tally report ;
|
||||
9
Task/Benfords-law/Fortran/benfords-law-1.f
Normal file
9
Task/Benfords-law/Fortran/benfords-law-1.f
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
-*- mode: compilation; default-directory: "/tmp/" -*-
|
||||
Compilation started at Sat May 18 01:13:00
|
||||
|
||||
a=./f && make $a && $a
|
||||
f95 -Wall -ffree-form f.F -o f
|
||||
0.301030010 0.176091254 0.124938756 9.69100147E-02 7.91812614E-02 6.69467747E-02 5.79919666E-02 5.11525236E-02 4.57575098E-02 THE LAW
|
||||
0.300999999 0.177000001 0.125000000 9.60000008E-02 7.99999982E-02 6.70000017E-02 5.70000000E-02 5.29999994E-02 4.50000018E-02 LEADING FIBONACCI DIGIT
|
||||
|
||||
Compilation finished at Sat May 18 01:13:00
|
||||
69
Task/Benfords-law/Fortran/benfords-law-2.f
Normal file
69
Task/Benfords-law/Fortran/benfords-law-2.f
Normal file
|
|
@ -0,0 +1,69 @@
|
|||
subroutine fibber(a,b,c,d)
|
||||
! compute most significant digits, Fibonacci like.
|
||||
implicit none
|
||||
integer (kind=8), intent(in) :: a,b
|
||||
integer (kind=8), intent(out) :: c,d
|
||||
d = a + b
|
||||
if (15 .lt. log10(float(d))) then
|
||||
c = b/10
|
||||
d = d/10
|
||||
else
|
||||
c = b
|
||||
endif
|
||||
end subroutine fibber
|
||||
|
||||
integer function leadingDigit(a)
|
||||
implicit none
|
||||
integer (kind=8), intent(in) :: a
|
||||
integer (kind=8) :: b
|
||||
b = a
|
||||
do while (9 .lt. b)
|
||||
b = b/10
|
||||
end do
|
||||
leadingDigit = transfer(b,leadingDigit)
|
||||
end function leadingDigit
|
||||
|
||||
real function benfordsLaw(a)
|
||||
implicit none
|
||||
integer, intent(in) :: a
|
||||
benfordsLaw = log10(1.0 + 1.0 / a)
|
||||
end function benfordsLaw
|
||||
|
||||
program benford
|
||||
|
||||
implicit none
|
||||
|
||||
interface
|
||||
|
||||
subroutine fibber(a,b,c,d)
|
||||
implicit none
|
||||
integer (kind=8), intent(in) :: a,b
|
||||
integer (kind=8), intent(out) :: c,d
|
||||
end subroutine fibber
|
||||
|
||||
integer function leadingDigit(a)
|
||||
implicit none
|
||||
integer (kind=8), intent(in) :: a
|
||||
end function leadingDigit
|
||||
|
||||
real function benfordsLaw(a)
|
||||
implicit none
|
||||
integer, intent(in) :: a
|
||||
end function benfordsLaw
|
||||
|
||||
end interface
|
||||
|
||||
integer (kind=8) :: a, b, c, d
|
||||
integer :: i, count(10)
|
||||
data count/10*0/
|
||||
a = 1
|
||||
b = 1
|
||||
do i = 1, 1001
|
||||
count(leadingDigit(a)) = count(leadingDigit(a)) + 1
|
||||
call fibber(a,b,c,d)
|
||||
a = c
|
||||
b = d
|
||||
end do
|
||||
write(6,*) (benfordsLaw(i),i=1,9),'THE LAW'
|
||||
write(6,*) (count(i)/1000.0 ,i=1,9),'LEADING FIBONACCI DIGIT'
|
||||
end program benford
|
||||
31
Task/Benfords-law/Go/benfords-law.go
Normal file
31
Task/Benfords-law/Go/benfords-law.go
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"math"
|
||||
)
|
||||
|
||||
func Fib1000() []float64 {
|
||||
a, b, r := 0., 1., [1000]float64{}
|
||||
for i := range r {
|
||||
r[i], a, b = b, b, b+a
|
||||
}
|
||||
return r[:]
|
||||
}
|
||||
|
||||
func main() {
|
||||
show(Fib1000(), "First 1000 Fibonacci numbers")
|
||||
}
|
||||
|
||||
func show(c []float64, title string) {
|
||||
var f [9]int
|
||||
for _, v := range c {
|
||||
f[fmt.Sprintf("%g", v)[0]-'1']++
|
||||
}
|
||||
fmt.Println(title)
|
||||
fmt.Println("Digit Observed Predicted")
|
||||
for i, n := range f {
|
||||
fmt.Printf(" %d %9.3f %8.3f\n", i+1, float64(n)/float64(len(c)),
|
||||
math.Log10(1+1/float64(i+1)))
|
||||
}
|
||||
}
|
||||
17
Task/Benfords-law/Haskell/benfords-law.hs
Normal file
17
Task/Benfords-law/Haskell/benfords-law.hs
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
import qualified Data.Map as M
|
||||
import Data.Char (digitToInt)
|
||||
|
||||
fstdigit :: Integer -> Int
|
||||
fstdigit = digitToInt . head . show
|
||||
|
||||
n = 1000::Int
|
||||
fibs = 1:1:zipWith (+) fibs (tail fibs)
|
||||
fibdata = map fstdigit $ take n fibs
|
||||
freqs = M.fromListWith (+) $ zip fibdata (repeat 1)
|
||||
|
||||
tab :: [(Int, Double, Double)]
|
||||
tab = [(d,
|
||||
(fromIntegral (M.findWithDefault 0 d freqs) /(fromIntegral n) ),
|
||||
logBase 10.0 $ 1 + 1/(fromIntegral d) ) | d<-[1..9]]
|
||||
|
||||
main = print tab
|
||||
34
Task/Benfords-law/Icon/benfords-law.icon
Normal file
34
Task/Benfords-law/Icon/benfords-law.icon
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
global counts, total
|
||||
|
||||
procedure main()
|
||||
|
||||
counts := table(0)
|
||||
total := 0.0
|
||||
every benlaw(fib(1 to 1000))
|
||||
|
||||
every i := 1 to 9 do
|
||||
write(i,": ",right(100*counts[string(i)]/total,9)," ",100*P(i))
|
||||
|
||||
end
|
||||
|
||||
procedure benlaw(n)
|
||||
if counts[n ? (tab(upto('123456789')),move(1))] +:= 1 then total +:= 1
|
||||
end
|
||||
|
||||
procedure P(d)
|
||||
return log(1+1.0/d, 10)
|
||||
end
|
||||
|
||||
procedure fib(n) # From Fibonacci Sequence task
|
||||
return fibMat(n)[1]
|
||||
end
|
||||
|
||||
procedure fibMat(n)
|
||||
if n <= 0 then return [0,0]
|
||||
if n = 1 then return [1,0]
|
||||
fp := fibMat(n/2)
|
||||
c := fp[1]*fp[1] + fp[2]*fp[2]
|
||||
d := fp[1]*(fp[1]+2*fp[2])
|
||||
if n%2 = 1 then return [c+d, d]
|
||||
else return [d, c]
|
||||
end
|
||||
36
Task/Benfords-law/J/benfords-law.j
Normal file
36
Task/Benfords-law/J/benfords-law.j
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
log10 =: 10&^.
|
||||
benford =: log10@:(1+%)
|
||||
assert '0.30 0.18 0.12 0.10 0.08 0.07 0.06 0.05 0.05' -: 5j2 ": benford >: i. 9
|
||||
|
||||
|
||||
append_next_fib =: , +/@:(_2&{.)
|
||||
assert 5 8 13 -: append_next_fib 5 8
|
||||
|
||||
leading_digits =: {.@":&>
|
||||
assert '581' -: leading_digits 5 8 13x
|
||||
|
||||
count =: #/.~ /: ~.
|
||||
assert 2 1 3 4 -: count 'XCXBAXACXC' NB. 2 A's, 1 B, 3 C's, and some X's.
|
||||
|
||||
normalize =: % +/
|
||||
assert 1r3 2r3 -: normalize 1 2x
|
||||
|
||||
FIB =: append_next_fib ^: (1000-#) 1 1
|
||||
LDF =: leading_digits FIB
|
||||
|
||||
|
||||
TALLY_BY_KEY =: count LDF
|
||||
assert 9 -: # TALLY_BY_KEY NB. If all of [1-9] are present then we know what the digits are.
|
||||
|
||||
mean =: +/ % #
|
||||
center=: - mean
|
||||
mp =: $:~ :(+/ .*)
|
||||
num =: mp&:center
|
||||
den =: %:@:(*&:(+/@:(*:@:center)))
|
||||
r =: num % den NB. r is the LibreOffice correl function
|
||||
assert '_0.982' -: 6j3 ": 1 2 3 r 6 5 3 NB. confirmed using LibreOffice correl function
|
||||
|
||||
|
||||
assert '0.9999' -: 6j4 ": (normalize TALLY_BY_KEY) r benford >: i.9
|
||||
|
||||
assert '0.9999' -: 6j4 ": TALLY_BY_KEY r benford >: i.9 NB. Of course we don't need normalization
|
||||
41
Task/Benfords-law/Java/benfords-law.java
Normal file
41
Task/Benfords-law/Java/benfords-law.java
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
import java.math.BigInteger;
|
||||
|
||||
public class Benford {
|
||||
private static interface NumberGenerator {
|
||||
BigInteger[] getNumbers();
|
||||
}
|
||||
|
||||
private static class FibonacciGenerator implements NumberGenerator {
|
||||
public BigInteger[] getNumbers() {
|
||||
final BigInteger[] fib = new BigInteger[ 1000 ];
|
||||
fib[ 0 ] = fib[ 1 ] = BigInteger.ONE;
|
||||
for ( int i = 2; i < fib.length; i++ )
|
||||
fib[ i ] = fib[ i - 2 ].add( fib[ i - 1 ] );
|
||||
return fib;
|
||||
}
|
||||
}
|
||||
|
||||
private final int[] firstDigits = new int[ 9 ];
|
||||
private final int count;
|
||||
|
||||
private Benford( final NumberGenerator ng ) {
|
||||
final BigInteger[] numbers = ng.getNumbers();
|
||||
count = numbers.length;
|
||||
for ( final BigInteger number : numbers )
|
||||
firstDigits[ Integer.valueOf( number.toString().substring( 0, 1 ) ) - 1 ]++;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
final StringBuilder result = new StringBuilder();
|
||||
for ( int i = 0; i < firstDigits.length; i++ )
|
||||
result.append( i + 1 )
|
||||
.append( '\t' ).append( firstDigits[ i ] / ( double )count )
|
||||
.append( '\t' ).append( Math.log10( 1 + 1d / ( i + 1 ) ) )
|
||||
.append( '\n' );
|
||||
return result.toString();
|
||||
}
|
||||
|
||||
public static void main( final String[] args ) {
|
||||
System.out.println( new Benford( new FibonacciGenerator() ) );
|
||||
}
|
||||
}
|
||||
5
Task/Benfords-law/Julia/benfords-law.julia
Normal file
5
Task/Benfords-law/Julia/benfords-law.julia
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
fib(n) = ([one(n) one(n) ; one(n) zero(n)]^n)[1,2]
|
||||
|
||||
ben(l) = [count(x->x==i, map(n->string(n)[1],l)) for i='1':'9']./length(l)
|
||||
|
||||
benford(l) = [Number[1:9] ben(l) log10(1.+1./[1:9])]
|
||||
35
Task/Benfords-law/Liberty-BASIC/benfords-law.liberty
Normal file
35
Task/Benfords-law/Liberty-BASIC/benfords-law.liberty
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
dim bin(9)
|
||||
|
||||
N=1000
|
||||
for i = 0 to N-1
|
||||
num$ = str$(fiboI(i))
|
||||
d=val(left$(num$,1))
|
||||
'print num$, d
|
||||
bin(d)=bin(d)+1
|
||||
next
|
||||
print
|
||||
|
||||
print "Digit", "Actual freq", "Expected freq"
|
||||
for i = 1 to 9
|
||||
print i, bin(i)/N, using("#.###", P(i))
|
||||
next
|
||||
|
||||
|
||||
function P(d)
|
||||
P = log10(d+1)-log10(d)
|
||||
end function
|
||||
|
||||
function log10(x)
|
||||
log10 = log(x)/log(10)
|
||||
end function
|
||||
|
||||
function fiboI(n)
|
||||
a = 0
|
||||
b = 1
|
||||
for i = 1 to n
|
||||
temp = a + b
|
||||
a = b
|
||||
b = temp
|
||||
next i
|
||||
fiboI = a
|
||||
end function
|
||||
20
Task/Benfords-law/Lua/benfords-law.lua
Normal file
20
Task/Benfords-law/Lua/benfords-law.lua
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
actual = {}
|
||||
expected = {}
|
||||
for i = 1, 9 do
|
||||
actual[i] = 0
|
||||
expected[i] = math.log10(1 + 1 / i)
|
||||
end
|
||||
|
||||
n = 0
|
||||
file = io.open("fibs1000.txt", "r")
|
||||
for line in file:lines() do
|
||||
digit = string.byte(line, 1) - 48
|
||||
actual[digit] = actual[digit] + 1
|
||||
n = n + 1
|
||||
end
|
||||
file:close()
|
||||
|
||||
print("digit actual expected")
|
||||
for i = 1, 9 do
|
||||
print(i, actual[i] / n, expected[i])
|
||||
end
|
||||
3
Task/Benfords-law/Mathematica/benfords-law.math
Normal file
3
Task/Benfords-law/Mathematica/benfords-law.math
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
fibdata = Array[First@IntegerDigits@Fibonacci@# &, 1000];
|
||||
Table[{d, N@Count[fibdata, d]/Length@fibdata, Log10[1. + 1/d]}, {d, 1,
|
||||
9}] // Grid
|
||||
41
Task/Benfords-law/NetRexx/benfords-law.netrexx
Normal file
41
Task/Benfords-law/NetRexx/benfords-law.netrexx
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
/* NetRexx */
|
||||
options replace format comments java crossref symbols nobinary
|
||||
|
||||
runSample(arg)
|
||||
return
|
||||
|
||||
-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
method brenfordDeveation(nlist = Rexx[]) public static
|
||||
observed = 0
|
||||
loop n_ over nlist
|
||||
d1 = n_.left(1)
|
||||
if d1 = 0 then iterate n_
|
||||
observed[d1] = observed[d1] + 1
|
||||
end n_
|
||||
say ' '.right(4) 'Observed'.right(11) 'Expected'.right(11) 'Deviation'.right(11)
|
||||
loop n_ = 1 to 9
|
||||
actual = (observed[n_] / (nlist.length - 1))
|
||||
expect = Rexx(Math.log10(1 + 1 / n_))
|
||||
deviat = expect - actual
|
||||
say n_.right(3)':' (actual * 100).format(3, 6)'%' (expect * 100).format(3, 6)'%' (deviat * 100).abs().format(3, 6)'%'
|
||||
end n_
|
||||
return
|
||||
|
||||
-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
method fibonacciList(size = 1000) public static returns Rexx[]
|
||||
fibs = Rexx[size + 1]
|
||||
fibs[0] = 0
|
||||
fibs[1] = 1
|
||||
loop n_ = 2 to size
|
||||
fibs[n_] = fibs[n_ - 1] + fibs[n_ - 2]
|
||||
end n_
|
||||
return fibs
|
||||
|
||||
-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
method runSample(arg) private static
|
||||
parse arg n_ .
|
||||
if n_ = '' then n_ = 1000
|
||||
fibList = fibonacciList(n_)
|
||||
say 'Fibonacci sequence to' n_
|
||||
brenfordDeveation(fibList)
|
||||
return
|
||||
9
Task/Benfords-law/PARI-GP/benfords-law.pari
Normal file
9
Task/Benfords-law/PARI-GP/benfords-law.pari
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
distribution(v)={
|
||||
my(t=vector(9,n,sum(i=1,#v,v[i]==n)));
|
||||
print("Digit\tActual\tExpected");
|
||||
for(i=1,9,print(i, "\t", t[i], "\t", round(#v*(log(i+1)-log(i))/log(10))))
|
||||
};
|
||||
dist(f)=distribution(vector(1000,n,digits(f(n))[1]));
|
||||
lucas(n)=fibonacci(n-1)+fibonacci(n+1);
|
||||
dist(fibonacci)
|
||||
dist(lucas)
|
||||
39
Task/Benfords-law/PL-I/benfords-law.pli
Normal file
39
Task/Benfords-law/PL-I/benfords-law.pli
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
(fofl, size, subrg):
|
||||
Benford: procedure options(main); /* 20 October 2013 */
|
||||
declare sc(1000) char(1), f(1000) float (16);
|
||||
declare d fixed (1);
|
||||
|
||||
call Fibonacci(f);
|
||||
call digits(sc, f);
|
||||
|
||||
put skip list ('digit expected obtained');
|
||||
do d= 1 upthru 9;
|
||||
put skip edit (d, log10(1 + 1/d), tally(sc, trim(d))/1000)
|
||||
(f(3), 2 f(13,8) );
|
||||
end;
|
||||
|
||||
Fibonacci: procedure (f);
|
||||
declare f(*) float (16);
|
||||
declare i fixed binary;
|
||||
|
||||
f(1), f(2) = 1;
|
||||
do i = 3 to 1000;
|
||||
f(i) = f(i-1) + f(i-2);
|
||||
end;
|
||||
end Fibonacci;
|
||||
|
||||
digits: procedure (sc, f);
|
||||
declare sc(*) char(1), f(*) float (16);
|
||||
sc = substr(trim(f), 1, 1);
|
||||
end digits;
|
||||
|
||||
tally: procedure (sc, d) returns (fixed binary);
|
||||
declare sc(*) char(1), d char(1);
|
||||
declare (i, t) fixed binary;
|
||||
t = 0;
|
||||
do i = 1 to 1000;
|
||||
if sc(i) = d then t = t + 1;
|
||||
end;
|
||||
return (t);
|
||||
end tally;
|
||||
end Benford;
|
||||
34
Task/Benfords-law/PL-pgSQL/benfords-law.sql
Normal file
34
Task/Benfords-law/PL-pgSQL/benfords-law.sql
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
WITH recursive
|
||||
constant(val) AS
|
||||
(
|
||||
select 1000.
|
||||
)
|
||||
,
|
||||
fib(a,b) AS
|
||||
(
|
||||
SELECT CAST(0 AS numeric), CAST(1 AS numeric)
|
||||
UNION ALL
|
||||
SELECT b,a+b
|
||||
FROM fib
|
||||
)
|
||||
,
|
||||
benford(first_digit, probability_real, probability_theoretical) AS
|
||||
(
|
||||
SELECT *,
|
||||
CAST(log(1. + 1./CAST(first_digit AS INT)) AS NUMERIC(5,4)) probability_theoretical
|
||||
FROM (
|
||||
SELECT first_digit, CAST(COUNT(1)/(select val from constant) AS NUMERIC(5,4)) probability_real FROM
|
||||
(
|
||||
SELECT SUBSTRING(CAST(a AS VARCHAR(100)),1,1) first_digit
|
||||
FROM fib
|
||||
WHERE SUBSTRING(CAST(a AS VARCHAR(100)),1,1) <> '0'
|
||||
LIMIT (select val from constant)
|
||||
) t
|
||||
GROUP BY first_digit
|
||||
) f
|
||||
ORDER BY first_digit ASC
|
||||
)
|
||||
select *
|
||||
from benford cross join
|
||||
(select cast(corr(probability_theoretical,probability_real) as numeric(5,4)) correlation
|
||||
from benford) c
|
||||
14
Task/Benfords-law/Perl-6/benfords-law.pl6
Normal file
14
Task/Benfords-law/Perl-6/benfords-law.pl6
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
sub benford(@a) { bag +« @a».comb: /<( <[ 1..9 ]> )> <[ , . \d ]>*/ }
|
||||
|
||||
sub show(%distribution) {
|
||||
printf "%9s %9s %s\n", <Actual Expected Deviation>;
|
||||
for 1 .. 9 -> $digit {
|
||||
my $actual = %distribution{$digit} * 100 / [+] %distribution.values;
|
||||
my $expected = (1 + 1 / $digit).log(10) * 100;
|
||||
printf "%d: %5.2f%% | %5.2f%% | %.2f%%\n",
|
||||
$digit, $actual, $expected, abs($expected - $actual);
|
||||
}
|
||||
}
|
||||
|
||||
multi MAIN($file) { show benford $file.IO.lines }
|
||||
multi MAIN() { show benford ( 1, 1, 2, *+* ... * )[^1000] }
|
||||
25
Task/Benfords-law/Perl/benfords-law.pl
Normal file
25
Task/Benfords-law/Perl/benfords-law.pl
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
#!/usr/bin/perl
|
||||
use strict ;
|
||||
use warnings ;
|
||||
use POSIX qw( log10 ) ;
|
||||
|
||||
my @fibonacci = ( 0 , 1 ) ;
|
||||
while ( @fibonacci != 1000 ) {
|
||||
push @fibonacci , $fibonacci[ -1 ] + $fibonacci[ -2 ] ;
|
||||
}
|
||||
my @actuals ;
|
||||
my @expected ;
|
||||
for my $i( 1..9 ) {
|
||||
my $sum = 0 ;
|
||||
map { $sum++ if $_ =~ /\A$i/ } @fibonacci ;
|
||||
push @actuals , $sum / 1000 ;
|
||||
push @expected , log10( 1 + 1/$i ) ;
|
||||
}
|
||||
print " Observed Expected\n" ;
|
||||
for my $i( 1..9 ) {
|
||||
print "$i : " ;
|
||||
my $result = sprintf ( "%.2f" , 100 * $actuals[ $i - 1 ] ) ;
|
||||
printf "%11s %%" , $result ;
|
||||
$result = sprintf ( "%.2f" , 100 * $expected[ $i - 1 ] ) ;
|
||||
printf "%15s %%\n" , $result ;
|
||||
}
|
||||
44
Task/Benfords-law/Prolog/benfords-law.pro
Normal file
44
Task/Benfords-law/Prolog/benfords-law.pro
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
%_________________________________________________________________
|
||||
% Does the Fibonacci sequence follow Benford's law?
|
||||
%~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
% Fibonacci sequence generator
|
||||
fib(C, [P,S], C, N) :- N is P + S.
|
||||
fib(C, [P,S], Cv, V) :- succ(C, Cn), N is P + S, !, fib(Cn, [S,N], Cv, V).
|
||||
|
||||
fib(0, 0).
|
||||
fib(1, 1).
|
||||
fib(C, N) :- fib(2, [0,1], C, N). % Generate from 3rd sequence on
|
||||
|
||||
% The benford law calculated
|
||||
benford(D, Val) :- Val is log10(1+1/D).
|
||||
|
||||
% Retrieves the first characters of the first 1000 fibonacci numbers
|
||||
% (excluding zero)
|
||||
firstchar(V) :-
|
||||
fib(C,N), N =\= 0, atom_chars(N, [Ch|_]), number_chars(V, [Ch]),
|
||||
(C>999-> !; true).
|
||||
|
||||
% Increment the n'th list item (1 based), result -> third argument.
|
||||
incNth(1, [Dh|Dt], [Ch|Dt]) :- !, succ(Dh, Ch).
|
||||
incNth(H, [Dh|Dt], [Dh|Ct]) :- succ(Hn, H), !, incNth(Hn, Dt, Ct).
|
||||
|
||||
% Calculate the frequency of the all the list items
|
||||
freq([], D, D).
|
||||
freq([H|T], D, C) :- incNth(H, D, L), !, freq(T, L, C).
|
||||
|
||||
freq([H|T], Freq) :-
|
||||
length([H|T], Len), min_list([H|T], Min), max_list([H|T], Max),
|
||||
findall(0, between(Min,Max,_), In),
|
||||
freq([H|T], In, F), % Frequency stored in F
|
||||
findall(N, (member(V, F), N is V/Len), Freq). % Normalise F->Freq
|
||||
|
||||
% Output the results
|
||||
writeHdr :-
|
||||
format('~t~w~15| - ~t~w\n', ['Benford', 'Measured']).
|
||||
writeData(Benford, Freq) :-
|
||||
format('~t~2f%~15| - ~t~2f%\n', [Benford*100, Freq*100]).
|
||||
|
||||
go :- % main goal
|
||||
findall(B, (between(1,9,N), benford(N,B)), Benford),
|
||||
findall(C, firstchar(C), Fc), freq(Fc, Freq),
|
||||
writeHdr, maplist(writeData, Benford, Freq).
|
||||
39
Task/Benfords-law/Python/benfords-law.py
Normal file
39
Task/Benfords-law/Python/benfords-law.py
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
from __future__ import division
|
||||
from itertools import islice, count
|
||||
from collections import Counter
|
||||
from math import log10
|
||||
from random import randint
|
||||
|
||||
expected = [log10(1+1/d) for d in range(1,10)]
|
||||
|
||||
def fib():
|
||||
a,b = 1,1
|
||||
while True:
|
||||
yield a
|
||||
a,b = b,a+b
|
||||
|
||||
# powers of 3 as a test sequence
|
||||
def power_of_threes():
|
||||
return (3**k for k in count(0))
|
||||
|
||||
def heads(s):
|
||||
for a in s: yield int(str(a)[0])
|
||||
|
||||
def show_dist(title, s):
|
||||
c = Counter(s)
|
||||
size = sum(c.values())
|
||||
res = [c[d]/size for d in range(1,10)]
|
||||
|
||||
print("\n%s Benfords deviation" % title)
|
||||
for r, e in zip(res, expected):
|
||||
print("%5.1f%% %5.1f%% %5.1f%%" % (r*100., e*100., abs(r - e)*100.))
|
||||
|
||||
def rand1000():
|
||||
while True: yield randint(1,9999)
|
||||
|
||||
if __name__ == '__main__':
|
||||
show_dist("fibbed", islice(heads(fib()), 1000))
|
||||
show_dist("threes", islice(heads(power_of_threes()), 1000))
|
||||
|
||||
# just to show that not all kind-of-random sets behave like that
|
||||
show_dist("random", islice(heads(rand1000()), 10000))
|
||||
31
Task/Benfords-law/R/benfords-law.r
Normal file
31
Task/Benfords-law/R/benfords-law.r
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
pbenford <- function(d){
|
||||
return(log10(1+(1/d)))
|
||||
}
|
||||
|
||||
get_lead_digit <- function(number){
|
||||
return(as.numeric(substr(number,1,1)))
|
||||
}
|
||||
|
||||
fib_iter <- function(n){
|
||||
first <- 1
|
||||
second <- 0
|
||||
for(i in 1:n){
|
||||
sum <- first + second
|
||||
first <- second
|
||||
second <- sum
|
||||
}
|
||||
return(sum)
|
||||
}
|
||||
|
||||
fib_sequence <- mapply(fib_iter,c(1:1000))
|
||||
lead_digits <- mapply(get_lead_digit,fib_sequence)
|
||||
|
||||
observed_frequencies <- table(lead_digits)/1000
|
||||
expected_frequencies <- mapply(pbenford,c(1:9))
|
||||
|
||||
data <- data.frame(observed_frequencies,expected_frequencies)
|
||||
colnames(data) <- c("digit","obs.frequency","exp.frequency")
|
||||
dev_percentage <- abs((data$obs.frequency-data$exp.frequency)*100)
|
||||
data <- data.frame(data,dev_percentage)
|
||||
|
||||
print(data)
|
||||
1
Task/Benfords-law/README
Normal file
1
Task/Benfords-law/README
Normal file
|
|
@ -0,0 +1 @@
|
|||
Data source: http://rosettacode.org/wiki/Benford's_law
|
||||
33
Task/Benfords-law/REXX/benfords-law.rexx
Normal file
33
Task/Benfords-law/REXX/benfords-law.rexx
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
/*REXX program demonstrates some common trig functions (30 digits shown)*/
|
||||
numeric digits 50 /*use only 50 digits for LN, LOG.*/
|
||||
parse arg N .; if N=='' then N=1000 /*allow sample size specification*/
|
||||
/*══════════════apply Benford's law to Fibonacci numbers.*/
|
||||
@.=1; do j=3 to N; jm1=j-1; jm2=j-2; @.j=@.jm2+@.jm1; end /*j*/
|
||||
call show_results "Benford's law applied to" N 'Fibonacci numbers'
|
||||
/*══════════════apply Benford's law to prime numbers. */
|
||||
p=0; do j=2 until p==N; if \isPrime(j) then iterate; p=p+1; @.p=j;end
|
||||
call show_results "Benford's law applied to" N 'prime numbers'
|
||||
/*══════════════apply Benford's law to factorials. */
|
||||
do j=1 for N; @.j=!(j); end /*j*/
|
||||
call show_results "Benford's law applied to" N 'factorial products'
|
||||
exit /*stick a fork in it, we're done.*/
|
||||
/*──────────────────────────────────SHOW_RESULTS subroutine─────────────*/
|
||||
show_results: w1=max(length('observed'),length(N-2)) ; say
|
||||
pad=' '; w2=max(length('expected' ),length(N ))
|
||||
say pad 'digit' pad center('observed',w1) pad center('expected',w2)
|
||||
say pad '─────' pad center('',w1,'─') pad center('',w2,'─') pad arg(1)
|
||||
!.=0; do j=1 for N; _=left(@.j,1); !._=!._+1; end /*get 1st digits.*/
|
||||
|
||||
do k=1 for 9 /*show results for Fibonacci nums*/
|
||||
say pad center(k,5) pad center(format(!.k/N,,length(N-2)),w1),
|
||||
pad center(format(log(1+1/k),,length(N)+2),w2)
|
||||
end /*k*/
|
||||
return
|
||||
/*──────────────────────────────────one─line subroutines───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────*/
|
||||
!: procedure; parse arg x; !=1; do j=2 to x; !=!*j; end /*j*/; return !
|
||||
e: return 2.7182818284590452353602874713526624977572470936999595749669676277240766303535
|
||||
isprime: procedure; parse arg x; if wordpos(x,'2 3 5 7')\==0 then return 1; if x//2==0 then return 0; if x//3==0 then return 0; do j=5 by 6 until j*j>x; if x//j==0 then return 0; if x//(j+2)==0 then return 0; end; return 1
|
||||
ln10:return 2.30258509299404568401799145468436420760110148862877297603332790096757260967735248023599720508959829834196778404228624863340952546508280675666628736909878168948290720832555468084379989482623319852839350530896538
|
||||
ln:procedure expose $.;parse arg x,f;if x==10 then do;_=ln10();xx=format(_);if xx\==_ then return xx;end;call e;ig=x>1.5;is=1-2*(ig\==1);ii=0;xx=x;return .ln_comp()
|
||||
.ln_comp:do while ig&xx>1.5|\ig&xx<.5;_=e();do k=-1;iz=xx*_**-is;if k>=0&(ig&iz<1|\ig&iz>.5) then leave;_=_*_;izz=iz;end;xx=izz;ii=ii+is*2**k;end;x=x*e()**-ii-1;z=0;_=-1;p=z;do k=1;_=-_*x;z=z+_/k;if z=p then leave;p=z;end;return z+ii
|
||||
log:return ln(arg(1))/ln(10)
|
||||
36
Task/Benfords-law/Racket/benfords-law.rkt
Normal file
36
Task/Benfords-law/Racket/benfords-law.rkt
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
#lang racket
|
||||
|
||||
(define (log10 n) (/ (log n) (log 10)))
|
||||
|
||||
(define (first-digit n)
|
||||
(quotient n (expt 10 (inexact->exact (floor (log10 n))))))
|
||||
|
||||
(define N 10000)
|
||||
|
||||
(define fibs
|
||||
(let loop ([n N] [a 0] [b 1])
|
||||
(if (zero? n) '() (cons b (loop (sub1 n) b (+ a b))))))
|
||||
|
||||
(define v (make-vector 10 0))
|
||||
(for ([n fibs])
|
||||
(define f (first-digit n))
|
||||
(vector-set! v f (add1 (vector-ref v f))))
|
||||
|
||||
(printf "N OBS EXP\n")
|
||||
(define (pct n) (~r (* n 100.0) #:precision 1 #:min-width 4))
|
||||
(for ([i (in-range 1 10)])
|
||||
(printf "~a: ~a% ~a%\n" i
|
||||
(pct (/ (vector-ref v i) N))
|
||||
(pct (log10 (+ 1 (/ i))))))
|
||||
|
||||
;; Output:
|
||||
;; N OBS EXP
|
||||
;; 1: 30.1% 30.1%
|
||||
;; 2: 17.6% 17.6%
|
||||
;; 3: 12.5% 12.5%
|
||||
;; 4: 9.7% 9.7%
|
||||
;; 5: 7.9% 7.9%
|
||||
;; 6: 6.7% 6.7%
|
||||
;; 7: 5.8% 5.8%
|
||||
;; 8: 5.1% 5.1%
|
||||
;; 9: 4.6% 4.6%
|
||||
37
Task/Benfords-law/Ruby/benfords-law.rb
Normal file
37
Task/Benfords-law/Ruby/benfords-law.rb
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
EXPECTED = (1..9).map{|d| Math.log10(1+1.0/d)}
|
||||
|
||||
def fib(n)
|
||||
a,b = 0,1
|
||||
n.times.map{ret, a, b = a, b, a+b; ret}
|
||||
end
|
||||
|
||||
# powers of 3 as a test sequence
|
||||
def power_of_threes(n)
|
||||
n.times.map{|k| 3**k}
|
||||
end
|
||||
|
||||
def heads(s)
|
||||
s.map{|a| a.to_s[0].to_i}
|
||||
end
|
||||
|
||||
def show_dist(title, s)
|
||||
s = heads(s)
|
||||
c = Array.new(10, 0)
|
||||
s.each{|x| c[x] += 1}
|
||||
size = s.size.to_f
|
||||
res = (1..9).map{|d| c[d]/size}
|
||||
puts "\n %s Benfords deviation" % title
|
||||
res.zip(EXPECTED).each.with_index(1) do |(r, e), i|
|
||||
puts "%2d: %5.1f%% %5.1f%% %5.1f%%" % [i, r*100, e*100, (r - e).abs*100]
|
||||
end
|
||||
end
|
||||
|
||||
def random(n)
|
||||
n.times.map{rand(1..n)}
|
||||
end
|
||||
|
||||
show_dist("fibbed", fib(1000))
|
||||
show_dist("threes", power_of_threes(1000))
|
||||
|
||||
# just to show that not all kind-of-random sets behave like that
|
||||
show_dist("random", random(10000))
|
||||
30
Task/Benfords-law/Run-BASIC/benfords-law.run
Normal file
30
Task/Benfords-law/Run-BASIC/benfords-law.run
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
N = 1000
|
||||
for i = 0 to N - 1
|
||||
n$ = str$(fibonacci(i))
|
||||
j = val(left$(n$,1))
|
||||
actual(j) = actual(j) +1
|
||||
next
|
||||
print
|
||||
html "<table border=1><TR bgcolor=wheat><TD>Digit<td>Actual<td>Expected</td><tr>"
|
||||
for i = 1 to 9
|
||||
html "<tr align=right><td>";i;"</td><td>";using("##.###",actual(i)/10);"</td><td>";using("##.###", frequency(i)*100);"</td></tr>"
|
||||
next
|
||||
html "</table>"
|
||||
end
|
||||
|
||||
function frequency(n)
|
||||
frequency = log10(n+1) - log10(n)
|
||||
end function
|
||||
|
||||
function log10(n)
|
||||
log10 = log(n) / log(10)
|
||||
end function
|
||||
|
||||
function fibonacci(n)
|
||||
b = 1
|
||||
for i = 1 to n
|
||||
temp = fibonacci + b
|
||||
fibonacci = b
|
||||
b = temp
|
||||
next i
|
||||
end function
|
||||
43
Task/Benfords-law/SQL/benfords-law.sql
Normal file
43
Task/Benfords-law/SQL/benfords-law.sql
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
-- Create table
|
||||
create table benford (num integer);
|
||||
|
||||
-- Seed table
|
||||
insert into benford (num) values (1);
|
||||
insert into benford (num) values (1);
|
||||
insert into benford (num) values (2);
|
||||
|
||||
-- Populate table
|
||||
insert into benford (num)
|
||||
select
|
||||
ult + penult
|
||||
from
|
||||
(select max(num) as ult from benford),
|
||||
(select max(num) as penult from benford where num not in (select max(num) from benford))
|
||||
|
||||
-- Repeat as many times as desired
|
||||
-- in Oracle SQL*Plus, press "Slash, Enter" a lot of times
|
||||
-- or wrap this in a loop, but that will require something db-specific...
|
||||
|
||||
-- Do sums
|
||||
select
|
||||
digit,
|
||||
count(digit) / numbers as actual,
|
||||
log(10, 1 + 1 / digit) as expected
|
||||
from
|
||||
(
|
||||
select
|
||||
floor(num/power(10,length(num)-1)) as digit
|
||||
from
|
||||
benford
|
||||
),
|
||||
(
|
||||
select
|
||||
count(*) as numbers
|
||||
from
|
||||
benford
|
||||
)
|
||||
group by digit, numbers
|
||||
order by digit;
|
||||
|
||||
-- Tidy up
|
||||
drop table benford;
|
||||
29
Task/Benfords-law/Scala/benfords-law.scala
Normal file
29
Task/Benfords-law/Scala/benfords-law.scala
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
// Fibonacci Sequence (begining with 1,1): 1 1 2 3 5 8 13 21 34 55 ...
|
||||
val fibs : Stream[BigInt] = { def series(i:BigInt,j:BigInt):Stream[BigInt] = i #:: series(j, i+j); series(1,0).tail.tail }
|
||||
|
||||
|
||||
/**
|
||||
* Given a numeric sequence, return the distribution of the most-signicant-digit
|
||||
* as expected by Benford's Law and then by actual distribution.
|
||||
*/
|
||||
def benford[N:Numeric]( data:Seq[N] ) : Map[Int,(Double,Double)] = {
|
||||
|
||||
import scala.math._
|
||||
|
||||
val maxSize = 10000000 // An arbitrary size to avoid problems with endless streams
|
||||
|
||||
val size = (data.take(maxSize)).size.toDouble
|
||||
|
||||
val distribution = data.take(maxSize).groupBy(_.toString.head.toString.toInt).map{ case (d,l) => (d -> l.size) }
|
||||
|
||||
(for( i <- (1 to 9) ) yield { (i -> (log10(1D + 1D / i), (distribution(i) / size))) }).toMap
|
||||
}
|
||||
|
||||
{
|
||||
println( "Fibonacci Sequence (size=1000): 1 1 2 3 5 8 13 21 34 55 ...\n" )
|
||||
println( "%9s %9s %9s".format( "Actual", "Expected", "Deviation" ) )
|
||||
|
||||
benford( fibs.take(1000) ).toList.sorted foreach {
|
||||
case (k, v) => println( "%d: %5.2f%% | %5.2f%% | %5.4f%%".format(k,v._2*100,v._1*100,math.abs(v._2-v._1)*100) )
|
||||
}
|
||||
}
|
||||
19
Task/Benfords-law/Tcl/benfords-law-1.tcl
Normal file
19
Task/Benfords-law/Tcl/benfords-law-1.tcl
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
proc benfordTest {numbers} {
|
||||
# Count the leading digits (RE matches first digit in each number,
|
||||
# even if negative)
|
||||
set accum {1 0 2 0 3 0 4 0 5 0 6 0 7 0 8 0 9 0}
|
||||
foreach n $numbers {
|
||||
if {[regexp {[1-9]} $n digit]} {
|
||||
dict incr accum $digit
|
||||
}
|
||||
}
|
||||
|
||||
# Print the report
|
||||
puts " digit | measured | theory"
|
||||
puts "-------+----------+--------"
|
||||
dict for {digit count} $accum {
|
||||
puts [format "%6d | %7.2f%% | %5.2f%%" $digit \
|
||||
[expr {$count * 100.0 / [llength $numbers]}] \
|
||||
[expr {log(1+1./$digit)/log(10)*100.0}]]
|
||||
}
|
||||
}
|
||||
7
Task/Benfords-law/Tcl/benfords-law-2.tcl
Normal file
7
Task/Benfords-law/Tcl/benfords-law-2.tcl
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
proc fibs n {
|
||||
for {set a 1;set b [set i 0]} {$i < $n} {incr i} {
|
||||
lappend result [set b [expr {$a + [set a $b]}]]
|
||||
}
|
||||
return $result
|
||||
}
|
||||
benfordTest [fibs 1000]
|
||||
Loading…
Add table
Add a link
Reference in a new issue