Easiest way to find divisors of 60 in Ruby on Rails - ruby-on-rails

Other than hardcoding or using the Math module, Is there any way I can find divisors of 60 in Ruby on Rails. Any helper methods/regular expression that I can make use of? Thanks for your help.

One of the easiest ways to achieve this would be to create a list of numbers between 1 and 60, and then only select the ones that divide 60 with no remainder.
To expand on SteveTurczyn's answer, we can do:
(1..60).select { |n| 60 % n == 0 }
The (1..60) part creates an enumerator (which in this case we can think of as an array of the numbers between 1 and 60).
Then you want to take this array, and select only the elements are divisors of 60.
We can use the modulus operator %, which gives us the remainder left over when we divide a number by another (e.g., 5 % 2 returns 1). Of course, if there is no remainder, then we know that the number divided cleanly, and is therefore a divisor of that number (i.e., if a % b == 0, then b is a divisor of a).
So what we want to do, is use the above as a criteria for selecting elements out of the array of numbers between 1 and 60, which we are able to do with the Array#select method.
If we have something, like an array (technically, I think, an Enumerable), we can use #select and a block to pull out only the elements that satisfy whatever criteria we specify in the block.
The { |n| 60 % n == 0 } is the block we are passing to #select, which will return true whenever 60 % n is 0 (each n is an element from the array of numbers 1 through 60). Array#select only returns the elements in the array for which the block evaluates to true- which is how SteveTurczyn's solution works.

This will give you the array of divisors
(1..60).select { |n| 60 % n == 0}
=> [1, 2, 3, 4, 5, 6, 10, 12, 15, 20, 30, 60]

For small numbers it's okay to use the brute force search, but for large numbers this approach doesn't suite. You can speed up your method significantly by selecting divisors as pairs.
Some examples with benchmarks:
require 'benchmark'
n = 10_000_000
def brute_force(n)
(1..n).select { |i| n % i == 0 }
end
def faster_way(n)
(1..Math.sqrt(n)).each_with_object([]) { |i, arr| (n % i).zero? && arr << i && n/i != i && arr << n/i }
end
Benchmark.bm do |x|
x.report { brute_force(n) }
x.report { faster_way(n) }
end
# Benchmark output
user system total real
0.799491 0.001417 0.800908 ( 0.802341)
0.000580 0.000002 0.000582 ( 0.000581)
As you can see the second approach is 1376 times faster for n = 10_000_000.

Related

What's the proper way to find the last parcel of an array?

