Set all values of a column in a multidimensional array - ruby

I have the following code that adds zero to values of a specific row in a multidimensional array:
def self.zero_row(matrix, row_index)
matrix[row_index].each_with_index do |item, index|
matrix[row_index][index] = 0
end
return matrix
end
I am wondering how I would go in order to make zeros all the values given a specific column_index.
def self.zero_column(matrix, col_index)
#..
end

To follow the same pattern as your other method you could do something like this:
def self.zero_column(matrix, col_index)
matrix.each_with_index do |item, row_index|
matrix[row_index][col_index] = 0
end
end

Would this fit the bill?
def self.zero_column(matrix, col_index)
matrix = matrix.transpose
matrix[col_index].map!{0}
matrix.transpose
end
Similarly, you could simplify your zero_row method
def self.zero_row(matrix, row_index)
matrix[row_index].map!{0}
matrix
end

If you need to deal with columns frequently, then I would say it is a design flaw to use a nested array. Nesting array has almost no benefit, and just makes things complicated. You should better have a flat array. It is much easier to manipulate columns equally as rows with flat arrays.
If you want a 3 by 2 matrix, then you can initialize it simply as an array with the length 3 * 2 like:
a = [1, 2, 3, 4, 5, 6]
Then, you can refer to the second column (index 1) or row as respectively:
a.select.with_index{|_, i| i % 2 == 1} # => [2, 4, 6]
a.select.with_index{|_, i| i / 2 == 1} # => [3, 4]
Rewriting all values of that column or row to 0 would be respectively:
a.each_index{|i| a[i] = 0 if i % 2 == 1} # => a: [1, 0, 3, 0, 5, 0]
or
a.each_index{|i| a[i] = 0 if i / 2 == 1} # => a: [1, 2, 0, 0, 5, 6]
Switching between an operation on a column and another on a row would be a matter of switching between % and /; you can see symmetry/consistency. If you need to keep the information regarding column length 2 within the array, then just assign it as an instance variable of that array.

Related

Ruby code to iterate over every n-th element of an array and print it until all elements are printed?

