diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml new file mode 100644 index 0000000..cfca6b2 --- /dev/null +++ b/.github/workflows/test.yml @@ -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 diff --git a/DIRECTORY.md b/DIRECTORY.md index 4a879d0..9dae632 100644 --- a/DIRECTORY.md +++ b/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) @@ -19,6 +21,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) @@ -39,10 +47,13 @@ * [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) * [Linear Search](https://github.com/TheAlgorithms/Ruby/blob/master/searches/linear_search.rb) + * [Recursive Linear Search](https://github.com/TheAlgorithms/Ruby/blob/master/searches/recursive_linear_search.rb) + * [Double Linear Search](https://github.com/TheAlgorithms/Ruby/blob/master/searches/double_linear_search.rb) * [Recursive Double Linear Search](https://github.com/TheAlgorithms/Ruby/blob/master/searches/recursive_double_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) diff --git a/Project Euler/Problem 3/problem3_sol1.rb b/Project Euler/Problem 3/problem3_sol1.rb new file mode 100644 index 0000000..30a8bca --- /dev/null +++ b/Project Euler/Problem 3/problem3_sol1.rb @@ -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) + diff --git a/Project Euler/Problem 4/problem4_sol1.rb b/Project Euler/Problem 4/problem4_sol1.rb new file mode 100644 index 0000000..fb1ac24 --- /dev/null +++ b/Project Euler/Problem 4/problem4_sol1.rb @@ -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 \ No newline at end of file diff --git a/Rakefile b/Rakefile new file mode 100644 index 0000000..d4dcdd1 --- /dev/null +++ b/Rakefile @@ -0,0 +1,7 @@ +require 'rake/testtask' + +Rake::TestTask.new(:test) do |t| + t.test_files = FileList['**/*_test.rb'] +end + +task default: :test diff --git a/data_structures/arrays/get_products_of_all_other_elements.rb b/data_structures/arrays/get_products_of_all_other_elements.rb new file mode 100644 index 0000000..0e7d97d --- /dev/null +++ b/data_structures/arrays/get_products_of_all_other_elements.rb @@ -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] diff --git a/searches/double_linear_search.rb b/searches/double_linear_search.rb new file mode 100644 index 0000000..86abbfe --- /dev/null +++ b/searches/double_linear_search.rb @@ -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 diff --git a/searches/recursive_linear_search.rb b/searches/recursive_linear_search.rb new file mode 100644 index 0000000..0c80a8d --- /dev/null +++ b/searches/recursive_linear_search.rb @@ -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 diff --git a/sorting/bogo_sort.rb b/sorting/bogo_sort.rb index c447cd5..c792026 100644 --- a/sorting/bogo_sort.rb +++ b/sorting/bogo_sort.rb @@ -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 diff --git a/sorting/bogo_sort_test.rb b/sorting/bogo_sort_test.rb new file mode 100644 index 0000000..3fc6e83 --- /dev/null +++ b/sorting/bogo_sort_test.rb @@ -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