primetable 0.2.2 → 0.2.4

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 06b99246be7a2bfd75f92c7fc00da6244f58e47f
4
- data.tar.gz: 4150b339ac4d875941fae7b3bc09777e431f28ee
3
+ metadata.gz: 299f5fbd29ce75cf104d0f2be372821a59d2d776
4
+ data.tar.gz: 9c18c6aef7dc6c7c500b8902399502a7527712db
5
5
  SHA512:
6
- metadata.gz: c9d32659b42c562551f8fe7365c990aa91a67e8a6eca00f99311010d8ce01b2f50b648bbc174bf9ec25886122346b491d8ddb40411888252c6c0d2eca8040716
7
- data.tar.gz: f67ba3a6d0d7de34e50eace6719ee3efde83e0c4279a19e0b7192b26598eda02207899e0406a2ece6801080dfbf036c5c2ce03b45e13a853521dba100073dff4
6
+ metadata.gz: dcb03e51222e85965ad491a05d4accc773cea77882692ead9f166e800222451f2a7a8f679a6fd31dc0acfe43ddf94dc0d1c2a91b081d5a4048d4860ff11de730
7
+ data.tar.gz: c59603ca941d2cf1fca3f141e25f19165318572cfd95231d2edf44ba909a992dfe16dcb1d1a3eee1e4c17ab4387e765c4c3f477df111c1a6b9b3bafcfead4642
data/Gemfile.lock CHANGED
@@ -1,14 +1,18 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- primetable (0.2.0)
4
+ primetable (0.2.3)
5
+ awesome_print (~> 1.6, >= 1.6.1)
6
+ therubyracer (~> 0.12.2)
5
7
 
6
8
  GEM
7
9
  remote: https://rubygems.org/
8
10
  specs:
9
11
  awesome_print (1.6.1)
10
12
  diff-lcs (1.2.5)
13
+ libv8 (3.16.14.13)
11
14
  rake (10.4.2)
15
+ ref (2.0.0)
12
16
  rspec (3.4.0)
13
17
  rspec-core (~> 3.4.0)
14
18
  rspec-expectations (~> 3.4.0)
@@ -22,16 +26,18 @@ GEM
22
26
  diff-lcs (>= 1.2.0, < 2.0)
23
27
  rspec-support (~> 3.4.0)
24
28
  rspec-support (3.4.0)
29
+ therubyracer (0.12.2)
30
+ libv8 (~> 3.16.14.0)
31
+ ref
25
32
 
26
33
  PLATFORMS
27
34
  ruby
28
35
 
29
36
  DEPENDENCIES
30
- awesome_print
31
37
  bundler (~> 1.6)
32
38
  primetable!
33
- rake
34
- rspec
39
+ rake (~> 10.4, >= 10.4.2)
40
+ rspec (~> 3.4, >= 3.4.0)
35
41
 
36
42
  BUNDLED WITH
37
43
  1.10.6
data/data/prime.dat CHANGED
@@ -13410,4 +13410,4 @@
13410
13410
  [1999121,1999163,1999177,1999187,1999211,1999219,1999223,1999243,1999247,1999273]
13411
13411
  [1999297,1999301,1999303,1999307,1999331,1999339,1999343,1999363,1999379,1999681]
13412
13412
  [1999691,1999703,1999721,1999733,1999771,1999799,1999817,1999819,1999853,1999859]
