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