mirror of
https://github.com/TheAlgorithms/Ruby
synced 2024-12-26 21:58:56 +01:00
Merge branch 'TheAlgorithms:master' into master
This commit is contained in:
commit
62333e03c7
24 changed files with 1208 additions and 1 deletions
25
DIRECTORY.md
25
DIRECTORY.md
|
@ -3,7 +3,13 @@
|
|||
* [Generate Paranthesis](https://github.com/TheAlgorithms/Ruby/blob/master/backtracking/generate_paranthesis.rb)
|
||||
|
||||
## Bit Manipulation
|
||||
* [Binary And Operator](https://github.com/TheAlgorithms/Ruby/blob/master/bit_manipulation/binary_and_operator.rb)
|
||||
* [Binary Count Setbits](https://github.com/TheAlgorithms/Ruby/blob/master/bit_manipulation/binary_count_setbits.rb)
|
||||
* [Binary Count Trailing Zeroes](https://github.com/TheAlgorithms/Ruby/blob/master/bit_manipulation/binary_count_trailing_zeroes.rb)
|
||||
* [Binary Or Operator](https://github.com/TheAlgorithms/Ruby/blob/master/bit_manipulation/binary_or_operator.rb)
|
||||
* [Binary Xor Operator](https://github.com/TheAlgorithms/Ruby/blob/master/bit_manipulation/binary_xor_operator.rb)
|
||||
* [Power Of Two](https://github.com/TheAlgorithms/Ruby/blob/master/bit_manipulation/power_of_two.rb)
|
||||
* [Single Bit Binary Operations](https://github.com/TheAlgorithms/Ruby/blob/master/bit_manipulation/single_bit_binary_operations.rb)
|
||||
|
||||
## Ciphers
|
||||
* [Merkle Hellman Cryptosystem](https://github.com/TheAlgorithms/Ruby/blob/master/ciphers/merkle_hellman_cryptosystem.rb)
|
||||
|
@ -19,10 +25,12 @@
|
|||
* [Find The Highest Altitude](https://github.com/TheAlgorithms/Ruby/blob/master/data_structures/arrays/find_the_highest_altitude.rb)
|
||||
* [Fizz Buzz](https://github.com/TheAlgorithms/Ruby/blob/master/data_structures/arrays/fizz_buzz.rb)
|
||||
* [Get Products Of All Other Elements](https://github.com/TheAlgorithms/Ruby/blob/master/data_structures/arrays/get_products_of_all_other_elements.rb)
|
||||
* [Good Pairs](https://github.com/TheAlgorithms/Ruby/blob/master/data_structures/arrays/good_pairs.rb)
|
||||
* [Intersection](https://github.com/TheAlgorithms/Ruby/blob/master/data_structures/arrays/intersection.rb)
|
||||
* [Next Greater Element](https://github.com/TheAlgorithms/Ruby/blob/master/data_structures/arrays/next_greater_element.rb)
|
||||
* [Remove Elements](https://github.com/TheAlgorithms/Ruby/blob/master/data_structures/arrays/remove_elements.rb)
|
||||
* [Richest Customer Wealth](https://github.com/TheAlgorithms/Ruby/blob/master/data_structures/arrays/richest_customer_wealth.rb)
|
||||
* [Shortest Word Distance](https://github.com/TheAlgorithms/Ruby/blob/master/data_structures/arrays/shortest_word_distance.rb)
|
||||
* [Shuffle Array](https://github.com/TheAlgorithms/Ruby/blob/master/data_structures/arrays/shuffle_array.rb)
|
||||
* [Single Number](https://github.com/TheAlgorithms/Ruby/blob/master/data_structures/arrays/single_number.rb)
|
||||
* [Sort Squares Of An Array](https://github.com/TheAlgorithms/Ruby/blob/master/data_structures/arrays/sort_squares_of_an_array.rb)
|
||||
|
@ -32,6 +40,7 @@
|
|||
* [Jewels And Stones](https://github.com/TheAlgorithms/Ruby/blob/master/data_structures/arrays/strings/jewels_and_stones.rb)
|
||||
* [Palindrome](https://github.com/TheAlgorithms/Ruby/blob/master/data_structures/arrays/strings/palindrome.rb)
|
||||
* [Remove Vowels](https://github.com/TheAlgorithms/Ruby/blob/master/data_structures/arrays/strings/remove_vowels.rb)
|
||||
* [Sudoku](https://github.com/TheAlgorithms/Ruby/blob/master/data_structures/arrays/sudoku.rb)
|
||||
* [Two Sum](https://github.com/TheAlgorithms/Ruby/blob/master/data_structures/arrays/two_sum.rb)
|
||||
* [Two Sum Ii](https://github.com/TheAlgorithms/Ruby/blob/master/data_structures/arrays/two_sum_ii.rb)
|
||||
* Binary Trees
|
||||
|
@ -43,13 +52,16 @@
|
|||
* [Anagram Checker](https://github.com/TheAlgorithms/Ruby/blob/master/data_structures/hash_table/anagram_checker.rb)
|
||||
* [Arrays Intersection](https://github.com/TheAlgorithms/Ruby/blob/master/data_structures/hash_table/arrays_intersection.rb)
|
||||
* [Find All Duplicates In An Array](https://github.com/TheAlgorithms/Ruby/blob/master/data_structures/hash_table/find_all_duplicates_in_an_array.rb)
|
||||
* [Good Pairs](https://github.com/TheAlgorithms/Ruby/blob/master/data_structures/hash_table/good_pairs.rb)
|
||||
* [Richest Customer Wealth](https://github.com/TheAlgorithms/Ruby/blob/master/data_structures/hash_table/richest_customer_wealth.rb)
|
||||
* [Two Sum](https://github.com/TheAlgorithms/Ruby/blob/master/data_structures/hash_table/two_sum.rb)
|
||||
* [Uncommon Words](https://github.com/TheAlgorithms/Ruby/blob/master/data_structures/hash_table/uncommon_words.rb)
|
||||
* Linked Lists
|
||||
* [Circular Linked List](https://github.com/TheAlgorithms/Ruby/blob/master/data_structures/linked_lists/circular_linked_list.rb)
|
||||
* [Doubly Linked List](https://github.com/TheAlgorithms/Ruby/blob/master/data_structures/linked_lists/doubly_linked_list.rb)
|
||||
* [Singly Linked List](https://github.com/TheAlgorithms/Ruby/blob/master/data_structures/linked_lists/singly_linked_list.rb)
|
||||
* Queues
|
||||
* [Circular Queue](https://github.com/TheAlgorithms/Ruby/blob/master/data_structures/queues/circular_queue.rb)
|
||||
* [Queue](https://github.com/TheAlgorithms/Ruby/blob/master/data_structures/queues/queue.rb)
|
||||
* Stacks
|
||||
* [Stack](https://github.com/TheAlgorithms/Ruby/blob/master/data_structures/stacks/stack.rb)
|
||||
|
@ -63,6 +75,7 @@
|
|||
|
||||
## Dynamic Programming
|
||||
* [Coin Change](https://github.com/TheAlgorithms/Ruby/blob/master/dynamic_programming/coin_change.rb)
|
||||
* [Count Sorted Vowel Strings](https://github.com/TheAlgorithms/Ruby/blob/master/dynamic_programming/count_sorted_vowel_strings.rb)
|
||||
* [Fibonacci](https://github.com/TheAlgorithms/Ruby/blob/master/dynamic_programming/fibonacci.rb)
|
||||
|
||||
## Maths
|
||||
|
@ -79,9 +92,10 @@
|
|||
* [Binary To Decimal](https://github.com/TheAlgorithms/Ruby/blob/master/maths/binary_to_decimal.rb)
|
||||
* [Ceil](https://github.com/TheAlgorithms/Ruby/blob/master/maths/ceil.rb)
|
||||
* [Ceil Test](https://github.com/TheAlgorithms/Ruby/blob/master/maths/ceil_test.rb)
|
||||
* [Count Sorted Vowel Strings](https://github.com/TheAlgorithms/Ruby/blob/master/maths/count_sorted_vowel_strings.rb)
|
||||
* [Decimal To Binary](https://github.com/TheAlgorithms/Ruby/blob/master/maths/decimal_to_binary.rb)
|
||||
* [Factorial](https://github.com/TheAlgorithms/Ruby/blob/master/maths/factorial.rb)
|
||||
* [Factorial Non-recursive and Non-iterative](https://github.com/TheAlgorithms/Ruby/blob/master/maths/factorial_non_recursive_non_iterative.rb)
|
||||
* [Factorial Non Recursive Non Iterative](https://github.com/TheAlgorithms/Ruby/blob/master/maths/factorial_non_recursive_non_iterative.rb)
|
||||
* [Fibonacci](https://github.com/TheAlgorithms/Ruby/blob/master/maths/fibonacci.rb)
|
||||
* [Find Max](https://github.com/TheAlgorithms/Ruby/blob/master/maths/find_max.rb)
|
||||
* [Find Min](https://github.com/TheAlgorithms/Ruby/blob/master/maths/find_min.rb)
|
||||
|
@ -89,6 +103,7 @@
|
|||
* [Number Of Digits](https://github.com/TheAlgorithms/Ruby/blob/master/maths/number_of_digits.rb)
|
||||
* [Power Of Two](https://github.com/TheAlgorithms/Ruby/blob/master/maths/power_of_two.rb)
|
||||
* [Prime Number](https://github.com/TheAlgorithms/Ruby/blob/master/maths/prime_number.rb)
|
||||
* [Roman To Integer](https://github.com/TheAlgorithms/Ruby/blob/master/maths/roman_to_integer.rb)
|
||||
* [Square Root](https://github.com/TheAlgorithms/Ruby/blob/master/maths/square_root.rb)
|
||||
* [Square Root Test](https://github.com/TheAlgorithms/Ruby/blob/master/maths/square_root_test.rb)
|
||||
* [Sum Of Digits](https://github.com/TheAlgorithms/Ruby/blob/master/maths/sum_of_digits.rb)
|
||||
|
@ -127,18 +142,26 @@
|
|||
* [Ternary Search](https://github.com/TheAlgorithms/Ruby/blob/master/searches/ternary_search.rb)
|
||||
|
||||
## Sorting
|
||||
* [Bead Sort](https://github.com/TheAlgorithms/Ruby/blob/master/sorting/bead_sort.rb)
|
||||
* [Bead Sort Test](https://github.com/TheAlgorithms/Ruby/blob/master/sorting/bead_sort_test.rb)
|
||||
* [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)
|
||||
* [Bubble Sort Test](https://github.com/TheAlgorithms/Ruby/blob/master/sorting/bubble_sort_test.rb)
|
||||
* [Bucket Sort](https://github.com/TheAlgorithms/Ruby/blob/master/sorting/bucket_sort.rb)
|
||||
* [Bucket Sort Test](https://github.com/TheAlgorithms/Ruby/blob/master/sorting/bucket_sort_test.rb)
|
||||
* [Cocktail Sort](https://github.com/TheAlgorithms/Ruby/blob/master/sorting/cocktail_sort.rb)
|
||||
* [Cocktail Sort Test](https://github.com/TheAlgorithms/Ruby/blob/master/sorting/cocktail_sort_test.rb)
|
||||
* [Comb Sort](https://github.com/TheAlgorithms/Ruby/blob/master/sorting/comb_sort.rb)
|
||||
* [Comb Sort Test](https://github.com/TheAlgorithms/Ruby/blob/master/sorting/comb_sort_test.rb)
|
||||
* [Heap Sort](https://github.com/TheAlgorithms/Ruby/blob/master/sorting/heap_sort.rb)
|
||||
* [Heap Sort Test](https://github.com/TheAlgorithms/Ruby/blob/master/sorting/heap_sort_test.rb)
|
||||
* [Insertion Sort](https://github.com/TheAlgorithms/Ruby/blob/master/sorting/insertion_sort.rb)
|
||||
* [Insertion Sort Test](https://github.com/TheAlgorithms/Ruby/blob/master/sorting/insertion_sort_test.rb)
|
||||
* [Merge Sort](https://github.com/TheAlgorithms/Ruby/blob/master/sorting/merge_sort.rb)
|
||||
* [Merge Sort Test](https://github.com/TheAlgorithms/Ruby/blob/master/sorting/merge_sort_test.rb)
|
||||
* [Pancake Sort](https://github.com/TheAlgorithms/Ruby/blob/master/sorting/pancake_sort.rb)
|
||||
* [Pancake Sort Test](https://github.com/TheAlgorithms/Ruby/blob/master/sorting/pancake_sort_test.rb)
|
||||
* [Quicksort](https://github.com/TheAlgorithms/Ruby/blob/master/sorting/quicksort.rb)
|
||||
* [Quicksort Test](https://github.com/TheAlgorithms/Ruby/blob/master/sorting/quicksort_test.rb)
|
||||
* [Radix Sort](https://github.com/TheAlgorithms/Ruby/blob/master/sorting/radix_sort.rb)
|
||||
|
|
23
bit_manipulation/binary_and_operator.rb
Normal file
23
bit_manipulation/binary_and_operator.rb
Normal file
|
@ -0,0 +1,23 @@
|
|||
def binary_and(x, y)
|
||||
raise 'Input must only contain positive integers' if x < 0 or y < 0
|
||||
|
||||
"0b" + (x & y).to_s(2)
|
||||
end
|
||||
|
||||
begin
|
||||
binary_and(-1, 0)
|
||||
rescue => e
|
||||
puts e.message
|
||||
end
|
||||
# Input must only contain positive integers
|
||||
|
||||
puts binary_and(1, 1)
|
||||
# 0b1
|
||||
puts binary_and(0, 1)
|
||||
# 0b0
|
||||
puts binary_and(1024, 1024)
|
||||
# 0b10000000000
|
||||
puts binary_and(0, 1023)
|
||||
# 0b0000000000
|
||||
puts binary_and(16, 58)
|
||||
# 0b010000
|
26
bit_manipulation/binary_count_setbits.rb
Normal file
26
bit_manipulation/binary_count_setbits.rb
Normal file
|
@ -0,0 +1,26 @@
|
|||
def binary_count_setbits(x)
|
||||
raise 'Input must be a positive integer' if x < 0
|
||||
|
||||
binary = x.to_s(2)
|
||||
|
||||
binary.chars.map { |c| c.to_i }.reduce(:+)
|
||||
end
|
||||
|
||||
begin
|
||||
binary_count_setbits(-1)
|
||||
rescue => e
|
||||
puts e.message
|
||||
end
|
||||
# Input must be a positive integer
|
||||
|
||||
puts binary_count_setbits(0)
|
||||
# 0
|
||||
|
||||
puts binary_count_setbits(1)
|
||||
# 1
|
||||
|
||||
puts binary_count_setbits(1024)
|
||||
# 1
|
||||
|
||||
puts binary_count_setbits(1023)
|
||||
# 10
|
36
bit_manipulation/binary_count_trailing_zeroes.rb
Normal file
36
bit_manipulation/binary_count_trailing_zeroes.rb
Normal file
|
@ -0,0 +1,36 @@
|
|||
def binary_count_trailing_zeroes(x)
|
||||
raise 'Input must be a positive integer' if x < 0
|
||||
|
||||
binary = x.to_s(2)
|
||||
|
||||
count = 0
|
||||
binary.chars.reverse_each do |char|
|
||||
break if char == "1"
|
||||
|
||||
count += 1
|
||||
end
|
||||
|
||||
count
|
||||
end
|
||||
|
||||
begin
|
||||
binary_count_trailing_zeroes(-1)
|
||||
rescue => e
|
||||
puts e.message
|
||||
end
|
||||
# Input must be a positive integer
|
||||
|
||||
puts binary_count_trailing_zeroes(0)
|
||||
# 1
|
||||
|
||||
puts binary_count_trailing_zeroes(1023)
|
||||
# 0
|
||||
|
||||
puts binary_count_trailing_zeroes(1024)
|
||||
# 10
|
||||
|
||||
puts binary_count_trailing_zeroes(54)
|
||||
# 1
|
||||
|
||||
puts binary_count_trailing_zeroes(121024)
|
||||
# 6
|
24
bit_manipulation/binary_or_operator.rb
Normal file
24
bit_manipulation/binary_or_operator.rb
Normal file
|
@ -0,0 +1,24 @@
|
|||
def binary_or(x, y)
|
||||
raise 'Input must only contain positive integers' if x < 0 or y < 0
|
||||
|
||||
"0b" + (x | y).to_s(2)
|
||||
end
|
||||
|
||||
begin
|
||||
binary_or(-1, 0)
|
||||
rescue => e
|
||||
puts e.message
|
||||
end
|
||||
# Input must only contain positive integers
|
||||
|
||||
puts binary_or(1, 1)
|
||||
# 0b1
|
||||
puts binary_or(0, 1)
|
||||
# 0b1
|
||||
puts binary_or(1024, 1024)
|
||||
# 0b10000000000
|
||||
puts binary_or(0, 1023)
|
||||
# 0b1111111111
|
||||
puts binary_or(16, 58)
|
||||
# 0b110010
|
||||
|
44
bit_manipulation/binary_xor_operator.rb
Normal file
44
bit_manipulation/binary_xor_operator.rb
Normal file
|
@ -0,0 +1,44 @@
|
|||
def binary_xor(x, y)
|
||||
raise 'Input must only contain positive integers' if x < 0 or y < 0
|
||||
|
||||
binary_x = x.to_s(2)
|
||||
binary_y = y.to_s(2)
|
||||
|
||||
if binary_x.length > binary_y.length
|
||||
prefix = "0" * (binary_x.length - binary_y.length)
|
||||
binary_y = prefix + binary_y
|
||||
elsif binary_y.length > binary_x.length
|
||||
prefix = "0" * (binary_y.length - binary_x.length)
|
||||
binary_x = prefix + binary_x
|
||||
end
|
||||
result = "0b"
|
||||
binary_x.each_char.with_index do |x_char, i|
|
||||
y_char = binary_y[i]
|
||||
|
||||
if (x_char == "1" && y_char != "1") || (x_char != "1" && y_char == "1")
|
||||
result += "1"
|
||||
else
|
||||
result += "0"
|
||||
end
|
||||
end
|
||||
|
||||
result
|
||||
end
|
||||
|
||||
begin
|
||||
binary_xor(-1, 0)
|
||||
rescue => e
|
||||
puts e.message
|
||||
end
|
||||
# Input must only contain positive integers
|
||||
|
||||
puts binary_xor(1, 1)
|
||||
# 0b0
|
||||
puts binary_xor(0, 1)
|
||||
# 0b1
|
||||
puts binary_xor(1024, 1024)
|
||||
# 0b00000000000
|
||||
puts binary_xor(0, 1023)
|
||||
# 0b1111111111
|
||||
puts binary_xor(16, 58)
|
||||
# 0b101010
|
100
bit_manipulation/single_bit_binary_operations.rb
Normal file
100
bit_manipulation/single_bit_binary_operations.rb
Normal file
|
@ -0,0 +1,100 @@
|
|||
def set_bit(x, position)
|
||||
raise "position must be >= 0" if position < 0
|
||||
|
||||
x | (1 << position)
|
||||
end
|
||||
|
||||
puts set_bit(0, 0)
|
||||
# 1
|
||||
|
||||
puts set_bit(0, 4)
|
||||
# 16
|
||||
|
||||
puts set_bit(8, 3)
|
||||
# 8
|
||||
|
||||
puts set_bit(8, 4)
|
||||
# 24
|
||||
|
||||
begin
|
||||
puts set_bit(8, -4)
|
||||
rescue => e
|
||||
puts e.message
|
||||
end
|
||||
# position must be >= 0
|
||||
|
||||
|
||||
def clear_bit(x, position)
|
||||
raise "position must be > 0" if position < 0
|
||||
|
||||
x & ~(1 << position)
|
||||
end
|
||||
|
||||
puts clear_bit(0, 0)
|
||||
# 0
|
||||
|
||||
puts clear_bit(0, 4)
|
||||
# 0
|
||||
|
||||
puts clear_bit(8, 3)
|
||||
# 0
|
||||
|
||||
puts clear_bit(24, 4)
|
||||
# 8
|
||||
|
||||
begin
|
||||
puts clear_bit(0, -4)
|
||||
rescue => e
|
||||
puts e.message
|
||||
end
|
||||
# position must be > 0
|
||||
|
||||
def flip_bit(x, position)
|
||||
raise "position must be > 0" if position < 0
|
||||
|
||||
x ^ (1 << position)
|
||||
end
|
||||
|
||||
puts flip_bit(0, 0)
|
||||
# 1
|
||||
|
||||
puts flip_bit(0, 4)
|
||||
# 16
|
||||
|
||||
puts flip_bit(8, 3)
|
||||
# 0
|
||||
|
||||
puts flip_bit(24, 4)
|
||||
# 8
|
||||
|
||||
begin
|
||||
puts flip_bit(0, -4)
|
||||
rescue => e
|
||||
puts e.message
|
||||
end
|
||||
# position must be > 0
|
||||
|
||||
def is_bit_set(x, position)
|
||||
raise "position must be > 0" if position < 0
|
||||
|
||||
((x >> position) & 1) == 1
|
||||
end
|
||||
|
||||
puts is_bit_set(0, 0)
|
||||
# false
|
||||
|
||||
puts is_bit_set(1, 0)
|
||||
# true
|
||||
|
||||
puts is_bit_set(8, 3)
|
||||
# true
|
||||
|
||||
puts is_bit_set(24, 4)
|
||||
# true
|
||||
|
||||
begin
|
||||
puts is_bit_set(0, -4)
|
||||
rescue => e
|
||||
puts e.message
|
||||
end
|
||||
# position must be > 0
|
42
data_structures/arrays/good_pairs.rb
Normal file
42
data_structures/arrays/good_pairs.rb
Normal file
|
@ -0,0 +1,42 @@
|
|||
# Challenge name: Number of good pairs
|
||||
#
|
||||
# Given an array of integers nums.
|
||||
# A pair (i,j) is called good if nums[i] == nums[j] and i < j.
|
||||
# Return the number of good pairs.
|
||||
#
|
||||
# @param {Integer[]} nums
|
||||
# @return {Integer}
|
||||
#
|
||||
|
||||
#
|
||||
# Approach 1: Brute Force
|
||||
#
|
||||
# Time Complexity: O(n^2)
|
||||
#
|
||||
def num_identical_pairs(nums)
|
||||
count = 0
|
||||
nums.each_with_index do |num, i|
|
||||
target = num
|
||||
nums.each_with_index do |num, j|
|
||||
next if i >= j
|
||||
if num == target
|
||||
count += 1
|
||||
end
|
||||
end
|
||||
end
|
||||
count
|
||||
end
|
||||
|
||||
nums = [1, 2, 3, 1, 1, 3]
|
||||
puts(num_identical_pairs(nums))
|
||||
# Output: 4
|
||||
# Explanation: There are 4 good pairs (0,3), (0,4), (3,4), (2,5) 0-indexed.
|
||||
|
||||
nums = [1, 1, 1, 1]
|
||||
puts(num_identical_pairs(nums))
|
||||
# Output: 6
|
||||
# Explanation: Each pair in the array are good.
|
||||
|
||||
nums = [1, 2, 3]
|
||||
puts(num_identical_pairs(nums))
|
||||
# Output: 0
|
33
data_structures/arrays/shortest_word_distance.rb
Normal file
33
data_structures/arrays/shortest_word_distance.rb
Normal file
|
@ -0,0 +1,33 @@
|
|||
# Shortest Word Distance
|
||||
# Given a list of words and two words word1 and word2,
|
||||
# return the shortest distance between these two words in the list.
|
||||
# @param {String[]} words
|
||||
# @param {String} word1
|
||||
# @param {String} word2
|
||||
# @return {Integer}
|
||||
|
||||
def shortest_distance(words, word1, word2)
|
||||
return 0 if word1 == word2
|
||||
return 0 unless words.include?(word1) && words.include?(word2)
|
||||
|
||||
minimum_distance = words.length
|
||||
words.each_with_index do |outer_value, outer_index|
|
||||
words.each_with_index do |inner_value, inner_index|
|
||||
if ((inner_value == word1 && outer_value == word2) || (inner_value == word2 && outer_value == word1)) && (minimum_distance > (outer_index - inner_index).abs)
|
||||
minimum_distance = (outer_index - inner_index).abs
|
||||
end
|
||||
end
|
||||
end
|
||||
minimum_distance
|
||||
end
|
||||
|
||||
words = %w[practice makes perfect coding makes]
|
||||
word1 = 'coding'
|
||||
word2 = 'practice'
|
||||
puts(shortest_distance(words, word1, word2))
|
||||
# Output: 3
|
||||
words = %w[practice makes perfect coding makes]
|
||||
word1 = 'makes'
|
||||
word2 = 'coding'
|
||||
puts(shortest_distance(words, word1, word2))
|
||||
# Output: 1
|
292
data_structures/arrays/sudoku.rb
Normal file
292
data_structures/arrays/sudoku.rb
Normal file
|
@ -0,0 +1,292 @@
|
|||
# Challenge name: Valid Sudoku
|
||||
|
||||
# Determine if a 9 x 9 Sudoku board is valid. Only the filled cells need to be validated according to the following rules:
|
||||
# Each row must contain the digits 1-9 without repetition.
|
||||
# Each column must contain the digits 1-9 without repetition.
|
||||
# Each of the nine 3 x 3 sub-boxes of the grid must contain the digits 1-9 without repetition.
|
||||
|
||||
# @param {Character[][]} board
|
||||
# @return {Boolean}
|
||||
|
||||
#
|
||||
# Approach 1: Hash & Brute Force
|
||||
#
|
||||
def is_valid_sudoku(board)
|
||||
rows = []
|
||||
columns = []
|
||||
grids = []
|
||||
|
||||
# make each row into a hash to track for duplicated values
|
||||
board.each do |row|
|
||||
row_hash = Hash.new(0)
|
||||
row.each do |num|
|
||||
next if num == "."
|
||||
row_hash[num] += 1
|
||||
end
|
||||
rows << row_hash
|
||||
end
|
||||
|
||||
# check each row hash for duplicated value
|
||||
rows.each do |row|
|
||||
row.each do |k, v|
|
||||
if v > 1
|
||||
return false
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# make each column into a hash to track for duplicated values
|
||||
(0..8).each do |i|
|
||||
column_hash = Hash.new(0)
|
||||
board.each do |row|
|
||||
next if row[i] == "."
|
||||
column_hash[row[i]] += 1
|
||||
columns << column_hash
|
||||
end
|
||||
end
|
||||
|
||||
# check each column hash for duplicated value
|
||||
columns.each do |column|
|
||||
column.each do |k, v|
|
||||
if v > 1
|
||||
return false
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# make each 3x3 grid into a hash to track for duplicated values
|
||||
(0..2).each do |i|
|
||||
grid_hash = Hash.new(0)
|
||||
board.first(3).each do |row|
|
||||
next if row[i] == "."
|
||||
grid_hash[row[i]] += 1
|
||||
grids << grid_hash
|
||||
end
|
||||
board[3..5].each do |row|
|
||||
next if row[i] == "."
|
||||
grid_hash[row[i]] += 1
|
||||
grids << grid_hash
|
||||
end
|
||||
board.each do |row|
|
||||
next if row[i] == "."
|
||||
grid_hash[row[i]] += 1
|
||||
grids << grid_hash
|
||||
end
|
||||
end
|
||||
(3..5).each do |i|
|
||||
grid_hash = Hash.new(0)
|
||||
board.first(3).each do |row|
|
||||
next if row[i] == "."
|
||||
grid_hash[row[i]] += 1
|
||||
grids << grid_hash
|
||||
end
|
||||
board[3..5].each do |row|
|
||||
next if row[i] == "."
|
||||
grid_hash[row[i]] += 1
|
||||
grids << grid_hash
|
||||
end
|
||||
board.each do |row|
|
||||
next if row[i] == "."
|
||||
grid_hash[row[i]] += 1
|
||||
grids << grid_hash
|
||||
end
|
||||
end
|
||||
(6..8).last(3).each do |i|
|
||||
grid_hash = Hash.new(0)
|
||||
board.first(3).each do |row|
|
||||
next if row[i] == "."
|
||||
grid_hash[row[i]] += 1
|
||||
grids << grid_hash
|
||||
end
|
||||
board[3..5].each do |row|
|
||||
next if row[i] == "."
|
||||
grid_hash[row[i]] += 1
|
||||
grids << grid_hash
|
||||
end
|
||||
board.each do |row|
|
||||
next if row[i] == "."
|
||||
grid_hash[row[i]] += 1
|
||||
grids << grid_hash
|
||||
end
|
||||
end
|
||||
|
||||
# check each grid hash for duplicated value
|
||||
grids.each do |grid|
|
||||
grid.each do |k, v|
|
||||
if v > 1
|
||||
return false
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
true
|
||||
end
|
||||
|
||||
board = [["5","3",".",".","7",".",".",".","."],
|
||||
["6",".",".","1","9","5",".",".","."],
|
||||
[".","9","8",".",".",".",".","6","."],
|
||||
["8",".",".",".","6",".",".",".","3"],
|
||||
["4",".",".","8",".","3",".",".","1"],
|
||||
["7",".",".",".","2",".",".",".","6"],
|
||||
[".","6",".",".",".",".","2","8","."],
|
||||
[".",".",".","4","1","9",".",".","5"],
|
||||
[".",".",".",".","8",".",".","7","9"]]
|
||||
print(is_valid_sudoku(board))
|
||||
# => true
|
||||
|
||||
board = [["8","3",".",".","7",".",".",".","."],
|
||||
["6",".",".","1","9","5",".",".","."],
|
||||
[".","9","8",".",".",".",".","6","."],
|
||||
["8",".",".",".","6",".",".",".","3"],
|
||||
["4",".",".","8",".","3",".",".","1"],
|
||||
["7",".",".",".","2",".",".",".","6"],
|
||||
[".","6",".",".",".",".","2","8","."],
|
||||
[".",".",".","4","1","9",".",".","5"],
|
||||
[".",".",".",".","8",".",".","7","9"]]
|
||||
print(is_valid_sudoku(board))
|
||||
# => false
|
||||
# explanation: duplicated value in column
|
||||
|
||||
board = [["8","3",".",".","7",".","3",".","."],
|
||||
["6",".",".","1","9","5",".",".","."],
|
||||
[".","9","8",".",".",".",".","6","."],
|
||||
["8",".",".",".","6",".",".",".","3"],
|
||||
["4",".",".","8",".","3",".",".","1"],
|
||||
["7",".",".",".","2",".",".",".","6"],
|
||||
[".","6",".",".",".",".","2","8","."],
|
||||
[".",".",".","4","1","9",".",".","5"],
|
||||
[".",".",".",".","8",".",".","7","9"]]
|
||||
print(is_valid_sudoku(board))
|
||||
# => false
|
||||
# explanation: duplicated value in row
|
||||
|
||||
board = [["8","3",".",".","7",".",".",".","."],
|
||||
["6",".",".","1","9","5",".",".","."],
|
||||
[".","9","8",".",".",".",".","6","."],
|
||||
[".",".",".",".","6",".",".",".","3"],
|
||||
["4",".",".","8",".","3",".",".","1"],
|
||||
["7",".",".",".","2",".",".",".","6"],
|
||||
[".","6",".",".",".",".","2","8","."],
|
||||
[".",".",".","4","1","9",".",".","5"],
|
||||
[".",".",".",".","8",".",".","7","9"]]
|
||||
print(is_valid_sudoku(board))
|
||||
# => false
|
||||
# explanation: duplicated value in 3x3 grid
|
||||
|
||||
#
|
||||
# Approach 2: Sets
|
||||
#
|
||||
require 'set'
|
||||
|
||||
def is_valid_sudoku(board)
|
||||
return false unless check_rows(board)
|
||||
return false unless check_cols(board)
|
||||
row = -3
|
||||
while (row += 3) < 9
|
||||
col = - 3
|
||||
while (col += 3) < 9
|
||||
start_point = [row, col]
|
||||
return false unless check_grid(board, start_point)
|
||||
end
|
||||
end
|
||||
true
|
||||
end
|
||||
|
||||
def check_grid(board, start_point)
|
||||
row = start_point[0]
|
||||
col = start_point[1]
|
||||
ss = Set.new
|
||||
(row..(row + 2)).each do |cur_row|
|
||||
(col..(col + 2)).each do |cur_col|
|
||||
next if board[cur_row][cur_col] == "."
|
||||
return false if ss.member?(board[cur_row][cur_col])
|
||||
ss.add board[cur_row][cur_col]
|
||||
end
|
||||
end
|
||||
true
|
||||
end
|
||||
|
||||
def check_col(board, col)
|
||||
ss = Set.new
|
||||
(0..8).each do |row|
|
||||
next if board[row][col] == "."
|
||||
return false if ss.member?(board[row][col])
|
||||
ss.add board[row][col]
|
||||
end
|
||||
true
|
||||
end
|
||||
|
||||
def check_row(board, row)
|
||||
ss = Set.new
|
||||
(0..8).each do |col|
|
||||
next if board[row][col] == "."
|
||||
return false if ss.member?(board[row][col])
|
||||
ss.add board[row][col]
|
||||
end
|
||||
true
|
||||
end
|
||||
|
||||
def check_rows(board)
|
||||
(0..8).each do |row|
|
||||
return false unless check_row(board, row)
|
||||
end
|
||||
true
|
||||
end
|
||||
|
||||
def check_cols(board)
|
||||
(0..8).each do |col|
|
||||
return false unless check_col(board, col)
|
||||
end
|
||||
true
|
||||
end
|
||||
|
||||
board = [["5","3",".",".","7",".",".",".","."],
|
||||
["6",".",".","1","9","5",".",".","."],
|
||||
[".","9","8",".",".",".",".","6","."],
|
||||
["8",".",".",".","6",".",".",".","3"],
|
||||
["4",".",".","8",".","3",".",".","1"],
|
||||
["7",".",".",".","2",".",".",".","6"],
|
||||
[".","6",".",".",".",".","2","8","."],
|
||||
[".",".",".","4","1","9",".",".","5"],
|
||||
[".",".",".",".","8",".",".","7","9"]]
|
||||
print(is_valid_sudoku(board))
|
||||
# => true
|
||||
|
||||
board = [["8","3",".",".","7",".",".",".","."],
|
||||
["6",".",".","1","9","5",".",".","."],
|
||||
[".","9","8",".",".",".",".","6","."],
|
||||
["8",".",".",".","6",".",".",".","3"],
|
||||
["4",".",".","8",".","3",".",".","1"],
|
||||
["7",".",".",".","2",".",".",".","6"],
|
||||
[".","6",".",".",".",".","2","8","."],
|
||||
[".",".",".","4","1","9",".",".","5"],
|
||||
[".",".",".",".","8",".",".","7","9"]]
|
||||
print(is_valid_sudoku(board))
|
||||
# => false
|
||||
# explanation: duplicated value in column
|
||||
|
||||
board = [["8","3",".",".","7",".","3",".","."],
|
||||
["6",".",".","1","9","5",".",".","."],
|
||||
[".","9","8",".",".",".",".","6","."],
|
||||
["8",".",".",".","6",".",".",".","3"],
|
||||
["4",".",".","8",".","3",".",".","1"],
|
||||
["7",".",".",".","2",".",".",".","6"],
|
||||
[".","6",".",".",".",".","2","8","."],
|
||||
[".",".",".","4","1","9",".",".","5"],
|
||||
[".",".",".",".","8",".",".","7","9"]]
|
||||
print(is_valid_sudoku(board))
|
||||
# => false
|
||||
# explanation: duplicated value in row
|
||||
|
||||
board = [["8","3",".",".","7",".",".",".","."],
|
||||
["6",".",".","1","9","5",".",".","."],
|
||||
[".","9","8",".",".",".",".","6","."],
|
||||
[".",".",".",".","6",".",".",".","3"],
|
||||
["4",".",".","8",".","3",".",".","1"],
|
||||
["7",".",".",".","2",".",".",".","6"],
|
||||
[".","6",".",".",".",".","2","8","."],
|
||||
[".",".",".","4","1","9",".",".","5"],
|
||||
[".",".",".",".","8",".",".","7","9"]]
|
||||
print(is_valid_sudoku(board))
|
||||
# => false
|
||||
# explanation: duplicated value in 3x3 grid
|
43
data_structures/hash_table/good_pairs.rb
Normal file
43
data_structures/hash_table/good_pairs.rb
Normal file
|
@ -0,0 +1,43 @@
|
|||
# Challenge name: Number of good pairs
|
||||
#
|
||||
# Given an array of integers nums.
|
||||
# A pair (i,j) is called good if nums[i] == nums[j] and i < j.
|
||||
# Return the number of good pairs.
|
||||
#
|
||||
# @param {Integer[]} nums
|
||||
# @return {Integer}
|
||||
#
|
||||
|
||||
#
|
||||
# Approach 1: Hash
|
||||
#
|
||||
# Time Complexity: O(n)
|
||||
def num_identical_pairs(nums)
|
||||
hash = Hash.new(0)
|
||||
|
||||
nums.each do |num|
|
||||
hash[num] = hash[num] + 1
|
||||
end
|
||||
|
||||
counter = 0
|
||||
# Count how many times each number appears.
|
||||
# If a number appears n times, then n * (n – 1) / 2 good pairs
|
||||
# can be made with this number.
|
||||
hash.values.each do |val|
|
||||
counter += (val * (val - 1) / 2)
|
||||
end
|
||||
|
||||
counter
|
||||
end
|
||||
|
||||
nums = [1, 2, 3, 1, 1, 3]
|
||||
puts(num_identical_pairs(nums))
|
||||
# Output: 4
|
||||
|
||||
nums = [1, 1, 1, 1]
|
||||
puts(num_identical_pairs(nums))
|
||||
# Output: 6
|
||||
|
||||
nums = [1, 2, 3]
|
||||
puts(num_identical_pairs(nums))
|
||||
# Output: 0
|
48
data_structures/hash_table/uncommon_words.rb
Normal file
48
data_structures/hash_table/uncommon_words.rb
Normal file
|
@ -0,0 +1,48 @@
|
|||
# Challenge name: Uncommon words from two sentences
|
||||
#
|
||||
# We are given two sentences A and B.
|
||||
# (A sentence is a string of space separated words.
|
||||
# Each word consists only of lowercase letters.)
|
||||
#
|
||||
# A word is uncommon if it appears exactly once in one of the sentences,
|
||||
# and does not appear in the other sentence.
|
||||
#
|
||||
# Return a list of all uncommon words.
|
||||
# You may return the list in any order.
|
||||
#
|
||||
# Example 1:
|
||||
# Input: A = "this apple is sweet", B = "this apple is sour"
|
||||
# Output: ["sweet","sour"]
|
||||
#
|
||||
# Example 2:
|
||||
# Input: A = "apple apple", B = "banana"
|
||||
# Output: ["banana"]
|
||||
|
||||
#
|
||||
# Approach 1: Hash
|
||||
#
|
||||
# Time Complexitiy: O(n)
|
||||
|
||||
def find_uncommon_words(strA, strB)
|
||||
array = strA.concat(" ", strB).split(" ")
|
||||
hash = Hash.new(0)
|
||||
result = []
|
||||
|
||||
array.each do |word|
|
||||
hash[word] += 1
|
||||
end
|
||||
|
||||
hash.each do |k, v|
|
||||
if v < 2
|
||||
result.push(k)
|
||||
end
|
||||
end
|
||||
|
||||
result
|
||||
end
|
||||
|
||||
puts find_uncommon_words("this apple is sweet", "this apple is sour")
|
||||
# => ["sweet", "sour"]
|
||||
|
||||
puts find_uncommon_words("apple apple", "banana")
|
||||
# => ["banana"]
|
88
data_structures/queues/circular_queue.rb
Normal file
88
data_structures/queues/circular_queue.rb
Normal file
|
@ -0,0 +1,88 @@
|
|||
# Challenge name: Circular Queue
|
||||
#
|
||||
# Design the implementation of a circular queue.
|
||||
# The circular queue is a linear data structure in which the operations are performed based on FIFO (First In First Out) principle and
|
||||
# the last position is connected back to the first position to make a circle. It is also called "Ring Buffer".
|
||||
#
|
||||
|
||||
#
|
||||
# Complexity Analysis
|
||||
#
|
||||
# Time complexity: O(1).
|
||||
# All of the methods in our circular data structure are of constant time complexity.
|
||||
#
|
||||
# Space Complexity: O(N).
|
||||
# The overall space complexity of the data structure is linear, where N is the pre-assigned capacity of the queue.
|
||||
# However, it is worth mentioning that the memory consumption of the data structure remains as its pre-assigned capacity during its entire life cycle.
|
||||
|
||||
class CircularQueue
|
||||
def initialize(max_size)
|
||||
@max_size = max_size
|
||||
@queue = Array.new(max_size, nil)
|
||||
@front = 0
|
||||
@back = 0
|
||||
@size = 0
|
||||
end
|
||||
|
||||
attr_accessor :front, :back, :size
|
||||
attr_reader :max_size, :queue
|
||||
|
||||
def empty?
|
||||
size == 0
|
||||
end
|
||||
|
||||
def peek
|
||||
return nil if empty?
|
||||
|
||||
queue[front]
|
||||
end
|
||||
|
||||
def add(x)
|
||||
raise "Queue is at max capacity" if size == max_size
|
||||
|
||||
|
||||
queue[back] = x
|
||||
@back = (back + 1) % max_size
|
||||
@size += 1
|
||||
end
|
||||
|
||||
def pop
|
||||
raise "Queue is empty" if size == 0
|
||||
|
||||
temp = queue[front]
|
||||
queue[front] = nil
|
||||
@front = (front + 1) % max_size
|
||||
@size -= 1
|
||||
|
||||
temp
|
||||
end
|
||||
end
|
||||
|
||||
queue = CircularQueue.new(3)
|
||||
|
||||
begin
|
||||
queue.pop
|
||||
rescue => e
|
||||
puts e.message
|
||||
end
|
||||
|
||||
queue.add(1)
|
||||
queue.add(2)
|
||||
queue.add(3)
|
||||
|
||||
begin
|
||||
queue.add(4)
|
||||
rescue => e
|
||||
puts e.message
|
||||
end
|
||||
|
||||
puts queue.inspect
|
||||
# => #<CircularQueue:0x00007fea23876cd8 @max_size=3, @queue=[1, 2, 3], @front=0, @back=0, @size=3>
|
||||
|
||||
puts queue.peek
|
||||
# => 1
|
||||
|
||||
queue.pop
|
||||
|
||||
puts queue.peek
|
||||
# => 2
|
91
dynamic_programming/count_sorted_vowel_strings.rb
Normal file
91
dynamic_programming/count_sorted_vowel_strings.rb
Normal file
|
@ -0,0 +1,91 @@
|
|||
# Challenge name: Count Sorted Vowel Strings
|
||||
#
|
||||
# Given an integer n, return the number of strings of length n that consist only
|
||||
# of vowels (a, e, i, o, u) and are lexicographically sorted.
|
||||
#
|
||||
# A string s is lexicographically sorted if for all valid i, s[i] is the same as
|
||||
# or comes before s[i+1] in the alphabet.
|
||||
#
|
||||
#
|
||||
# Example 1:
|
||||
#
|
||||
# Input: n = 1
|
||||
# Output: 5
|
||||
# Explanation: The 5 sorted strings that consist of vowels only are ["a","e","i","o","u"].
|
||||
#
|
||||
# Example 2:
|
||||
#
|
||||
# Input: n = 2
|
||||
# Output: 15
|
||||
# Explanation: The 15 sorted strings that consist of vowels only are
|
||||
# ["aa","ae","ai","ao","au","ee","ei","eo","eu","ii","io","iu","oo","ou","uu"].
|
||||
# Note that "ea" is not a valid string since 'e' comes after 'a' in the alphabet.
|
||||
#
|
||||
# Example 3:
|
||||
#
|
||||
# Input: n = 33
|
||||
# Output: 66045
|
||||
|
||||
#
|
||||
# Approach: Using Recursion + Memoization, Top Down Dynamic Programming
|
||||
#
|
||||
|
||||
#
|
||||
# Algorithm: Dynamic Programming state transition.
|
||||
#
|
||||
# F(0) = 1
|
||||
# F(n)a = F(n-1)a + F(n-1)e + F(n-1)i + F(n-1)o +F(n-1)u
|
||||
# F(n)e = F(n-1)e + F(n-1)i + F(n-1)o + F(n-1)u
|
||||
# F(n)i = F(n-1)i + F(n-1)o +F(n-1)u
|
||||
# F(n)o = F(n-1)o + F(n-1)u
|
||||
# F(n)u = F(n-1)u
|
||||
#
|
||||
|
||||
# @param {Integer} n
|
||||
# @return {Integer}
|
||||
|
||||
def count_vowel_strings(n, letter = 'a')
|
||||
return 1 if n < 1
|
||||
|
||||
@h ||= {}
|
||||
key = [n, letter]
|
||||
return @h[key] if @h[key]
|
||||
|
||||
result = case letter
|
||||
when 'a'
|
||||
count_vowel_strings(n - 1, letter = 'a') +
|
||||
count_vowel_strings(n - 1, letter = 'e') +
|
||||
count_vowel_strings(n - 1, letter = 'i') +
|
||||
count_vowel_strings(n - 1, letter = 'o') +
|
||||
count_vowel_strings(n - 1, letter = 'u')
|
||||
when 'e'
|
||||
count_vowel_strings(n - 1, letter = 'e') +
|
||||
count_vowel_strings(n - 1, letter = 'i') +
|
||||
count_vowel_strings(n - 1, letter = 'o') +
|
||||
count_vowel_strings(n - 1, letter = 'u')
|
||||
when 'i'
|
||||
count_vowel_strings(n - 1, letter = 'i') +
|
||||
count_vowel_strings(n - 1, letter = 'o') +
|
||||
count_vowel_strings(n - 1, letter = 'u')
|
||||
when 'o'
|
||||
count_vowel_strings(n - 1, letter = 'o') +
|
||||
count_vowel_strings(n - 1, letter = 'u')
|
||||
when 'u'
|
||||
count_vowel_strings(n - 1, letter = 'u')
|
||||
end
|
||||
|
||||
@h[key] = result
|
||||
@h[key]
|
||||
end
|
||||
|
||||
n = 33
|
||||
puts count_vowel_strings(n)
|
||||
# Output: 66045
|
||||
|
||||
n = 2
|
||||
puts count_vowel_strings(n)
|
||||
# Output: 15
|
||||
|
||||
n = 1
|
||||
puts count_vowel_strings(n)
|
||||
# Output: 5
|
65
maths/count_sorted_vowel_strings.rb
Normal file
65
maths/count_sorted_vowel_strings.rb
Normal file
|
@ -0,0 +1,65 @@
|
|||
# Challenge name: Count Sorted Vowel Strings
|
||||
#
|
||||
# Given an integer n, return the number of strings of length n that consist only
|
||||
# of vowels (a, e, i, o, u) and are lexicographically sorted.
|
||||
#
|
||||
# A string s is lexicographically sorted if for all valid i, s[i] is the same as
|
||||
# or comes before s[i+1] in the alphabet.
|
||||
#
|
||||
#
|
||||
# Example 1:
|
||||
#
|
||||
# Input: n = 1
|
||||
# Output: 5
|
||||
# Explanation: The 5 sorted strings that consist of vowels only are ["a","e","i","o","u"].
|
||||
#
|
||||
# Example 2:
|
||||
#
|
||||
# Input: n = 2
|
||||
# Output: 15
|
||||
# Explanation: The 15 sorted strings that consist of vowels only are
|
||||
# ["aa","ae","ai","ao","au","ee","ei","eo","eu","ii","io","iu","oo","ou","uu"].
|
||||
# Note that "ea" is not a valid string since 'e' comes after 'a' in the alphabet.
|
||||
#
|
||||
# Example 3:
|
||||
#
|
||||
# Input: n = 33
|
||||
# Output: 66045
|
||||
|
||||
|
||||
#
|
||||
# Approach: Math
|
||||
#
|
||||
|
||||
#
|
||||
# Intuition and Algorithm
|
||||
#
|
||||
# The problem is a variant of finding Combinations.
|
||||
# Mathematically, the problem can be described as,
|
||||
# given 5 vowels (let k = 5), we want to find the
|
||||
# number of combinations using only n vowels. Also,
|
||||
# we can repeat each of those vowels multiple times.
|
||||
#
|
||||
|
||||
# Complexity Analysis
|
||||
#
|
||||
# Time Complexity: O(1), as the approach runs in constant time.
|
||||
# Space Complexity: O(1), as the approach uses constant extra space.
|
||||
|
||||
# @param {Integer} n
|
||||
# @return {Integer}
|
||||
def count_vowel_strings(n)
|
||||
(n + 4) * (n + 3) * (n + 2) * (n + 1) / 24
|
||||
end
|
||||
|
||||
n = 33
|
||||
puts count_vowel_strings(n)
|
||||
# Output: 66045
|
||||
|
||||
n = 2
|
||||
puts count_vowel_strings(n)
|
||||
# Output: 15
|
||||
|
||||
n = 1
|
||||
puts count_vowel_strings(n)
|
||||
# Output: 5
|
96
maths/roman_to_integer.rb
Normal file
96
maths/roman_to_integer.rb
Normal file
|
@ -0,0 +1,96 @@
|
|||
# Challenge name: Roman to Integer
|
||||
#
|
||||
# Roman numerals are represented by seven different symbols: I, V, X, L, C, D and M.
|
||||
#
|
||||
# Symbol Value
|
||||
# I 1
|
||||
# V 5
|
||||
# X 10
|
||||
# L 50
|
||||
# C 100
|
||||
# D 500
|
||||
# M 1000
|
||||
#
|
||||
# For example, 2 is written as II in Roman numeral, just two one's added together. 12 is written as XII, which is simply X + II. The number 27 is written as XXVII, which is XX + V + II.
|
||||
#
|
||||
# Roman numerals are usually written largest to smallest from left to right. However, the numeral for four is not IIII. Instead, the number four is written as IV. Because the one is before the five we subtract it making four. The same principle applies to the number nine, which is written as IX. There are six instances where subtraction is used:
|
||||
#
|
||||
# I can be placed before V (5) and X (10) to make 4 and 9.
|
||||
# X can be placed before L (50) and C (100) to make 40 and 90.
|
||||
# C can be placed before D (500) and M (1000) to make 400 and 900.
|
||||
# Given a roman numeral, convert it to an integer.
|
||||
#
|
||||
#
|
||||
|
||||
# Approach 1: Left-to-Right Pass
|
||||
#
|
||||
|
||||
# Complexity Analysis
|
||||
#
|
||||
# Let n be the length of the input string (the total number of symbols in it).
|
||||
#
|
||||
# Time complexity: O(1).
|
||||
# As there is a finite set of roman numerals.
|
||||
#
|
||||
# Space complexity: O(1).
|
||||
# Because only a constant number of single-value variables are used, the space complexity is O(1).
|
||||
|
||||
ROM_NUMS = {
|
||||
"I" => 1,
|
||||
"V" => 5,
|
||||
"X" => 10,
|
||||
"L" => 50,
|
||||
"C" => 100,
|
||||
"D" => 500,
|
||||
"M" => 1000
|
||||
}
|
||||
|
||||
# Now, recall that each symbol adds its own value, except for when a smaller
|
||||
# valued symbol is before a larger valued symbol. In those cases, instead of
|
||||
# adding both symbols to the total, we need to subtract the large from the
|
||||
# small, adding that instead.
|
||||
|
||||
# Therefore, the simplest algorithm is to use a pointer to scan through the
|
||||
# string, at each step deciding whether to add the current symbol and
|
||||
# go forward 1 place, or add the difference of the next 2 symbols and
|
||||
# go forward 2 places.
|
||||
|
||||
def roman_to_int(s)
|
||||
res = 0
|
||||
temp = 0
|
||||
|
||||
s.chars.each_with_index do |el, i|
|
||||
# subtractive case: if at least 2 symbols remaining AND value of s[i] < value of s[i + 1]
|
||||
if ROM_NUMS[s[i + 1]] && ROM_NUMS[el] < ROM_NUMS[s[i+1]]
|
||||
temp = ROM_NUMS[el]
|
||||
else
|
||||
# Else this is NOT the subtractive case.
|
||||
res += (ROM_NUMS[el] - temp)
|
||||
temp = 0
|
||||
end
|
||||
end
|
||||
|
||||
res
|
||||
end
|
||||
|
||||
s = "III"
|
||||
puts roman_to_int(s)
|
||||
# Output: 3
|
||||
|
||||
s = "IV"
|
||||
puts roman_to_int(s)
|
||||
# Output: 4
|
||||
|
||||
s = "IX"
|
||||
puts roman_to_int(s)
|
||||
# Output: 9
|
||||
|
||||
s = "LVIII"
|
||||
puts roman_to_int(s)
|
||||
# Output: 58
|
||||
# Explanation: L = 50, V= 5, III = 3.
|
||||
|
||||
s = "MCMXCIV"
|
||||
puts roman_to_int(s)
|
||||
# Output: 1994
|
||||
# Explanation: M = 1000, CM = 900, XC = 90 and IV = 4.
|
24
sorting/bead_sort.rb
Normal file
24
sorting/bead_sort.rb
Normal file
|
@ -0,0 +1,24 @@
|
|||
class Array
|
||||
def columns
|
||||
x = map(&:length).max
|
||||
Array.new(x) do |row|
|
||||
Array.new(length) { |column| self[column][row] }.compact
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def bead_sort(array)
|
||||
array
|
||||
.map { |element| [1] * element }
|
||||
.columns
|
||||
.columns
|
||||
.map(&:length)
|
||||
.reverse
|
||||
end
|
||||
|
||||
if $0 == __FILE__
|
||||
puts 'Enter a list of numbers separated by space'
|
||||
|
||||
list = gets.split.map(&:to_i)
|
||||
p bead_sort(list)
|
||||
end
|
11
sorting/bead_sort_test.rb
Normal file
11
sorting/bead_sort_test.rb
Normal file
|
@ -0,0 +1,11 @@
|
|||
require 'minitest/autorun'
|
||||
require_relative './sort_tests'
|
||||
require_relative './bead_sort'
|
||||
|
||||
class TestInsertionSort < Minitest::Test
|
||||
include SortTests
|
||||
|
||||
def sort(input)
|
||||
bead_sort(input)
|
||||
end
|
||||
end
|
24
sorting/cocktail_sort.rb
Normal file
24
sorting/cocktail_sort.rb
Normal file
|
@ -0,0 +1,24 @@
|
|||
def cocktail_sort(array)
|
||||
start = 0
|
||||
finish = array.length - 1
|
||||
way = 1
|
||||
loop do
|
||||
swapped = false
|
||||
start.step(finish - way, way) do |i|
|
||||
if (array[i] <=> array[i + way]) == way
|
||||
array[i], array[i + way] = array[i + way], array[i]
|
||||
swapped = i
|
||||
end
|
||||
end
|
||||
break unless swapped
|
||||
start, finish, way = swapped, start, -way
|
||||
end
|
||||
array
|
||||
end
|
||||
|
||||
if $0 == __FILE__
|
||||
puts 'Enter a list of numbers separated by space'
|
||||
|
||||
list = gets.split.map(&:to_i)
|
||||
p cocktail_sort(list)
|
||||
end
|
12
sorting/cocktail_sort_test.rb
Normal file
12
sorting/cocktail_sort_test.rb
Normal file
|
@ -0,0 +1,12 @@
|
|||
require 'minitest/autorun'
|
||||
require_relative './sort_tests'
|
||||
require_relative './cocktail_sort'
|
||||
|
||||
class TestInsertionSort < Minitest::Test
|
||||
include SortTests
|
||||
|
||||
def sort(input)
|
||||
cocktail_sort(input)
|
||||
end
|
||||
end
|
||||
|
22
sorting/comb_sort.rb
Normal file
22
sorting/comb_sort.rb
Normal file
|
@ -0,0 +1,22 @@
|
|||
def comb_sort(array)
|
||||
gap = array.length
|
||||
swaps = true
|
||||
while gap > 1 or swaps
|
||||
gap = [1, (gap / 1.25).to_i].max
|
||||
swaps = false
|
||||
0.upto(array.length - gap - 1) do |i|
|
||||
if array[i] > array[i + gap]
|
||||
array[i], array[i + gap] = array[i + gap], array[i]
|
||||
swaps = true
|
||||
end
|
||||
end
|
||||
end
|
||||
array
|
||||
end
|
||||
|
||||
if $0 == __FILE__
|
||||
puts 'Enter a list of numbers separated by space'
|
||||
|
||||
list = gets.split.map(&:to_i)
|
||||
p insertion_sort(list)
|
||||
end
|
11
sorting/comb_sort_test.rb
Normal file
11
sorting/comb_sort_test.rb
Normal file
|
@ -0,0 +1,11 @@
|
|||
require 'minitest/autorun'
|
||||
require_relative './sort_tests'
|
||||
require_relative './comb_sort'
|
||||
|
||||
class TestInsertionSort < Minitest::Test
|
||||
include SortTests
|
||||
|
||||
def sort(input)
|
||||
comb_sort(input)
|
||||
end
|
||||
end
|
18
sorting/pancake_sort.rb
Normal file
18
sorting/pancake_sort.rb
Normal file
|
@ -0,0 +1,18 @@
|
|||
def pancake_sort(array)
|
||||
return array if array.length <= 1
|
||||
(array.length - 1).downto(1) do |index|
|
||||
max_index = array[0..index].index(array[0..index].max)
|
||||
next if max_index == index
|
||||
|
||||
array[0..max_index] = array[0..max_index].reverse if max_index > 0
|
||||
array[0..index] = array[0..index].reverse
|
||||
end
|
||||
array
|
||||
end
|
||||
|
||||
if $0 == __FILE__
|
||||
puts 'Enter a list of numbers separated by space'
|
||||
|
||||
list = gets.split.map(&:to_i)
|
||||
p pancake_sort(list)
|
||||
end
|
11
sorting/pancake_sort_test.rb
Normal file
11
sorting/pancake_sort_test.rb
Normal file
|
@ -0,0 +1,11 @@
|
|||
require 'minitest/autorun'
|
||||
require_relative './sort_tests'
|
||||
require_relative './pancake_sort'
|
||||
|
||||
class TestInsertionSort < Minitest::Test
|
||||
include SortTests
|
||||
|
||||
def sort(input)
|
||||
pancake_sort(input)
|
||||
end
|
||||
end
|
Loading…
Reference in a new issue