primetable 1.0.0 → 1.1.0

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: c24c22e449b7f2120749f470e461236d7ed95aac
4
- data.tar.gz: 331b1e2a79c976356115ac1e5fd6528bb6674bd6
3
+ metadata.gz: f529942f1f2d716e11f9609269616f35df535a74
4
+ data.tar.gz: 7edabbe0d6900024c84ea305916e1f0febab1631
5
5
  SHA512:
6
- metadata.gz: 427232225c8ca84f6dcd02be2e15629d5bf8295709b19675567b368dc84ad76f600deaa135096ed5bdf7ffbe5b0c3c0fd98ea1f030ff2c4d26d08637943fbb63
7
- data.tar.gz: 25911f922666fa41e124cc955e562b36df10b74b3fc64256d8efd291bdba9cafcb155809dd1ba93c96e72adf55cc12138a5e9bcbf0d4bb4f47c1bc5a32ecdffa
6
+ metadata.gz: 00104a159da8a03925648e49f8ef36ab92d00e1eb76cded4d178c1b2847f26bc00ae00e2650a5c6aa1b8050c229213f6953268a6521ecbef23c558e96588093a
7
+ data.tar.gz: bb899a0aa5e6d5d646e23604b07b8dae355f2f440e385041caf602ba859175546349a64ecc4c4e337b339e25f0c65abf9fc95028599349d11b54601ede89355f
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- primetable (0.4.0)
4
+ primetable (1.0.0)
5
5
  formatador (~> 0.2, >= 0.2.5)
6
6
  therubyracer (~> 0.12, >= 0.12.2)
7
7
 
data/README.md CHANGED
@@ -13,11 +13,12 @@
13
13
  Usage: primetable [options]
14
14
 
15
15
  Specific options:
16
- --code CODE Select encoding
17
- (jis,sjis,iso-2022-jp,shift_jis,euc-jp,utf8,binary)
16
+ -f F First prime (default is 2, limit is 2000003 w/ -m load|fast, 9007199254740727 w/ -m calc)
17
+ -n N Number of primes for which you wish to generate a table
18
+ -m, --method METHOD Select method of generating primes (fast|load|calc) (default is 'calc')
19
+ -t, --time Display run time
18
20
 
19
21
  Common options:
20
- -t, --time Display run time
21
22
  -h, --help Show this message
22
23
  -v, --version Show version
23
24
 
@@ -19,7 +19,7 @@ class OptParse
19
19
  # The options specified on the command line will be collected in *options*.
20
20
  # We set default values here.
21
21
  options = OpenStruct.new
22
- options.flags = OpenStruct.new({time: false, n: 0, help: false, version: false})
22
+ options.flags = OpenStruct.new({f: 2, n: 10, prime_method: :calc, time: false, version: false, help: false})
23
23
  options.encoding = "utf8"
24
24
 
25
25
  opt_parser = OptionParser.new do |opts|
@@ -27,50 +27,39 @@ class OptParse
27
27
 
28
28
  opts.separator ""
29
29
  opts.separator "Specific options:"
30
-
31
- # This will add a display of the run time to the usual output.
32
- opts.on_tail("-t", "--time", "Display run time") do
33
- options.flags.time = true
34
- end
35
-
36
- # I think we can agree it's wise to limit the starting prime index to no more than 9999999999
37
- opts.on("-f F", Float, "First prime (where count starts). E.g. Default is 2 for the 1st prime.") do |f|
38
- if f.to_i <= 9999999999
39
- options.flags.f = f.to_i
40
- end
30
+
31
+ # The first prime
32
+ opts.on("-f F", Float, "First prime (default is 2, limit is 2000003 w/ -m load|fast, 9007199254740727 w/ -m calc)") do |f|
33
+ options.flags.f = f.to_i
41
34
  end
42
-
43
- # I'm limiting the count arbitraily to 99 here, and silently ignoring requests for counts of 100 or higher
35
+
36
+ # Number of primes
44
37
  opts.on("-n N", Float, "Number of primes for which you wish to generate a table") do |n|
45
- if n.to_i < 99
46
- options.flags.n = n.to_i
47
- end
38
+ options.flags.n = n.to_i
48
39
  end
