algorithms 0.2.0 → 1.0.0

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
+ SHA256:
3
+ metadata.gz: 7cee1c06e078dc124212a3462d765d26ce5fbe16dd6b31ca6392388d8f51644c
4
+ data.tar.gz: 491e3540ee5567752d208bb7b8502d1ee998b55e9664c66b5cf5fc17394e10e7
5
+ SHA512:
6
+ metadata.gz: a4a533a2053ae799f87df22b51ff93744e8128e0982239f3d6717bfb6f8ee8817d9c6ebffd6b4a2b478694a3f2f742fc4465eba242e5d2d0d23bfc0c881c1daa
7
+ data.tar.gz: 4ffaed30fc92fca18dd258102a702f8fceb1a77594ac6b086c627e1a3ab8ae1ad6650295acd0fb423a6ce441b6b7ab686bb56ae9ff937448d031f319d937a427
@@ -1,3 +1,28 @@
1
+ === January 22, 2013
2
+
3
+ * JRuby support
4
+
5
+ === April 15, 2012
6
+
7
+ * Use long instead of int for string methods
8
+ * Use VALUE instead of int for comparison vars
9
+ * Now compiles without warnings (OS X 10.7)
10
+
11
+ === April 19, 2012
12
+
13
+ * Pulled in fix for ruby 1.9 compilation error (sorry!!)
14
+ * Fix specs that broke with new rspec
15
+ * Migration to rubygems.org
16
+ * 0.4.0 release
17
+
18
+ === Jan 3, 2009
19
+
20
+ * Levenshtein distance in C
21
+
22
+ === April 3, 2009
23
+
24
+ * Finished C refactorization of SplayTree
25
+
1
26
  === March 28, 2009
2
27
 
3
28
  * Implemented SplayTree in C
data/Gemfile ADDED
@@ -0,0 +1,9 @@
1
+ source "https://rubygems.org"
2
+
3
+ gemspec
4
+
5
+ group :development do
6
+ gem "rspec"
7
+ gem "rake-compiler"
8
+ end
9
+
data/Manifest CHANGED
@@ -1,17 +1,25 @@
1
+ CHANGELOG.markdown
2
+ Manifest
3
+ README.markdown
4
+ Rakefile
1
5
  algorithms.gemspec
2
6
  benchmarks/deque.rb
3
7
  benchmarks/sorts.rb
4
8
  benchmarks/treemaps.rb
9
+ ext/algorithms/string/extconf.rb
10
+ ext/algorithms/string/string.c
11
+ ext/containers/bst/bst.c
12
+ ext/containers/bst/extconf.rb
5
13
  ext/containers/deque/deque.c
6
14
  ext/containers/deque/extconf.rb
7
15
  ext/containers/rbtree_map/extconf.rb
8
16
  ext/containers/rbtree_map/rbtree.c
9
17
  ext/containers/splaytree_map/extconf.rb
10
18
  ext/containers/splaytree_map/splaytree.c
11
- History.txt
19
+ lib/algorithms.rb
12
20
  lib/algorithms/search.rb
13
21
  lib/algorithms/sort.rb
14
- lib/algorithms.rb
22
+ lib/algorithms/string.rb
15
23
  lib/containers/deque.rb
16
24
  lib/containers/heap.rb
17
25
  lib/containers/kd_tree.rb
@@ -22,20 +30,22 @@ lib/containers/splay_tree_map.rb
22
30
  lib/containers/stack.rb
23
31
  lib/containers/suffix_array.rb
24
32
  lib/containers/trie.rb
25
- Manifest
26
- Rakefile
27
- README.markdown
33
+ spec/bst_gc_mark_spec.rb
34
+ spec/bst_spec.rb
28
35
  spec/deque_gc_mark_spec.rb
29
36
  spec/deque_spec.rb
30
37
  spec/heap_spec.rb
38
+ spec/kd_expected_out.txt
39
+ spec/kd_test_in.txt
31
40
  spec/kd_tree_spec.rb
41
+ spec/map_gc_mark_spec.rb
32
42
  spec/priority_queue_spec.rb
33
43
  spec/queue_spec.rb
34
- spec/rb_tree_map_gc_mark_spec.rb
35
44
  spec/rb_tree_map_spec.rb
36
45
  spec/search_spec.rb
37
46
  spec/sort_spec.rb
38
47
  spec/splay_tree_map_spec.rb
39
48
  spec/stack_spec.rb
49
+ spec/string_spec.rb
40
50
  spec/suffix_array_spec.rb
41
51
  spec/trie_spec.rb
data/README.markdown CHANGED
@@ -1,7 +1,6 @@
1
- # algorithms
1
+ # algorithms [![Build Status](https://travis-ci.org/kanwei/algorithms.png)](https://travis-ci.org/kanwei/algorithms)
2
2
 
3
- * Official homes are here on github, and at [rubyforge](http://rubyforge.org/projects/algorithms/)
4
- * Documentation: [http://algorithms.rubyforge.org/](http://algorithms.rubyforge.org/)
3
+ [API Documentation](http://kanwei.github.io/algorithms/)
5
4
 
6
5
  ## DESCRIPTION:
7
6
 
@@ -9,7 +8,9 @@ Started as a [Google Summer of Code 2008](http://code.google.com/soc/2008/ruby/a
9
8
 
10
9
  Written by [Kanwei Li](http://kanwei.com/), mentored by Austin Ziegler
11
10
 
12
- Original Proposal: Using the right data structure or algorithm for the situation is an important
11
+ ### Original Proposal: ###
12
+
13
+ Using the right data structure or algorithm for the situation is an important
13
14
  aspect of programming. In computer science literature, many data structures
14
15
  and algorithms have been researched and extensively documented. However, there
15
16
  is still no standard library in Ruby implementing useful structures and
@@ -18,75 +19,48 @@ This project will create such a library with documentation on when to use a
18
19
  particular structure/algorithm. It will also come with a benchmark suite to
19
20
  compare performance in different situations.
20
21
 
21
- ## FEATURES:
22
-
23
- Done so far:
24
-
25
- * Heaps Containers::Heap, Containers::MaxHeap, Containers::MinHeap
26
- * Priority Queue Containers::PriorityQueue
27
- * Deque Containers::Deque, Containers::CDeque (C extension), Containers::RubyDeque
28
- * Stack Containers::Stack (uses Deque)
29
- * Queue Containers::Queue (uses Deque)
30
- * Red-Black Trees Containers::RBTreeMap, Containers::CRBTreeMap (C extension), Containers::RubyRBTreeMap
31
- * Splay Trees Containers::SplayTreeMap, Containers::CSplayTreeMap (C extension), Containers::RubySplayTreeMap
32
- * Tries Containers::Trie
33
- * Suffix Array Containers::SuffixArray
34
-
35
- * Search algorithms
36
- - Binary Search Algorithms::Search.binary_search
37
- - Knuth-Morris-Pratt Algorithms::Search.kmp_search
38
- * Sort algorithms
39
- - Bubble sort Algorithms::Sort.bubble_sort
40
- - Comb sort Algorithms::Sort.comb_sort
41
- - Selection sort Algorithms::Sort.selection_sort
42
- - Heapsort Algorithms::Sort.heapsort
43
- - Insertion sort Algorithms::Sort.insertion_sort
44
- - Shell sort Algorithms::Sort.shell_sort
45
- - Quicksort Algorithms::Sort.quicksort
46
- - Mergesort Algorithms::Sort.mergesort
22
+ ## COMPLETED:
23
+
24
+ * Heaps Containers::Heap, Containers::MaxHeap, Containers::MinHeap
25
+ * Priority Queue Containers::PriorityQueue
26
+ * Deque Containers::Deque, Containers::CDeque (C ext)
27
+ * Stack Containers::Stack
28
+ * Queue Containers::Queue
29
+ * Red-Black Trees Containers::RBTreeMap, Containers::CRBTreeMap (C ext)
30
+ * Splay Trees Containers::SplayTreeMap, Containers::CSplayTreeMap (C ext)
31
+ * Tries Containers::Trie
32
+ * Suffix Array Containers::SuffixArray
33
+
34
+ * Search algorithms
35
+ - Binary Search Algorithms::Search.binary_search
36
+ - Knuth-Morris-Pratt Algorithms::Search.kmp_search
37
+ * Sorting algorithms
38
+ - Bubble sort Algorithms::Sort.bubble_sort
39
+ - Comb sort Algorithms::Sort.comb_sort
40
+ - Selection sort Algorithms::Sort.selection_sort
41
+ - Heapsort Algorithms::Sort.heapsort
42
+ - Insertion sort Algorithms::Sort.insertion_sort
43
+ - Shell sort Algorithms::Sort.shell_sort
44
+ - Quicksort Algorithms::Sort.quicksort
45
+ - Mergesort Algorithms::Sort.mergesort
46
+ - Dual-Pivot Quicksort Algorithms::Sort.dualpivotquicksort
47
47
 
48
48
  ## SYNOPSIS:
49
49
 
50
- require 'rubygems'
51
- require 'algorithms'
52
-
53
- max_heap = Containers::MaxHeap.new
54
-
55
- # To not have to type "Containers::" before each class, use:
56
- include Containers
57
- max_heap = MaxHeap.new
58
-
50
+ require 'rubygems'
51
+ require 'algorithms'
59
52
 
60
- ## REQUIREMENTS:
53
+ max_heap = Containers::MaxHeap.new
61
54
 
62
- * Ruby 1.8 compatible Ruby, or Ruby 1.9
63
- * C compiler for C extensions (optional, but very much recommended for vast performance benefits)
55
+ # To not have to type "Containers::" before each class, use:
56
+ include Containers
57
+ max_heap = MaxHeap.new
64
58
 
65
- ## INSTALL:
59
+ ## REQUIREMENTS:
66
60
 
67
- * sudo gem install algorithms
61
+ * Ruby 1.8, Ruby 1.9, JRuby
62
+ * C extensions (optional, but very much recommended for vast performance benefits)
68
63
 
69
64
  ## LICENSE:
70
65
 
71
- (The MIT License)
72
-
73
- Algorithms and Containers project is Copyright (c) 2009 Kanwei Li
74
-
75
- Permission is hereby granted, free of charge, to any person obtaining
76
- a copy of this software and associated documentation files (the
77
- 'Software'), to deal in the Software without restriction, including
78
- without limitation the rights to use, copy, modify, merge, publish,
79
- distribute, sublicense, and/or sell copies of the Software, and to
80
- permit persons to whom the Software is furnished to do so, subject to
81
- the following conditions:
82
-
83
- The above copyright notice and this permission notice shall be
84
- included in all copies or substantial portions of the Software.
85
-
86
- THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
87
- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
88
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
89
- IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
90
- CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
91
- TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
92
- SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
66
+ See [LICENSE.md](LICENSE.md).
data/Rakefile CHANGED
@@ -1,31 +1,22 @@
1
1
  require 'rubygems'
2
- require 'echoe'
3
-
4
- Echoe.new('algorithms') do |p|
5
- p.author = 'Kanwei Li'
6
- p.email = 'kanwei@gmail.com'
7
- p.summary = 'A library of algorithms and containers.'
8
- p.url = 'http://rubyforge.org/projects/algorithms/'
9
- p.version = "0.2.0"
10
- p.runtime_dependencies = []
11
- end
12
-
13
- task :default => :spec
2
+ require 'rake/extensiontask'
3
+ require 'rspec/core/rake_task'
4
+ require 'bundler/gem_tasks'
14
5
 
15
- task :spec do
16
- sh "spec spec/*.rb --color"
17
- end
6
+ Rake::ExtensionTask.new('algorithms/string') { |ext| ext.name = "CString" }
7
+ Rake::ExtensionTask.new('containers/deque') { |ext| ext.name = "CDeque" }
8
+ Rake::ExtensionTask.new('containers/bst') { |ext| ext.name = "CBst" }
9
+ Rake::ExtensionTask.new('containers/rbtree_map') { |ext| ext.name = "CRBTreeMap" }
10
+ Rake::ExtensionTask.new('containers/splaytree_map') { |ext| ext.name = "CSplayTreeMap" }
18
11
 
19
- task :push do
20
- sh "git push" # Rubyforge
21
- sh "git push --tags" # Rubyforge
22
- sh "git push gh" # Github
23
- sh "git push gh --tags" # Github
24
- end
12
+ RSpec::Core::RakeTask.new
25
13
 
26
- task :hanna do
27
- sh "rm -fr doc"
28
- sh "hanna -SN lib/ -m Algorithms"
29
- sh "scp -rq doc/* kanwei@rubyforge.org:/var/www/gforge-projects/algorithms"
14
+ if defined?(RUBY_ENGINE) && RUBY_ENGINE == 'jruby'
15
+ task :default => [:spec]
16
+ else
17
+ task :default => [:compile, :spec]
30
18
  end
31
19
 
20
+ task :rdoc do
21
+ `rdoc -f hanna --main algorithms.rb -t "Ruby Algorithms and Containers Documentation"`
22
+ end
data/algorithms.gemspec CHANGED
@@ -1,32 +1,22 @@
1
1
  # -*- encoding: utf-8 -*-
2
2
 
3
3
  Gem::Specification.new do |s|
4
- s.name = %q{algorithms}
5
- s.version = "0.2.0"
4
+ s.name = "algorithms"
5
+ s.version = "1.0.0"
6
6
 
7
- s.required_rubygems_version = Gem::Requirement.new(">= 1.2") if s.respond_to? :required_rubygems_version=
8
7
  s.authors = ["Kanwei Li"]
9
- s.date = %q{2009-03-29}
10
- s.description = %q{A library of algorithms and containers.}
11
- s.email = %q{kanwei@gmail.com}
12
- s.extensions = ["ext/containers/deque/extconf.rb", "ext/containers/rbtree_map/extconf.rb", "ext/containers/splaytree_map/extconf.rb"]
13
- s.extra_rdoc_files = ["ext/containers/deque/deque.c", "ext/containers/deque/extconf.rb", "ext/containers/rbtree_map/extconf.rb", "ext/containers/rbtree_map/rbtree.c", "ext/containers/splaytree_map/extconf.rb", "ext/containers/splaytree_map/splaytree.c", "lib/algorithms/search.rb", "lib/algorithms/sort.rb", "lib/algorithms.rb", "lib/containers/deque.rb", "lib/containers/heap.rb", "lib/containers/kd_tree.rb", "lib/containers/priority_queue.rb", "lib/containers/queue.rb", "lib/containers/rb_tree_map.rb", "lib/containers/splay_tree_map.rb", "lib/containers/stack.rb", "lib/containers/suffix_array.rb", "lib/containers/trie.rb", "README.markdown"]
14
- s.files = ["algorithms.gemspec", "benchmarks/deque.rb", "benchmarks/sorts.rb", "benchmarks/treemaps.rb", "ext/containers/deque/deque.c", "ext/containers/deque/extconf.rb", "ext/containers/rbtree_map/extconf.rb", "ext/containers/rbtree_map/rbtree.c", "ext/containers/splaytree_map/extconf.rb", "ext/containers/splaytree_map/splaytree.c", "History.txt", "lib/algorithms/search.rb", "lib/algorithms/sort.rb", "lib/algorithms.rb", "lib/containers/deque.rb", "lib/containers/heap.rb", "lib/containers/kd_tree.rb", "lib/containers/priority_queue.rb", "lib/containers/queue.rb", "lib/containers/rb_tree_map.rb", "lib/containers/splay_tree_map.rb", "lib/containers/stack.rb", "lib/containers/suffix_array.rb", "lib/containers/trie.rb", "Manifest", "Rakefile", "README.markdown", "spec/deque_gc_mark_spec.rb", "spec/deque_spec.rb", "spec/heap_spec.rb", "spec/kd_tree_spec.rb", "spec/priority_queue_spec.rb", "spec/queue_spec.rb", "spec/rb_tree_map_gc_mark_spec.rb", "spec/rb_tree_map_spec.rb", "spec/search_spec.rb", "spec/sort_spec.rb", "spec/splay_tree_map_spec.rb", "spec/stack_spec.rb", "spec/suffix_array_spec.rb", "spec/trie_spec.rb"]
15
- s.has_rdoc = true
16
- s.homepage = %q{http://rubyforge.org/projects/algorithms/}
17
- s.rdoc_options = ["--line-numbers", "--inline-source", "--title", "Algorithms", "--main", "README.markdown"]
18
- s.require_paths = ["lib", "ext"]
19
- s.rubyforge_project = %q{algorithms}
20
- s.rubygems_version = %q{1.3.1}
21
- s.summary = %q{A library of algorithms and containers.}
22
-
23
- if s.respond_to? :specification_version then
24
- current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
25
- s.specification_version = 2
26
-
27
- if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
28
- else
29
- end
8
+ s.email = "kanwei@gmail.com"
9
+ s.license = 'MIT'
10
+ s.date = "2021-04-04"
11
+ s.summary = "Useful algorithms and data structures for Ruby. Optional C extensions."
12
+ s.description = "Heap, Priority Queue, Deque, Stack, Queue, Red-Black Trees, Splay Trees, sorting algorithms, and more"
13
+ if defined?(RUBY_ENGINE) && RUBY_ENGINE == 'jruby'
14
+ s.platform = "java"
30
15
  else
16
+ s.extensions = ["ext/algorithms/string/extconf.rb", "ext/containers/bst/extconf.rb", "ext/containers/deque/extconf.rb", "ext/containers/rbtree_map/extconf.rb", "ext/containers/splaytree_map/extconf.rb"]
31
17
  end
18
+ s.files = ["Gemfile", "CHANGELOG.markdown", "Manifest", "README.markdown", "Rakefile", "algorithms.gemspec", "benchmarks/deque.rb", "benchmarks/sorts.rb", "benchmarks/treemaps.rb", "ext/algorithms/string/extconf.rb", "ext/algorithms/string/string.c", "ext/containers/bst/bst.c", "ext/containers/bst/extconf.rb", "ext/containers/deque/deque.c", "ext/containers/deque/extconf.rb", "ext/containers/rbtree_map/extconf.rb", "ext/containers/rbtree_map/rbtree.c", "ext/containers/splaytree_map/extconf.rb", "ext/containers/splaytree_map/splaytree.c", "lib/algorithms.rb", "lib/algorithms/search.rb", "lib/algorithms/sort.rb", "lib/algorithms/string.rb", "lib/containers/deque.rb", "lib/containers/heap.rb", "lib/containers/kd_tree.rb", "lib/containers/priority_queue.rb", "lib/containers/queue.rb", "lib/containers/rb_tree_map.rb", "lib/containers/splay_tree_map.rb", "lib/containers/stack.rb", "lib/containers/suffix_array.rb", "lib/containers/trie.rb", "spec/bst_gc_mark_spec.rb", "spec/bst_spec.rb", "spec/deque_gc_mark_spec.rb", "spec/deque_spec.rb", "spec/heap_spec.rb", "spec/kd_expected_out.txt", "spec/kd_test_in.txt", "spec/kd_tree_spec.rb", "spec/map_gc_mark_spec.rb", "spec/priority_queue_spec.rb", "spec/queue_spec.rb", "spec/rb_tree_map_spec.rb", "spec/search_spec.rb", "spec/sort_spec.rb", "spec/splay_tree_map_spec.rb", "spec/stack_spec.rb", "spec/string_spec.rb", "spec/suffix_array_spec.rb", "spec/trie_spec.rb"]
19
+ s.homepage = "https://github.com/kanwei/algorithms"
20
+ s.rdoc_options = ["--line-numbers", "--inline-source", "--title", "Algorithms", "--main", "README.markdown"]
21
+ s.require_paths = ["lib", "ext"]
32
22
  end
@@ -1,20 +1,19 @@
1
1
  $: << File.join(File.expand_path(File.dirname(__FILE__)), '../lib')
2
2
  require 'algorithms'
3
- include Algorithms
3
+ include Containers
4
4
 
5
5
  require 'rubygems'
6
6
  require 'rbench'
7
7
 
8
- RBench.run(10) do
8
+ RBench.run(2) do
9
9
  trees = %w(hash rbtree splaytree)
10
10
  trees.each { |tree| self.send(:column, tree.intern) }
11
11
 
12
- rbtree = Containers::RBTreeMap.new
13
- splaytree = Containers::SplayTreeMap.new
12
+ rbtree = RBTreeMap.new
13
+ splaytree = SplayTreeMap.new
14
14
  hash = Hash.new
15
15
 
16
- random_array = Array.new(10000) { |i| rand(i) }
17
- num = 1000
16
+ random_array = Array.new(300000) { |i| rand(i) }
18
17
 
19
18
  report "Insertion" do
20
19
  rbtree { random_array.each_with_index { |x,index| rbtree[index] = x } }
@@ -22,15 +21,31 @@ RBench.run(10) do
22
21
  hash { random_array.each_with_index { |x,index| hash[index] = x } }
23
22
  end
24
23
 
25
- report "has_key?" do
26
- rbtree { num.times { |n| rbtree.has_key?(n) } }
27
- splaytree { num.times { |n| splaytree.has_key?(n) } }
28
- hash { num.times { |n| hash.has_key?(n) } }
24
+ report "has_key? (linear order)" do
25
+ rbtree { random_array.each { |n| rbtree.has_key?(n) } }
26
+ splaytree { random_array.each { |n| splaytree.has_key?(n) } }
27
+ hash { random_array.each { |n| hash.has_key?(n) } }
29
28
  end
30
29
 
31
30
  report "Lookup in sorted order" do
32
31
  rbtree { rbtree.each { |k, v| k } }
33
32
  splaytree { splaytree.each { |k, v| k } }
34
33
  hash { hash.sort.each { |k, v| k } }
34
+
35
+ # a1, a2, a3 = [], [], []
36
+ # rbtree.each { |k, v| a1 << k }
37
+ # splaytree.each { |k, v| a2 << k }
38
+ # hash.sort.each { |k, v| a3 << k }
39
+ #
40
+ # puts "Lookup correct" if a1 == a2 && a1 == a3
35
41
  end
42
+
43
+ report "Random lookups in a smaller subset" do
44
+ select_subset = random_array[0..random_array.size/20] # 5%
45
+ size = select_subset.size
46
+ rbtree { 10000.times { rbtree[ select_subset[rand(size)] ] } }
47
+ splaytree { 10000.times { splaytree[ select_subset[rand(size)] ] } }
48
+ hash { 10000.times { hash[ select_subset[rand(size)] ] } }
49
+ end
50
+
36
51
  end
@@ -0,0 +1,4 @@
1
+ require 'mkmf'
2
+ extension_name = "CString"
3
+ dir_config(extension_name)
4
+ create_makefile(extension_name)
@@ -0,0 +1,68 @@
1
+ #include "ruby.h"
2
+
3
+ long min_three(long a, long b, long c) {
4
+ long min = a;
5
+ if (b < min)
6
+ min = b;
7
+ if( c < min)
8
+ min = c;
9
+ return min;
10
+ }
11
+
12
+ long levenshtein_distance(VALUE str1, VALUE str2) {
13
+ long i, j, s1_len, s2_len, *d;
14
+ char * s = RSTRING_PTR(str1);
15
+ char * t = RSTRING_PTR(str2);
16
+ s1_len = RSTRING_LEN(str1);
17
+ s2_len = RSTRING_LEN(str2);
18
+
19
+ if (s1_len == 0) {
20
+ return s2_len;
21
+ } else if (s2_len == 0) {
22
+ return s1_len;
23
+ }
24
+
25
+ // We need one extra col and row for the matrix for starting values
26
+ s1_len++;
27
+ s2_len++;
28
+
29
+ d = xmalloc(sizeof(typeof(d)) * s1_len * s2_len);
30
+
31
+ for (i = 0; i < s1_len; i++) {
32
+ d[i] = i; // d[i, 0] = i
33
+ }
34
+ for (j = 0; j < s2_len; j++) {
35
+ d[j*s1_len] = j; // d[0, j] = j
36
+ }
37
+
38
+ for (i = 1; i < s1_len; i++) {
39
+ for (j = 1; j < s2_len; j++) {
40
+ if (s[i-1] == t[j-1]) {
41
+ d[j * s1_len + i] = d[(j-1) * s1_len + (i-1)];
42
+ } else {
43
+ d[j * s1_len + i] = 1 + min_three(
44
+ d[j * s1_len + (i-1)],
45
+ d[(j-1) * s1_len + i],
46
+ d[(j-1) * s1_len + (i-1)]
47
+ );
48
+ }
49
+ }
50
+ }
51
+ i = d[s1_len * s2_len -1];
52
+ xfree(d);
53
+ return i;
54
+ }
55
+
56
+ static VALUE lev_dist(VALUE self, VALUE str1, VALUE str2) {
57
+ return LONG2FIX(levenshtein_distance( str1, str2 ));
58
+ }
59
+
60
+ static VALUE mAlgorithms;
61
+ static VALUE mString;
62
+
63
+ void Init_CString() {
64
+ mAlgorithms = rb_define_module("Algorithms");
65
+ mString = rb_define_module_under(mAlgorithms, "String");
66
+ rb_define_singleton_method(mString, "levenshtein_dist", lev_dist, 2);
67
+ }
68
+