H
hp gobelli
Hi,
my solution uses a constant amount of memory and is fairly fast, however
understanding the algorithm is left as an exercise to the reader
These are the default tests:
$ time ./sample.rb 5_000_000 1_000_000_000 > big_sample.txt
real 0m52.744s
user 0m47.006s
sys 0m2.092s
$ head big_sample.txt
2
261
445
677
917
1101
1213
1521
1677
1926
$ tail big_sample.txt
999998055
999998267
999998407
999998703
999998970
999999110
999999221
999999439
999999637
999999818
$ ./sample.rb 3 10
1
4
8
$ ./sample.rb 3 10
3
4
7
$ ./sample.rb 3 10
1
3
9
$ ./sample.rb 9 10
0
1
2
3
4
5
6
7
8
$ ./sample.rb 20 400
1
25
46
68
96
109
134
145
173
180
206
228
258
271
298
303
338
348
372
386
....and here is the algorithm:
#! /usr/bin/env ruby
require 'set'
if ARGV.length != 2
puts "Usage: sample MEMBERS LIMIT"
exit
end
members = ARGV[0].to_f
limit = ARGV[1].to_f
raise "Bad parameters" if members > limit
i = -1
range = min_val = 0
sub_limit = limit / members
steps = (limit / sub_limit).ceil.to_i
(0...steps).each do |step|
min_val = (sub_limit * step).floor
range = sub_limit
if i >= min_val
min_val = i + 1
range = sub_limit * step - i
end
i = (rand(1000.0 * range) / 1000.0 + min_val).floor
puts i
end
Regards,
Paolo.
my solution uses a constant amount of memory and is fairly fast, however
understanding the algorithm is left as an exercise to the reader
These are the default tests:
$ time ./sample.rb 5_000_000 1_000_000_000 > big_sample.txt
real 0m52.744s
user 0m47.006s
sys 0m2.092s
$ head big_sample.txt
2
261
445
677
917
1101
1213
1521
1677
1926
$ tail big_sample.txt
999998055
999998267
999998407
999998703
999998970
999999110
999999221
999999439
999999637
999999818
$ ./sample.rb 3 10
1
4
8
$ ./sample.rb 3 10
3
4
7
$ ./sample.rb 3 10
1
3
9
$ ./sample.rb 9 10
0
1
2
3
4
5
6
7
8
$ ./sample.rb 20 400
1
25
46
68
96
109
134
145
173
180
206
228
258
271
298
303
338
348
372
386
....and here is the algorithm:
#! /usr/bin/env ruby
require 'set'
if ARGV.length != 2
puts "Usage: sample MEMBERS LIMIT"
exit
end
members = ARGV[0].to_f
limit = ARGV[1].to_f
raise "Bad parameters" if members > limit
i = -1
range = min_val = 0
sub_limit = limit / members
steps = (limit / sub_limit).ceil.to_i
(0...steps).each do |step|
min_val = (sub_limit * step).floor
range = sub_limit
if i >= min_val
min_val = i + 1
range = sub_limit * step - i
end
i = (rand(1000.0 * range) / 1000.0 + min_val).floor
puts i
end
Regards,
Paolo.