49
-
50
- # Likewise, here I'm limiting the count arbitraily to 99
51
- opts.on(/[0-9]{1,2}/, "Number of primes for which you wish to generate a table") do |n|
40
+
41
+ # We can also pass the number of primes as N without a swiitch
42
+ opts.on(/[0-9]{1,2}/) do |n|
52
43
  options.flags.n = n.to_i
53
44
  end
54
-
55
- # And finally, here as well I'm limiting the count arbitraily to 99...honestly we can't reasonably display > 20
56
- # I'm also limiting us to starting prime indices 10 digits or less (as above)
57
- opts.on(/[0-9]{1,10},[0-9]{1,2}/, "Number of primes for which you wish to generate a table") do |fn|
45
+
46
+ # We can pass the first prime and the number of primes as F,N without a switch
47
+ opts.on(/[0-9]{1,10},[0-9]{1,2}/) do |fn|
58
48
  options.flags.f = fn.split(",")[0].to_i
59
49
  options.flags.n = fn.split(",")[1].to_i
60
50
  end
61
51
 
62
- opts.on("-m METHOD", "--method METHOD", METHODS, "Select method of generating primes") do |method|
52
+ # Specify a method of generating primes, the options are fast, load, and calc (default is calc)
53
+ opts.on("-m METHOD", "--method METHOD", "Select method of generating primes (fast|load|calc) (default is 'calc')") do |method|
63
54
  options.flags.prime_method = method.to_sym
64
55
  end
65
56
 
66
- # Keyword completion. We are specifying a specific set of arguments (CODES and CODE_ALIASES - notice the
67
- # latter is a Hash), and the user may provide the shortest unambiguous text.
68
- code_list = (CODE_ALIASES.keys + CODES).join(',')
69
- opts.on("--code CODE", CODES, CODE_ALIASES, "Select encoding",
70
- " (#{code_list})") do |encoding|
71
- options.encoding = encoding
57
+ # Add a display of the run time to the usual output.
58
+ opts.on("-t", "--time", "Display run time") do
59
+ options.flags.time = true
72
60
  end
73
61
 
62
+ # For display of the usage instructions
74
63
  opts.separator ""
75
64
  opts.separator "Common options:"
76
65
 
@@ -87,9 +76,9 @@ class OptParse
87
76
 
88
77
  opt_parser.parse!(args)
89
78
  options
90
- end # parse()
79
+ end # parse()
91
80
 
92
- end # class OptParse
81
+ end # class OptParse
93
82
 
94
83
  # copy ARGV so I can check it later after it's gone
95
84
  ARGS = ARGV.clone
@@ -97,62 +86,130 @@ ARGS = ARGV.clone
97
86
  # Parse the options and behave accordingly...this code alters, er, empties ARGV
98
87
  options = OptParse.parse(ARGV)
99
88
 
100
- # Default behavior if no options are passed
101
- if ARGS.length == 0
102
- PrimeTable.new()
89
+ # We might have feedback to display later
90
+ messages = []
91
+
92
+ # Input limitations on first prime (F)
93
+ if options.flags.f > 2000003 and options.flags.prime_method != :calc
94
+ # I'm limiting us to starting primes of 2000003 or less if we're not using :calc
95
+ # This is because the file and the constant only have a certain number of primes
96
+ options.flags.f = 2000003
97
+ messages.push("Warning! The first prime (F) is limited to 2000003 w/ -m load|fast. Try -m calc for F up to 9007199254740727.")
98
+ elsif options.flags.f > 9007199254740727 and options.flags.prime_method == :calc
99
+ # And I'm limiting us to starting primes of 9007199254740727 or less if we are using :calc because JS will time out
100
+ options.flags.f = 9007199254740727
101
+ messages.push("Warning! The first prime (F) is limited to 9007199254740727 w/ -m calc. JS times out after 7 secs.")
103
102
  end
104
103
 
