mirror of
https://github.com/TheAlgorithms/Ruby
synced 2025-01-14 08:01:05 +01:00
Merge branch 'master' into add-stack-data-structure-example
This commit is contained in:
commit
9125b8ae3f
12 changed files with 329 additions and 4 deletions
12
.github/workflows/test.yml
vendored
Normal file
12
.github/workflows/test.yml
vendored
Normal file
|
@ -0,0 +1,12 @@
|
|||
name: test
|
||||
on: [push, pull_request]
|
||||
jobs:
|
||||
test:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@master
|
||||
- uses: actions/setup-ruby@master
|
||||
with:
|
||||
ruby-version: '2.7'
|
||||
- name: Run tests
|
||||
run: rake test
|
15
DIRECTORY.md
15
DIRECTORY.md
|
@ -3,6 +3,8 @@
|
|||
* [Merkle Hellman Cryptosystem](https://github.com/TheAlgorithms/Ruby/blob/master/ciphers/merkle_hellman_cryptosystem.rb)
|
||||
|
||||
## Data Structures
|
||||
* Arrays
|
||||
* [Get Products Of All Other Elements](https://github.com/TheAlgorithms/Ruby/blob/master/data_structures/arrays/get_products_of_all_other_elements.rb)
|
||||
* Binary Trees
|
||||
* [Inorder Traversal](https://github.com/TheAlgorithms/Ruby/blob/master/data_structures/binary_trees/inorder_traversal.rb)
|
||||
* [Invert](https://github.com/TheAlgorithms/Ruby/blob/master/data_structures/binary_trees/invert.rb)
|
||||
|
@ -13,7 +15,8 @@
|
|||
* [Single List](https://github.com/TheAlgorithms/Ruby/blob/master/data_structures/linked_lists/single_list.rb)
|
||||
* Stacks
|
||||
* [Stack](https://github.com/TheAlgorithms/Ruby/blob/master/data_structures/stacks/stack.rb)
|
||||
|
||||
* Tries
|
||||
* [Trie](https://github.com/TheAlgorithms/Ruby/blob/master/data_structures/tries/trie.rb)
|
||||
|
||||
## Discrete Mathematics
|
||||
* [Euclidean Gcd](https://github.com/TheAlgorithms/Ruby/blob/master/discrete_mathematics/euclidean_gcd.rb)
|
||||
|
@ -22,6 +25,12 @@
|
|||
## Other
|
||||
* [Fisher Yates](https://github.com/TheAlgorithms/Ruby/blob/master/other/fisher_yates.rb)
|
||||
|
||||
## Project Euler
|
||||
* Problem 3
|
||||
* [Problem3 Sol1](https://github.com/TheAlgorithms/Ruby/blob/master/Project%20Euler/Problem%203/problem3_sol1.rb)
|
||||
* Problem 4
|
||||
* [Problem4 Sol1](https://github.com/TheAlgorithms/Ruby/blob/master/Project%20Euler/Problem%204/problem4_sol1.rb)
|
||||
|
||||
## Project Euler
|
||||
* Problem 1
|
||||
* [Problem1 Sol1](https://github.com/TheAlgorithms/Ruby/blob/master/project_euler/problem_1/problem1_sol1.rb)
|
||||
|
@ -41,10 +50,14 @@
|
|||
## Searches
|
||||
* [Binary Search](https://github.com/TheAlgorithms/Ruby/blob/master/searches/binary_search.rb)
|
||||
* [Depth First Search](https://github.com/TheAlgorithms/Ruby/blob/master/searches/depth_first_search.rb)
|
||||
* [Double Linear Search](https://github.com/TheAlgorithms/Ruby/blob/master/searches/double_linear_search.rb)
|
||||
* [Linear Search](https://github.com/TheAlgorithms/Ruby/blob/master/searches/linear_search.rb)
|
||||
* [Recursive Double Linear Search](https://github.com/TheAlgorithms/Ruby/blob/master/searches/recursive_double_linear_search.rb)
|
||||
* [Recursive Linear Search](https://github.com/TheAlgorithms/Ruby/blob/master/searches/recursive_linear_search.rb)
|
||||
|
||||
## Sorting
|
||||
* [Bogo Sort](https://github.com/TheAlgorithms/Ruby/blob/master/sorting/bogo_sort.rb)
|
||||
* [Bogo Sort Test](https://github.com/TheAlgorithms/Ruby/blob/master/sorting/bogo_sort_test.rb)
|
||||
* [Bubble Sort](https://github.com/TheAlgorithms/Ruby/blob/master/sorting/bubble_sort.rb)
|
||||
* [Bucket Sort](https://github.com/TheAlgorithms/Ruby/blob/master/sorting/bucket_sort.rb)
|
||||
* [Heap Sort](https://github.com/TheAlgorithms/Ruby/blob/master/sorting/heap_sort.rb)
|
||||
|
|
19
Project Euler/Problem 3/problem3_sol1.rb
Normal file
19
Project Euler/Problem 3/problem3_sol1.rb
Normal file
|
@ -0,0 +1,19 @@
|
|||
# The prime factors of 13195 are 5, 7, 13 and 29.
|
||||
# What is the largest prime factor of the number 600851475143 ?
|
||||
|
||||
def solution(n)
|
||||
prime = 1
|
||||
i = 2
|
||||
while i * i <= n
|
||||
while (n % i).zero?
|
||||
prime = i
|
||||
n = n.fdiv i
|
||||
end
|
||||
i += 1
|
||||
end
|
||||
prime = n if n > 1
|
||||
prime.to_i
|
||||
end
|
||||
|
||||
puts solution(600851475143)
|
||||
|
11
Project Euler/Problem 4/problem4_sol1.rb
Normal file
11
Project Euler/Problem 4/problem4_sol1.rb
Normal file
|
@ -0,0 +1,11 @@
|
|||
# A palindromic number reads the same both ways. The largest palindrome made from the product of two 2-digit numbers is 9009 = 91 × 99.
|
||||
# Find the largest palindrome made from the product of two 3-digit numbers.
|
||||
|
||||
answer = 0
|
||||
999.downto(99) do |i|
|
||||
999.downto(99) do |j|
|
||||
t = (i * j)
|
||||
answer = i * j if (t.to_s == t.to_s.reverse) && (t > answer) && (t > answer)
|
||||
end
|
||||
end
|
||||
puts answer
|
7
Rakefile
Normal file
7
Rakefile
Normal file
|
@ -0,0 +1,7 @@
|
|||
require 'rake/testtask'
|
||||
|
||||
Rake::TestTask.new(:test) do |t|
|
||||
t.test_files = FileList['**/*_test.rb']
|
||||
end
|
||||
|
||||
task default: :test
|
89
data_structures/arrays/get_products_of_all_other_elements.rb
Normal file
89
data_structures/arrays/get_products_of_all_other_elements.rb
Normal file
|
@ -0,0 +1,89 @@
|
|||
# Arrays - Get Products of all other elements in Ruby
|
||||
|
||||
# Algorithm challenge description:
|
||||
# Given an array of integers, return a new array such that
|
||||
# each element at index `i` of the new array is the product of
|
||||
# all the numbers in the original array except the one at `i`.
|
||||
|
||||
#
|
||||
# 1. Brute force solution
|
||||
#
|
||||
def calculate_products_of_all_other_elements(nums)
|
||||
product_of_other_elements = Array.new(nums.length, 1)
|
||||
|
||||
nums.each_with_index do |num1, i|
|
||||
nums.each_with_index do |num2, j|
|
||||
if (i != j)
|
||||
product_of_other_elements[i] = product_of_other_elements[i] * num2
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
product_of_other_elements
|
||||
end
|
||||
|
||||
puts(calculate_products_of_all_other_elements([1, 2, 3]))
|
||||
|
||||
#
|
||||
# 2. O(n) time and space
|
||||
# Arrays - Get Products of all other elements in Ruby
|
||||
#
|
||||
|
||||
# Generates prefix products
|
||||
def build_prefix_products(nums)
|
||||
prefix_products = []
|
||||
|
||||
nums.each do |num|
|
||||
if prefix_products.count > 0
|
||||
prefix_products << (prefix_products.last * num)
|
||||
else
|
||||
prefix_products << num
|
||||
end
|
||||
end
|
||||
|
||||
return prefix_products
|
||||
end
|
||||
|
||||
# Generates suffix products
|
||||
def build_suffix_products(nums)
|
||||
suffix_products = []
|
||||
|
||||
nums.reverse.each do |num|
|
||||
if suffix_products.count > 0
|
||||
suffix_products << (suffix_products.last * num)
|
||||
else
|
||||
suffix_products << num
|
||||
end
|
||||
end
|
||||
|
||||
return suffix_products
|
||||
end
|
||||
|
||||
# Builds output
|
||||
def output(prefix_products, suffix_products, nums)
|
||||
result = []
|
||||
|
||||
nums.reverse.each_with_index do |num, index|
|
||||
if index == 0
|
||||
result << suffix_products[index + 1]
|
||||
elsif index == nums.length - 1
|
||||
result << prefix_products[index - 1]
|
||||
else
|
||||
result << (prefix_products[index - 1] * suffix_products[index + 1])
|
||||
end
|
||||
end
|
||||
|
||||
return result
|
||||
end
|
||||
|
||||
# Generate result from the product of prefixes and suffixes
|
||||
def products(nums)
|
||||
prefix_products = build_prefix_products(nums)
|
||||
suffix_products = build_suffix_products(nums)
|
||||
suffix_products = suffix_products.reverse
|
||||
|
||||
return output(prefix_products, suffix_products, nums)
|
||||
end
|
||||
|
||||
puts(products([1, 2, 3]))
|
||||
# => [6, 3, 2]
|
75
data_structures/tries/trie.rb
Normal file
75
data_structures/tries/trie.rb
Normal file
|
@ -0,0 +1,75 @@
|
|||
# A Trie (prefix tree) is a kind of search tree used to provide quick lookup
|
||||
# of words/patterns in a set of words. A basic Trie however has O(n^2)
|
||||
# space complexity making it impractical in practice.
|
||||
# It however provides O(max(search_string, length of longest word))
|
||||
# lookup time making it an optimal approach when space is not an issue.
|
||||
|
||||
class Node
|
||||
attr_reader :value, :next
|
||||
attr_accessor :word
|
||||
|
||||
def initialize(value)
|
||||
@value = value
|
||||
@word = false
|
||||
@next = []
|
||||
end
|
||||
end
|
||||
|
||||
class Trie
|
||||
def initialize
|
||||
@root = Node.new('*')
|
||||
end
|
||||
|
||||
def insert_many(word)
|
||||
letters = word.chars
|
||||
base = @root
|
||||
|
||||
letters.each do |letter|
|
||||
base = insert(letter, base.next)
|
||||
end
|
||||
end
|
||||
|
||||
def include?(word)
|
||||
letters = word.chars
|
||||
base = @root
|
||||
|
||||
letters.all? do |letter|
|
||||
base = find(letter, base.next)
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
# check if it already exists
|
||||
# if not add character to node
|
||||
def insert(character, trie)
|
||||
found = trie.find do |n|
|
||||
n.value == character
|
||||
end
|
||||
|
||||
add_node(character, trie) unless found
|
||||
end
|
||||
|
||||
def add_node(character, trie)
|
||||
Node.new(character).tap do |new_node|
|
||||
trie << new_node
|
||||
end
|
||||
end
|
||||
|
||||
def find(character, trie)
|
||||
trie.find do |n|
|
||||
n.value == character
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
trie = Trie.new
|
||||
trie.insert_many('Dogs')
|
||||
trie.insert_many('South')
|
||||
trie.insert_many('Cape Town')
|
||||
|
||||
puts trie.include?('Cape Town')
|
||||
# => true
|
||||
|
||||
puts trie.include?('not presented')
|
||||
# => false
|
29
searches/double_linear_search.rb
Normal file
29
searches/double_linear_search.rb
Normal file
|
@ -0,0 +1,29 @@
|
|||
# Iterate through the array from both sides to find the index of search_item.
|
||||
|
||||
def double_linear_search(array, search_item)
|
||||
start_ind = 0
|
||||
end_ind = array.length - 1
|
||||
|
||||
while start_ind <= end_ind
|
||||
return start_ind if array[start_ind] == search_item
|
||||
return end_ind if array[end_ind] == search_item
|
||||
|
||||
start_ind += 1
|
||||
end_ind -= 1
|
||||
end
|
||||
|
||||
# returns -1 if search_item is not found in array
|
||||
-1
|
||||
end
|
||||
|
||||
puts(double_linear_search([1, 5, 5, 10], 1))
|
||||
# => 0
|
||||
|
||||
puts(double_linear_search([1, 5, 5, 10], 5))
|
||||
# => 1
|
||||
|
||||
puts(double_linear_search([1, 5, 5, 10], 100))
|
||||
# => -1
|
||||
|
||||
puts(double_linear_search([1, 5, 5, 10], 10))
|
||||
# => 3
|
27
searches/recursive_double_linear_search.rb
Normal file
27
searches/recursive_double_linear_search.rb
Normal file
|
@ -0,0 +1,27 @@
|
|||
# Iterate through the array to find the index of key using recursion.
|
||||
|
||||
def recursive_double_linear_search(data, key, left = 0, right = 0)
|
||||
right &&= data.length - 1
|
||||
|
||||
return -1 if left > right
|
||||
|
||||
return left if data[left] == key
|
||||
return right if data[right] == key
|
||||
|
||||
recursive_double_linear_search(data, key, left + 1, right - 1)
|
||||
end
|
||||
|
||||
puts(recursive_double_linear_search([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11], 5))
|
||||
# => 5
|
||||
|
||||
puts(recursive_double_linear_search([1, 2, 4, 5, 3], 4))
|
||||
# => 2
|
||||
|
||||
puts(recursive_double_linear_search([1, 2, 4, 5, 3], 6))
|
||||
# => -1
|
||||
|
||||
puts(recursive_double_linear_search([5], 5))
|
||||
# => 0
|
||||
|
||||
puts(recursive_double_linear_search([], 1))
|
||||
# => -1
|
25
searches/recursive_linear_search.rb
Normal file
25
searches/recursive_linear_search.rb
Normal file
|
@ -0,0 +1,25 @@
|
|||
# A pure Ruby implementation of a recursive linear search algorithm
|
||||
|
||||
def rec_linear_search(sequence, low, high, target)
|
||||
raise Exception('Invalid upper or lower bound!') unless high < sequence.length && low < sequence.length
|
||||
|
||||
return -1 if high < low
|
||||
|
||||
return low if sequence[low] == target
|
||||
|
||||
return high if sequence[high] == target
|
||||
|
||||
rec_linear_search(sequence, low + 1, high - 1, target)
|
||||
end
|
||||
|
||||
puts(rec_linear_search([0, 30, 500, 100, 700], 0, 4, 0))
|
||||
# => 0
|
||||
|
||||
puts(rec_linear_search([0, 30, 500, 100, 700], 0, 4, 700))
|
||||
# => 4
|
||||
|
||||
puts(rec_linear_search([0, 30, 500, 100, 700], 0, 4, 30))
|
||||
# => 1
|
||||
|
||||
puts(rec_linear_search([0, 30, 500, 100, 700], 0, 4, -6))
|
||||
# => -1
|
|
@ -13,6 +13,8 @@ class Array
|
|||
end
|
||||
end
|
||||
|
||||
puts "Enter a list of numbers separated by space"
|
||||
str = gets.chomp.split('')
|
||||
puts str.bogosort.join('')
|
||||
if $0 == __FILE__
|
||||
puts "Enter a list of numbers separated by space"
|
||||
str = gets.chomp.split('')
|
||||
puts str.bogosort.join('')
|
||||
end
|
||||
|
|
16
sorting/bogo_sort_test.rb
Normal file
16
sorting/bogo_sort_test.rb
Normal file
|
@ -0,0 +1,16 @@
|
|||
require 'minitest/autorun'
|
||||
require_relative './bogo_sort'
|
||||
|
||||
class TestBogoSort < Minitest::Test
|
||||
def test_sorted_array
|
||||
input = [1, 2, 3, 4, 5]
|
||||
expected = input.dup
|
||||
assert_equal expected, input.bogosort
|
||||
end
|
||||
|
||||
def test_reversed_array
|
||||
input = [5, 4, 3, 2, 1]
|
||||
expected = [1, 2, 3, 4, 5]
|
||||
assert_equal expected, input.bogosort
|
||||
end
|
||||
end
|
Loading…
Reference in a new issue