kata-algorithms 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
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