105
- # We default to calculating the primes on the fly
106
- if options.flags.prime_method === nil
107
- options.flags.prime_method = :calc
104
+ # I'm limiting the table display (N) based on what will fit on the screen here.
105
+ # I'm sure there's a crafty equation here that would put this all on one line...but, this will do for now.
106
+ # TODO: Discover the crafty equation
107
+ if options.flags.n > 4
108
+ f = options.flags.f
109
+ if f >= 1 and f <= 7
110
+ n_limit = 24
111
+ elsif f >= 8 and f <= 23
112
+ n_limit = 23
113
+ elsif f >= 24 and f <= 43 # < 2x
114
+ n_limit = 22
115
+ elsif f >= 44 and f <= 199 # > 4x
116
+ n_limit = 21
117
+ elsif f >= 200 and f <= 239 # > 1x
118
+ n_limit = 20
119
+ elsif f >= 240 and f <= 863 # > 3x
120
+ n_limit = 19
121
+ elsif f >= 864 and f <= 907 # > 1x
122
+ n_limit = 18
123
+ elsif f >= 908 and f <= 2999 # > 3x
124
+ n_limit = 17
125
+ elsif f >= 3000 and f <= 3061 # > 1x
126
+ n_limit = 16
127
+ elsif f >= 3062 and f <= 9859 # > 3x
128
+ n_limit = 15
129
+ elsif f >= 9859 and f <= 31489 # > 3x
130
+ n_limit = 14
131
+ elsif f >= 31490 and f <= 99839 # > 3x
132
+ n_limit = 13
133
+ elsif f >= 99839 and f <= 316097 # > 3x
134
+ n_limit = 12
135
+ elsif f >= 316098 and f <= 999863 # > 3x
136
+ n_limit = 11
137
+ elsif f >= 999863 and f <= 3162149 # > 3x
138
+ n_limit = 10
139
+ elsif f >= 3162150 and f <= 31622699 # > 10x
140
+ n_limit = 9
141
+ elsif f >= 31622700 and f <= 316227671 # > 10x
142
+ n_limit = 8
143
+ elsif f >= 316227672 and f <= 9999999851 # > 30x
144
+ n_limit = 7
145
+ elsif f >= 9999999852 and f <= 999999999877 # > 100x
146
+ n_limit = 6
147
+ elsif f >= 999999999878 and f <= 99999999999931 # > 100x
148
+ n_limit = 5
149
+ elsif f >= 99999999999932 and f <= 9007199254740727 # Would be > 100x except JS times out
150
+ n_limit = 4
151
+ end
152
+ if options.flags.n > n_limit
153
+ options.flags.n = n_limit
154
+ messages.push("Warning! Table display (N) is limited to #{n_limit} for F of #{f}. More don't really fit nicely on the screen.")
155
+ end
108
156
  end
109
157
 
110
158
  # Otherwise we do various things based on the options.
111
- # TODO: DRY this up! I'm repeating myself a lot right here.
112
159
  if options.flags.version
113
- puts "PrimeTable v#{PrimeTable::VERSION}"
160
+ messages.push("PrimeTable v#{PrimeTable::VERSION}")
114
161
  end
