fibonacci_rng 0.4.1 → 0.4.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/fibonacci.reek +112 -0
- data/lib/fibonacci_rng/generator.rb +56 -0
- data/lib/fibonacci_rng/hasher.rb +37 -0
- data/lib/fibonacci_rng/seeder.rb +36 -0
- data/lib/fibonacci_rng/spinner.rb +25 -0
- data/lib/fibonacci_rng/version.rb +1 -1
- data/lib/fibonacci_rng.rb +21 -138
- data/reek.txt +1 -2
- metadata +7 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c178772afcc6c24037cf6b161276603f52e16c27
|
4
|
+
data.tar.gz: 921d717758b803609d2e4db12153542d1129c0f9
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: eab6f383927f08b52f9c82ffd8a428ba7ae091bda1c35c56444cb04df6c9188ca32d2ffefa8a14ea6726ae249ccd3eeced18ca5468df2fdb51a623ca95f71bab
|
7
|
+
data.tar.gz: 99114d55d8493734d1ca608c5f3f151677e51b72a40dd0f1d69360b34170d86b13548ae6ddf903be48327102dcbdc4752d875f8246b63e01febe6fe6f3749924
|
data/fibonacci.reek
ADDED
@@ -0,0 +1,112 @@
|
|
1
|
+
---
|
2
|
+
Attribute:
|
3
|
+
enabled: false
|
4
|
+
exclude: []
|
5
|
+
BooleanParameter:
|
6
|
+
enabled: true
|
7
|
+
exclude: []
|
8
|
+
ClassVariable:
|
9
|
+
enabled: true
|
10
|
+
exclude: []
|
11
|
+
ControlParameter:
|
12
|
+
enabled: true
|
13
|
+
exclude: []
|
14
|
+
DataClump:
|
15
|
+
enabled: true
|
16
|
+
exclude: []
|
17
|
+
max_copies: 2
|
18
|
+
min_clump_size: 2
|
19
|
+
DuplicateMethodCall:
|
20
|
+
enabled: true
|
21
|
+
exclude: []
|
22
|
+
max_calls: 1
|
23
|
+
allow_calls: []
|
24
|
+
FeatureEnvy:
|
25
|
+
enabled: true
|
26
|
+
exclude: []
|
27
|
+
IrresponsibleModule:
|
28
|
+
enabled: true
|
29
|
+
exclude: []
|
30
|
+
LongParameterList:
|
31
|
+
enabled: true
|
32
|
+
exclude: []
|
33
|
+
max_params: 3
|
34
|
+
overrides:
|
35
|
+
initialize:
|
36
|
+
max_params: 5
|
37
|
+
LongYieldList:
|
38
|
+
enabled: true
|
39
|
+
exclude: []
|
40
|
+
max_params: 3
|
41
|
+
NestedIterators:
|
42
|
+
enabled: true
|
43
|
+
exclude: []
|
44
|
+
max_allowed_nesting: 1
|
45
|
+
ignore_iterators: []
|
46
|
+
NilCheck:
|
47
|
+
enabled: true
|
48
|
+
exclude: []
|
49
|
+
PrimaDonnaMethod:
|
50
|
+
enabled: true
|
51
|
+
exclude: []
|
52
|
+
RepeatedConditional:
|
53
|
+
enabled: true
|
54
|
+
exclude: []
|
55
|
+
max_ifs: 2
|
56
|
+
TooManyInstanceVariables:
|
57
|
+
enabled: true
|
58
|
+
exclude: []
|
59
|
+
max_instance_variables: 9
|
60
|
+
TooManyMethods:
|
61
|
+
enabled: true
|
62
|
+
exclude: []
|
63
|
+
max_methods: 25
|
64
|
+
TooManyStatements:
|
65
|
+
enabled: true
|
66
|
+
exclude:
|
67
|
+
- initialize
|
68
|
+
max_statements: 7
|
69
|
+
UncommunicativeMethodName:
|
70
|
+
enabled: true
|
71
|
+
exclude: []
|
72
|
+
reject:
|
73
|
+
- !ruby/regexp /^[a-z]$/
|
74
|
+
- !ruby/regexp /[0-9]$/
|
75
|
+
- !ruby/regexp /[A-Z]/
|
76
|
+
accept: []
|
77
|
+
UncommunicativeModuleName:
|
78
|
+
enabled: true
|
79
|
+
exclude: []
|
80
|
+
reject:
|
81
|
+
- !ruby/regexp /^.$/
|
82
|
+
- !ruby/regexp /[0-9]$/
|
83
|
+
accept:
|
84
|
+
- Inline::C
|
85
|
+
UncommunicativeParameterName:
|
86
|
+
enabled: true
|
87
|
+
exclude: []
|
88
|
+
reject:
|
89
|
+
- !ruby/regexp /^.$/
|
90
|
+
- !ruby/regexp /[0-9]$/
|
91
|
+
- !ruby/regexp /[A-Z]/
|
92
|
+
- !ruby/regexp /^_/
|
93
|
+
accept: []
|
94
|
+
UncommunicativeVariableName:
|
95
|
+
enabled: true
|
96
|
+
exclude: []
|
97
|
+
reject:
|
98
|
+
- !ruby/regexp /^.$/
|
99
|
+
- !ruby/regexp /[0-9]$/
|
100
|
+
- !ruby/regexp /[A-Z]/
|
101
|
+
accept:
|
102
|
+
- _
|
103
|
+
UnusedParameters:
|
104
|
+
enabled: true
|
105
|
+
exclude: []
|
106
|
+
UnusedPrivateMethod:
|
107
|
+
enabled: false
|
108
|
+
exclude: []
|
109
|
+
UtilityFunction:
|
110
|
+
enabled: true
|
111
|
+
exclude: []
|
112
|
+
max_helper_calls: 1
|
@@ -0,0 +1,56 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
|
3
|
+
#The class of Fibonacci inspired random number generators.
|
4
|
+
class FibonacciRng
|
5
|
+
|
6
|
+
#A (mostly) compatible access point for random numbers.
|
7
|
+
#<br>Endemic Code Smells
|
8
|
+
#* :reek:FeatureEnvy
|
9
|
+
def rand(max=0)
|
10
|
+
if max.is_a?(Range)
|
11
|
+
min = max.min
|
12
|
+
dice(1 + max.max - min) + min
|
13
|
+
elsif max.zero?
|
14
|
+
float
|
15
|
+
else
|
16
|
+
dice(max.to_i)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
#Roll a dice.
|
21
|
+
def dice(sides)
|
22
|
+
limit = ((CHOP+1) / sides) * sides
|
23
|
+
|
24
|
+
begin
|
25
|
+
do_spin
|
26
|
+
end until (value = @buffer[0]) < limit
|
27
|
+
|
28
|
+
value % sides
|
29
|
+
end
|
30
|
+
|
31
|
+
#Get a pseudo random byte
|
32
|
+
def byte
|
33
|
+
do_spin
|
34
|
+
@buffer[0] & BYTE
|
35
|
+
end
|
36
|
+
|
37
|
+
#Get a string of random bytes
|
38
|
+
def bytes(length)
|
39
|
+
result = ""
|
40
|
+
length.times {result << byte.chr}
|
41
|
+
result
|
42
|
+
end
|
43
|
+
|
44
|
+
#Get a pseudo random word
|
45
|
+
def word
|
46
|
+
do_spin
|
47
|
+
@buffer[0] & WORD
|
48
|
+
end
|
49
|
+
|
50
|
+
#Get a pseudo random float
|
51
|
+
def float
|
52
|
+
do_spin
|
53
|
+
@buffer[0].to_f / BASE
|
54
|
+
end
|
55
|
+
|
56
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
|
3
|
+
#The class of Fibonacci inspired random number generators.
|
4
|
+
class FibonacciRng
|
5
|
+
|
6
|
+
#Get the value of the rng state as a number.
|
7
|
+
def hash_value
|
8
|
+
result = 0
|
9
|
+
@buffer[0...@depth].each {|value| result = (result << 29) + value }
|
10
|
+
result
|
11
|
+
end
|
12
|
+
|
13
|
+
#Get the value of the rng state as a string.
|
14
|
+
def hash_string
|
15
|
+
hash_value.to_s(36)
|
16
|
+
end
|
17
|
+
|
18
|
+
#Append data to the generator
|
19
|
+
def <<(data)
|
20
|
+
(str = data.to_s).each_byte.each do |value|
|
21
|
+
add_value(value)
|
22
|
+
end
|
23
|
+
|
24
|
+
do_spin if str.empty?
|
25
|
+
end
|
26
|
+
|
27
|
+
private
|
28
|
+
|
29
|
+
#Add a value to the generator.
|
30
|
+
def add_value(value)
|
31
|
+
index = @buffer[0] % @depth
|
32
|
+
do_spin
|
33
|
+
@buffer[index] += value
|
34
|
+
do_spin
|
35
|
+
end
|
36
|
+
|
37
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
|
3
|
+
#The class of Fibonacci inspired random number generators.
|
4
|
+
class FibonacciRng
|
5
|
+
|
6
|
+
#Set up a new seed value
|
7
|
+
def srand(seed=FibonacciRng.new_seed)
|
8
|
+
@seed = seed
|
9
|
+
@buffer = Array.new(@depth+2, 0)
|
10
|
+
seedsrc = (seed.to_s + seed.class.to_s + 'Leonardo Pisano').each_byte.cycle
|
11
|
+
indxsrc = (0...depth).cycle
|
12
|
+
do_reseed(indxsrc, seedsrc)
|
13
|
+
end
|
14
|
+
|
15
|
+
private
|
16
|
+
|
17
|
+
#A class instance variable to hold the tickle value.
|
18
|
+
@tickle = '0'
|
19
|
+
|
20
|
+
#A synchronizer for access to the @tickle variable
|
21
|
+
@sync = Mutex.new
|
22
|
+
|
23
|
+
#Create the default seed string.
|
24
|
+
def self.new_seed
|
25
|
+
@sync.synchronize {Time.now.to_s + @tickle.succ!}
|
26
|
+
end
|
27
|
+
|
28
|
+
#Do the work of reseeding the PRNG
|
29
|
+
def do_reseed(indxsrc, seedsrc)
|
30
|
+
(32*@depth+768).times do
|
31
|
+
@buffer[indxsrc.next] += seedsrc.next
|
32
|
+
do_spin
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
|
3
|
+
#The class of Fibonacci inspired random number generators.
|
4
|
+
class FibonacciRng
|
5
|
+
|
6
|
+
#Cycle through the PRNG count times.
|
7
|
+
def spin(count=1)
|
8
|
+
count.times do
|
9
|
+
do_spin
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
private
|
14
|
+
|
15
|
+
#Cycle through the PRNG once.
|
16
|
+
def do_spin
|
17
|
+
@buffer[-2] = @buffer[0]
|
18
|
+
@buffer[-1] = @buffer[1]
|
19
|
+
|
20
|
+
(0...@depth).each do |idx|
|
21
|
+
@buffer[idx] = (@buffer[idx+1] + (@buffer[idx+2] >> 1)) & CHOP
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
data/lib/fibonacci_rng.rb
CHANGED
@@ -1,30 +1,14 @@
|
|
1
1
|
# coding: utf-8
|
2
2
|
|
3
|
-
|
3
|
+
require_relative "fibonacci_rng/seeder"
|
4
|
+
require_relative "fibonacci_rng/hasher"
|
5
|
+
require_relative "fibonacci_rng/spinner"
|
6
|
+
require_relative "fibonacci_rng/generator"
|
7
|
+
require_relative "fibonacci_rng/version"
|
4
8
|
|
5
9
|
#The class of Fibonacci inspired random number generators.
|
6
10
|
class FibonacciRng
|
7
11
|
|
8
|
-
#Get a random number from the class based generator. This exists only
|
9
|
-
#for compatibility purposes. It is far better to create instances of
|
10
|
-
#generators than to use a shared, global one.
|
11
|
-
#<br>Returns
|
12
|
-
#* The computed pseudo-random value.
|
13
|
-
def self.rand(max=0)
|
14
|
-
(@hidden ||= FibonacciRng.new).rand(max)
|
15
|
-
end
|
16
|
-
|
17
|
-
#Initialize the class based generator. This exists only
|
18
|
-
#for compatibility purposes. It is far better to create instances of
|
19
|
-
#generators than to use a shared, global one.
|
20
|
-
#<br>Returns
|
21
|
-
#* The old seed value.
|
22
|
-
def self.srand(seed=FibonacciRng.new_seed, depth=8)
|
23
|
-
old = (@hidden && @hidden.seed)
|
24
|
-
@hidden = FibonacciRng.new(seed, depth)
|
25
|
-
old
|
26
|
-
end
|
27
|
-
|
28
12
|
CHOP = 0x1FFFFFFF
|
29
13
|
BYTE = 0xFF
|
30
14
|
WORD = 0xFFFF
|
@@ -61,125 +45,24 @@ class FibonacciRng
|
|
61
45
|
srand(seed)
|
62
46
|
end
|
63
47
|
|
64
|
-
#Get
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
#Get the value of the rng state as a string.
|
72
|
-
def hash_string
|
73
|
-
hash_value.to_s(36)
|
74
|
-
end
|
75
|
-
|
76
|
-
#Set up a new seed value
|
77
|
-
def srand(seed=FibonacciRng.new_seed)
|
78
|
-
@seed = seed
|
79
|
-
@buffer = Array.new(@depth+2, 0)
|
80
|
-
seedsrc = (seed.to_s + seed.class.to_s + 'Leonardo Pisano').each_byte.cycle
|
81
|
-
indxsrc = (0...depth).cycle
|
82
|
-
do_reseed(indxsrc, seedsrc)
|
83
|
-
end
|
84
|
-
|
85
|
-
#A (mostly) compatible access point for random numbers.
|
86
|
-
def rand(max=0)
|
87
|
-
if max.is_a?(Range)
|
88
|
-
min = max.min
|
89
|
-
dice(1 + max.max - min) + min
|
90
|
-
elsif max.zero?
|
91
|
-
float
|
92
|
-
else
|
93
|
-
dice(max.to_i)
|
94
|
-
end
|
95
|
-
end
|
96
|
-
|
97
|
-
#Roll a dice.
|
98
|
-
def dice(sides)
|
99
|
-
limit = ((CHOP+1) / sides) * sides
|
100
|
-
|
101
|
-
begin
|
102
|
-
do_spin
|
103
|
-
end until (value = @buffer[0]) < limit
|
104
|
-
|
105
|
-
value % sides
|
106
|
-
end
|
107
|
-
|
108
|
-
#Get a pseudo random byte
|
109
|
-
def byte
|
110
|
-
do_spin
|
111
|
-
@buffer[0] & BYTE
|
112
|
-
end
|
113
|
-
|
114
|
-
#Get a string of random bytes
|
115
|
-
def bytes(length)
|
116
|
-
result = ""
|
117
|
-
length.times {result << byte.chr}
|
118
|
-
result
|
119
|
-
end
|
120
|
-
|
121
|
-
#Get a pseudo random word
|
122
|
-
def word
|
123
|
-
do_spin
|
124
|
-
@buffer[0] & WORD
|
125
|
-
end
|
126
|
-
|
127
|
-
#Get a pseudo random float
|
128
|
-
def float
|
129
|
-
do_spin
|
130
|
-
@buffer[0].to_f / BASE
|
131
|
-
end
|
132
|
-
|
133
|
-
#Cycle through the PRNG count times.
|
134
|
-
def spin(count=1)
|
135
|
-
count.times do
|
136
|
-
do_spin
|
137
|
-
end
|
138
|
-
end
|
139
|
-
|
140
|
-
#Append data to the generator
|
141
|
-
def <<(data)
|
142
|
-
str = data.to_s
|
143
|
-
|
144
|
-
str.each_byte.each do |value|
|
145
|
-
index = @buffer[0] % @depth
|
146
|
-
do_spin
|
147
|
-
@buffer[index] += value
|
148
|
-
do_spin
|
149
|
-
end
|
150
|
-
|
151
|
-
do_spin if str.empty?
|
152
|
-
end
|
153
|
-
|
154
|
-
private
|
155
|
-
|
156
|
-
#A class instance variable to hold the tickle value.
|
157
|
-
@tickle = '0'
|
158
|
-
|
159
|
-
#A synchronizer for access to the @tickle variable
|
160
|
-
@sync = Mutex.new
|
161
|
-
|
162
|
-
#Create the default seed string.
|
163
|
-
def self.new_seed
|
164
|
-
@sync.synchronize {Time.now.to_s + @tickle.succ!}
|
165
|
-
end
|
166
|
-
|
167
|
-
#Do the work of reseeding the PRNG
|
168
|
-
def do_reseed(indxsrc, seedsrc)
|
169
|
-
(32*@depth+768).times do
|
170
|
-
@buffer[indxsrc.next] += seedsrc.next
|
171
|
-
do_spin
|
172
|
-
end
|
48
|
+
#Get a random number from the class based generator. This exists only
|
49
|
+
#for compatibility purposes. It is far better to create instances of
|
50
|
+
#generators than to use a shared, global one.
|
51
|
+
#<br>Returns
|
52
|
+
#* The computed pseudo-random value.
|
53
|
+
def self.rand(max=0)
|
54
|
+
(@hidden ||= FibonacciRng.new).rand(max)
|
173
55
|
end
|
174
56
|
|
175
|
-
#
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
57
|
+
#Initialize the class based generator. This exists only
|
58
|
+
#for compatibility purposes. It is far better to create instances of
|
59
|
+
#generators than to use a shared, global one.
|
60
|
+
#<br>Returns
|
61
|
+
#* The old seed value.
|
62
|
+
def self.srand(seed=FibonacciRng.new_seed, depth=8)
|
63
|
+
old = (@hidden && @hidden.seed)
|
64
|
+
@hidden = FibonacciRng.new(seed, depth)
|
65
|
+
old
|
183
66
|
end
|
184
67
|
|
185
68
|
end
|
data/reek.txt
CHANGED
@@ -1,2 +1 @@
|
|
1
|
-
|
2
|
-
0 total warnings
|
1
|
+
0 total warnings
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: fibonacci_rng
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.4.
|
4
|
+
version: 0.4.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Peter Camilleri
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-03-
|
11
|
+
date: 2016-03-22 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: minitest_visible
|
@@ -106,8 +106,13 @@ files:
|
|
106
106
|
- Gemfile
|
107
107
|
- LICENSE.txt
|
108
108
|
- README.md
|
109
|
+
- fibonacci.reek
|
109
110
|
- fibonacci_rng.gemspec
|
110
111
|
- lib/fibonacci_rng.rb
|
112
|
+
- lib/fibonacci_rng/generator.rb
|
113
|
+
- lib/fibonacci_rng/hasher.rb
|
114
|
+
- lib/fibonacci_rng/seeder.rb
|
115
|
+
- lib/fibonacci_rng/spinner.rb
|
111
116
|
- lib/fibonacci_rng/version.rb
|
112
117
|
- prng.rb
|
113
118
|
- rakefile.rb
|