I'm doing some codewars and arr[index] keeps returning nil. I've done this a few different ways, and I'm sure the array exists, as well as the index. What's wrong here, is it syntax?
As I've mentioned in the title, I want to find the last digit of the array.
if arr[index] <= 0 then
return -1
end
Full Code:
local solution = {}
function solution.newAvg(arr, navg)
local currentAverage = 0
local index = 0
for i, v in pairs(arr) do
index = i
currentAverage = currentAverage + v
end
if arr[index] <= 0 then
return -1
end
return math.ceil(((index+1) * navg) - currentAverage)
end
return solution
I see two issues with your code:
Edge case: Empty array
If arr = {}, the loop for i, v in pairs(arr) do won't execute at all and index will remain at 0. Since arr is empty, arr[0] will be nil and arr[index] <= 0 will fail with an "attempt to compare a nil value" error.
Lack of ordering guarantee
You use pairs rather than ipairs to loop over what I assume is a list. This means keys & values might be traversed in any order. In practice pairs usually (but not always!) traverses the list part of a table in the same order as ipairs, but the reference manual clearly states that you can't rely on no specific order. I don't think CodeWars is this advanced but consider the possibility that pairs may be overridden to deliberately shuffle the order of traversal in order to check whether you're relying on the dreaded "undefined behavior". If this is the case, your "last index" might actually be any index that happens to be visited last, obviously breaking your algorithm.
Fixes
I'll assume arr is an "array", that is, it only contains keys from 1 to n and all values are non-nil (i.e. there are no holes). Then you can (and should!) use ipairs to loop over the "array":
for i, v in ipairs(arr) do ... end
I don't know the problem statement so it's hard to tell how an empty array should be handled. I'll assume that it should probably return 0. You could add a simply early return at the top of the function for that: if arr[1] == nil then return 0 end. Nonempty arrays will always have arr[1] ~= nil.
I want to find the last digit of the array.
If you mean the last integer (or entry/item) of the array:
local last = array[#array]
If you mean the last digit (for example array = {10, 75, 44, 62} and you want 2), then you can get the last item and then get the last digit using modulo 10:
local last = array[#array] % 10
for i, v in pairs(arr) do
index = i
currentAverage = currentAverage + v
end
Just a reminder:
#array returns the number of items in a table.
In Lua, arrays are implemented using integer-indexed tables.
There's a difference between pairs() and ipairs().
Regarding point 3 above, the following code:
local array = {
[1] = 12,
[2] = 32,
[3] = 41,
[4] = 30,
[5] = 14,
[6] = 50,
[7] = 62,
[8] = 57
}
for key, value in pairs(array) do
print(key, value)
end
produces the following output (note that the order of keys is not respected):
8 57
1 12
2 32
3 41
4 30
5 14
6 50
7 62
while the same code above with pairs() replaced with ipairs() gives:
1 12
2 32
3 41
4 30
5 14
6 50
7 62
8 57
So, this might be the cause of your problem.

How to optimize the program with two for loops

I have a following programm
def calc_res(a)
n = a.length
result = 0
for i in 0 .. (n - 1)
for j in i .. (n - 1)
if (a[i] != a[j] && j - i > result) then
result = j - i
end
end
end
return result
end
which return following output
irb(main):013:0> calc_res([4, 6, 2, 2, 6, 6, 4])
=> 5
but it is taking time if array size is too large e.g. [0,1,2,3,.....70000]
can any one suggest me how can I optimize it.
Thanks
If I have understood the problem you are trying to solve (from code)
def calc_res(a)
last_index = a.length - 1
index = 0
while a[index] == a.last do
index = index + 1
break if index == last_index
end
last_index - index
end
It checks items from start if they are equal to items from end, end it moves the index toward the last element. As I understood you search for max length between different elements.
For you problem with [4, 6, 2, 2, 6, 6, 4] it will have one iteration and return 5, for the problem with [1...70000] it will have zero iterations and will return the difference in positions for those two (size of the array - 1)
My understanding is that the problem is to find two unique elements in the array whose distance apart (difference in indices) is maximum, and to return the distance they are apart. I return nil if all elements are the same.
My solution attempts to minimize the numbers of pairs of elements that must be examined before an optimal solution is identified. For the example given in the question only two pairs of elements need be considered.
def calc_res(a)
sz = a.size-1
sz.downto(2).find { |n| (0..sz-n).any? { |i| a[i] != a[i+n] } }
end
a = [4,6,2,2,6,6,4]
calc_res a
#=> 5
If sz = a.size-1, sz is the greatest possible distance two elements can be apart. If, for example, a = [1,2,3,4], sz = 3, which is the number of positions 1 and 4 are apart.
For a, sz = a.size-1 #=> 6. I first determine if any pair of elements that are n = sz positions apart are unique. [a[0], a[6]] #=> [4,4] is the only pair of elements 6 positions apart. Since they are not unique I reduce n by one (to 5) and examine all pairs of elements n positions apart, looking for one whose elements are unique. There are two pairs 5 positions apart: [a[0], a[5]] #=> [4,6] and [a[1], a[6]] #=> [6,4]. Both of these meet the test, so we are finished, and return n #=> 5. In fact we are finished after testing the first of these two pairs. Had neither these pairs contained unique values n would have been reduced by 1 to 4 and the three pairs [a[0], a[4]] #=> [4,6], [a[1], a[5]] #=> [6,6] and [a[2], a[6]] #=> [2,6] would have been searched for one with unique values, and so on.
See Integer#downto, Enumerable#find and Enumerable#any?.
A more rubyesque versions include:
def calc_res(a)
last = a.last
idx = a.find_index {|e| e != last }&.+(1) || a.size
a.size - idx
end
def calc_res(a)
last = a.last
a.size - a.each.with_index(1).detect(->{[a.size]}) {|e,_| e != last }.last
end
def calc_res(a)
last = a.last
a.reduce(a.size) do |memo, e|
return memo unless e == last
memo -= 1
end
end
def calc_res(a)
return 0 if b = a.uniq and b.size == 1
a.size - a.index(b[-1]).+(1)
end

Random sum of elements in an array equals to y - ruby [duplicate]

This question already has answers here:
Finding all possible combinations of numbers to reach a given sum
(32 answers)
Closed 6 years ago.
Need to create an array whose sum should be equal to expected value.
inp = [1,2,3,4,5,6,7,8,9,10]
sum = 200
output:
out = [10,10,9,1,3,3,3,7,.....] whose sum should be 200
or
out = [10,7,3,....] Repeated values can be used
or
out = [2,3,4,9,2,....]
I tried as,
arr = [5,10,15,20,30]
ee = []
max = 200
while (ee.sum < max) do
ee << arr.sample(1).first
end
ee.pop(2)
val = max - ee.sum
pair = arr.uniq.combination(2).detect { |a, b| a + b == val }
ee << pair
ee.flatten
Is there any effective way to do it.
inp = [1,2,3,4,5,6,7,8,9,10]
sum = 20
inp.length.downto(1).flat_map do |i|
inp.combination(i).to_a # take all subarrays of length `i`
end.select do |a|
a.inject(:+) == sum # select only those summing to `sum`
end
One might take a random element of resulting array.
result = inp.length.downto(1).flat_map do |i|
inp.combination(i).to_a # take all subarrays of length `i`
end.select do |a|
a.inject(:+) == sum # select only those summing to `sum`
end
puts result.length
#⇒ 31
puts result.sample
#⇒ [2, 4, 5, 9]
puts result.sample
#⇒ [1, 2, 3, 6, 8]
...
Please note, that this approach is not efficient for long-length inputs. As well, if any original array’s member might be taken many times, combination above should be changed to permutation, but this solution is too ineffective to be used with permutation.
I found an answer of this question in the following link:
Finding all possible combinations of numbers to reach a given sum
def subset_sum(numbers, target, partial=[])
s = partial.inject 0, :+
#check if the partial sum is equals to target
puts "sum(#{partial})=#{target}" if s == target
return if s >= target #if we reach the number why bother to continue
(0..(numbers.length - 1)).each do |i|
n = numbers[i]
remaining = numbers.drop(i+1)
subset_sum(remaining, target, partial + [n])
end
end
subset_sum([1,2,3,4,5,6,7,8,9,10],20)

This seems to just be filling up an array with the greatest number, why?

def third_greatest(nums)
idx = 0
arr = []
i = 1
largest = 0
while idx < nums.length
while i < nums.length
if nums[idx] > nums [i]
largest = nums[idx]
else
largest = nums[idx]
end
i += 1
end
arr.push(largest)
idx += 1
i += idx
end
return arr[2]
end
puts(third_greatest([4, 3, 2, 1]) == 2)
#should equal true
I'm trying to get the third largest number out of the array but I keep getting four for any value of the array that returns data.
Any help would be great!
Here is an easier solution for finding the third greatest number in an array:
def third_greatest(nums)
nums.sort!
nums[-3]
end
third_greatest([4, 3, 2, 1])
=> 2
puts(third_greatest([4, 3, 2, 1]) == 2)
=> true
at the end of the first time to the loop, i will be nums.length.
afterwards you increase i with idx so it is now bigger than nums.length.
In the next loops you will never enter the inner loop again, so the largest is never updated anymore.
That's why you always get largest in the result.
to fix it do something like :
end
arr.push(largest)
idx += 1
i = idx + 1
end
so that i is reset to one higher than idx.
But the real solution is to leverage the rich standard library as Alex suggests.
Recent versions of Enumerable#max have allowed a parameter:
(0..9).to_a.max(3).last #=> 7
max(n) returns the three largest values, in decreasing magnitude. This could be expected to be more efficient than sort (unless n == arr.size, of course). Related Enumerable methods (max_by, min, min_by) also have this functionality.

Codility: Passing cars in Lua

I'm currently practicing programming problems and out of interest, I'm trying a few Codility exercises in Lua. I've been stuck on the Passing Cars problem for a while.
Problem:
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:
function 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.
My attempt in Lua keeps failing but I can't seem to find the issue.
local function solution(A)
local zeroes = 0
local pairs = 0
for i = 1, #A do
if A[i] == 0 then
zeroes = zeroes + 1
else
pairs = pairs + zeroes
if pairs > 1e9 then
return -1
end
end
end
return pairs
end
In terms of time-space complexity constraints, I think it should pass so I can't seem to find the issue. What am I doing wrong? Any advice or tips to make my code more efficient would be appreciated.
FYI: I keep getting a result of 2 when the desired example result is 5.
The problem statement says A is 0-based so if we ignore the first and start at 1, the output would be 2 instead of 5. 0-based tables should be avoided in Lua, they go against convention and will lead to a lot of off-by one errors: for i=1,#A do will not do what you want.
function solution1based(A)
local zeroes = 0
local pairs = 0
for i = 1, #A do
if A[i] == 0 then
zeroes = zeroes + 1
else
pairs = pairs + zeroes
if pairs > 1e9 then
return -1
end
end
end
return pairs
end
print(solution1based{0, 1, 0, 1, 1}) -- prints 5 as you wanted
function solution0based(A)
local zeroes = 0
local pairs = 0
for i = 0, #A do
if A[i] == 0 then
zeroes = zeroes + 1
else
pairs = pairs + zeroes
if pairs > 1e9 then
return -1
end
end
end
return pairs
end
print(solution0based{[0]=0, [1]=1, [2]=0, [3]=1, [4]=1}) -- prints 5

Resources