So let's say I have a list/array which contains only integers (positive and negative). I want to make a method that gets the sum of only the numbers that are the same and consecutive. The result should be an array as shown in examples below.
The 'same' condition meaning: 1 == 1
Examples:
[1,4,4,4,0,4,3,3,1] # => [1,12,0,4,6,1]
So as you can see sum of consecutives 1 is 1
sum of 3 consecutives 4 is 12
sum of 0... and sum of 2
consecutives 3 is 6 ...
[1,1,7,7,3] # => [2,14,3]
[-5,-5,7,7,12,0] # => [-10,14,12,0]
I tried this, but it doesn't have the consecutive condition, how would I add that condition?
def sum_consecutives(string)
string.map{|num| string.count(num) > 1 ? num * string.count(num) : num}
end
Thanks in advance :-)
You can split the original Array into chunks of consecutive numbers: Enumerable#chunk_while
a = [1,4,4,4,0,4,3,3,1]
a.chunk_while {|a,b| a == b }
#=> [[1], [4, 4, 4], [0], [4], [3, 3], [1]]
Then just map and sum the sub arrays: Enumerable#sum
a.chunk_while {|a,b| a == b }.map(&:sum)
#=> [1, 12, 0, 4, 6, 1]
Related
I am using hacker rank and I do not understand why my ruby code only works for one test case out of like 20. Here is the question:
John Watson knows of an operation called a right circular rotation on
an array of integers. One rotation operation moves the last array
element to the first position and shifts all remaining elements right
one. To test Sherlock's abilities, Watson provides Sherlock with an
array of integers. Sherlock is to perform the rotation operation a
number of times then determine the value of the element at a given
position.
For each array, perform a number of right circular rotations and
return the values of the elements at the given indices.
Function Description
Complete the circularArrayRotation function in the editor below.
circularArrayRotation has the following parameter(s):
int a[n]: the array to rotate
int k: the rotation count
int queries[1]: the indices to report
Returns
int[q]: the values in the rotated a as requested in m
Input Format
The first line contains 3 space-separated integers, n, k, and q, the number of elements in the integer array, the rotation count and the number of queries. The second line contains n space-separated integers,
where each integer i describes array element a[i] (where 0 <= i < n). Each of the q subsequent lines contains a single integer, queries[i], an index of an element
in a to return.
Constraints
Sample Input 0
3 2 3
1 2 3
0
1
2
Sample Output 0
2
3
1
Here is my code :
def circularArrayRotation(a, k, queries)
q = []
while k >= 1
m = a.pop()
a.unshift m
k = k - 1
end
for i in queries do
v = a[queries[i]]
q.push v
end
return q
end
It only works for the sample text case but I can't figure out why. Thanks for any help you can provide.
Haven't ran any benchmarks, but this seems like a job for the aptly named Array.rotate() method:
def index_at_rotation (array, num_rotations, queries)
array = array.rotate(-num_rotations)
queries.map {|q| array[q]}
end
a = [1, 2, 3]
k = 2
q = [0,1, 2]
index_at_rotation(a, k, q)
#=> [2, 3, 1]
Handles negative rotation values and nil results as well:
a = [1, 6, 9, 11]
k = -1
q = (1..4).to_a
index_at_rotation(a, k, q)
#=> [9, 11, 1, nil]
I don't see any errors in your code, but I would like to suggest a more efficient way of making the calculation.
First observe that after q rotations the element at index i will at index (i+q) % n.
For example, suppose
n = 3
a = [1,2,3]
q = 5
Then after q rotations the array will be as follows.
arr = Array.new(3)
arr[(0+5) % 3] = a[0] #=> arr[2] = 1
arr[(1+5) % 3] = a[1] #=> arr[0] = 2
arr[(2+5) % 3] = a[2] #=> arr[1] = 3
arr #=> [2,3,1]
We therefore can write
def doit(n,a,q,queries)
n.times.with_object(Array.new(n)) do |i,arr|
arr[(i+q) % n] = a[i]
end.values_at(*queries)
end
doit(3,[1,2,3],5,[0,1,2])
#=> [2,3,1]
doit(3,[1,2,3],5,[2,1])
#=> [1, 3]
doit(3,[1,2,3],2,[0,1,2])
#=> [2, 3, 1]
p doit(3,[1,2,3],0,[0,1,2])
#=> [1,2,3]
doit(20,(0..19).to_a,25,(0..19).to_a.reverse)
#=> [14, 13, 12, 11, 10, 9, 8, 7, 6, 5,
# 4, 3, 2, 1, 0, 19, 18, 17, 16, 15]
Alternatively, we may observe that after q rotations the element at index j was initially at index (j-q) % n.
For the earlier example, after q rotations the array will be
[a[(0-5) % 3], a[(1-5) % 3], a[(2-5) % 3]]
#=> [a[1], a[2], a[0]]
#=> [2,3,1]
We therefore could instead write
def doit(n,a,q,queries)
n.times.map { |j| a[(j-q) % n] }.values_at(*queries)
end
For example, we have such array arr = [1, 1, 3, 4, 5, 7] and we have given number 8, we need to find any n number of elements in this array that will be the sum of the given number. In this case, it should be [1, 3, 4] or [1, 7] or [3, 5]. What is the easiest way to do it in Ruby?
Like #Stefan and #Jorg said in comments there is no easy way to do it. If this was a question to myself, I would probably write down something like this.
arr = [1, 1, 3, 4, 5, 7]
number = 8
result = []
for i in 0..(arr.length) do
arr.combination(i).each do |combination|
result.push(combination) if combination.sum == number
end
end
print result.uniq
Depending on the magnitude of the given number, it may be faster to use dynamic programming. If tot is the given number and arr is the array of possible summands, the method given below has a computational complexity of O(tot*arr.size).
Code
def find_summands(arr, tot)
return [] if tot.zero?
arr.each_with_object([{tot=>nil}]) do |n,a|
h = a.last.each_key.with_object({}) do |t,h|
return soln(arr,a.drop(1),n) if t==n
h[t] = 0
h[t-n] = n
end
a << h
end
nil
end
def soln(arr,a,n)
t = n
a.reverse.each_with_object([n]) do |h,b|
m = h[t]
b << m
t += m
end.reverse.tap { |a| (arr.size-a.size).times { a << 0 } }
end
Examples
arr = [1, 1, 3, 4, 5, 7]
find_summands(arr, 8)
#=> [1, 0, 3, 4, 0, 0]
find_summands(arr, 11)
#=> [1, 1, 0, 4, 5, 0]
find_summands(arr, 21)
#=> [1, 1, 3, 4, 5, 7]
find_summands(arr, 22)
#=> nil
find_summands([1, -2, 3, 4, 5, 7], 6)
#=> [1, -2, 3, 4, 0, 0]
Each zero in the array returned indicates that the corresponding element in arr is not used in the summation.
Explanation
Suppose:
arr = [4, 2, 6, 3, 5, 1]
tot = 13
then
find_summands(arr, tot)
#=> [4, 0, 6, 3, 0, 0]
When a solution is obtained soln is called to put it into a more useful form:
soln(arr, a.drop(1), n)
Here, arr is as above and
n #=> 3
a #=> [
{13=>nil}, # for tot
{13=>0, 9=>4}, # for arr[0] => 4
{13=>0, 11=>2, 9=>0, 7=>2}, # for arr[1] => 2
{13=>0, 7=>0, 11=>0, 5=>6, 9=>0, 3=>6, 1=>6} # for arr[2] => 6
]
n equals the value of the last summand used from arr, left to right.
When considering arr[0] #=> 4 the remaining amount to be summed is 13, the key of a[0] #=> {13=>nil}. There are two possibilities, 4 is a summand or it is not. This gives rise to the hash
a[1]
#=> {13-0=>0, 13-4=>4}
# { 13=>0, 9=>4}
where the keys are the remaining amount to be summed and the value is 4 if 4 is a summand and is zero if it is not.
Now consider arr[1] #=> 2. We look to the keys of a[1] to see what the possible remaining amounts might be after 4 is used or not. (13 and 9). For each of these we consider using or not using 2. That gives rise to the hash
a[2]
#=> {13-0=>0, 13-2=>2, 9-0=>0, 9-2=>2}
# { 13=>0, 11=>2, 9=>0, 7=>2}
7=>2 can be read, if 2 (the value) is a summand, there is a choice of using arr[0] or not that results in the remaining amount to be summed after 2 is included being 7.
Next consider arr[2] #=> 6. We look to the keys of a[2] to see what the possible remaining amounts might be after 4 and 6 are used or not. (13, 11, 9 and 7). For each of these we consider using or not using 6. We therefore now create the hash
a[3]
#=> {13-0=>0, 13-6=>6, 11-0=>0, 11-6=>6, 9-0=>0, 9-6=>6, 7-0=>0, 7-6=>6}
# { 13=>0, 7=>6, 11=>0, 5=>6, 9=>0, 3=>6, 7=>0, 1=>6}
# { 13=>0, 11=>0, 5=>6, 9=>0, 3=>6, 7=>0, 1=>6}
The pair 11=>0 can be read, "if 6 is not a summand, there is a choice of using or not using arr[0] #=> 4 and arr[2] #=> 2 that results in the remaining amount to be summed after 6 is excluded being 11".
Note that the key-value pair 7=>6 was overwritten with 7=>0 when not using 6 was considered with a remaining amount of 7. We are only looking for one solution, so it doesn't matter how we get to a remaining amount of 7 after the first three elements of arr are considered. These collisions tend to increase as we move left-to-right in arr, so the number of states we need to keep track of is greatly reduced because we are able to "throw away" so many of them.
Lastly (as it turns out), we consider arr[3] #=> 3. We look to the keys of a[3] to see what the possible remaining amounts might be after 4, 2 and 6 have been used or not (13, 11, 5, 9, 3, 7 and 1). For each of these we consider using or not using 3. We get this far in creating the hash a[4]:
{13=>0, 10=>3, 11=>0, 8=>3, 5=>0, 2=>3, 9=>0, 6=>3, 3=>0, 0=>3}
As the last key-value pair has a key of zero we know we have found a solution.
Let's construct the solution. Because the value of 0 is 3, 3 is a summand. (We would have found the solution earlier if the value were zero.) We now work backwards. As 3 is used, the remaining amount before 3 is used is 0+3 #=> 3. We find that a[3][3] #=> 6, meaning 6 is also a summand. The remaining balance before using the 6 was 3+6 #=> 9, so we compute a[2][9] #=> 0, which tells us that the 2 is not a summand. Lastly, a[1][9-0] #=> 4 shows that 4 is also a summand. Hence the solution
[4, 0, 6, 3, 0, 0]
I have an array #ary = [1, 3, 4, 2, 7, 8, 9] and I want to know how many possibilities of combination can add equal to 9.
I should have four possibilities can add equal to 9 [1,8]、[2, 3, 4]、[9]、[2, 7],but in my code, I just can know two of possibilities and just can show one possibility in this problem.
def sums (num, target)
random1 = num.sample
random2 = num.sample
if random1+random2 == target
ary1 = [random1, random2]
end
end
If you're interested in the combinations themselves as opposed to just the count:
(1..a.size).flat_map { |n| a.combination(n).to_a }
.keep_if { |c| c.inject(:+) == 9 }
#=> [[9], [1, 8], [2, 7], [3, 4, 2]]
You can use Array#combination:
(1..ary.size).inject(0) do |a, e|
a + ary.combination(e).count { |e| e.sum == 9 }
end
#=> 4
You can use inject(:+) instead of sum if your ruby version is lower than 2.4.
I have an array of arrays like so...
a1 = [[9, -1811.4], [8, 959.86], [7, -385], [6, -1731.39], [5, 806.78], [4, 2191.65]]
I need to get the average of the 2nd items(the amounts) from the total array.
So add -1811.4,959.86,-385,-1731.39,806.78 divided by the count (6)
I have tried...
a1.inject{ |month, amount| amount }.to_f / a1.size
This is not right and I cant see what I need to do
a1.map(&:last).inject(:+) / a1.size.to_f
#=> 5.0833333333332575
Steps:
# 1. select last elements
a1.map(&:last)
#=> [-1811.4, 959.86, -385, -1731.39, 806.78, 2191.65]
# 2. sum them up
a1.map(&:last).inject(:+)
#=> 30.499999999999545
# 3. divide by the size of a1
a1.map(&:last).inject(:+) / a1.size.to_f
#5.0833333333332575
One pass through a1 is sufficient.
a1.reduce(0) { |tot, (_,b)| tot + b }/a1.size.to_f
#=> 5.0833333333332575
.to_f allows a1 to contain only integer values.
The steps:
tot = a1.reduce(0) { |tot, (_,b)| tot + b }
#=> 30.499999999999545
n = a1.size.to_f
#=> 6.0
tot/n
#=> 5.0833333333332575
Let's say I have an array with 5 elements. How can I calculate all possible repetitive permutations of this array in C.
Edit: What I mean is creating all possible arrays by using that 5 number. So the positon matters.
Example:
array = [1,2,3,4,5]
[1,1,1,1,1]
[1,1,1,1,2]
[1,1,1,2,3]
.
.
A common way to generate combinations or permutations is to use recursion: enumerate each of the possibilities for the first element, and prepend those to each of the combinations or permutations for the same set reduced by one element. So, if we say that you're looking for the number of permutations of n things taken k at a time and we use the notation perms(n, k), you get:
perms(5,5) = {
[1, perms(5,4)]
[2, perms(5,4)]
[3, perms(5,4)]
[4, perms(5,4)]
[5, perms(5,4)]
}
Likewise, for perms(5,4) you get:
perms(5,4) = {
[1, perms(5,3)]
[2, perms(5,3)]
[3, perms(5,3)]
[4, perms(5,3)]
[5, perms(5,3)]
}
So part of perms(5,5) looks like:
[1, 1, perms(5,3)]
[1, 2, perms(5,3)]
[1, 3, perms(5,3)]
[1, 4, perms(5,3)]
[1, 5, perms(5,3)]
[2, 1, perms(5,3)]
[2, 2, perms(5,3)]
...
Defining perms(n, k) is easy. As for any recursive definition, you need two things: a base case and a recursion step. The base case is where k = 0: perms(n, 0) is an empty array, []. For the recursive step, you generate elements by prepending each of the possible values in your set to all of the elements of perms(n, k-1).
If I get your question correctly, you need to generate all 5 digit numbers with digits 1,2,3,4 and 5. So there is a simple solution - generate all numbers base five up to 44444 and then map the 0 to 1, 1 to 2 and so on. Add leading zeros where needed - so 10 becomes 00010 or [1,1,1,2,1].
NOTE: you don't actually have to generate the numbers themselves, you may just iterate the numbers up to 5**5(excluding) and for each of them find the corresponing sequence by getting it's digits base 5.
int increment(size_t *dst, size_t len, size_t base) {
if (len == 0) return 0;
if (dst[len-1] != base-1) {
++dst[len-1];
return 1;
} else {
dst[len-1] = 0;
return increment(dst, len-1, base);
}
}
Armed with this function you can iterate over all repetitive permutations of (0 ... 4) starting from {0, 0, 0, 0, 0}. The function will return 0 when it runs out of repetitive permutations.
Then for each repetitive permutation in turn, use the contents as indexes into your array so as to get a repetitive permutation of the array rather than of (0 ... 4).
In your given example, each position could be occupied by either 1, 2, 3, 4, 5. As there are 5 positions, the total number of possibilities = 5 * 5 * 5 * 5 * 5 = 5 ^ 5 = 3125. In general, it would be N ^ N. (where ^ is the exponentiation operator).
To generate these possibilities, in each of the positions, put the numbers 1, 2, 3, 4, 5, one by one, and increment starting from the last position, similar to a 5 digit counter.
Hence, start with 11111. Increment the last position to get 11112 ... until 11115.
Then wrap back to 1, and increment the next digit 11121 continue with 11122 ... 11125, etc. Repeat this till you reach the first position, and you would end at 55555.