I am asked to write some code in Ruby that iterates over every n-th element of an array and prints it until all elements of the array are printed.
The question reads:
Imagine an iterator that accesses an array in strides and runs some code at each stride. If the strides reach the end of the array then they simply begin anew from the array's beginning.
For example:
x = [0,1,2,3,4]
x.stride(1) do |elem|; puts elem; end # prints 0,1,2,3,4
x.stride(2) do |elem|; puts elem; end # prints 0,2,4,1,3
x.stride(8) do |elem|; puts elem; end # prints 0,3,1,4,2
[].stride(2) do |elem|; puts elem; end # does not print anything, but the code is correct
Assume that the stride is equal or greater than 1, and that both the stride and the array's size are not a integral/whole multiple of each other, meaning that the whole array can be printed using a given stride. Fill in the code that's missing:
class Array
def stride(step)
numelems = ... # size of the array
...
end
end
It is obvious that numelemns = self.length(). However am having trouble with the rest.
I am going to try writing some code in Python that accomplishes this task, but I am afraid that I will not be able to translate it to Ruby.
Any ideas? The answer should not be more than 4-5 lines long as the question is one that our proffessor gave us to solve in a couple of minutes.
A solution to this is provided below (thanks #user3574603):
class Array
def stride(step)
yield self[0]
(self * step).map.with_index do |element, index|
next element if index == 0
yield element if index % step == 0
end
end
end
The following assumes that arr.size and n are not both even numbers and arr.size is not a multiple of n.
def striding(arr, n)
sz = arr.size
result = '_' * sz
idx = 0
sz.times do
result[idx] = arr[idx].to_s
puts "S".rjust(idx+1)
puts result
idx = (idx + n) % sz
end
end
striding [1,2,3,4,5,6,7,8,9,1,2,3,4,5,6], 7
S
1______________
S
1______8_______
S
1______8______6
S
1_____78______6
S
1_____78_____56
S
1____678_____56
S
1____678____456
S
1___5678____456
S
1___5678___3456
S
1__45678___3456
S
1__45678__23456
S
1_345678__23456
S
1_345678_123456
S
12345678_123456
S
123456789123456
Here is an example where arr.size is a multiple of n.
striding [1,2,3,4,5,6], 3
S
1_____
S
1__4__
S
1__4__
S
1__4__
S
1__4__
S
1__4__
Here is an example where arr.size and n are both even numbers.
striding [1,2,3,4,5,6,7,8], 6
S
1_______
S
1_____7_
S
1___5_7_
S
1_3_5_7_
S
1_3_5_7_
S
1_3_5_7_
S
1_3_5_7_
S
1_3_5_7_
Imagine an iterator that accesses an array in strides and runs some code at each stride. If the strides reach the end of the array then they simply begin anew from the array's beginning.
Based on this specification, stride will always iterate forever, unless the array is empty. But that is not a problem, since we can easily take only the amount of elements we need.
In fact, that is a good design: producing an infinite stream of values lets the consumer decide how many they need.
A simple solution could look like this:
module CoreExtensions
module EnumerableExtensions
module EnumerableWithStride
def stride(step = 1)
return enum_for(__callee__, step) unless block_given?
enum = cycle
loop do
yield(enum.next)
(step - 1).times { enum.next }
end
self
end
end
end
end
Enumerable.include(CoreExtensions::EnumerableExtensions::EnumerableWithStride)
A couple of things to note here:
I chose to add the stride method to Enumerable instead of Array. Enumerable is Ruby's work horse for iteration and there is nothing in the stride method that requires self to be an Array. Enumerable is simply the better place for it.
Instead of directly monkey-patching Enumerable, I put the method in a separate module. That makes it easier to debug code for others. If they see a stride method they don't recognize, and inspect the inheritance chain of the object, they will immediately see a module named EnumerableWithStride in the inheritance chain and can make the reasonable assumption that the method is probably coming from here:
[].stride
# Huh, what is this `stride` method? I have never seen it before.
# And it is not documented on https://ruby-doc.org/
# Let's investigate:
[].class.ancestors
#=> [
# Array,
# Enumerable,
# CoreExtensions::EnumerableExtensions::EnumerableWithStride,
# Object,
# Kernel,
# BasicObject
# ]
# So, we're confused about a method named `stride` and we
# found a module whose name includes `Stride`.
# We can reasonably guess that somewhere in the system,
# there must be a file named
# `core_extensions/enumerable_extensions/enumerable_with_stride.rb`.
# Or, we could ask the method directly:
meth = [].method(:stride)
meth.owner
#=> CoreExtensions::EnumerableExtensions::EnumerableWithStride
meth.source_location
#=> [
# 'core_extensions/enumerable_extensions/enumerable_with_stride.rb',
# 6
# ]
For an empty array, nothing happens:
[].stride(2, &method(:p))
#=> []
stride just returns self (just like each does) and the block is never executed.
For a non-empty array, we get an infinite stream of values:
x.stride(&method(:p))
# 0
# 1
# 2
# 3
# 4
# 0
# 1
# …
x.stride(2, &method(:p))
# 0
# 2
# 4
# 1
# 3
# 0
# 2
# …
x.stride(8, &method(:p))
# 0
# 3
# 1
# 4
# 2
# 0
# 3
# …
The nice thing about this infinite stream of values is that we, as the consumer can freely choose how many elements we want. For example, if I want 10 elements, I simply take 10 elements:
x.stride(3).take(10)
#=> [0, 3, 1, 4, 2, 0, 3, 1, 4, 2]
This works because, like all well-behaved iterators, our stride method returns an Enumerator in case no block is supplied:
enum = x.stride(2)
#=> #<Enumerator: ...>
enum.next
#=> 0
enum.next
#=> 2
enum.next
#=> 4
enum.next
#=> 1
enum.next
#=> 3
enum.next
#=> 0
enum.next
#=> 2
So, if we want to implement the requirement "until all the elements of the array are printed":
I am asked to write some code in Ruby that iterates over every n-th element of an array and prints it until all elements of the array are printed.
We could implement that something like this:
x.stride.take(x.length).each(&method(:p))
x.stride(2).take(x.length).each(&method(:p))
x.stride(8).take(x.length).each(&method(:p))
This is a pretty simplistic implementation, though. Here, we simply print as many elements as there are elements in the original array.
We could implement a more sophisticated logic using Enumerable#take_while that keeps track of which elements have been printed and which haven't, and only stops if all elements are printed. But we can easily prove that after x.length iterations either all elements have been printed or there will never be all elements printed (if the stride size is an integral multiple of the array length or vice versa). So, this should be fine.
This almost does what I think you want but breaks if the step is array.length + 1 array.length (but you mention that we should assume the stride is not a multiply of the array length).
class Array
def exhaustive_stride(step)
(self * step).map.with_index do |element, index|
next element if index == 0
element if index % step == 0
end.compact
end
end
x.exhaustive_stride 1
#=> [0, 1, 2, 3, 4]
x.exhaustive_stride 2
#=> [0, 2, 4, 1, 3]
x.exhaustive_stride 8
#=> [0, 3, 1, 4, 2]
[].exhaustive_stride 2
#=> []
Using the example array, it breaks when the stride is 5.
[0,1,2,3,4].exhaustive_stride 5
#=> [0, 0, 0, 0, 0]
Note
This works but the intermediate array makes it highly inefficient. Consider other answers.
Here's another solution that uses recursion. Not the most efficient but one way of doing it.
class Array
def exhaustive_stride(x, r = [])
return [] if self.empty?
r << self[0] if r.empty?
while x > self.length
x -= self.length
end
r << self[x]
x += x
return r if r.count == self.count
stride(x, r)
end
end
[0,1,2,3,4].exhaustive_stride 1
#=> [0, 1, 2, 4, 3]
[0,1,2,3,4].exhaustive_stride 2
#=> [0, 2, 4, 3, 1]
[0,1,2,3,4].exhaustive_stride 8
#=> [0, 3, 1, 2, 4]
[].exhaustive_stride 2
#=> []
[0,1,2,3,4].exhaustive_stride 100_000_001
#=> [0, 1, 2, 4, 3]
This would work:
def stride(ary, step)
raise ArgumentError unless step.gcd(ary.size) == 1
Array.new(ary.size) { |i| ary[(i * step) % ary.size] }
end
Example:
x = [0, 1, 2, 3, 4]
stride(x, 1) #=> [0, 1, 2, 3, 4]
stride(x, 2) #=> [0, 2, 4, 1, 3]
stride(x, 8) #=> [0, 3, 1, 4, 2]
stride(x, -1) #=> [0, 4, 3, 2, 1]
First of all, the guard clause checks whether step and ary.size are coprime to ensure that all elements can be visited via step.
Array.new(ary.size) creates a new array of the same size as the original array. The elements are then retrieved from the original array by multiplying the element's index by step and then performing a modulo operation using the array's size.
Having % arr.size is equivalent to fetching the elements from a cyclic array, e.g. for a step value of 2:
0 1 2 3 4
| | | | |
[0, 1, 2, 3, 4, 0, 1, 2, 3, 4, ...
To turn this into an instance method for Array you merely replace ary with self (which can be omitted most of the time):
class Array
def stride(step)
raise ArgumentError unless step.gcd(size) == 1
Array.new(size) { |i| self[(i * step) % size] }
end
end

Adding the number to the according index it is positioned in

def incrementer(num)
num.map.with_index(1) do |row, index|
if row > 9
row.to_s.reverse.chop.to_i
else
index + row
end
end
end
Hi,
I have a method which adds the number to the according index it is positioned in. However I have two rules:
The index starts at (1)
If the number is a multiple, remove the first integer off the end of it. 12 would become 2 for example.
The problem is I am unsure how to include an 'if' statement inside a block and I believe I am doing it wrong. I know there is a much better way to write this statement but I am finding it hard.
Example:
incrementer([4,6,9,1,3]) => [5,8,2,5,8]
- 9 + 3 (position of 9 in array) = 12
- Only its last digit 2 should be returned
Fixing your code
Use map followed by with_index(1), the argument offsetting the initial index by +1.
def incrementer(num)
num.map.with_index(1) do |row, index|
row = index + row
if row > 9
row.digits.first
else
row
end
end
end
incrementer [3, 2, 4, 10] #=> [4, 4, 7, 4]
incrementer [4, 6, 9, 1, 3] #=> [5, 8, 2, 5, 8]
Negative numbers
Numbers can be negative and for which we can use abs.digits but it may be better to use Integer#remainder.
def incrementer(num)
num.map.with_index(1) do |row, index|
row = index + row
case row
when -9..9
row
else
row.remainder 10
end
end
end
incrementer [3, 2, 4, 10]
#=> [4, 4, 7, 4]
incrementer [4, 6, 9, 1, 3]
#=> [5, 8, 2, 5,8]
incrementer [3, 2, 4,-17]
#=> [4, 4, 7, -3]
incrementer [4, 6, -22, 1, 3]
#=> [5, 8, -9, 5, 8]
Why not use % instead of Integer#remainder?
a % b returns a modulo b which is not the same thing as the remainder. This has consequences for negative numbers:
-12 % 10 #=> 8 not the last digit
So we need to use Integer#remainder, so:
-12.remainder 10 #=> -2
Which is what we need, i.e. the last digit (parity included). It can be noted in other languages such as JavaScript, a % b returns the remainder.
As noted by #moveson the above code can be refactored to:
num.map.with_index(1) { |row, index| (index + row).remainder 10 }
The #digits method requires Rails or ActiveSupport (or Ruby 2.4+), and it's not necessary. Here is a pure Ruby solution that works with any Ruby version:
def incrementer(array)
array.map.with_index(1) { |integer, index| (integer + index) % 10 }
end
This code above says: For each element of the array, add its index (starting from 1), divide the sum by 10, and return the remainder.
The % (modulo) operator divides the number before it by the number after it and returns the remainder. For example, 22 % 7 returns 1. It's an extremely useful tool and can often help avoid the use of conditionals entirely, such as in your example. Using %, you can get the last digit of a number n (whether or not n is greater than 9) by simply taking n % 10.
Now you can do:
>> incrementer([3,2,4,10])
=> [4, 4, 7, 4]
>> incrementer([4,6,9,1,3])
=> [5, 8, 2, 5, 8]
You've got two separate problems. The first problem is your use of each_with_index. Ruby functions return the value of the last expression they execute, so if you look at your function:
def incrementer(num)
num.each_with_index do |row, index|
# do some stuff
end
end
It essentially calls each_with_index and returns the value. The issue here is that each_with_index iterates over an array and then returns the original array. What you want to do is change each item in the array and return a new array with the new values. For this, you can use map:
def incrementer(num)
num.map.with_index(1) do |row, index|
# do some stuff
end
end
In this case, you can even conveniently pass in the parameter 1 to tell the iterator to start at index 1.
Now the second problem is that your if-else-statement either iterates a number or wraps it around. But what you actually want to do is iterate a number and wrap it around if it's bigger than 9. You can do that like so:
def incrementer(num)
num.map.with_index(1) do |row, index|
row = index + row
if row > 9
row.to_s.reverse.chop.to_i
else
row
end
end
end
What we're doing here is iterating the number first, saving it into row and then checking to see if it's over 9. If it is, we return the last digit; otherwise, we just return the value row.
This code will do what you want, but let's make one more change for the sake of clarity. This code:
row.to_s.reverse.chop.to_i
Is a little bit confusing. Ruby 2.4 has a convenient method for getting at the digits of an integer:
row.digits.first
This is easy to read, but it's a bit slow since it turns an integer into an array of integers. A better way is to use modulus % to get the remainder of your number, divided by 10. This is fast and easy to read for most programmers, since it's a common trick.
row % 10
Putting it all together, you get:
def incrementer(num)
num.map.with_index(1) do |row, index|
row = index + row
if row > 9
row % 10
else
row
end
end
end
Special thanks to (#sagarpandya84) and (#moveson) for allowing me to build on their answers.

Ruby, is there a built in method to split an array into two sub arrays at a specified index?

Doing a ruby problem and thinking to myself, there must be an easier way.
I want to split an array at a specified index into two sub arrays. The first sub array containing the numbers up to the specified index, and the second sub array containing the numbers after and including the specified index.
Example
([2, 1, 2, 2, 2],2) => [2,1] [2,2,2]
#here, the specified index is two, so the first array is index 0 and 1,
the second is index 2, 3, and 4.
def array_split(arr,i)
arr1 = []
arr2 = []
x = 0
while x < arr.count
x < i ? arr1 << arr[x] : arr2 << arr[x]
x += 1
end
return arr1, arr2
end
This was no issue with a while loop. I want to know if there is a simpler solution.
There is :)
arr1 = [2, 1, 2, 2, 2].take 2
arr2 = [2, 1, 2, 2, 2].drop 2
def split a, i
[a[0...i], a[i..-1]]
end
p split [2,1,2,2,2], 2
# here is another way
class Array
def split i
[self[0...i], self[i..-1]]
end
end
p [2,1,2,2,2].split 2

Replace all zeros in array with elements of another array

Say I've got an array like this:
array_1 = [0, 0, 1, 2, 3, 0]
and another one like this:
array_2 = [4, 5, 6]
How can I create an array like this, such that each 0 in the array_1 is replaced by the first and subsequent elements of the array_2?:
[4, 5, 1, 2, 3, 6]
That is, every time we encounter a 0 in the first array, we'd like to replace it with the result of array_2.shift.
This one is shorter but the shift method it will modify array_2 in-place.
array_1.map {|x| x == 0 ? array_2.shift : x}
The following uses an enumerator object with external iteration and will not modify any of the original arrays.
e = array_2.each
array_1.map {|x| x == 0 ? e.next : x}
You could do something like this, iterate and shift when you encounter a 0
array_1.each_with_index do |val, i|
array_1[i] = array_2.shift if val == 0
end

How to refactor this code to remove output variable?

def peel array
output = []
while ! array.empty? do
output << array.shift
mutate! array
end
output.flatten
end
I have not included the mutate! method, because I am only interested in removing the output variable. The mutate! call is important because we cannot iterate over the array using each because array is changing.
EDIT: I am getting an array as output, which is what I want. The method works correctly, but I think there is a way to collect the array.shift values without using a temp variable.
EDIT #2: OK, here is the mutate! method and test case:
def mutate! array
array.reverse!
end
a = (1..5).to_a
peel( a ).should == [ 1, 5, 2, 4, 3 ]
It doesn't matter if peel modifies array. I guess it should be called peel!. Yes, mutate! must be called after each element is removed.
All this reversing makes me dizzy.
def peel(array)
indices = array.size.times.map do |i|
i = -i if i.odd?
i = i/2
end
array.values_at(*indices) # indices will be [0, -1, 1, -2, 2] in the example
end
a = (1..5).to_a
p peel(a) #=>[1, 5, 2, 4, 3]
Another approach:
def peel(array)
mid = array.size/2
array[0..mid]
.zip(array[mid..-1].reverse)
.flatten(1)
.take(array.size)
end
Usage:
peel [1,2,3,4,5,6]
#=> [1, 6, 2, 5, 3, 4]
peel [1,2,3,4,5]
#=> [1, 5, 2, 4, 3]
Here's a way using parallel assignment:
def peel array
n = array.size
n.times {|i| (n-2-2*i).times {|j| array[n-1-j], array[n-2-j] = array[n-2-j], array[n-1-j]}}
array
end
peel [1,2,3,4,5] # => [1,5,2,4,3]
peel [1,2,3,4,5,6] # => [1,6,2,5,3,4]
What I'm doing here is a series of pairwise exchanges. By way of example, for [1,2,3,4,5,6], the first 6-2=4 steps (6 being the size of the array) alter the array as follows:
[1,2,3,4,6,5]
[1,2,3,6,4,5]
[1,2,6,3,4,5]
[1,6,2,3,4,5]
The 1, 6 and the 2 are in now the right positions. We repeat these steps, but this time only 6-4=2 times, to move the 5 and 3 into the correct positions:
[1,6,2,3,5,4]
[1,6,2,5,3,4]
The 4 is pushed to the end, it's correct position, so we are finished.

Resources