Merge branch 'master' into add-stack-data-structure-example

This commit is contained in:
Vitor Oliveira 2020-12-28 14:39:53 -08:00 committed by GitHub
commit 9125b8ae3f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
12 changed files with 329 additions and 4 deletions

12
.github/workflows/test.yml vendored Normal file
View 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

View file

@ -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)

View 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)

View 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
View file

@ -0,0 +1,7 @@
require 'rake/testtask'
Rake::TestTask.new(:test) do |t|
t.test_files = FileList['**/*_test.rb']
end
task default: :test

View 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]

View 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

View 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

View 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

View 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

View file

@ -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
View 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