115
- if options.flags.time
116
- Timer.timer{
117
- if options.flags.f && options.flags.f > 0
118
- if options.flags.n && options.flags.n > 0
119
- PrimeTable.new(options.flags.f,options.flags.n,options.flags.prime_method)
120
- else
121
- # TODO: Pass a hash or args so I don't have order-dependency forcing redundant defaults
122
- PrimeTable.new(options.flags.f,10,options.flags.prime_method)
123
- end
124
- else
125
- if options.flags.n && options.flags.n > 0
126
- # TODO: Pass a hash or args so I don't have order-dependency forcing redundant defaults
127
- PrimeTable.new(2,options.flags.n,options.flags.prime_method)
128
- else
129
- # TODO: Pass a hash or args so I don't have order-dependency forcing redundant defaults
130
- PrimeTable.new(2,10,options.flags.prime_method)
131
- end
132
- end
133
- }
134
- puts "PrimeTable completed in #{Timer.time}"
135
- else
136
- if options.flags.f && options.flags.f > 0
137
- if options.flags.n && options.flags.n > 0
138
- PrimeTable.new(options.flags.f,options.flags.n,options.flags.prime_method)
162
+
163
+ # TODO: DRY this up! I'm repeating myself a lot right here.
164
+ if ARGS != ["-h"]
165
+ if options.flags.time
166
+ Timer.timer{
167
+ if options.flags.f && options.flags.f > 0
168
+ if options.flags.n && options.flags.n > 0
169
+ PrimeTable.new(options.flags.f,options.flags.n,options.flags.prime_method)
170
+ else
171
+ # TODO: Pass a hash or args so I don't have order-dependency forcing redundant defaults
172
+ PrimeTable.new(options.flags.f,10,options.flags.prime_method)
173
+ end
139
174
  else
140
- # TODO: Pass a hash or args so I don't have order-dependency forcing redundant defaults
141
- PrimeTable.new(options.flags.f,10,options.flags.prime_method)
175
+ if options.flags.n && options.flags.n > 0
176
+ # TODO: Pass a hash or args so I don't have order-dependency forcing redundant defaults
177
+ PrimeTable.new(2,options.flags.n,options.flags.prime_method)
178
+ else
179
+ # TODO: Pass a hash or args so I don't have order-dependency forcing redundant defaults
180
+ PrimeTable.new(2,10,options.flags.prime_method)
181
+ end
142
182
  end
143
- else
144
- if options.flags.n && options.flags.n > 0
145
- # TODO: Pass a hash or args so I don't have order-dependency forcing redundant defaults
146
- PrimeTable.new(2,options.flags.n,options.flags.prime_method)
183
+ }
184
+ messages.push("PrimeTable completed in #{Timer.time}")
185
+ else
186
+ if options.flags.f && options.flags.f > 0
187
+ if options.flags.n && options.flags.n > 0
188
+ PrimeTable.new(options.flags.f,options.flags.n,options.flags.prime_method)
189
+ else
190
+ # TODO: Pass a hash or args so I don't have order-dependency forcing redundant defaults
191
+ PrimeTable.new(options.flags.f,10,options.flags.prime_method)
192
+ end
147
193
  else
148
- # TODO: Pass a hash or args so I don't have order-dependency forcing redundant defaults
149
- PrimeTable.new(2,10,options.flags.prime_method)
194
+ if options.flags.n && options.flags.n > 0
195
+ # TODO: Pass a hash or args so I don't have order-dependency forcing redundant defaults
196
+ PrimeTable.new(2,options.flags.n,options.flags.prime_method)
197
+ else
198
+ # TODO: Pass a hash or args so I don't have order-dependency forcing redundant defaults
199
+ PrimeTable.new(2,10,options.flags.prime_method)
200
+ end
150
201
  end
151
- end
202
+ end
152
203
  end
204
+
205
+ # Now display any messages we have accumualted above
206
+ messages.each{|message|
207
+ puts message
208
+ }
209
+
210
+ # And finally the help if they asked for it
153
211
  if options.flags.help
154
212
  puts options.flags.help
155
213
  end
156
- # Eventually, we hope to allow the user to pass a first|start flag as well; currently defaulting to 1
157
214
 
158
215
  exit
@@ -63,11 +63,11 @@ class PrimeTable
63
63
  # Of course, we calculate the primes by default. But having three methods is not only
64
64
  # fancy; it's also comes in handy for testing that our calculated values are correct.
65
65
  case prime_method
66
- when :fast # Using precalculated values from code. 3-8ms on benchmark run.
66
+ when :fast # Using precalculated values from code. 8-17ms, mode 13ms on benchmark (2,10) run, 14-24ms/20ms on (200000,12)
67
67
  fast_primes(first,count)
68
- when :load # Using precalculated values from file. 13-23ms on benchmark run.
68
+ when :load # Using precalculated values from file. 45-256ms, mode 50ms on benchmark (2,10) run, 669-913ms/681ms on (200000,12)
69
69
  load_primes(first,count)
70
- when :calc # Using JS generated values. 8-16ms on benchmark run.
70
+ when :calc # Using JS generated values. 14-84ms, Mode 18ms on benchmark (2,10) run, 17-25ms/21ms on (200000,12)
71
71
  calc_primes(first,count)
72
72
  end # case prime_method
73
73
 
@@ -96,11 +96,11 @@ class PrimeTable
96
96
 
97
97
  # Previously, the 'first' argument was an index, now it's a best guess for the first prime,
98
98
  # so we have to find the index in order to find the line number
99
- if first === 1
99
+ if first == 1
100
100
  first = 2
101
101
  end
102
102
 
103
- if first === 2
103
+ if first == 2
104
104
  wb_before = ""
105
105
  else
106
106
  wb_before = ","
