Create array with different sizes of array in C++ - c++11

One can generate list with different length of list in python :
layers = 3
lst = []
for i in range(1, layers+2):
lst.append([0]*i)
Above code generates 2d list:
[[0],
[0, 0],
[0, 0, 0],
[0, 0, 0, 0]]
So how can I create a 2d array like the 2d list above in C++?
Thanks!

Related

How to convert a monochrome image to 2d array in ruby

digit 5 monochrome image
How to convert the sample monochrome image to 2d array in ruby.
[[0, 0, 0, 0, 0],
[0, 1, 1, 1, 1],
[0, 1, 1, 1, 1],
[0, 0, 0, 0, 1],
[0, 1, 1, 1, 0],
[1, 1, 1, 1, 0],
[0, 1, 1, 1, 0],
[0, 1, 1, 1, 0],
[1, 0, 0, 0, 1]]
I had tried do it use pycall plugin. However, I had to import again manual when execute in rails console. Pycall not work sometimes.
require 'pycall'
require 'pycall/import'
include PyCall::Import
pyimport 'numpy', as: :np
pyimport 'PIL.Image', as: :pil_image
image = pil_image.open.(image_path).convert.('1')
img = np.asarray.(image, dtype: np.uint8)
list = img.tolist.().map { |l| l.to_a }
RMagick offers a couple of solutions. Use get_pixels to get an array of Pixel objects. Pixel objects are structures from which you can get the values of the red, green, and blue channel. Because the image is monochrome the channel values will either be 0 or QuantumRange. Scale the values by QuantumRange to force them to either 0 or 1.
Alternatively, use export_pixels. Again, scale the returned values by QuantumRange to get either 0 or 1.
In either case you can minimize the storage requirements (if your image is large) by operating on successive subsets (a single row, for example) of the image.

Odd behavior with Ruby arrays?