13413
- [1999867,1999871,1999889,1999891,1999957,1999969,1999979,1999993]
13413
+ [1999867,1999871,1999889,1999891,1999957,1999969,1999979,1999993,2000003,2000029]
data/js/prime.js ADDED
@@ -0,0 +1,87 @@
1
+ var factors = [];
2
+ var primes = [];
3
+
4
+ function libPrime(method, n) {
5
+ if (method === "isPrime" && n === 1) {
6
+ return false;
7
+ }
8
+ if (method === "generatePrimes") {
9
+ var count = 10;
10
+ // console.log("primes.length:"+primes.length);
11
+ while (primes.length<count) {
12
+ if (isPrime(n) && (primes.indexOf(n) === -1)) {
13
+ // console.log("isPrime(n):true:"+n);
14
+ primes.push(n);
15
+ // console.log("primes:"+primes+", primes.length:"+primes.length);
16
+ } else {
17
+ // console.log("isPrime(n):false:"+n);
18
+ n++;
19
+ generatePrimes(n);
20
+ }
21
+ }
22
+ return primes;
23
+ }
24
+ // console.log("* n:"+n);
25
+ // We don't care about divisibility by 1, so we begin at 2
26
+ var divisor = 2;
27
+
28
+ // If a suitable divisor exists it will be less than or equal to the square root of n
29
+ // Due to the commutative property of multiplication
30
+ while ((divisor <= Math.floor(Math.sqrt(n)))) {
31
+ // console.log("** n:"+n+", divisor:"+divisor+", n % divisor:"+(n % divisor));
32
+ if (!(n % divisor)) {
33
+ // console.log("*** n:"+n+", divisor:"+divisor);
34
+ // If n is divisible with remainder zero, then it's non-prime
35
+ switch (method) {
36
+ case "isPrime":
37
+ return false;
38
+ case "primeFactors":
39
+ // The divisor will always be a prime factor
40
+ factors.push(divisor);
41
+ // The quotient may or may not be prime, so we recurse here
42
+ // console.log("**** n:"+n+", divisor:"+divisor+", n/divisor:"+n/divisor);
43
+ primeFactors(n/divisor);
44
+ return factors;
45
+ }
46
+ }
47
+ else {
48
+ // If n is not evenly divisible then we increment the divisor and continue
49
+ if (divisor >= 3) {
50
+ divisor += 2; // Because all even numbers > 2 are non-prime
51
+ } else {
52
+ divisor += 1; // Just once, from 2 to 3
53
+ }
54
+ }
55
+ }
56
+ switch (method) {
57
+ case "isPrime":
58
+ return true;
59
+ case "primeFactors":
60
+ factors.push(n);
61
+ return factors;
62
+ case "generatePrimes":
63
+ primes.push(n);
64
+ }
65
+ }
66
+
67
+ // Returns true if n is prime
68
+ function isPrime(n) {
69
+ return libPrime("isPrime",n);
70
+ }
71
+
72
+ // Returns n if prime, or the prime factors of n if composite
73
+ function primeFactors(n) {
74
+ return libPrime("primeFactors",n);
75
+ }
76
+
77
+ // Generate an array of prime numbers greater than or equal to n with length count
78
+ function generatePrimes(n) {
79
+ return libPrime("generatePrimes",n);
80
+ }
81
+ // Try it out
82
+ // // console.log(isPrime(1));
83
+ // console.log(generatePrimes(1999867));
84
+ // Try it out
85
+ // for (var i = 1; i < 1002; i++) {
86
+ // // console.log(i + " is " + (isPrime(i) ? "PRIME" : "COMPOSITE") + (!(isPrime(i)) ? (": " + primeFactors(i)) : ""));
87
+ // }
data/lib/primetable.rb CHANGED
@@ -1,5 +1,5 @@
1
- # Not sure why this is here. I'll have to experiment with taking it out.
2
- require "primetable/version"
1
+ # Require modules from the lib/primetable directory...right now it's just our VERSION constant
2
+ Dir["#{File.dirname(__FILE__)}/primetable/**/*.rb"].each { |f| require(f) }
3
3
 
4
4
  # This is needed for load_primes method, which loads data from a file.
5
5
  require "yaml"
@@ -7,13 +7,18 @@ require "yaml"
7
7
  # I'll probably remove this later, but it's my interim table display solution.
8
8
  require "awesome_print"
9
9
 
10
+ # So, just for fun, I'm going to write my Ruby prime generation method and a few others as
11
+ # wrappers for some JS functionality I've already written. We'll test as usual. Perhaps, if
12
+ # I ever get around to writing Ruby native versions, we can have them race eachother.
13
+ require "v8"
14
+
10
15
  # It's a pretty simple program. I considered making multiple classes, but it's not necessary.
11
16
  class PrimeTable
12
17
 
13
18
  # We're going to want to get and set things from inside multiple methods, so...
14
19
  attr_accessor :primes, :table
15
20
 
