Skip to content

Instantly share code, notes, and snippets.

@caio-nas
Last active July 19, 2017 15:05
Show Gist options
  • Save caio-nas/b06486ab2094834818409a833a2d92fc to your computer and use it in GitHub Desktop.
Save caio-nas/b06486ab2094834818409a833a2d92fc to your computer and use it in GitHub Desktop.
Ruby code challenges
=begin
A binary gap within a positive integer N is any maximal sequence of consecutive zeros
that is surrounded by ones at both ends in the binary representation of N.
Write a function:
def solution(n)
that, given a positive integer N, returns the length of its longest binary gap.
The function should return 0 if N doesn't contain a binary gap.
For example, given N = 1041 the function should return 5, because N has binary representation 10000010001
and so its longest binary gap is of length 5.
The number 20 has binary representation 10100 and contains one binary gap of length 1.
=end
def solution(n)
n.to_s(2).scan(/(?<=1)0+(?=1)/).max.length rescue 0
end
=begin
Write a function:
def solution(a, b, k)
that, given three integers A, B and K, returns the number of integers within the range [A..B] that are divisible by K, i.e.:
{ i : A ≤ i ≤ B, i mod K = 0 }
For example, for A = 6, B = 11 and K = 2, your function should return 3,
because there are three numbers divisible by 2 within the range [6..11], namely 6, 8 and 10.
Assume that:
A and B are integers within the range [0..2,000,000,000];
K is an integer within the range [1..2,000,000,000];
A ≤ B.
Complexity:
expected worst-case time complexity is O(1);
expected worst-case space complexity is O(1).
=end
def solution(a, b, k)
(b / k) - ((a - 1) / k)
end
=begin
A zero-indexed array A consisting of N integers is given.
Rotation of the array means that each element is shifted right by one index,
and the last element of the array is also moved to the first place.
For example, the rotation of array A = [3, 8, 9, 7, 6] is [6, 3, 8, 9, 7].
The goal is to rotate array A K times; that is, each element of A will be shifted to the right by K indexes.
Write a function:
def solution(a, k)
that, given a zero-indexed array A consisting of N integers and an integer K, returns the array A rotated K times.
For example, given array A = [3, 8, 9, 7, 6] and K = 3, the function should return [9, 7, 6, 3, 8].
Assume that:
N and K are integers within the range [0..100];
each element of array A is an integer within the range [−1,000..1,000].
In your solution, focus on correctness. The performance of your solution will not be the focus of the assessment.
=end
def solution(a, k)
#Iterative
[0, 1, k].include?(a.size) ? a : k.times.reduce(a) { |arr| arr[-1, 1] + arr[0..-2] }
#Constant time
rotate_by_slice = ->(shift, target) { target[-shift..-1] + target[0..-shift -1] }
(k == 0 || [0, 1, k].include?(a.size)) ? a : rotate_by_slice[k % a.size, a]
end
=begin
A small frog wants to get to the other side of the road. The frog is currently located
at position X and wants to get to a position greater than or equal to Y.
The small frog always jumps a fixed distance, D.
Count the minimal number of jumps that the small frog must perform to reach its target.
Write a function:
def solution(x, y, d)
that, given three integers X, Y and D, returns the minimal number of jumps from position X
to a position equal to or greater than Y.
For example, given:
X = 10
Y = 85
D = 30
the function should return 3, because the frog will be positioned as follows:
after the first jump, at position 10 + 30 = 40
after the second jump, at position 10 + 30 + 30 = 70
after the third jump, at position 10 + 30 + 30 + 30 = 100
Assume that:
X, Y and D are integers within the range [1..1,000,000,000];
X ≤ Y.
Complexity:
expected worst-case time complexity is O(1);
expected worst-case space complexity is O(1).
=end
def solution(x, y, d)
((y-x)/d.to_f).ceil
end
=begin
A small frog wants to get to the other side of a river.
The frog is initially located on one bank of the river (position 0) and wants to get to the opposite bank (position X+1).
Leaves fall from a tree onto the surface of the river.
You are given a zero-indexed array A consisting of N integers representing the falling leaves.
A[K] represents the position where one leaf falls at time K, measured in seconds.
The goal is to find the earliest time when the frog can jump to the other side of the river.
The frog can cross only when leaves appear at every position across the river from 1 to X
(that is, we want to find the earliest moment when all the positions from 1 to X are covered by leaves).
You may assume that the speed of the current in the river is negligibly small,
i.e. the leaves do not change their positions once they fall in the river.
For example, you are given integer X = 5 and array A such that:
A[0] = 1
A[1] = 3
A[2] = 1
A[3] = 4
A[4] = 2
A[5] = 3
A[6] = 5
A[7] = 4
In second 6, a leaf falls into position 5. This is the earliest time when leaves appear in every position across the river.
Write a function:
def solution(x, a)
that, given a non-empty zero-indexed array A consisting of N integers and integer X,
returns the earliest time when the frog can jump to the other side of the river.
If the frog is never able to jump to the other side of the river, the function should return −1.
For example, given X = 5 and array A such that:
A[0] = 1
A[1] = 3
A[2] = 1
A[3] = 4
A[4] = 2
A[5] = 3
A[6] = 5
A[7] = 4
the function should return 6, as explained above.
Assume that:
N and X are integers within the range [1..100,000];
each element of array A is an integer within the range [1..X].
Complexity:
expected worst-case time complexity is O(N);
expected worst-case space complexity is O(X), beyond input storage (not counting the storage required for input arguments).
Elements of input arrays can be modified.
=end
def solution(x, a)
track = Array.new(x, nil)
covered = 0
position = nil
a.each_with_index do |leaf, idx|
position = leaf - 1
if track[position].nil?
covered += 1
track[position] = idx
return idx if covered >= track.size
end
end
return -1
end
=begin
You are given N counters, initially set to 0, and you have two possible operations on them:
increase(X) − counter X is increased by 1,
max counter − all counters are set to the maximum value of any counter.
A non-empty zero-indexed array A of M integers is given. This array represents consecutive operations:
if A[K] = X, such that 1 ≤ X ≤ N, then operation K is increase(X),
if A[K] = N + 1 then operation K is max counter.
For example, given integer N = 5 and array A such that:
A[0] = 3
A[1] = 4
A[2] = 4
A[3] = 6
A[4] = 1
A[5] = 4
A[6] = 4
the values of the counters after each consecutive operation will be:
(0, 0, 1, 0, 0)
(0, 0, 1, 1, 0)
(0, 0, 1, 2, 0)
(2, 2, 2, 2, 2)
(3, 2, 2, 2, 2)
(3, 2, 2, 3, 2)
(3, 2, 2, 4, 2)
The goal is to calculate the value of every counter after all operations.
Write a function:
def solution(n, a)
that, given an integer N and a non-empty zero-indexed array A consisting of M integers,
returns a sequence of integers representing the values of the counters.
The sequence should be returned as:
a structure Results (in C), or
a vector of integers (in C++), or
a record Results (in Pascal), or
an array of integers (in any other programming language).
For example, given:
A[0] = 3
A[1] = 4
A[2] = 4
A[3] = 6
A[4] = 1
A[5] = 4
A[6] = 4
the function should return [3, 2, 2, 4, 2], as explained above.
Assume that:
N and M are integers within the range [1..100,000];
each element of array A is an integer within the range [1..N + 1].
Complexity:
expected worst-case time complexity is O(N+M);
expected worst-case space complexity is O(N), beyond input storage (not counting the storage required for input arguments).
Elements of input arrays can be modified.
=end
##
# Original solution, poor performance
def solution(n, a)
max = 0
counters = [0] * n
a.each do |op|
if op == n + 1
counters.fill(max)
else
val = (counters[op - 1] += 1)
max = val if max < val
end
end
return counters
end
##
# Performance adjustments to avoid array copies
def solution(n, a)
max = 0
counters = Hash.new(0)
a.each do |op|
if op == n + 1
counters.clear
counters.default = max
else
val = (counters[op - 1] += 1)
max = val if max < val
end
end
(0..n - 1).map { |idx| counters[idx] }
end
=begin
A non-empty zero-indexed array A consisting of N integers is given.
The product of triplet (P, Q, R) equates to A[P] * A[Q] * A[R] (0 ≤ P < Q < R < N).
For example, array A such that:
A[0] = -3
A[1] = 1
A[2] = 2
A[3] = -2
A[4] = 5
A[5] = 6
contains the following example triplets:
(0, 1, 2), product is −3 * 1 * 2 = −6
(1, 2, 4), product is 1 * 2 * 5 = 10
(2, 4, 5), product is 2 * 5 * 6 = 60
Your goal is to find the maximal product of any triplet.
Write a function:
def solution(a)
that, given a non-empty zero-indexed array A, returns the value of the maximal product of any triplet.
For example, given array A such that:
A[0] = -3
A[1] = 1
A[2] = 2
A[3] = -2
A[4] = 5
A[5] = 6
the function should return 60, as the product of triplet (2, 4, 5) is maximal.
Assume that:
N is an integer within the range [3..100,000];
each element of array A is an integer within the range [−1,000..1,000].
Complexity:
expected worst-case time complexity is O(N*log(N));
expected worst-case space complexity is O(1), beyond input storage (not counting the storage required for input arguments).
Elements of input arrays can be modified.
=end
def solution(a)
a.sort!
upper = a[-1] * a[-2] * a[-3]
lower = a[-1] * a[0] * a[1]
upper > lower ? upper : lower
end
=begin
A zero-indexed array A consisting of N different integers is given.
The array contains integers in the range [1..(N + 1)], which means that exactly one element is missing.
Your goal is to find that missing element.
Write a function:
def solution(a)
that, given a zero-indexed array A, returns the value of the missing element.
For example, given array A such that:
A[0] = 2
A[1] = 3
A[2] = 1
A[3] = 5
the function should return 4, as it is the missing element.
Assume that:
N is an integer within the range [0..100,000];
the elements of A are all distinct;
each element of array A is an integer within the range [1..(N + 1)].
Complexity:
expected worst-case time complexity is O(N);
expected worst-case space complexity is O(1), beyond input storage (not counting the storage required for input arguments).
Elements of input arrays can be modified.
=end
def solution(a)
#(1..a.size + 1).reduce(:+) - a.reduce(:+)
size = a.size
r = a.each_with_index.reduce([1, 0]) do |sum, (val, idx)|
sum[0] += (size + 1) - idx
sum[1] += val
sum
end
r[0] - r[1]
end
=begin
Write a function:
def solution(a)
that, given a non-empty zero-indexed array A of N integers,
returns the minimal positive integer (greater than 0) that does not occur in A.
For example, given:
A[0] = 1
A[1] = 3
A[2] = 6
A[3] = 4
A[4] = 1
A[5] = 2
the function should return 5.
Assume that:
N is an integer within the range [1..100,000];
each element of array A is an integer within the range [−2,147,483,648..2,147,483,647].
Complexity:
expected worst-case time complexity is O(N);
expected worst-case space complexity is O(N), beyond input storage (not counting the storage required for input arguments).
Elements of input arrays can be modified.
Solution description: https://stackoverflow.com/questions/25002381/missing-integer-variation-on-solution-needed
=end
require 'set'
def solution(a)
sorted = SortedSet.new(a)
sorted.select! { |x| x > 0 }
sorted = sorted.to_a
return 1 if (sorted.empty? || sorted.first != 1)
sorted[0..-2].each_with_index do |elm, idx|
return (elm + 1) if (sorted[idx + 1] - elm) > 1
end
return sorted.last + 1
end
def solution(a)
sorted = SortedSet.new(a).to_a
size = sorted.size
found_positive = false
sorted.each_with_index do |elm, idx|
if !found_positive && elm > 0
return 1 if elm != 1
found_positive = true
end
if found_positive && idx < size - 1
return elm + 1 if sorted[idx + 1] - elm > 1
end
end
return found_positive ? sorted.last + 1 : 1
end
=begin
A non-empty zero-indexed array A consisting of N integers is given.
The array contains an odd number of elements, and each element of the array can be paired with another element
that has the same value, except for one element that is left unpaired.
For example, in array A such that:
A[0] = 9 A[1] = 3 A[2] = 9
A[3] = 3 A[4] = 9 A[5] = 7
A[6] = 9
the elements at indexes 0 and 2 have value 9,
the elements at indexes 1 and 3 have value 3,
the elements at indexes 4 and 6 have value 9,
the element at index 5 has value 7 and is unpaired.
Write a function:
def solution(a)
that, given an array A consisting of N integers fulfilling the above conditions,
returns the value of the unpaired element.
For example, given array A such that:
A[0] = 9 A[1] = 3 A[2] = 9
A[3] = 3 A[4] = 9 A[5] = 7
A[6] = 9
the function should return 7, as explained in the example above.
Assume that:
N is an odd integer within the range [1..1,000,000];
each element of array A is an integer within the range [1..1,000,000,000];
all but one of the values in A occur an even number of times.
Complexity:
expected worst-case time complexity is O(N);
expected worst-case space complexity is O(1), beyond input storage
(not counting the storage required for input arguments).
Elements of input arrays can be modified.
=end
def solution(a)
a.reduce(Hash.new) { |h, item| h.delete(item) || h[item] = 1; h }.keys[0]
end
=begin
A non-empty zero-indexed array A consisting of N integers is given.
The consecutive elements of array A represent consecutive cars on a road.
Array A contains only 0s and/or 1s:
0 represents a car traveling east,
1 represents a car traveling west.
The goal is to count passing cars. We say that a pair of cars (P, Q), where 0 ≤ P < Q < N,
is passing when P is traveling to the east and Q is traveling to the west.
For example, consider array A such that:
A[0] = 0
A[1] = 1
A[2] = 0
A[3] = 1
A[4] = 1
We have five pairs of passing cars: (0, 1), (0, 3), (0, 4), (2, 3), (2, 4).
Write a function:
def solution(a)
that, given a non-empty zero-indexed array A of N integers, returns the number of pairs of passing cars.
The function should return −1 if the number of pairs of passing cars exceeds 1,000,000,000.
For example, given:
A[0] = 0
A[1] = 1
A[2] = 0
A[3] = 1
A[4] = 1
the function should return 5, as explained above.
Assume that:
N is an integer within the range [1..100,000];
each element of array A is an integer that can have one of the following values: 0, 1.
Complexity:
expected worst-case time complexity is O(N);
expected worst-case space complexity is O(1), beyond input storage (not counting the storage required for input arguments).
Elements of input arrays can be modified.
=end
def solution(a)
n = a.size
sum = [0] * (n + 1)
cars_east = 0
(1..n).each do |k|
car = a[k - 1]
sum[k] = sum[k - 1] + (car * cars_east)
return -1 if sum[k] > 10 ** 9
cars_east += car == 0 ? 1 : 0
end
return sum.last
end
=begin
A non-empty zero-indexed array A consisting of N integers is given.
A permutation is a sequence containing each element from 1 to N once, and only once.
For example, array A such that:
A[0] = 4
A[1] = 1
A[2] = 3
A[3] = 2
is a permutation, but array A such that:
A[0] = 4
A[1] = 1
A[2] = 3
is not a permutation, because value 2 is missing.
The goal is to check whether array A is a permutation.
Write a function:
def solution(a)
that, given a zero-indexed array A, returns 1 if array A is a permutation and 0 if it is not.
For example, given array A such that:
A[0] = 4
A[1] = 1
A[2] = 3
A[3] = 2
the function should return 1.
Given array A such that:
A[0] = 4
A[1] = 1
A[2] = 3
the function should return 0.
Assume that:
N is an integer within the range [1..100,000];
each element of array A is an integer within the range [1..1,000,000,000].
Complexity:
expected worst-case time complexity is O(N);
expected worst-case space complexity is O(N), beyond input storage (not counting the storage required for input arguments).
Elements of input arrays can be modified.
=end
def solution(a)
track = {}
expected = 0
actual = 0
a.each_with_index do |x, idx|
return 0 if track.has_key? x
track[x] = true
expected += idx + 1
actual += x
end
track.size == a.size && actual == expected ? 1 : 0
end
### Recursive
def reverse(input, idx=0)
idx >= input.length ? [] : reverse(input, idx + 1) << input[idx]
end
r1 = reverse "Hello \nWorld"
### Iterative options
# ruby > 1.8.7
r3 = "Hello \nWorld".chars.reduce([]) { |result, char| result.unshift char }
# ruby > 1.9
r2 = "Hello \nWorld".each_char.reduce([]) { |output, c| output.unshift c }
# You also can use as:
# result = []
# "Hello \nWorld".each_char { |c| result.unshift c }
# 'm' modifier for multiline mode
r4 = "Hello \nWorld".scan(/./m).reduce([]) { |result, char| result.unshift char }
r5 = "Hello \nWorld".split(//).reduce([]) { |result, char| result.unshift char }
# FYI a quick little test I did showed that the scan method above is 1.6 times faster than the split.
# "Classic" for loop
s = "Hello \nWorld"
result = []
for idx in 0..s.length - 1
result.unshift s[idx]
end
r6 = result
#Check all results are the same
[r1, r2, r3, r4, r5, r6].uniq.length == 1
=begin
Task description
A non-empty zero-indexed array A consisting of N integers is given. Array A represents numbers on a tape.
Any integer P, such that 0 < P < N, splits this tape into two non-empty parts:
A[0], A[1], ..., A[P − 1] and A[P], A[P + 1], ..., A[N − 1].
The difference between the two parts is the value of:
|(A[0] + A[1] + ... + A[P − 1]) − (A[P] + A[P + 1] + ... + A[N − 1])|
In other words, it is the absolute difference between the sum of the first part and the sum of the second part.
For example, consider array A such that:
A[0] = 3
A[1] = 1
A[2] = 2
A[3] = 4
A[4] = 3
We can split this tape in four places:
P = 1, difference = |3 − 10| = 7
P = 2, difference = |4 − 9| = 5
P = 3, difference = |6 − 7| = 1
P = 4, difference = |10 − 3| = 7
Write a function:
def solution(a)
that, given a non-empty zero-indexed array A of N integers, returns the minimal difference that can be achieved.
For example, given:
A[0] = 3
A[1] = 1
A[2] = 2
A[3] = 4
A[4] = 3
the function should return 1, as explained above.
Assume that:
N is an integer within the range [2..100,000];
each element of array A is an integer within the range [−1,000..1,000].
Complexity:
expected worst-case time complexity is O(N);
expected worst-case space complexity is O(N), beyond input storage (not counting the storage required for input arguments).
Elements of input arrays can be modified.
=end
def solution(a)
a_side = a[0]
b_side = a[1..-1].reduce(:+)
first_split = (a_side - b_side).abs
return first_split if a.size == 2
a[1..-2].reduce(first_split) do |minimal, elm|
current_split = ((a_side += elm) - (b_side -= elm)).abs
minimal > current_split ? current_split : minimal
end
end
def count_carries(x, y)
stx = x.to_s.split("").reverse
sty = y.to_s.split("").reverse
big = small = nil
if stx.count > sty.count
big = stx
small = sty
else
big = sty
small = stx
end
carries = 0
remainder = 0
big.each_with_index do |c, idx|
remainder += small[idx].to_i if idx < small.count
if big[idx].to_i + remainder >= 10
carries += 1
remainder = 1
else
remainder = 0
end
end
return carries
end
count_carries(1, 99999)
count_carries(145,55)
count_carries(0,0)
count_carries(5, 5)
count_carries(55, 65)
count_carries(55,26)
ex1 = ["9C", "KS", "AC", "AH", "8D", "4C", "KD", "JC", "7D", "9D", "2H", "7C", "3C", "7S", "5C", "6H", "TH"]
ex2 = ["2S", "2C", "2D", "2H", "3S", "3C", "3D", "3H", "4S", "4C", "4D", "4H", "5S", "5C", "5D", "5H", "6S", "6C", "6D", "6H", "7S", "7C", "7D", "7H", "8S", "8C", "8D", "8H", "9S", "9C", "9D", "9H", "TS", "TC", "TD", "TH", "JS", "JC", "JD", "JH", "QS", "QC", "QD", "QH", "KS", "KC", "KD", "KH", "AS", "AC", "AD", "AH", "2S", "2C", "2D", "2H", "3S", "3C", "3D", "3H", "4S", "4C", "4D", "4H", "5S", "5C", "5D", "5H", "6S", "6C", "6D", "6H", "7S", "7C", "7D", "7H", "8S", "8C", "8D", "8H", "9S", "9C", "9D", "9H", "TS", "TC", "TD", "TH", "JS", "JC", "JD", "JH", "QS", "QC", "QD", "QH", "KS", "KC", "KD", "KH", "AS", "AC", "AD", "AH", "2S", "2C", "2D", "2H", "3S", "3C", "3D", "3H", "4S", "4C", "4D", "4H", "5S", "5C", "5D", "5H", "6S", "6C", "6D", "6H", "7S", "7C", "7D", "7H", "8S", "8C", "8D", "8H", "9S", "9C", "9D", "9H", "TS", "TC", "TD", "TH", "JS", "JC", "JD", "JH", "QS", "QC", "QD", "QH", "KS", "KC", "KD", "KH", "AS", "AC", "AD"]
def find_decks(input)
p input
ranks = ['2','3','4','5','6','7','8','9','T','J','Q','K','A']
suits = ['S','C', 'H', 'D']
deck = ranks.product(suits).map(&:join)
counter = {}
deck.each { |c| counter[c] = 0 }
input.each do |card|
counter[card] += 1
end
return counter.values.min
end
find_decks(ex1)
=begin
A zero-indexed array A consisting of N integers is given. A triplet (P, Q, R) is triangular if 0 ≤ P < Q < R < N and:
A[P] + A[Q] > A[R],
A[Q] + A[R] > A[P],
A[R] + A[P] > A[Q].
For example, consider array A such that:
A[0] = 10 A[1] = 2 A[2] = 5
A[3] = 1 A[4] = 8 A[5] = 20
Triplet (0, 2, 4) is triangular.
Write a function:
def solution(a)
that, given a zero-indexed array A consisting of N integers,
returns 1 if there exists a triangular triplet for this array and returns 0 otherwise.
For example, given array A such that:
A[0] = 10 A[1] = 2 A[2] = 5
A[3] = 1 A[4] = 8 A[5] = 20
the function should return 1, as explained above. Given array A such that:
A[0] = 10 A[1] = 50 A[2] = 5
A[3] = 1
the function should return 0.
Assume that:
N is an integer within the range [0..100,000];
each element of array A is an integer within the range [−2,147,483,648..2,147,483,647].
Complexity:
expected worst-case time complexity is O(N*log(N));
expected worst-case space complexity is O(N), beyond input storage (not counting the storage required for input arguments).
Elements of input arrays can be modified.
=end
def solution(a)
a.sort!
_p = _q = _r = 0
(a.size - 1).downto(2) do |i|
_r = a[i]
_q = a[i - 1]
_p = a[i - 2]
return 1 if _p + _q > _r && _r + _p > _q
end
return 0
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment