-
Notifications
You must be signed in to change notification settings - Fork 0
/
problem35.rb
executable file
·69 lines (51 loc) · 1.48 KB
/
problem35.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
#! /usr/bin/env ruby
=begin
The number, 197, is called a circular prime because all rotations of the digits: 197, 971, and 719, are themselves prime.
There are thirteen such primes below 100: 2, 3, 5, 7, 11, 13, 17, 31, 37, 71, 73, 79, and 97.
How many circular primes are there below one million?
=end
require "benchmark"
class Prime
def self.is_circular_prime?(number)
rotations(number).all? { |n| is_prime?(n) }
end
def self.is_prime?(number)
return false if number == 0
return true if number < 3
top = Math.sqrt(number).floor
!((2..top).any? { |f| is_factor?(number, f) })
end
def self.sieve(max)
sieve = []
(2..max).each { |i| sieve[i] = i }
(2..Math.sqrt(max).to_i).each do |i|
next unless sieve[i]
(i ** 2).step(max, i) do |j|
sieve[j] = nil
end
end
sieve.compact
end
# private
def self.is_factor?(number, factor)
number % factor == 0
end
private_class_method :is_factor?
def self.rotations(number)
digits = number.to_s.split(//)
(0..digits.length - 1).collect do |index|
first_part = digits.slice(0, index)
last_part = digits.slice(index, digits.length - index)
(last_part + first_part).join.to_i
end
end
private_class_method :rotations
end
circulars = []
time = Benchmark.measure do
list = Prime.sieve(1000000)
list.each do |number|
circulars << number if Prime.is_circular_prime?(number)
end
end
puts "COUNT: #{circulars.count}, TIME: #{time.inspect}"