I am using Ruby 2.3.1 and I cannot tell if I've encountered a bug or if this is intended behavior.
If you create an NxN matrix by making nested arrays, as such:
matrix = [[0]*5]*5
and then set the elements on the diagonals, as such:
(0..4).each {|i| matrix[i][i] = i}
this ends up affecting every column in every row:
[
[0, 1, 2, 3, 4],
[0, 1, 2, 3, 4],
[0, 1, 2, 3, 4],
[0, 1, 2, 3, 4],
[0, 1, 2, 3, 4]
]
Is this intended behavior?
P.S. I do not want to use Ruby's Matrix library, but would rather work with plain arrays.
Thanks in advance :)
In Ruby, arrays are, behind the scenes, objects of type array, which can contain primitive types and references to other objects. Now, this last bit is important - the array doesn't contain the object itself, but instead a pointer to it, which is interpreted as necessary when the programmer asks for it.
So the OP's original initialization code
matrix = [[0]*5]*5
Really creates a single array object containing 5 0s, and then copies the pointer to it 5 times. This also happens when you do
matrix = Array.new(5, Array.new(5, 0))
for precisely the same reason. So, as posted in the comments, the idiomatically correct Ruby way to create an array of 5 different array objects is
matrix = Array.new(5){Array.new(5, 0)}
Which yields a single array that contains pointers to 5 different array objects, preventing the issue encountered by the OP. Full documentation on the behaviour of Ruby arrays can be found at this finely-crafted link.
You don't need to change the diagonal to observe that behaviour; just change any element, say
matrix[1][1] = 1
Then
matrix
#=> [[0, 1, 0, 0, 0], [0, 1, 0, 0, 0], [0, 1, 0, 0, 0],
# [0, 1, 0, 0, 0], [0, 1, 0, 0, 0]]
Consider
matrix.map { |row| row.object_id }
#=> [70153694327100, 70153694327100, 70153694327100,
# 70153694327100, 70153694327100].
This shows that all elements ("rows") of matrix are the same object, ergo, if that object is changed, all elements of matrix are affected. matrix = [[0]*5]*5 is equivalent to
matrix = Array.new(5, Array.new(5,0))
(See Array::new, expecially "Common gotchas".) What you want (as #Sebastian notes) is
matrix = Array.new(5) { Array.new(5,0) }
#=> [[0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0],
# [0, 0, 0, 0, 0], [0, 0, 0, 0, 0]]
so that
matrix[1][1] = 1
only affects that one element:
matrix
#=> [[0, 0, 0, 0, 0], [0, 1, 0, 0, 0], [0, 0, 0, 0, 0],
# [0, 0, 0, 0, 0], [0, 0, 0, 0, 0]]
matrix = [[0]*5]*5
Let's break this down:
a = [0]*5
Create an array of 5 zeros; this is an array of integers.
matrix = [a] * 5
Create an array of 5 references to the same array a.
So of course when you modify one, the others will be modified; it's the same array.
I don't know Ruby, so please feel free to correct any incorrect terminology.

Why does my diagonal matrix calculator not return the total?

My method should take an array of subarrays, find the sum of the first value of the first array, the second value of the second array, the third value of the third array, and so on. Some examples of inputs and expected results are as follows:
exampleArray = [
[1, 0, 0, 0],
[0, 1, 0, 0],
[0, 0, 1, 0],
[0, 0, 0, 1]
]
diagonalSum(exampleArray) # => 4
exampleArray = [
[1, 0, 0, 0, 0],
[0, 1, 0, 0, 0],
[0, 0, 1, 0, 0],
[0, 0, 0, 1, 0],
[0, 0, 0, 0, 1]
]
diagonalSum(exampleArray) # => 5
I wrote this:
def diagonalSum(matrix)
total = 0
counter = 0
while matrix.length <= counter + 1 do
total += matrix[counter][counter]
counter += 1
end
total
end
and it returns 0.
It's easiest to convert the array to a matrix and apply Matrix#trace.
require 'matrix'
arr = [[1, 0, 0, 7],
[0, 2, 0, 0],
[0, 0, 3, 0],
[8, 0, 0, 4]]
Matrix[*arr].trace
#=> 10
According to the code you provide, in which the input is an array of arrays, the first advice I could give you is that in Ruby you must avoid using for/while loops and make use of iterators such as each/each_with_index instead (based on this Ruby style guide and the suggestions of #tadman and #Yu Hao).
The each with index iterator takes a Ruby block with the current array of the iteration along with its index position, so you don't need to define your own index variable and update it in every iteration.
Applying this to your code will result in the following:
def diagonal_sum(matrix)
total = 0
matrix.each_with_index do |row, index|
total+=row[index]
end
total
end
Also note that the convention in Ruby is to write variable and method names in snake_case (according to the previous style guide).

Inserting values at empty indexes in arrays. How can I write this code shorter or more modular?

I have the following code I wrote which takes a 2d array with arrays of varying length and appends the value 0 to every index until all arrays are of the same length.
Can this code be written shorter or more efficient and modular?
a = [[1,7],[2,3],[5,1,2],[3],[1],[]]
l = a.map(&:length).max
a2 = a.each{|e| e.push(Array.new(l - e.length, 0) )}
a2.each{|e| e.flatten!}
#=> [[1, 7, 0], [2, 3, 0], [5, 1, 2], [3, 0, 0], [1, 0, 0], [0, 0, 0]]
UPDATE
Because I feel unable to award an accepted answer to the two answers given thus far based on the simplicity of the written code itself, I have decided to award it based on the efficiency of the running speed of the code.
100 test cases running code block 10000 times.
#My Code:
#average run time of test case -> 0.24267sec
#standard deviation -> 0.00735sec
#Stefan’s Code:
#average run time of test case -> 0.06389sec
#standard deviation -> 0.00756sec
#steenslag’s Code:
#average run time of test case -> 0.0577sec
#standard deviation -> 0.00413sec
tests were conducted under the same conditions using a custom written ruby timer class I made and are only relative to each other and my crappy 2010-macbookpro on which I ran them.
Another option using Array#fill:
l = a.map(&:length).max
a.each { |e| e.fill(0, e.length...l) }
a #=> [[1, 7, 0], [2, 3, 0], [5, 1, 2], [3, 0, 0], [1, 0, 0], [0, 0, 0]]
The flatten could be avoided by splatting the array:
l = a.max_by(&:size).size
a2 = a.each{|e| e.push(*Array.new(l - e.length, 0) )}
One more way, four days late:
len = a.map(&:size).max
a.map { |e| Array.new(len) { |i| e[i].to_i } }
#=> [[1,7,0],[2,3,0],[5,1,2],[3,0,0],[1,0,0],[0,0,0]]

Two dimensional array - sum 'row' and add as new element of array

I have a two dimensional array, which represents columns and rows of data. I need to sum both the columns and rows, but I need to total from the the new 'summary' row.
Data (6x5 array)
[1, 0, 3, 0, 0],
[0, 4, 0, 0, 4],
[0, 0, 0, 0, 0],
[0, 0, 0, 0, 0],
[0, 0, 0, 0, 0],
[0, 0, 0, 0, 0]
so the result should be a 7x6 array
[1, 0, 3, 0, 0, 4],
[0, 4, 0, 0, 4, 8],
[0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0],
[1, 4, 3, 0, 4, 12]
I know I can sum each column and add an additional row to my two dimensional array via
# Sum the columns, add additional one row for summary
a << a.transpose.map{|x| x.reduce(:+)}
but how do I add the additional column
a.map! {|row| row + [row.reduce(:+)]}
map! takes each element of the array, passes it to the block and replaces that element with whatever that block returns. So since we call it on a 2d array, row will be a 1d array - the row of the original array.
Then I calculate the sum with reduce(:+) of that row. Then I need to append it to that row. What I've done here is to wrap the result of sum into an array and then used + to concatenate those two arrays.
I could have also done this:
a.map! {|row| row << row.reduce(:+) }
As I was asking the question I came up with a solution, but I'd like to know if there is a better approach.
My solution
# Sum the rows (including the new summary row)
row_sum = a.map{|x| x.reduce(:+)}
# transpose the original array, add the summary column as a new row
c = a.transpose << row_sum
# transpose it back to the original view, now we have both summary of rows and columns
c.tranpose
Update
Here is my new short answer thanks to Jakub Hampl
# Create the summary column (row totals), update the array
a.map! {|r| r + [r.reduce(:+)]}
# Create the summary row (column totals)
a.transpose.map{|x| x + [x.reduce(:+)]}

Resources