16
- def initialize(first=1, count=10, prime_method=:calc, suppress_output=false)
21
+ def initialize(first=1, count=10, prime_method=:fast, suppress_output=false)
17
22
 
18
23
  # This is only for testing, I'm unlikely to implement a command-line flag for this
19
24
  unless suppress_output
@@ -22,7 +27,7 @@ class PrimeTable
22
27
  end
23
28
 
24
29
  # Ye olde instance variables
25
- @primes = init_primes(:load,first,count)
30
+ @primes = init_primes(prime_method,first,count)
26
31
  @table = build_data(@primes)
27
32
 
28
33
  # I added this suppress_output so I could run certain tests without a huge, admittly
@@ -39,12 +44,11 @@ class PrimeTable
39
44
  # Of course, we calculate the primes by default. But having three methods is not only
40
45
  # fancy; it's also comes in handy for testing that our calculated values are correct.
41
46
  case prime_method
42
- when :fast # Shaves off about between 10 and 40 milliseconds vs. the :load method
43
- [2, 3, 5, 7, 11, 13, 17, 19, 23, 29]
44
-
45
- when :load # Using precalculated values saves us a lot of time vs. the :calc method
47
+ when :fast # Using precalculated values from code. 3-8ms on benchmark run.
48
+ PrimeTable::PRIMES.slice(first-1,count)
49
+ when :load # Using precalculated values from file. 13-23ms on benchmark run.
46
50
  load_primes(first,count)
47
- when :calc # The slowest, but presumably preferred, method in our arsenal
51
+ when :calc # Using JS generated values. 8-16ms on benchmark run.
48
52
  calc_primes(first,count)
49
53
  end # case prime_method
50
54
 
@@ -55,21 +59,29 @@ class PrimeTable
55
59
  # TODO: Include note on average run time using this method.
56
60
  def calc_primes(first, count)
57
61
 
62
+ # One nice thing about this is that I can easily set a timeout, so I someone asks us to run
63
+ # some astronomical prime, we won't seize up the CPU forever. 700ms is arbitrary.
64
+ calc_primes_js = V8::Context.new timeout: 700
65
+ File.open("js/prime.js") do |file|
66
+ calc_primes_js.eval(file, "js/prime.js")
67
+ end
68
+ primes_js = calc_primes_js.eval("generatePrimes(#{first})")
69
+ primes = YAML::load("[#{primes_js}]")
70
+ return primes
71
+
58
72
  end
59
73
 
60
74
  # Loads precalculated primes from a data file. The file is formatted with 10 primes per line.
61
75
  # Each line is enclosed in square brackets, and the primes are comma-delimited. Thus, it's
62
76
  # trivial to read each line in as an array of ten primes. Please note that this file is 995K
63
-
64
77
  # and contains 13413 lines. You don't want to just slurp this file. That would be rude. Instead
65
-
66
78
  # we read lines one at a time and only keep what we need. Also note the highest prime in this
67
- # file is currently 1999993, although conceivably we could use the :calc method and extend it.
79
+ # file is currently 2000029, although conceivably we could use the :calc method and extend it.
68
80
  def load_primes(first, count)
69
81
 
70
- # Again, we only have the first 134128 primes in here right now
71
- if (first + count) > 134128
72
- throw "We only have the first 134128 primes in the data file right now. Please pass -c to use calculated primes."
82
+ # Again, we only have the first 134130 primes in here right now
83
+ if (first + count) > 134130
84
+ throw "We only have the first 134130 primes in the data file right now. Please pass -c to use calculated primes."
73
85
  end
74
86
 
75
87
  # An array to keep our prime numbers in, right?
@@ -77,10 +89,8 @@ class PrimeTable
77
89
 
78
90
  # Because there are ten primes on each line, we can get the line number we're looking for by
79
91
  # dividing the indices we want by 10 and rounding down for the bottom of our range and up for
80
-
81
92
  # the top. It's not immediately intuitive why we might want to do this, but it's because:
82
93
  # 1) We don't want to slurp the whole file...what if the file was even larger? Not cool.
83
-
84
94
  # 2) IO.readlines gets the file one line at a time, so we need a line number, not an index.
85
95
 
86
96
  first_line = (first/10).floor
@@ -1,3 +1,3 @@
1
1
  class PrimeTable
2
- VERSION = "0.2.2"
2
+ VERSION = "0.2.4"
3
3
  end
data/primetable.gemspec CHANGED
@@ -19,6 +19,7 @@ Gem::Specification.new do |spec|
19
19
  spec.require_paths = ["lib"]
20
20
 
21
21
  spec.add_runtime_dependency "awesome_print", '~> 1.6', '>= 1.6.1'
22
+ spec.add_runtime_dependency 'therubyracer', '~> 0.12.2'
22
23
 
23
24
  spec.add_development_dependency "bundler", "~> 1.6"
24
25
  spec.add_development_dependency "rake", '~> 10.4', '>= 10.4.2'
@@ -22,9 +22,11 @@ describe PrimeTable do
22
22
  [23,46,69,115,161,253,299,391,437,529,667],
23
23
  [29,58,87,145,203,319,377,493,551,667,841]]
24
24
  end
25
+
25
26
  it 'has a version number' do
26
27
  expect(PrimeTable::VERSION).not_to be nil
27
28
  end
29
+
28
30
  it 'executes when called on the command line' do
29
31
  expect(`primetable`).to include("PrimeTable is running...\n")
30
32
  end
@@ -46,7 +48,7 @@ describe PrimeTable do
46
48
  expect(execution_output).to include(@expected_version_output)
47
49
  end
48
50
  it 'executes *and* prints out a run time *and* prints out the version number when passed both --time and --version arguments' do
49
- execution_output = `primetable -tv`
51
+ execution_output = `primetable --time --version`
50
52
  expect(execution_output).to include(@expected_execution_output)
51
53
  expect(execution_output).to include(@expected_time_output)
52
54
  expect(execution_output).to include(@expected_version_output)
@@ -57,9 +59,20 @@ describe PrimeTable do
57
59
  execution_output = `primetable --help`
58
60
  expect(execution_output).to include(@expected_help_output)
59
61
  end
62
+
60
63
  it "has the right data when we run it with :load" do
61
64
  test_instance = PrimeTable.new(1,10,:load,true)
62
65
  expect(test_instance.primes).to eq(@expected_first_ten_primes)
63
66
  expect(test_instance.table).to eq(@expected_table_with_first_ten_primes)
64
67
  end
68
+ it "has the right data when we run it with :fast" do
69
+ test_instance = PrimeTable.new(1,10,:fast,true)
70
+ expect(test_instance.primes).to eq(@expected_first_ten_primes)
71
+ expect(test_instance.table).to eq(@expected_table_with_first_ten_primes)
72
+ end
73
+ it "has the right data when we run it with :calc" do
74
+ test_instance = PrimeTable.new(1,10,:calc,true)
75
+ expect(test_instance.primes).to eq(@expected_first_ten_primes)
76
+ expect(test_instance.table).to eq(@expected_table_with_first_ten_primes)
77
+ end
65
78
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: primetable
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.2
4
+ version: 0.2.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Day Davis Waterbury
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-11-21 00:00:00.000000000 Z
11
+ date: 2015-11-22 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: awesome_print
@@ -30,6 +30,20 @@ dependencies:
30
30
  - - ">="
31
31
  - !ruby/object:Gem::Version
32
32
  version: 1.6.1
33
+ - !ruby/object:Gem::Dependency
34
+ name: therubyracer
35
+ requirement: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - "~>"
38
+ - !ruby/object:Gem::Version
39
+ version: 0.12.2
40
+ type: :runtime
41
+ prerelease: false
42
+ version_requirements: !ruby/object:Gem::Requirement
43
+ requirements:
44
+ - - "~>"
45
+ - !ruby/object:Gem::Version
46
+ version: 0.12.2
33
47
  - !ruby/object:Gem::Dependency
34
48
  name: bundler
35
49
  requirement: !ruby/object:Gem::Requirement
@@ -102,6 +116,7 @@ files:
102
116
  - Rakefile
103
117
  - bin/primetable
104
118
  - data/prime.dat
119
+ - js/prime.js
105
120
  - lib/primetable.rb
106
121
  - lib/primetable/version.rb
107
122
  - lib/timer.rb