Skip to content

Instantly share code, notes, and snippets.

@havenwood
Last active November 2, 2022 06:36
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save havenwood/0a81a8663cb55e7ad1ed90ed4fe0c168 to your computer and use it in GitHub Desktop.
Save havenwood/0a81a8663cb55e7ad1ed90ed4fe0c168 to your computer and use it in GitHub Desktop.
A quick implementation to generate numbers that roughly comply with Bendford's law.
module Bendford
VARIED_DIGITS = 5
PLACES = [
[0, *(1..9).map { Math.log10(1.fdiv(_1) + 1) }],
*(2..VARIED_DIGITS).map do |place|
(0..9).map do |d|
(10 ** (place - 2)..((10 ** (place - 1)) - 1)).sum do
Math.log10(1 + 1.fdiv(10 * _1 + d))
end
end
end
]
def self.number(digits:)
Array.new(digits) do |nth_digit|
next rand(0..9) if nth_digit >= VARIED_DIGITS
bar = rand
PLACES.fetch(nth_digit).each_with_index do |chance, winner|
break winner if chance > bar
bar -= chance
end
end.reduce { |acc, digit| acc * 10 + digit }
end
end
sample_size = 10_000
digits = 3
example = Array.new(sample_size) { Bendford.number(digits:) }
result = (1..digits).to_h do |n|
[n, example.map { _1.digits[-n] }.tally]
end
pp result
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment