如果一个数字的所有旋转都是素数,则称为圆形素数。
例如,数字197有两个旋转:971和719.它们都是素数。
在100:2,3,5,7,11,13,17,31,37,71,73,79和97之下有十三个这样的素数。
N下方有多少个圆形素数?
1 <= N <= 1000000
require 'prime'
require 'benchmark'
def circular_prime_count(kk)
primes = []
count = 0
Prime.each(kk) do |prime|
pa= prime.to_s.split('')
flag = true
pa.count.times do |i|
pa.rotate!
flag = false if !Prime.prime?(pa.join.to_i)
end
count+=1 if flag
end
count
end
[100, 200, 1000, 2000 ,10_000, 100_000, 1_000_000 ].each do |number|
puts "Count of primes below #{number} is: #{circular_prime_count(number)}"
Benchmark.bm do |x|
x.report do
circular_prime_count(number)
end
end
end
我对ruby 2.0.0p247的基准是:
100以下的素数是:13
user system total real
0.000000 0.000000 0.000000 ( 0.001891)
200以下的素数是:17
user system total real
0.000000 0.000000 0.000000 ( 0.004775)
1000以下的素数是:25
user system total real
0.010000 0.000000 0.010000 ( 0.005716)
2000以下的素数是:27
user system total real
0.020000 0.000000 0.020000 ( 0.018399)
10000以下的素数是:33
user system total real
0.110000 0.000000 0.110000 ( 0.105365)
100000以下的素数是:43
user system total real
1.790000 0.000000 1.790000 ( 1.789223)
低于1000000的素数是:55
user system total real
43.870000 0.010000 43.880000 ( 43.971832)
你能帮助提高性能,在20秒内找到100万的数量吗?
我的笔记本型号是:HP Probook 4530s
处理器信息:
家庭:Core i5
制造商:英特尔(R)公司
ID:A7 06 02 00 FF FB EB BF
版本:Intel(R)Core(TM)i5-2450M CPU @ 2.50GHz
电压:1.2 V
外部时钟:100 MHz
最高速度:2500 MHz
当前速度:2500 MHz
状态:已填充,已启用
核心数:2
核心已启用:2
线程数:4
谢谢大家,所以最终的解决方案是:
require 'prime'
require 'benchmark'
require 'set'
def circular_prime_count_v2(search_max)
max = if search_max == 10 ** (search_max.to_s.length - 1)
search_max
else
10 ** search_max.to_s.length - 1
end
primes = Prime.each(max).to_set
count = 0
primes.each do |prime|
break if prime > search_max
s = prime.to_s
l = s.length
l.times { |i| primes.include?(((s * 2)[i, l]).to_i) || break } || next
count+=1
end
count
end
[100, 200, 1000, 2000 ,10_000, 100_000, 1_000_000 ].each do |number|
puts "Count of primes below #{number} is: #{circular_prime_count_v2(number)}"
Benchmark.bm do |x|
x.report('circular_prime_count') do
circular_prime_count_v2(number)
end
end
end
100以下的素数计数为:13
user system total real
circular_prime_count 0.000000 0.000000 0.000000 ( 0.000482)
200以下的素数是:17
user system total real
circular_prime_count 0.000000 0.000000 0.000000 ( 0.002683)
1000以下的素数计数为:25
user system total real
circular_prime_count 0.000000 0.000000 0.000000 ( 0.003666)
2000年以下的素数计数是:27
user system total real
circular_prime_count 0.010000 0.000000 0.010000 ( 0.005241)
10000以下的素数是:33
user system total real
circular_prime_count 0.000000 0.000000 0.000000 ( 0.007074)
100000以下的素数计数为:43
user system total real
circular_prime_count 0.060000 0.000000 0.060000 ( 0.057128)
1000000以下的素数计数为:55
user system total real
circular_prime_count 0.720000 0.000000 0.720000 ( 0.727345)
答案 0 :(得分:1)
更新
我创建了一个更快的实现。对于历史价值,它大致基于this post。从我的基本测试(有100万条记录),它比原来快40倍。
require 'prime'
require 'benchmark'
require 'set'
def circular_prime_count(kk)
primes, count = [], 0
Prime.each(kk) do |prime|
pa= prime.to_s.split('')
flag = true
pa.count.times do |i|
pa.rotate!
flag = false if !Prime.prime?(pa.join.to_i)
end
count+=1 if flag
end
count
end
def circular_prime_count_v2(search_max)
primes = Prime.each(search_max).to_set
count = 0
primes.each do |prime|
str = prime.to_s
all_points_match = (0...str.length).collect { |i| primes.include?(((str * 2)[i, str.length]).to_i) || break }
count+=1 if all_points_match
end
count
end
Benchmark.bm do |x|
x.report('circular_prime_count') do
puts " Count: #{circular_prime_count(1000000)}"
end
x.report('circular_prime_count_v2') do
puts " Count: #{circular_prime_count_v2(1000000)}"
end
end
新结果
user system total real
circular_prime_count Count: 55
39.430000 0.080000 39.510000 ( 39.603969)
circular_prime_count_v2 Count: 55
0.900000 0.000000 0.900000 ( 0.906725)