prime_multiplication_table 0.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.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: be3fd8276121c35cd3bf8f27e68e130902b7fee2
4
+ data.tar.gz: 71e1a2188bc8f8f0ab2335eac253825a54c1a11a
5
+ SHA512:
6
+ metadata.gz: 82b0212d5ef41ddd16ce8a9912ade4f4a3f2e25532f717aa7054b96028b6b2f8f8af0581268b82e3f675554f13e8267399e2e2a6e543ab4dd660fbdc1ea667f5
7
+ data.tar.gz: 2a7ee9b6966c7dcbdd127b771abe79b6ee80d523a38e3edb955d8c1c83779183da21d537667cb48baa092ef9102848f8572af8ce96f051d64744de0778c65677
@@ -0,0 +1,3 @@
1
+ # Created by .ignore support plugin (hsz.mobi)
2
+ .idea
3
+ .ruby-*
@@ -0,0 +1,19 @@
1
+ # See full list of defaults here: https://github.com/bbatsov/rubocop/blob/master/config/default.yml
2
+ # To see all cops used see here: https://github.com/bbatsov/rubocop/blob/master/config/enabled.yml
3
+
4
+ AllCops:
5
+ TargetRubyVersion: 2.3
6
+ DisplayCopNames: true
7
+
8
+ LineLength:
9
+ Max: 120
10
+
11
+ Style/OpMethod:
12
+ Enabled: false
13
+
14
+ Style/FrozenStringLiteralComment:
15
+ Enabled: false
16
+
17
+ Metrics/BlockLength:
18
+ Exclude:
19
+ - '**/*_spec.rb'
data/Gemfile ADDED
@@ -0,0 +1,12 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in prime_multiplication_table.gemspec
4
+ gemspec
5
+
6
+ group :test do
7
+ gem 'rspec', require: false
8
+ end
9
+
10
+ group :development do
11
+ gem 'rubocop'
12
+ end
@@ -0,0 +1,48 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ prime_multiplication_table (0.1.0)
5
+
6
+ GEM
7
+ remote: https://rubygems.org/
8
+ specs:
9
+ ast (2.3.0)
10
+ diff-lcs (1.3)
11
+ parser (2.4.0.0)
12
+ ast (~> 2.2)
13
+ powerpack (0.1.1)
14
+ rainbow (2.2.2)
15
+ rake
16
+ rake (12.0.0)
17
+ rspec (3.5.0)
18
+ rspec-core (~> 3.5.0)
19
+ rspec-expectations (~> 3.5.0)
20
+ rspec-mocks (~> 3.5.0)
21
+ rspec-core (3.5.4)
22
+ rspec-support (~> 3.5.0)
23
+ rspec-expectations (3.5.0)
24
+ diff-lcs (>= 1.2.0, < 2.0)
25
+ rspec-support (~> 3.5.0)
26
+ rspec-mocks (3.5.0)
27
+ diff-lcs (>= 1.2.0, < 2.0)
28
+ rspec-support (~> 3.5.0)
29
+ rspec-support (3.5.0)
30
+ rubocop (0.48.1)
31
+ parser (>= 2.3.3.1, < 3.0)
32
+ powerpack (~> 0.1)
33
+ rainbow (>= 1.99.1, < 3.0)
34
+ ruby-progressbar (~> 1.7)
35
+ unicode-display_width (~> 1.0, >= 1.0.1)
36
+ ruby-progressbar (1.8.1)
37
+ unicode-display_width (1.2.1)
38
+
39
+ PLATFORMS
40
+ ruby
41
+
42
+ DEPENDENCIES
43
+ prime_multiplication_table!
44
+ rspec
45
+ rubocop
46
+
47
+ BUNDLED WITH
48
+ 1.13.6
@@ -0,0 +1,36 @@
1
+ ### Installation
2
+
3
+ ```bash
4
+ gem install prime_multiplication_table
5
+ ```
6
+
7
+ ### Usage
8
+
9
+ ```bash
10
+ $ prime_multiplication_table
11
+ prime_multiplication_table (version: 0.1.0)
12
+ 2 3 5 7 11 13 17 19 23 29
13
+ 2 4 6 10 14 22 26 34 38 46 58
14
+ 3 6 9 15 21 33 39 51 57 69 87
15
+ 5 10 15 25 35 55 65 85 95 115 145
16
+ 7 14 21 35 49 77 91 119 133 161 203
17
+ 11 22 33 55 77 121 143 187 209 253 319
18
+ 13 26 39 65 91 143 169 221 247 299 377
19
+ 17 34 51 85 119 187 221 289 323 391 493
20
+ 19 38 57 95 133 209 247 323 361 437 551
21
+ 23 46 69 115 161 253 299 391 437 529 667
22
+ 29 58 87 145 203 319 377 493 551 667 841
23
+
24
+
25
+ $ prime_multiplication_table 1
26
+ prime_multiplication_table (version: 0.1.0)
27
+ 2
28
+ 2 4
29
+
30
+
31
+ $ prime_multiplication_table 2
32
+ prime_multiplication_table (version: 0.1.0)
33
+ 2 3
34
+ 2 4 6
35
+ 3 6 9
36
+ ```
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env ruby
2
+ require 'prime_multiplication_table'
3
+ require 'prime_multiplication_table_cli'
4
+
5
+ PrimeMultiplicationTableCLI.run(ARGV)
@@ -0,0 +1,11 @@
1
+ require 'forwardable'
2
+
3
+ # This is main namespace for the library.
4
+ module PrimeMultiplicationTable
5
+ end
6
+
7
+ require 'prime_multiplication_table/version'
8
+ require 'prime_multiplication_table/cache'
9
+ require 'prime_multiplication_table/atkin_sieve'
10
+ require 'prime_multiplication_table/prime'
11
+ require 'prime_multiplication_table/renderer'
@@ -0,0 +1,85 @@
1
+ module PrimeMultiplicationTable
2
+ # AtkinSieve contains implementation of atkin algorithm to find prime numbers.
3
+ module AtkinSieve
4
+ def nth_prime(n)
5
+ return Cache[n] if Cache[n]
6
+ Cache.primes = compute_primes(n)
7
+ Cache[n]
8
+ end
9
+
10
+ private
11
+
12
+ def compute_primes(count)
13
+ return Cache.primes if Cache.size > count
14
+ sieve_size = compute_sieve_size(count)
15
+ atkin_sieve(sieve_size).each_with_index.map { |v, p| p if v }.compact
16
+ end
17
+
18
+ # TODO: 52 should be replaced with algorithm to find range which cover expected count of prime numbers
19
+ #
20
+ # As we know the range 1..10**23 contains 1_925_320_391_606_803_968_923 prime numbers
21
+ # (so, the range contains 1.92 % on prime numbers)
22
+ # to find 100 prime numbers we need to create sieve 100 * (100 / 1.92) or 100 * 52
23
+ def compute_sieve_size(count)
24
+ count * 52
25
+ end
26
+
27
+ def atkin_sieve(sieve_size)
28
+ sieve = init_sieve
29
+ filter_sieve(sieve, sieve_size)
30
+ finalize_sieve(sieve, sieve_size)
31
+ sieve
32
+ end
33
+
34
+ def init_sieve
35
+ # 0, 1, 2, 3
36
+ [nil, nil, true, true]
37
+ end
38
+
39
+ def filter_sieve(sieve, sieve_size)
40
+ sieve_size_sqrt = Math.sqrt(sieve_size).floor
41
+
42
+ (1..sieve_size_sqrt).each do |x|
43
+ (1..sieve_size_sqrt).each do |y|
44
+ filter_sieve_iteration(sieve, sieve_size, x, y)
45
+ end
46
+ end
47
+ end
48
+
49
+ def finalize_sieve(sieve, sieve_size)
50
+ sieve_size_sqrt = Math.sqrt(sieve_size).floor
51
+
52
+ (5..sieve_size_sqrt).each do |n|
53
+ next if Cache[n] || !sieve[n]
54
+ step = n**2
55
+ (step..sieve_size).step(step) do |not_prime|
56
+ sieve[not_prime] = false
57
+ end
58
+ end
59
+ end
60
+
61
+ def filter_sieve_iteration(sieve, sieve_size, x, y)
62
+ x2 = x**2
63
+ y2 = y**2
64
+
65
+ apply_first_filter(sieve, sieve_size, x2, y2)
66
+ apply_second_filter(sieve, sieve_size, x2, y2)
67
+ apply_third_filter(sieve, sieve_size, x2, y2) if x > y
68
+ end
69
+
70
+ def apply_first_filter(sieve, sieve_size, x2, y2)
71
+ n = x2 * 4 + y2
72
+ sieve[n] = !sieve[n] if n <= sieve_size && (n % 12 == 1 || n % 12 == 5)
73
+ end
74
+
75
+ def apply_second_filter(sieve, sieve_size, x2, y2)
76
+ n = x2 * 4 + y2 - x2
77
+ sieve[n] = !sieve[n] if n <= sieve_size && n % 12 == 7
78
+ end
79
+
80
+ def apply_third_filter(sieve, sieve_size, x2, y2)
81
+ n = x2 * 4 + y2 - x2 - 2 * y2
82
+ sieve[n] = !sieve[n] if n <= sieve_size && n % 12 == 11
83
+ end
84
+ end
85
+ end
@@ -0,0 +1,15 @@
1
+ module PrimeMultiplicationTable
2
+ # Cache contains already calculated prime numbers.
3
+ module Cache
4
+ class << self
5
+ extend Forwardable
6
+ attr_writer :primes
7
+
8
+ def_delegators :primes, :[], :[]=, :last, :size
9
+
10
+ def primes
11
+ @primes ||= [2, 3]
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,22 @@
1
+ module PrimeMultiplicationTable
2
+ # Prime contains implementation of comparable prime number.
3
+ class Prime
4
+ include Comparable
5
+ include AtkinSieve
6
+
7
+ attr_reader :value
8
+
9
+ def initialize(position)
10
+ @position = position
11
+ @value = nth_prime(@position)
12
+ end
13
+
14
+ def succ
15
+ self.class.new(@position + 1)
16
+ end
17
+
18
+ def <=>(other)
19
+ @value <=> other.value
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,31 @@
1
+ module PrimeMultiplicationTable
2
+ # Renderer contains implementation of table renderer functionality.
3
+ class Renderer
4
+ def initialize(primes_array)
5
+ @primes_array = primes_array
6
+ end
7
+
8
+ def render
9
+ matrix.map { |r| render_row(r) }.join("\n")
10
+ end
11
+
12
+ private
13
+
14
+ def render_row(row_array)
15
+ row_array.each_with_index.map { |c, i| c.to_s.rjust(cell_size(i)) }.join(' ')
16
+ end
17
+
18
+ def matrix
19
+ @matrix ||= [[nil] + @primes_array] + @primes_array.map do |prime_x|
20
+ @primes_array.each_with_index.each_with_object([]) do |(prime_y, index), result|
21
+ result << prime_x if index.to_i.zero?
22
+ result << prime_x * prime_y
23
+ end
24
+ end
25
+ end
26
+
27
+ def cell_size(cell_index)
28
+ matrix.last[cell_index].to_s.size
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,3 @@
1
+ module PrimeMultiplicationTable
2
+ VERSION = '0.1.0'.freeze
3
+ end
@@ -0,0 +1,19 @@
1
+ # Command line interface of prime_multiplication_table gem.
2
+ module PrimeMultiplicationTableCLI
3
+ DEFAULT_TABLE_SIZE = 10
4
+
5
+ class << self
6
+ def run(args)
7
+ puts "prime_multiplication_table (version: #{PrimeMultiplicationTable::VERSION})"
8
+ size = parse_table_size_argument(args)
9
+ prime_class = PrimeMultiplicationTable::Prime
10
+ array = (prime_class.new(0)...prime_class.new(size)).map(&:value)
11
+ puts PrimeMultiplicationTable::Renderer.new(array).render
12
+ end
13
+
14
+ def parse_table_size_argument(args)
15
+ size = args.first.to_i
16
+ size.positive? ? size : DEFAULT_TABLE_SIZE
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,18 @@
1
+ require File.expand_path('../lib/prime_multiplication_table/version', __FILE__)
2
+
3
+ Gem::Specification.new do |gem|
4
+ gem.name = 'prime_multiplication_table'
5
+ gem.version = PrimeMultiplicationTable::VERSION
6
+ gem.date = '2017-05-08'
7
+ gem.summary = 'Prime multiplication table printer'
8
+ gem.description = 'Ruby gem for printing prime multiplication tables'
9
+ gem.authors = ['Konstantin Lynda']
10
+ gem.email = 'knlynda@gmail.com'
11
+ gem.files = `git ls-files`.split($OUTPUT_RECORD_SEPARATOR)
12
+ gem.test_files = gem.files.grep(%r{^spec/})
13
+ gem.require_paths = ['lib']
14
+ gem.bindir = 'bin'
15
+ gem.executables = gem.files.grep(%r{^bin/}).map { |f| File.basename(f) }
16
+ gem.homepage = 'http://rubygems.org/gems/prime_multiplication_table'
17
+ gem.license = 'MIT'
18
+ end
@@ -0,0 +1,11 @@
1
+ require 'spec_helper'
2
+
3
+ RSpec.describe PrimeMultiplicationTable::Cache do
4
+ it { is_expected.to respond_to :primes, :primes=, :[], :[]=, :last, :size }
5
+
6
+ describe '.primes' do
7
+ subject { described_class.primes }
8
+
9
+ it { is_expected.to eql [2, 3] }
10
+ end
11
+ end
@@ -0,0 +1,71 @@
1
+ require 'spec_helper'
2
+
3
+ RSpec.describe PrimeMultiplicationTable::Prime do
4
+ describe '#succ' do
5
+ subject { described_class.new(position) }
6
+
7
+ context 'when position is zero' do
8
+ let(:position) { 0 }
9
+ it { expect(subject.value).to eql 2 }
10
+ end
11
+
12
+ context 'when position is 1' do
13
+ let(:position) { 1 }
14
+ it { expect(subject.value).to eql 3 }
15
+ end
16
+
17
+ context 'when position is 499' do
18
+ let(:position) { 499 }
19
+ it { expect(subject.value).to eql 3571 }
20
+ end
21
+
22
+ context 'when position is -1' do
23
+ let(:position) { -1 }
24
+ it { expect(subject.value).to eql PrimeMultiplicationTable::Cache[-1] }
25
+ end
26
+
27
+ context 'when position is -500_000' do
28
+ let(:position) { -500_000 }
29
+ it { expect(subject.value).to be_nil }
30
+ end
31
+ end
32
+
33
+ describe '#nth_prime' do
34
+ subject { described_class.new(position).nth_prime(new_position) }
35
+
36
+ context 'when position is zero and new_position is 1' do
37
+ let(:position) { 0 }
38
+ let(:new_position) { 1 }
39
+
40
+ it { is_expected.to eql 3 }
41
+ end
42
+
43
+ context 'when position is zero and new_position is zero' do
44
+ let(:position) { 0 }
45
+ let(:new_position) { 0 }
46
+
47
+ it { is_expected.to eql 2 }
48
+ end
49
+
50
+ context 'when position is zero and new_position is 499' do
51
+ let(:position) { 0 }
52
+ let(:new_position) { 499 }
53
+
54
+ it { is_expected.to eql 3571 }
55
+ end
56
+
57
+ context 'when position is zero and new_position is -1' do
58
+ let(:position) { 0 }
59
+ let(:new_position) { -1 }
60
+
61
+ it { is_expected.to eql PrimeMultiplicationTable::Cache[-1] }
62
+ end
63
+
64
+ context 'when position is zero and new_position is -500_000' do
65
+ let(:position) { 0 }
66
+ let(:new_position) { -500_000 }
67
+
68
+ it { is_expected.to be_nil }
69
+ end
70
+ end
71
+ end
@@ -0,0 +1,22 @@
1
+ require 'spec_helper'
2
+
3
+ RSpec.describe PrimeMultiplicationTable::Renderer do
4
+ describe '#render' do
5
+ subject { described_class.new(table_basis).render }
6
+
7
+ context 'when table_basis is empty' do
8
+ let(:table_basis) { [] }
9
+ it { is_expected.to be_empty }
10
+ end
11
+
12
+ context 'when table_basis is not empty' do
13
+ let(:table_basis) { [1, 2, 3] }
14
+ it { is_expected.to eql " 1 2 3\n1 1 2 3\n2 2 4 6\n3 3 6 9" }
15
+ end
16
+
17
+ context 'when table_basis includes big and small numbers' do
18
+ let(:table_basis) { [11, 2, 33] }
19
+ it { is_expected.to eql " 11 2 33\n11 121 22 363\n 2 22 4 66\n33 363 66 1089" }
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,55 @@
1
+ require 'spec_helper'
2
+
3
+ RSpec.describe PrimeMultiplicationTableCLI do
4
+ describe '.run' do
5
+ subject(:run) { described_class.run(args) }
6
+ let(:renderer) { double }
7
+
8
+ before do
9
+ expect(PrimeMultiplicationTable::Renderer).to receive(:new).with(renderer_args).and_return(renderer)
10
+ expect(renderer).to receive(:render)
11
+ end
12
+
13
+ context 'when args is [0]' do
14
+ let(:args) { [0] }
15
+ let(:renderer_args) { [2, 3, 5, 7, 11, 13, 17, 19, 23, 29] }
16
+
17
+ it { run }
18
+ end
19
+
20
+ context 'when args is [1]' do
21
+ let(:args) { [1] }
22
+ let(:renderer_args) { [2] }
23
+
24
+ it { run }
25
+ end
26
+
27
+ context 'when args is [1]' do
28
+ let(:args) { [1] }
29
+ let(:renderer_args) { [2] }
30
+
31
+ it { run }
32
+ end
33
+
34
+ context 'when args is [5]' do
35
+ let(:args) { [5] }
36
+ let(:renderer_args) { [2, 3, 5, 7, 11] }
37
+
38
+ it { run }
39
+ end
40
+
41
+ context 'when args is [-1]' do
42
+ let(:args) { [-1] }
43
+ let(:renderer_args) { [2, 3, 5, 7, 11, 13, 17, 19, 23, 29] }
44
+
45
+ it { run }
46
+ end
47
+
48
+ context 'when args is ["one"]' do
49
+ let(:args) { ['one'] }
50
+ let(:renderer_args) { [2, 3, 5, 7, 11, 13, 17, 19, 23, 29] }
51
+
52
+ it { run }
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,7 @@
1
+ require 'rubygems'
2
+ require 'bundler/setup'
3
+
4
+ require 'prime_multiplication_table'
5
+ require 'prime_multiplication_table_cli'
6
+
7
+ RSpec.configure(&:disable_monkey_patching!)
metadata ADDED
@@ -0,0 +1,68 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: prime_multiplication_table
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Konstantin Lynda
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2017-05-08 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description: Ruby gem for printing prime multiplication tables
14
+ email: knlynda@gmail.com
15
+ executables:
16
+ - prime_multiplication_table
17
+ extensions: []
18
+ extra_rdoc_files: []
19
+ files:
20
+ - ".gitignore"
21
+ - ".rubocop.yml"
22
+ - Gemfile
23
+ - Gemfile.lock
24
+ - README.md
25
+ - bin/prime_multiplication_table
26
+ - lib/prime_multiplication_table.rb
27
+ - lib/prime_multiplication_table/atkin_sieve.rb
28
+ - lib/prime_multiplication_table/cache.rb
29
+ - lib/prime_multiplication_table/prime.rb
30
+ - lib/prime_multiplication_table/renderer.rb
31
+ - lib/prime_multiplication_table/version.rb
32
+ - lib/prime_multiplication_table_cli.rb
33
+ - prime_multiplication_table.gemspec
34
+ - spec/lib/prime_multiplication_table/cache_spec.rb
35
+ - spec/lib/prime_multiplication_table/prime_spec.rb
36
+ - spec/lib/prime_multiplication_table/renderer_spec.rb
37
+ - spec/prime_multiplication_table_cli_spec.rb
38
+ - spec/spec_helper.rb
39
+ homepage: http://rubygems.org/gems/prime_multiplication_table
40
+ licenses:
41
+ - MIT
42
+ metadata: {}
43
+ post_install_message:
44
+ rdoc_options: []
45
+ require_paths:
46
+ - lib
47
+ required_ruby_version: !ruby/object:Gem::Requirement
48
+ requirements:
49
+ - - ">="
50
+ - !ruby/object:Gem::Version
51
+ version: '0'
52
+ required_rubygems_version: !ruby/object:Gem::Requirement
53
+ requirements:
54
+ - - ">="
55
+ - !ruby/object:Gem::Version
56
+ version: '0'
57
+ requirements: []
58
+ rubyforge_project:
59
+ rubygems_version: 2.5.1
60
+ signing_key:
61
+ specification_version: 4
62
+ summary: Prime multiplication table printer
63
+ test_files:
64
+ - spec/lib/prime_multiplication_table/cache_spec.rb
65
+ - spec/lib/prime_multiplication_table/prime_spec.rb
66
+ - spec/lib/prime_multiplication_table/renderer_spec.rb
67
+ - spec/prime_multiplication_table_cli_spec.rb
68
+ - spec/spec_helper.rb