algorithmable 0.13.0 → 0.14.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 +4 -4
- data/.rubocop.yml +1 -1
- data/algorithmable.gemspec +1 -0
- data/lib/algorithmable/cache/imp.rb +19 -0
- data/lib/algorithmable/cache/primitive_max_heap.rb +38 -0
- data/lib/algorithmable/cache/primitive_min_heap.rb +38 -0
- data/lib/algorithmable/cache.rb +15 -0
- data/lib/algorithmable/cups/circular_dependencies.rb +27 -0
- data/lib/algorithmable/cups/longest_common_subsequence.rb +46 -0
- data/lib/algorithmable/cups/merge_two_arrays.rb +31 -0
- data/lib/algorithmable/cups/nested_lists_problem.rb +105 -0
- data/lib/algorithmable/cups/number_of_occurrences_in_array.rb +49 -0
- data/lib/algorithmable/cups/primitives.rb +205 -2
- data/lib/algorithmable/cups/root_cube_issue.rb +39 -0
- data/lib/algorithmable/cups/stacks_and_queues/stack_sorter.rb +25 -0
- data/lib/algorithmable/cups/stacks_and_queues/stack_with_min.rb +23 -0
- data/lib/algorithmable/cups/stacks_and_queues/towers_of_hanoi.rb +48 -0
- data/lib/algorithmable/cups/stacks_and_queues/triple_stack.rb +52 -0
- data/lib/algorithmable/cups/stacks_and_queues/two_stacks_queue.rb +37 -0
- data/lib/algorithmable/cups/stacks_and_queues.rb +31 -0
- data/lib/algorithmable/cups/stocks.rb +80 -0
- data/lib/algorithmable/cups/task_shedule_with_coldtime.rb +16 -0
- data/lib/algorithmable/cups/two_sum.rb +59 -0
- data/lib/algorithmable/cups.rb +7 -0
- data/lib/algorithmable/data_structs/linked_list/base.rb +21 -1
- data/lib/algorithmable/data_structs/linked_list/doubly.rb +1 -1
- data/lib/algorithmable/data_structs/linked_list/singly.rb +62 -1
- data/lib/algorithmable/data_structs/queue.rb +4 -0
- data/lib/algorithmable/data_structs/stack.rb +4 -0
- data/lib/algorithmable/data_structs/tree/binary.rb +10 -0
- data/lib/algorithmable/data_structs/tree/binary_search.rb +206 -0
- data/lib/algorithmable/data_structs/tree.rb +13 -0
- data/lib/algorithmable/data_structs.rb +6 -0
- data/lib/algorithmable/sort/bubble.rb +9 -16
- data/lib/algorithmable/sort/insertion.rb +24 -0
- data/lib/algorithmable/sort/merge.rb +4 -8
- data/lib/algorithmable/sort/quick_sort.rb +35 -0
- data/lib/algorithmable/sort/selection.rb +23 -0
- data/lib/algorithmable/sort/shell.rb +27 -0
- data/lib/algorithmable/sort/shuffle.rb +15 -0
- data/lib/algorithmable/sort/utils.rb +66 -0
- data/lib/algorithmable/sort.rb +28 -0
- data/lib/algorithmable/union_find.rb +51 -0
- data/lib/algorithmable/version.rb +1 -1
- data/lib/algorithmable.rb +2 -0
- data/script/benchmarks/sort.rb +37 -0
- metadata +46 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2819e21aacb2d64cd559ea000b1e91a3e522ed64
|
4
|
+
data.tar.gz: 2c44dfea8b1f9552fd28d0de362b7c4617d9772f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7518a1f6a826af9f6a232f77ec85dd4e09d2f93ac1c272d01d3aa20a6ea1c1a25950ba81abcd28ce62c752ed15c599bb3e9de25321f9a1f8e1d0de32240647fc
|
7
|
+
data.tar.gz: 912456f9bb48de78827502407b6967c48321f4a8066d1e667f58db0cfca4f4ec16fddbe1408a065e517803f94a982964ed5359019556e890cb7ed2b43ffb1e56
|
data/.rubocop.yml
CHANGED
data/algorithmable.gemspec
CHANGED
@@ -0,0 +1,19 @@
|
|
1
|
+
module Algorithmable
|
2
|
+
module Cache
|
3
|
+
class Imp
|
4
|
+
extend Forwardable
|
5
|
+
|
6
|
+
def_delegators :@heap, :size, :empty?, :[]
|
7
|
+
|
8
|
+
def initialize(max_size, heap)
|
9
|
+
@max_size = max_size
|
10
|
+
@heap = heap
|
11
|
+
end
|
12
|
+
|
13
|
+
def []=(key, value)
|
14
|
+
@heap.pop if @heap.size >= @max_size
|
15
|
+
@heap[key] = value
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
module Algorithmable
|
2
|
+
module Cache
|
3
|
+
class PrimitiveMaxHeap
|
4
|
+
extend Forwardable
|
5
|
+
|
6
|
+
def_delegators :@index, :size, :empty?
|
7
|
+
|
8
|
+
def initialize(index = [])
|
9
|
+
@storage = {}
|
10
|
+
@index = index
|
11
|
+
end
|
12
|
+
|
13
|
+
def []=(key, value)
|
14
|
+
swim key
|
15
|
+
@storage[key] = value
|
16
|
+
end
|
17
|
+
|
18
|
+
def [](key)
|
19
|
+
@storage[key].tap do |value|
|
20
|
+
swim key if value
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def pop
|
25
|
+
key = @index.delete @index.last
|
26
|
+
@storage.delete key
|
27
|
+
end
|
28
|
+
|
29
|
+
private
|
30
|
+
|
31
|
+
def swim(key)
|
32
|
+
@index.delete(key)
|
33
|
+
@index.unshift(key)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
private_constant :PrimitiveMaxHeap
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
module Algorithmable
|
2
|
+
module Cache
|
3
|
+
class PrimitiveMinHeap
|
4
|
+
extend Forwardable
|
5
|
+
|
6
|
+
def_delegators :@index, :size, :empty?
|
7
|
+
|
8
|
+
def initialize(index = [])
|
9
|
+
@storage = {}
|
10
|
+
@index = index
|
11
|
+
end
|
12
|
+
|
13
|
+
def []=(key, value)
|
14
|
+
sink key
|
15
|
+
@storage[key] = value
|
16
|
+
end
|
17
|
+
|
18
|
+
def [](key)
|
19
|
+
@storage[key].tap do |value|
|
20
|
+
sink key if value
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def pop
|
25
|
+
key = @index.delete @index.last
|
26
|
+
@storage.delete key
|
27
|
+
end
|
28
|
+
|
29
|
+
private
|
30
|
+
|
31
|
+
def sink(key)
|
32
|
+
@index.delete(key)
|
33
|
+
@index.push(key)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
private_constant :PrimitiveMinHeap
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module Algorithmable
|
2
|
+
module Cache
|
3
|
+
autoload :Imp, 'algorithmable/cache/imp'
|
4
|
+
autoload :PrimitiveMinHeap, 'algorithmable/cache/primitive_min_heap'
|
5
|
+
autoload :PrimitiveMaxHeap, 'algorithmable/cache/primitive_max_heap'
|
6
|
+
|
7
|
+
def new_lru_cache(size, heap = PrimitiveMaxHeap.new)
|
8
|
+
Imp.new size, heap
|
9
|
+
end
|
10
|
+
|
11
|
+
def new_mru_cache(size, heap = PrimitiveMinHeap.new)
|
12
|
+
Imp.new size, heap
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module Algorithmable
|
2
|
+
module Cups
|
3
|
+
module CircularDependencies
|
4
|
+
def lib_dependencies(item, dependencies)
|
5
|
+
visited = []
|
6
|
+
dfs(item, dependencies, visited) do |entry, dep|
|
7
|
+
puts "circular dependency: #{entry} <=> #{dep}"
|
8
|
+
end
|
9
|
+
visited
|
10
|
+
end
|
11
|
+
|
12
|
+
def dfs(item, dependencies, visited, &block)
|
13
|
+
next_items = dependencies[item]
|
14
|
+
return [] unless next_items
|
15
|
+
visited << item
|
16
|
+
|
17
|
+
next_items.each do |dep|
|
18
|
+
if visited.include? dep
|
19
|
+
yield item, dep if block_given?
|
20
|
+
next
|
21
|
+
end
|
22
|
+
dfs(dep, dependencies, visited, &block)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
module Algorithmable
|
2
|
+
module Cups
|
3
|
+
class LongestCommonSubSequence
|
4
|
+
#
|
5
|
+
# @see https://en.wikipedia.org/wiki/Longest_common_subsequence_problem
|
6
|
+
#
|
7
|
+
# >> a = "aaaaabbbb34354354345"
|
8
|
+
# >> b = "abbb34aaabbbb"
|
9
|
+
# >> find(a, b)
|
10
|
+
# => "aaaabbbb"
|
11
|
+
#
|
12
|
+
def find(a, b)
|
13
|
+
max_len = Array.new(a.size + 1, 0)
|
14
|
+
max_len.map! { Array.new(b.size + 1, 0) }
|
15
|
+
|
16
|
+
(a.size - 1).downto(0) do |i|
|
17
|
+
(b.size - 1).downto(0) do |j|
|
18
|
+
if a[i] == b[j]
|
19
|
+
max_len[i][j] = 1 + max_len[i + 1][j + 1]
|
20
|
+
else
|
21
|
+
max_len[i][j] = [max_len[i + 1][j], max_len[i][j + 1]].max
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
res = ''
|
27
|
+
i = 0
|
28
|
+
j = 0
|
29
|
+
while max_len[i][j] != 0 && i < a.size && j < b.size
|
30
|
+
if a[i] == b[j]
|
31
|
+
res << a[i]
|
32
|
+
i += 1
|
33
|
+
j += 1
|
34
|
+
else
|
35
|
+
if max_len[i][j] == max_len[i + 1][j]
|
36
|
+
i += 1
|
37
|
+
else
|
38
|
+
j += 1
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
res
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module Algorithmable
|
2
|
+
module Cups
|
3
|
+
# Given two lists of numbers in descending order, write a function that returns a single list sorted in the same order.
|
4
|
+
# E.g.
|
5
|
+
# list1: 4, 2, 1
|
6
|
+
# list2: 7, 6, 5, 3
|
7
|
+
# Result list should be: 7,6,5,4,3,2,1
|
8
|
+
|
9
|
+
# right = [4, 2, 1]
|
10
|
+
# left = [7, 6, 5, 3]
|
11
|
+
#
|
12
|
+
# l1 = [1]
|
13
|
+
# l2 = []
|
14
|
+
|
15
|
+
def merge_arrays(left, right)
|
16
|
+
sorted = []
|
17
|
+
|
18
|
+
while !left.empty? && !right.empty?
|
19
|
+
if left[0] >= right[0]
|
20
|
+
sorted.push(left.shift)
|
21
|
+
else
|
22
|
+
sorted.push(right.shift)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
sorted += left if right.empty?
|
27
|
+
sorted += right if left.empty?
|
28
|
+
sorted # [1]
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,105 @@
|
|
1
|
+
module Algorithmable
|
2
|
+
module Cups
|
3
|
+
module NestedListsProblem
|
4
|
+
# /**
|
5
|
+
# * Given a nested list of integers, returns the sum of all integers in the list weighted by their depth
|
6
|
+
# * For example, given the list {{1,1},2,{1,1}} the function should return 10 (four 1's at depth 2, one 2 at depth 1)
|
7
|
+
# * Given the list {1,{4,{6}}} the function should return 27 (one 1 at depth 1, one 4 at depth 2, and one 6 at depth 3)
|
8
|
+
# */
|
9
|
+
#
|
10
|
+
# public int depthSum (List<NestedInteger> input)
|
11
|
+
# {
|
12
|
+
# // ur implementation here
|
13
|
+
# }
|
14
|
+
#
|
15
|
+
# **
|
16
|
+
# * This is the interface that represents nested lists.
|
17
|
+
# * You should not implement it, or speculate about its implementation.
|
18
|
+
# */
|
19
|
+
# public interface NestedInteger
|
20
|
+
# {
|
21
|
+
# /** @return true if this NestedInteger holds a single integer, rather than a nested list */
|
22
|
+
# boolean isInteger();
|
23
|
+
#
|
24
|
+
# /** @return the single integer that this NestedInteger holds, if it holds a single integer
|
25
|
+
# * Return null if this NestedInteger holds a nested list
|
26
|
+
# */
|
27
|
+
# Integer getInteger();
|
28
|
+
#
|
29
|
+
# /** @return the nested list that this NestedInteger holds, if it holds a nested list
|
30
|
+
# * Return null if this NestedInteger holds a single integer
|
31
|
+
# */
|
32
|
+
# List<NestedInteger> getList();
|
33
|
+
# }
|
34
|
+
|
35
|
+
def make_list(collection, level = 0, buffer = new_nested_list)
|
36
|
+
collection.each do |entry|
|
37
|
+
if entry.is_a? Array
|
38
|
+
buffer << make_list(entry, level + 1)
|
39
|
+
else
|
40
|
+
buffer << entry
|
41
|
+
end
|
42
|
+
end
|
43
|
+
buffer
|
44
|
+
end
|
45
|
+
|
46
|
+
def new_nested_list(collection = [])
|
47
|
+
NestedListImp.new collection
|
48
|
+
end
|
49
|
+
|
50
|
+
def solve_puzzle(nested_list)
|
51
|
+
PuzzleSolver.find_sum_of_nodes_in nested_list
|
52
|
+
end
|
53
|
+
|
54
|
+
class NestedListImp
|
55
|
+
attr_accessor :value
|
56
|
+
|
57
|
+
def initialize(collection = [])
|
58
|
+
@collection = collection
|
59
|
+
end
|
60
|
+
|
61
|
+
def integer?
|
62
|
+
@collection.is_a? Fixnum
|
63
|
+
end
|
64
|
+
|
65
|
+
def <<(other)
|
66
|
+
@collection << other
|
67
|
+
end
|
68
|
+
|
69
|
+
def value
|
70
|
+
@collection
|
71
|
+
end
|
72
|
+
|
73
|
+
def each(&block)
|
74
|
+
@collection.each(&block)
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
private_constant :NestedListImp
|
79
|
+
|
80
|
+
class PuzzleSolver
|
81
|
+
def self.find_sum_of_nodes_in(nested_list)
|
82
|
+
new.find_sum_of_nodes_in nested_list
|
83
|
+
end
|
84
|
+
|
85
|
+
def find_sum_of_nodes_in(nested_list)
|
86
|
+
recursive_sum nested_list, 1
|
87
|
+
end
|
88
|
+
|
89
|
+
def recursive_sum(list, at_level)
|
90
|
+
sum = 0
|
91
|
+
list.each do |entry|
|
92
|
+
if entry.integer?
|
93
|
+
sum += entry * at_level
|
94
|
+
else
|
95
|
+
sum += recursive_sum entry, at_level + 1
|
96
|
+
end
|
97
|
+
end
|
98
|
+
sum
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
private_constant :PuzzleSolver
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
module Algorithmable
|
2
|
+
module Cups
|
3
|
+
module NumberOfOccurrencesInArray
|
4
|
+
include Algorithmable::Searches
|
5
|
+
|
6
|
+
def linear_solve(collection, target)
|
7
|
+
result = Hash.new 0
|
8
|
+
collection.each do |item|
|
9
|
+
result[item] += 1
|
10
|
+
end
|
11
|
+
result[target]
|
12
|
+
end
|
13
|
+
|
14
|
+
def logarithmic(collection, target)
|
15
|
+
i = find_first_one collection, 0, collection.size - 1, target
|
16
|
+
j = find_last_one collection, i, collection.size - 1, target
|
17
|
+
j - i + 1
|
18
|
+
end
|
19
|
+
|
20
|
+
def find_first_one(collection, low, high, target)
|
21
|
+
# if(high >= low)
|
22
|
+
# {
|
23
|
+
# int mid = (low + high)/2; /*low + (high - low)/2;*/
|
24
|
+
# if( ( mid == 0 || x > arr[mid-1]) && arr[mid] == x)
|
25
|
+
# return mid;
|
26
|
+
# else if(x > arr[mid])
|
27
|
+
# return first(arr, (mid + 1), high, x, n);
|
28
|
+
# else
|
29
|
+
# return first(arr, low, (mid -1), x, n);
|
30
|
+
# }
|
31
|
+
# return -1
|
32
|
+
end
|
33
|
+
|
34
|
+
def find_last_one(collection, low, high, target)
|
35
|
+
# if(high >= low)
|
36
|
+
# {
|
37
|
+
# int mid = (low + high)/2; /*low + (high - low)/2;*/
|
38
|
+
# if( ( mid == n-1 || x < arr[mid+1]) && arr[mid] == x )
|
39
|
+
# return mid;
|
40
|
+
# else if(x < arr[mid])
|
41
|
+
# return last(arr, low, (mid -1), x, n);
|
42
|
+
# else
|
43
|
+
# return last(arr, (mid + 1), high, x, n);
|
44
|
+
# }
|
45
|
+
# return -1;
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -20,7 +20,7 @@ module Algorithmable
|
|
20
20
|
j = index + 1
|
21
21
|
chars[new_length - j] = char
|
22
22
|
end
|
23
|
-
new_length
|
23
|
+
new_length -= replacement.length
|
24
24
|
else
|
25
25
|
new_length -= 1
|
26
26
|
chars[new_length] = string[i]
|
@@ -71,7 +71,7 @@ module Algorithmable
|
|
71
71
|
end
|
72
72
|
|
73
73
|
def find_cycled_node(root)
|
74
|
-
return unless root.next
|
74
|
+
return unless root.next || root.next.next
|
75
75
|
slow = root
|
76
76
|
fast = root
|
77
77
|
|
@@ -93,6 +93,209 @@ module Algorithmable
|
|
93
93
|
# at this point return value is a node which is tail pointing to.
|
94
94
|
fast
|
95
95
|
end
|
96
|
+
|
97
|
+
def ransom_note(note, magazine)
|
98
|
+
ascii_table = Hash.new 0
|
99
|
+
source = magazine.chars
|
100
|
+
|
101
|
+
source.each do |char|
|
102
|
+
ascii_table[char] += 1
|
103
|
+
end
|
104
|
+
|
105
|
+
note.chars.each do |char|
|
106
|
+
return false unless ascii_table[char].nonzero?
|
107
|
+
ascii_table[char] -= 1
|
108
|
+
end
|
109
|
+
|
110
|
+
true
|
111
|
+
end
|
112
|
+
|
113
|
+
def anagrams?(string, other_string)
|
114
|
+
return false unless string.size == other_string.size
|
115
|
+
registry = Hash.new 0
|
116
|
+
string.each_char do |char|
|
117
|
+
registry[char] += 1
|
118
|
+
end
|
119
|
+
other_string.chars.none? do |char|
|
120
|
+
(registry[char] -= 1) < 0
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
def parse_string_with_escapes(string)
|
125
|
+
app_state = {
|
126
|
+
chunk_id: 0,
|
127
|
+
escaping: false,
|
128
|
+
prev_char: nil,
|
129
|
+
chunks: Hash.new { |h, k| h[k] = [] }
|
130
|
+
}
|
131
|
+
|
132
|
+
string.each_char do |char|
|
133
|
+
parse_char char, app_state
|
134
|
+
end
|
135
|
+
|
136
|
+
app_state[:chunks].values
|
137
|
+
end
|
138
|
+
|
139
|
+
def parse_char(char, state)
|
140
|
+
chunk_id = state[:chunk_id]
|
141
|
+
case char
|
142
|
+
when /[\(\{\[\)\}\]]/
|
143
|
+
state[:escaping] = char != state[:prev_char]
|
144
|
+
state[:chunks][chunk_id] << char unless state[:escaping]
|
145
|
+
else
|
146
|
+
if state[:escaping]
|
147
|
+
chunk_id = state[:chunk_id] += 1
|
148
|
+
state[:escaping] = false
|
149
|
+
end
|
150
|
+
state[:chunks][chunk_id] << char
|
151
|
+
end
|
152
|
+
state[:prev_char] = char
|
153
|
+
end
|
154
|
+
|
155
|
+
def remove_duplicates_from_list(list)
|
156
|
+
map = {}
|
157
|
+
prev = nil
|
158
|
+
node = list.front
|
159
|
+
|
160
|
+
while node
|
161
|
+
if map[node.item]
|
162
|
+
prev.next = node.next
|
163
|
+
else
|
164
|
+
map[node.item] = true
|
165
|
+
prev = node
|
166
|
+
end
|
167
|
+
node = node.next
|
168
|
+
end
|
169
|
+
end
|
170
|
+
|
171
|
+
def nth_to_last_in_list(list, nth = 1)
|
172
|
+
return if list.nil? || list.empty?
|
173
|
+
node1 = list.front
|
174
|
+
node2 = list.front
|
175
|
+
|
176
|
+
nth.downto(nth).each do |_i|
|
177
|
+
if node1
|
178
|
+
|
179
|
+
end
|
180
|
+
end
|
181
|
+
end
|
182
|
+
|
183
|
+
#
|
184
|
+
# int maxDiff(int arr[], int arr_size)
|
185
|
+
# {
|
186
|
+
# int max_diff = arr[1] - arr[0];
|
187
|
+
# int i, j;
|
188
|
+
# for(i = 0; i < arr_size; i++)
|
189
|
+
# {
|
190
|
+
# for(j = i+1; j < arr_size; j++)
|
191
|
+
# {
|
192
|
+
# if(arr[j] - arr[i] > max_diff)
|
193
|
+
# max_diff = arr[j] - arr[i];
|
194
|
+
# }
|
195
|
+
# }
|
196
|
+
# return max_diff;
|
197
|
+
# }
|
198
|
+
#
|
199
|
+
# getBestTime(int stocks[], int sz, int &buy, int &sell) {
|
200
|
+
# int min = 0;
|
201
|
+
# int maxDiff = 0;
|
202
|
+
# buy = sell = 0;
|
203
|
+
# for (int i = 0; i < sz; i++) {
|
204
|
+
# if (stocks[i] < stocks[min])
|
205
|
+
# min = i;
|
206
|
+
# int diff = stocks[i] - stocks[min];
|
207
|
+
# if (diff > maxDiff) {
|
208
|
+
# buy = min;
|
209
|
+
# sell = i;
|
210
|
+
# maxDiff = diff;
|
211
|
+
# }
|
212
|
+
# }
|
213
|
+
# }
|
214
|
+
#
|
215
|
+
|
216
|
+
def sort_linked_list(node)
|
217
|
+
return unless node || node.empty?
|
218
|
+
swapped = false
|
219
|
+
prev = nil
|
220
|
+
|
221
|
+
begin
|
222
|
+
swapped = false
|
223
|
+
current = node
|
224
|
+
|
225
|
+
until current.next == prev
|
226
|
+
if current.item > current.next.item
|
227
|
+
swap_nodes current, current.next
|
228
|
+
swapped = true
|
229
|
+
end
|
230
|
+
current = current.next
|
231
|
+
end
|
232
|
+
|
233
|
+
prev = current
|
234
|
+
end while swapped
|
235
|
+
end
|
236
|
+
|
237
|
+
def swap_nodes(node1, node2)
|
238
|
+
tmp = node1.item
|
239
|
+
node1.item = node2.item
|
240
|
+
node2.item = tmp
|
241
|
+
end
|
242
|
+
|
243
|
+
# Write a program that gives count of common characters presented in an array of strings..(or array of character arrays)
|
244
|
+
#
|
245
|
+
# For eg.. for the following input strings..
|
246
|
+
#
|
247
|
+
# aghkafgklt
|
248
|
+
# dfghako
|
249
|
+
# qwemnaarkf
|
250
|
+
#
|
251
|
+
# The output should be 3. because the characters a, f and k are present in all 3 strings.
|
252
|
+
#
|
253
|
+
# Note: The input strings contains only lower case alphabets
|
254
|
+
def find_common_chars_in_words(collection)
|
255
|
+
map = Hash.new 0
|
256
|
+
|
257
|
+
collection.each_with_index do |word, index|
|
258
|
+
word.chars.each do |char|
|
259
|
+
map[char] += 1 if map[char] == index
|
260
|
+
end
|
261
|
+
end
|
262
|
+
|
263
|
+
map.select do |key, value|
|
264
|
+
{ key => value } if value == collection.size
|
265
|
+
end
|
266
|
+
end
|
267
|
+
|
268
|
+
# /* This class will be given a list of words (such as might be tokenized
|
269
|
+
# * from a paragraph of text), and will provide a method that takes two
|
270
|
+
# * words and returns the shortest distance (in words) between those two
|
271
|
+
# * words in the provided text.
|
272
|
+
# * Example:
|
273
|
+
# * WordDistanceFinder finder = new WordDistanceFinder(Arrays.asList("the", "quick", "brown", "fox", "quick"));
|
274
|
+
# * assert(finder.distance("fox","the") == 3);
|
275
|
+
# * assert(finder.distance("quick", "fox") == 1);
|
276
|
+
# * /
|
277
|
+
|
278
|
+
def find_distance_between_words(dictionary, from, to)
|
279
|
+
return 0 if from == to
|
280
|
+
|
281
|
+
dict_size = dictionary.size
|
282
|
+
distance = -1
|
283
|
+
|
284
|
+
dictionary.each_with_index do |word, index|
|
285
|
+
next unless [from, to].include? word
|
286
|
+
temp = word == from
|
287
|
+
to = temp ? to : from
|
288
|
+
distance += 1
|
289
|
+
|
290
|
+
i = index
|
291
|
+
while i < dict_size - 1 && dictionary[i] != to
|
292
|
+
i += 1
|
293
|
+
distance += 1
|
294
|
+
return distance if dictionary[i] == to
|
295
|
+
end
|
296
|
+
end
|
297
|
+
distance
|
298
|
+
end
|
96
299
|
end
|
97
300
|
end
|
98
301
|
end
|