kata-algorithms 0.0.1

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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 90aac947c57fde27f904e20c09ae9276ae21f3b4
4
+ data.tar.gz: 0ebcc3abc31c17bfed448377b3dab7a38019c505
5
+ SHA512:
6
+ metadata.gz: e8ce09b15a615dc8c1f1af17fd194e760f48cc7ff4f61a7a5aac09ef828a97d5ec8cc692d00cf97c592ea3b5b6a6626c41a0caf8e6471020283214afa34f436c
7
+ data.tar.gz: 26624f7cfee3cec901b680c3477d52d5716beae2df75b97c1fda9cbbca2ec14a2ece0f53778b887fb5157edb07914249a9fd6e058fce3fba324c9c73135d3c0c
data/.gitignore ADDED
@@ -0,0 +1,18 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
18
+ .idea
data/.rvmrc ADDED
@@ -0,0 +1,62 @@
1
+ #!/usr/bin/env bash
2
+
3
+ # This is an RVM Project .rvmrc file, used to automatically load the ruby
4
+ # development environment upon cd'ing into the directory
5
+
6
+ # First we specify our desired <ruby>[@<gemset>], the @gemset name is optional,
7
+ # Only full ruby name is supported here, for short names use:
8
+ # echo "rvm use 2.0.0" > .rvmrc
9
+ environment_id="ruby-2.0.0-p247@kata-algorithms"
10
+
11
+ # Uncomment the following lines if you want to verify rvm version per project
12
+ # rvmrc_rvm_version="1.22.3 (stable)" # 1.10.1 seems like a safe start
13
+ # eval "$(echo ${rvm_version}.${rvmrc_rvm_version} | __rvm_awk -F. '{print "[[ "$1*65536+$2*256+$3" -ge "$4*65536+$5*256+$6" ]]"}' )" || {
14
+ # echo "This .rvmrc file requires at least RVM ${rvmrc_rvm_version}, aborting loading."
15
+ # return 1
16
+ # }
17
+
18
+ # First we attempt to load the desired environment directly from the environment
19
+ # file. This is very fast and efficient compared to running through the entire
20
+ # CLI and selector. If you want feedback on which environment was used then
21
+ # insert the word 'use' after --create as this triggers verbose mode.
22
+ if [[ -d "${rvm_path:-$HOME/.rvm}/environments"
23
+ && -s "${rvm_path:-$HOME/.rvm}/environments/$environment_id" ]]
24
+ then
25
+ \. "${rvm_path:-$HOME/.rvm}/environments/$environment_id"
26
+ for __hook in "${rvm_path:-$HOME/.rvm}/hooks/after_use"*
27
+ do
28
+ if [[ -f "${__hook}" && -x "${__hook}" && -s "${__hook}" ]]
29
+ then \. "${__hook}" || true
30
+ fi
31
+ done
32
+ unset __hook
33
+ if (( ${rvm_use_flag:=1} >= 2 )) # display only when forced
34
+ then
35
+ if [[ $- == *i* ]] # check for interactive shells
36
+ then printf "%b" "Using: \E[32m$GEM_HOME\E[0m
37
+ " # show the user the ruby and gemset they are using in green
38
+ else printf "%b" "Using: $GEM_HOME
39
+ " # don't use colors in non-interactive shells
40
+ fi
41
+ fi
42
+ else
43
+ # If the environment file has not yet been created, use the RVM CLI to select.
44
+ rvm --create "$environment_id" || {
45
+ echo "Failed to create RVM environment '${environment_id}'."
46
+ return 1
47
+ }
48
+ fi
49
+
50
+ # If you use bundler, this might be useful to you:
51
+ # if [[ -s Gemfile ]] && {
52
+ # ! builtin command -v bundle >/dev/null ||
53
+ # builtin command -v bundle | GREP_OPTIONS="" \grep $rvm_path/bin/bundle >/dev/null
54
+ # }
55
+ # then
56
+ # printf "%b" "The rubygem 'bundler' is not installed. Installing it now.\n"
57
+ # gem install bundler
58
+ # fi
59
+ # if [[ -s Gemfile ]] && builtin command -v bundle >/dev/null
60
+ # then
61
+ # bundle install | GREP_OPTIONS="" \grep -vE '^Using|Your bundle is complete'
62
+ # fi
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in kata-algorithms.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2013 Panayotis Matsinopoulos
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,40 @@
1
+ # Kata::Algorithms
2
+
3
+ A set of algorithm implementations in Ruby.
4
+
5
+ While reading the book [Algorithms in a Nutshell](http://www.amazon.com/gp/product/059651624X/ref=as_li_qf_sp_asin_il_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=059651624X&linkCode=as2&tag=panayotmatsin-20), we have
6
+ decided to implement a set of the algorithms presented there.
7
+
8
+ ## Installation
9
+
10
+ Add this line to your application's Gemfile:
11
+
12
+ gem 'algorithms'
13
+
14
+ And then execute:
15
+
16
+ $ bundle
17
+
18
+ Or install it yourself as:
19
+
20
+ $ gem install algorithms
21
+
22
+ ## Usage
23
+
24
+ If you want to run a set of programs that use the algorithms
25
+ implemented, you can find them in the `bin` folder.
26
+
27
+ For example:
28
+
29
+ bundle exec bin/addition
30
+
31
+ demonstrates the `Algorithms.addition` algorithm implementation.
32
+
33
+ ## Contributing
34
+
35
+ 1. Fork it
36
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
37
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
38
+ 4. Push to the branch (`git push origin my-new-feature`)
39
+ 5. Create new Pull Request
40
+
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
data/bin/addition ADDED
@@ -0,0 +1,15 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "kata/algorithms"
4
+
5
+ print "Give me the first number: "
6
+ a = gets.strip
7
+
8
+ print "Give me the second number: "
9
+ b = gets.strip
10
+
11
+ result = Kata::Algorithms.addition(a, b)
12
+
13
+ puts "Result is #{result}"
14
+
15
+
@@ -0,0 +1,15 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "kata/algorithms"
4
+
5
+ print "Give me the first number: "
6
+ a = gets.strip
7
+
8
+ print "Give me the second number: "
9
+ b = gets.strip
10
+
11
+ result = Kata::Algorithms.multiplication(a, b)
12
+
13
+ puts "Result is #{result}"
14
+
15
+
@@ -0,0 +1,23 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'kata/algorithms/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "kata-algorithms"
8
+ spec.version = Kata::Algorithms::VERSION
9
+ spec.authors = ["Panayotis Matsinopoulos"]
10
+ spec.email = ["panayotis@matsinopoulos.gr"]
11
+ spec.description = %q{A set of algorithms implementation}
12
+ spec.summary = %q{A series of algorithms implementation. This is more of a practice while reading books about algorithms}
13
+ spec.homepage = ""
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files`.split($/)
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_development_dependency "bundler", "~> 1.3"
22
+ spec.add_development_dependency "rspec"
23
+ end
@@ -0,0 +1,5 @@
1
+ module Kata
2
+ module Algorithms
3
+ VERSION = "0.0.1"
4
+ end
5
+ end
@@ -0,0 +1,134 @@
1
+ require "kata/algorithms/version"
2
+
3
+ module Kata
4
+ module Algorithms
5
+ # ADDITION OF INTEGERS WHEN REPRESENTED AS STRINGS
6
+ # ================================================
7
+ #
8
+ # E.g. "345" + "7890" = "8235"
9
+ #
10
+ # Inspired by the book "Algorithms In a Nutshell - Chapter 2 - The Mathematics of Algorithms"
11
+ #
12
+ # Assume that we have two integers represented as strings, For example:
13
+ #
14
+ # a = "2382738"
15
+ #
16
+ # (a.k.a. `a[1] = "8", a[2] = "3", ... , a[7] = "2"`)
17
+ #
18
+ # and
19
+ #
20
+ # b = "9891829"
21
+ #
22
+ # (a.k.a. `b[1] = "9", b[2] = "2", ..., b[7] = "9"`)
23
+ #
24
+ # Can we calculate their sum, without converting them to integers?
25
+ #
26
+ # c = c[n+1]...c[1] = "12274567"
27
+ #
28
+ # (a.k.a. `c[1] = "7", c[2] = "6", ..., c[7] = "2", c[8] = "1"`)
29
+ #
30
+ # Or in other words, how one would do this addition on a piece of paper?
31
+ #
32
+ # The primitive operations used in this ADDITION algorithm are as follows:
33
+ #
34
+ # c[i] = (a[i] + b[i] + carry[i]) mod 10
35
+ # carry[i+1] = (a[i] + b[i] + carry[i]) >= 10 ? 1 : 0
36
+ #
37
+ # The above algorithm is implemented in this addition. However,
38
+ # there is an optimization, because "mod 10" is an expensive operation.
39
+ # So, we do not use it.
40
+ #
41
+ # Also, we have implemented that so that it can work with operands of
42
+ # different length. So, "a" and 'b" do not have to be of same length.
43
+ #
44
+ # @param a [String] An integer represented as string, e.g. "123412"
45
+ # @param b [String] An integer represented as string, e.g. "3742834"
46
+ # @return [String] The string representation of a + b, e.g. "3866246"
47
+ #
48
+ def self.addition(a, b)
49
+ a = a.split('').reverse
50
+ b = b.split('').reverse
51
+ carry = 0
52
+ i = 0
53
+ c = ""
54
+
55
+ # while I have a digit I process it
56
+ while !a[i].nil? || !b[i].nil?
57
+ result_on_i = a[i].to_i + b[i].to_i + carry # .to_i on nil works perfect. returns 0
58
+ if result_on_i >= 10
59
+ c = "#{result_on_i - 10}#{c}"
60
+ carry = 1
61
+ else
62
+ c = "#{result_on_i}#{c}"
63
+ carry = 0
64
+ end
65
+ i += 1
66
+ end
67
+
68
+ c = "1#{c}" if carry == 1
69
+ c == "" ? "0" : c
70
+ end
71
+
72
+ # MULTIPLICATION OF INTEGERS WHEN REPRESENTED AS STRINGS
73
+ # ======================================================
74
+ #
75
+ # E.g. "345" * "7890" = "2722050"
76
+ #
77
+ # Inspired by the book "Algorithms In a Nutshell - Chapter 2 - The Mathematics of Algorithms"
78
+ #
79
+ # Assume that we have two integers represented as strings, For example:
80
+ #
81
+ # a = "2382738"
82
+ #
83
+ # (a.k.a. `a[1] = "8", a[2] = "3", ... , a[7] = "2"`)
84
+ #
85
+ # and
86
+ #
87
+ # b = "9891829"
88
+ #
89
+ # (a.k.a. `b[1] = "9", b[2] = "2", ..., b[7] = "9"`)
90
+ #
91
+ # Can we calculate their multiplication, without converting them to integers?
92
+ #
93
+ # c = c[k]...c[1] = "23569636847802"
94
+ #
95
+ # (a.k.a. `c[1] = "2", c[2] = "0", ..., c[k] = "2"`)
96
+ #
97
+ #
98
+ # This MULTIPLICAITON algorithm works, more or less, as follows:
99
+ #
100
+ # assume A X B
101
+ #
102
+ # n scans B from right to left
103
+ # m scans A from right to left, for each on of the digits of B
104
+ # result holds the intermediate and final results
105
+ #
106
+ # initialize result to "0"
107
+ #
108
+ # for each digit on B starting from least significant to most significant - scan with n
109
+ # for each digit on A starting from least significant to most significant - scan with m
110
+ # result is increased by B[n] * A[m] * 10^(n+m)
111
+ #
112
+ # at the end of the iterations, result will hold the correct answer
113
+ #
114
+ # Note that we have not used the native addition operation. We have used the
115
+ # +Algorithms.addition+ to increase the results.
116
+ #
117
+ #
118
+ # @param a [String] An integer represented as string, e.g. "123412"
119
+ # @param b [String] An integer represented as string, e.g. "3742834"
120
+ # @return [String] The string representation of a + b, e.g. "461910629608"
121
+ #
122
+ def self.multiplication(a, b)
123
+ a = a.split('')
124
+ b = b.split('')
125
+ result = "0"
126
+ (0..b.size-1).step do |n|
127
+ (0..a.size-1).step do |m|
128
+ result = Kata::Algorithms.addition(result, (b[b.size - 1 - n].to_i * a[a.size - 1 -m].to_i * 10 ** (n + m)).to_s)
129
+ end
130
+ end
131
+ result
132
+ end
133
+ end
134
+ end
@@ -0,0 +1,101 @@
1
+ require 'spec_helper'
2
+
3
+ describe Kata::Algorithms do
4
+ describe ".addition" do
5
+ context 'when a is 2' do
6
+ let(:a) { '2' }
7
+ context 'when b is 8' do
8
+ let(:b) { '8' }
9
+ it { expect(subject.addition(a, b)).to eq((a.to_i + b.to_i).to_s) }
10
+ end
11
+ context 'when b is 123' do
12
+ let(:b) { '123' }
13
+ it { expect(subject.addition(a, b)).to eq((a.to_i + b.to_i).to_s) }
14
+ end
15
+ end
16
+ context 'when a is 32' do
17
+ let(:a) { '32' }
18
+ context 'when b is 8' do
19
+ let(:b) { '8' }
20
+ it { expect(subject.addition(a, b)).to eq((a.to_i + b.to_i).to_s) }
21
+ end
22
+ context 'when b is 123' do
23
+ let(:b) { '123' }
24
+ it { expect(subject.addition(a, b)).to eq((a.to_i + b.to_i).to_s) }
25
+ end
26
+ context 'when b is 92' do
27
+ let(:b) { '92' }
28
+ it { expect(subject.addition(a, b)).to eq((a.to_i + b.to_i).to_s) }
29
+ end
30
+ end
31
+ context 'when a is 0 and b is 0' do
32
+ let(:a) { "0" }
33
+ let(:b) { "0" }
34
+ it { expect(subject.addition(a, b)).to eq((a.to_i + b.to_i).to_s) }
35
+ end
36
+ context 'when a is 0 and b is 20' do
37
+ let(:a) { "0" }
38
+ let(:b) { "20" }
39
+ it { expect(subject.addition(a, b)).to eq((a.to_i + b.to_i).to_s) }
40
+ end
41
+ context 'when a is 1 and b is 1' do
42
+ let(:a) { "0" }
43
+ let(:b) { "20" }
44
+ it { expect(subject.addition(a, b)).to eq((a.to_i + b.to_i).to_s) }
45
+ end
46
+ end
47
+
48
+ describe ".multiplication" do
49
+ context 'when a is 82 and b is 56' do
50
+ let(:a) { "82" }
51
+ let(:b) { "56" }
52
+ it { expect(subject.multiplication(a, b)).to eq((a.to_i * b.to_i).to_s) }
53
+ end
54
+ context 'when a is 2 and b is 10' do
55
+ let(:a) { "2" }
56
+ let(:b) { "10" }
57
+ it { expect(subject.multiplication(a, b)).to eq((a.to_i * b.to_i).to_s) }
58
+ end
59
+ context 'when a is 583 and b is 267' do
60
+ let(:a) { "583" }
61
+ let(:b) { "267" }
62
+ it { expect(subject.multiplication(a, b)).to eq((a.to_i * b.to_i).to_s) }
63
+ end
64
+ context 'when a is 0 and b is 0' do
65
+ let(:a) { "0" }
66
+ let(:b) { "0" }
67
+ it { expect(subject.multiplication(a, b)).to eq((a.to_i * b.to_i).to_s) }
68
+ end
69
+ context "when a is 20 and b is 0" do
70
+ let(:a) { "20" }
71
+ let(:b) { "0" }
72
+ it { expect(subject.multiplication(a, b)).to eq((a.to_i * b.to_i).to_s) }
73
+ end
74
+ context 'when a is 1 and b is 1' do
75
+ let(:a) { "1" }
76
+ let(:b) { "1" }
77
+ it { expect(subject.multiplication(a, b)).to eq((a.to_i * b.to_i).to_s) }
78
+ end
79
+ context 'when a is 1 and b is 0' do
80
+ let(:a) { "1" }
81
+ let(:b) { "0" }
82
+ it { expect(subject.multiplication(a, b)).to eq((a.to_i * b.to_i).to_s) }
83
+ end
84
+ context 'when a is 1 and b is 1000' do
85
+ let(:a) { "1" }
86
+ let(:b) { "1000" }
87
+ it { expect(subject.multiplication(a, b)).to eq((a.to_i * b.to_i).to_s) }
88
+ end
89
+ context 'when a is 345 and b is 7890' do
90
+ let(:a) { "345" }
91
+ let(:b) { "7890" }
92
+ it { expect(subject.multiplication(a, b)).to eq((a.to_i * b.to_i).to_s) }
93
+ end
94
+ context 'when a is 123481023412304981230491234 and b is 123094812309481239481239048123401948123' do
95
+ let(:a) { "123481023412304981230491234" }
96
+ let(:b) { "123094812309481239481239048123401948123" }
97
+ it { expect(subject.multiplication(a, b)).to eq((a.to_i * b.to_i).to_s) }
98
+ end
99
+ end
100
+ end
101
+
@@ -0,0 +1,2 @@
1
+ require 'kata/algorithms'
2
+
metadata ADDED
@@ -0,0 +1,90 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: kata-algorithms
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Panayotis Matsinopoulos
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2013-12-29 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ~>
18
+ - !ruby/object:Gem::Version
19
+ version: '1.3'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ~>
25
+ - !ruby/object:Gem::Version
26
+ version: '1.3'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rspec
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - '>='
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - '>='
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ description: A set of algorithms implementation
42
+ email:
43
+ - panayotis@matsinopoulos.gr
44
+ executables:
45
+ - addition
46
+ - multiplication
47
+ extensions: []
48
+ extra_rdoc_files: []
49
+ files:
50
+ - .gitignore
51
+ - .rvmrc
52
+ - Gemfile
53
+ - LICENSE.txt
54
+ - README.md
55
+ - Rakefile
56
+ - bin/addition
57
+ - bin/multiplication
58
+ - kata-algorithms.gemspec
59
+ - lib/kata/algorithms.rb
60
+ - lib/kata/algorithms/version.rb
61
+ - spec/kata/algorithms_spec.rb
62
+ - spec/spec_helper.rb
63
+ homepage: ''
64
+ licenses:
65
+ - MIT
66
+ metadata: {}
67
+ post_install_message:
68
+ rdoc_options: []
69
+ require_paths:
70
+ - lib
71
+ required_ruby_version: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - '>='
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ required_rubygems_version: !ruby/object:Gem::Requirement
77
+ requirements:
78
+ - - '>='
79
+ - !ruby/object:Gem::Version
80
+ version: '0'
81
+ requirements: []
82
+ rubyforge_project:
83
+ rubygems_version: 2.0.3
84
+ signing_key:
85
+ specification_version: 4
86
+ summary: A series of algorithms implementation. This is more of a practice while reading
87
+ books about algorithms
88
+ test_files:
89
+ - spec/kata/algorithms_spec.rb
90
+ - spec/spec_helper.rb