@@ -113,9 +113,9 @@ class PrimeTable
113
113
  end
114
114
 
115
115
  grep_result = []
116
- while grep_result === []
116
+ while grep_result == []
117
117
  grep_result = `grep -n -e "#{wb_before}#{first}#{wb_after}" data/prime.dat`.split(":")
118
- if grep_result === []
118
+ if grep_result == []
119
119
  first = first + 1
120
120
  end
121
121
  end
@@ -149,9 +149,9 @@ class PrimeTable
149
149
  # TODO: Include note on average run time using this method.
150
150
  def calc_primes(first, count)
151
151
 
152
- # One nice thing about this is that I can easily set a timeout, so I someone asks us to run
153
- # some astronomical prime, we won't seize up the CPU forever. 700ms is arbitrary.
154
- calc_primes_js = V8::Context.new timeout: 700
152
+ # One nice thing about this is that I can easily set a timeout, so if someone asks us to run
153
+ # some astronomical prime, we won't seize up the CPU forever. 7000ms is arbitrary.
154
+ calc_primes_js = V8::Context.new timeout: 7000
155
155
  File.open("js/prime.js") do |file|
156
156
  calc_primes_js.eval(file, "js/prime.js")
157
157
  end
@@ -1,3 +1,3 @@
1
1
  class PrimeTable
2
- VERSION = "1.0.0"
2
+ VERSION = "1.1.0"
3
3
  end
@@ -21,8 +21,8 @@ Gem::Specification.new do |spec|
21
21
  spec.add_runtime_dependency 'therubyracer', '~> 0.12', '>= 0.12.2'
22
22
  spec.add_runtime_dependency 'formatador', '~> 0.2', '>= 0.2.5'
23
23
 
24
- spec.add_development_dependency "bundler", "~> 1.6"
25
- spec.add_development_dependency "rake", '~> 10.4', '>= 10.4.2'
26
- spec.add_development_dependency "rspec", '~> 3.4', '>= 3.4.0'
27
- spec.add_development_dependency "pry"
24
+ spec.add_development_dependency 'bundler', "~> 1.6"
25
+ spec.add_development_dependency 'rake', '~> 10.4', '>= 10.4.2'
26
+ spec.add_development_dependency 'rspec', '~> 3.4', '>= 3.4.0'
27
+ spec.add_development_dependency 'pry', '~> 0.10', '>= 0.10.2'
28
28
  end
@@ -5,8 +5,15 @@ describe PrimeTable do
5
5
  @expected_execution_output = "PrimeTable is running...\n"
6
6
  @expected_time_output = "ms"
7
7
  @expected_version_output = PrimeTable::VERSION
8
- @expected_help_output = "Common options:
8
+ @expected_help_output = "Usage: primetable [options]
9
+
10
+ Specific options:
11
+ -f F First prime (default is 2, limit is 2000003 w/ -m load|fast, 9007199254740727 w/ -m calc)
12
+ -n N Number of primes for which you wish to generate a table
13
+ -m, --method METHOD Select method of generating primes (fast|load|calc) (default is 'calc')
9
14
  -t, --time Display run time
15
+
16
+ Common options:
10
17
  -h, --help Show this message
11
18
  -v, --version Show version"
12
19
  @expected_first_ten_primes = [2,3,5,7,11,13,17,19,23,29]
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: primetable
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 1.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Day Davis Waterbury
@@ -108,16 +108,22 @@ dependencies:
108
108
  name: pry
109
109
  requirement: !ruby/object:Gem::Requirement
110
110
  requirements:
111
+ - - "~>"
112
+ - !ruby/object:Gem::Version
113
+ version: '0.10'
111
114
  - - ">="
112
115
  - !ruby/object:Gem::Version
113
- version: '0'
116
+ version: 0.10.2
114
117
  type: :development
115
118
  prerelease: false
116
119
  version_requirements: !ruby/object:Gem::Requirement
117
120
  requirements:
121
+ - - "~>"
122
+ - !ruby/object:Gem::Version
123
+ version: '0.10'
118
124
  - - ">="
119
125
  - !ruby/object:Gem::Version
120
- version: '0'
126
+ version: 0.10.2
121
127
  description: Displays the products of N primes in a table format. Optionally uses
122
128
  generated primes or precalculated.
123
129
  email: