Getting array index for non-zero elements

V

Victor Reyes

[Note: parts of this message were removed to make it a legal post.]

Team,

Given multi-dimension array @ga:

@ga = [
[0,0,0,0,1,9,0,4,0],
[0,0,4,8,0,0,6,0,0],
[7,5,0,0,0,0,0,0,2],
[0,9,0,1,0,2,0,0,4],
[0,0,0,0,0,3,0,0,0],
[5,0,0,4,0,6,0,3,0],
[8,0,0,0,0,0,0,7,3],
[0,0,6,0,0,8,4,0,0],
[0,1,0,2,9,0,0,0,0]
]

I am able to find then non-zero elements of a particular row:

# If r = 0
rowArr = @ga[r]
puts rowArr
# Output: 0 0 0 0 1 9 0 4 0

nonzeroElements = rowArr.find_all {|e| e > 0}
puts nonzeroElements #
Output: 1 9 4

However, I don't actually want the elements, I would like to get the index
of those non-zero elements. I tried the following but it fails:

nonzeroIndex = rowArr.index rowArr.find_all {|e| e > 0}
puts
nonzeroIndex #
Output: *nil*

Any help will be greatly appreciated, as usual!

Thank you

Victor
 
R

Rob Biedenharn

Team,

Given multi-dimension array @ga:

@ga = [
[0,0,0,0,1,9,0,4,0],
[0,0,4,8,0,0,6,0,0],
[7,5,0,0,0,0,0,0,2],
[0,9,0,1,0,2,0,0,4],
[0,0,0,0,0,3,0,0,0],
[5,0,0,4,0,6,0,3,0],
[8,0,0,0,0,0,0,7,3],
[0,0,6,0,0,8,4,0,0],
[0,1,0,2,9,0,0,0,0]
]

I am able to find then non-zero elements of a particular row:

# If r = 0
rowArr = @ga[r]
puts rowArr
# Output: 0 0 0 0 1 9 0 4 0

nonzeroElements = rowArr.find_all {|e| e > 0}
puts nonzeroElements #
Output: 1 9 4

However, I don't actually want the elements, I would like to get the
index
of those non-zero elements. I tried the following but it fails:

nonzeroIndex = rowArr.index rowArr.find_all {|e| e > 0}
puts
nonzeroIndex
#
Output: *nil*

Any help will be greatly appreciated, as usual!

Thank you

Victor



irb> require 'code/ruby/ext/enumerable.rb'
=> true
irb> @ga[0]
=> [0, 0, 0, 0, 1, 9, 0, 4, 0]
irb> @ga[0].map_with_index {|e,i| e.zero? ? nil : i}
=> [nil, nil, nil, nil, 4, 5, nil, 7, nil]
irb> @ga[0].map_with_index {|e,i| e.zero? ? nil : i}.compact
=> [4, 5, 7]

Then you just need Enumerable#map_with_index

module Enumerable
# Like each_with_index, but the value is the array of block results.
def map_with_index
a = []
each_with_index { |e,i| a << yield(e, i) }
a
end
end

-Rob

Rob Biedenharn http://agileconsultingllc.com
(e-mail address removed)
 
S

Stefano Crocco

However, I don't actually want the elements, I would like to get the index
of those non-zero elements. I tried the following but it fails:

=A0 =A0 =A0 =A0 =A0 nonzeroIndex =3D rowArr.index rowArr.find_all {|e| e =
0}
=A0 =A0 =A0 =A0 =A0 puts
nonzeroIndex =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =
=A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0#
Output: *nil*

Array#find_all returns an array containing all the elements for which the=20
block returns true. Since this array is not a member of rowArr, rowArr.inde=
x=20
returns nil.

The simplest way to achieve what you want, in my opinion, is the following:

require 'enumerator'

rowArr.enum_for:)each_index).find_all{|i| rowArr > 0}

This creates an Enumerator (see ri Enumerator and ri enum_for) whose 'each'=
=20
method calls rowArr.each_index instead rowArr.each. The block is thus passe=
d=20
the index of the elements instead of the elements themselves, and the array=
=20
returned by findAll will contain the indexes of the items greater than 0.

I hope this helps

Stefano
 
S

Siep Korteling

Rob said:
[5,0,0,4,0,6,0,3,0],
# Output: 0 0 0 0 1 9 0 4 0
puts
nonzeroIndex
#
Output: *nil*

Any help will be greatly appreciated, as usual!

Thank you

Victor



irb> require 'code/ruby/ext/enumerable.rb'
=> true
irb> @ga[0]
=> [0, 0, 0, 0, 1, 9, 0, 4, 0]
irb> @ga[0].map_with_index {|e,i| e.zero? ? nil : i}
=> [nil, nil, nil, nil, 4, 5, nil, 7, nil]
irb> @ga[0].map_with_index {|e,i| e.zero? ? nil : i}.compact
=> [4, 5, 7]

Then you just need Enumerable#map_with_index

module Enumerable
# Like each_with_index, but the value is the array of block results.
def map_with_index
a = []
each_with_index { |e,i| a << yield(e, i) }
a
end
end

-Rob

Rob Biedenharn http://agileconsultingllc.com
(e-mail address removed)

It works without the 'require' here.(VERSION=1.8.6). I like the
map_with_index method (new for me), but isn't it overkill here?

@ga.each do |sub_arr|
sub_arr.each_with_index do |value,index|
print index.to_s + " " unless value == 0
end
puts
end

Regards,

Siep
 
D

David A. Black

Hi --

Rob said:
[5,0,0,4,0,6,0,3,0],
# Output: 0 0 0 0 1 9 0 4 0
puts
nonzeroIndex
#
Output: *nil*

Any help will be greatly appreciated, as usual!

Thank you

Victor



irb> require 'code/ruby/ext/enumerable.rb'
=> true
irb> @ga[0]
=> [0, 0, 0, 0, 1, 9, 0, 4, 0]
irb> @ga[0].map_with_index {|e,i| e.zero? ? nil : i}
=> [nil, nil, nil, nil, 4, 5, nil, 7, nil]
irb> @ga[0].map_with_index {|e,i| e.zero? ? nil : i}.compact
=> [4, 5, 7]

Then you just need Enumerable#map_with_index

module Enumerable
# Like each_with_index, but the value is the array of block results.
def map_with_index
a = []
each_with_index { |e,i| a << yield(e, i) }
a
end
end

-Rob

Rob Biedenharn http://agileconsultingllc.com
(e-mail address removed)

It works without the 'require' here.(VERSION=1.8.6). I like the
map_with_index method (new for me), but isn't it overkill here?

@ga.each do |sub_arr|
sub_arr.each_with_index do |value,index|
print index.to_s + " " unless value == 0
end
puts
end

If all you need is side-effects, like printing, then you can used
#each (with_ or without index). #map_with_index, like #map itself,
returns a second collection.


David

--
Rails training from David A. Black and Ruby Power and Light:
INTRO TO RAILS June 9-12 Berlin
ADVANCING WITH RAILS June 16-19 Berlin
INTRO TO RAILS June 24-27 London (Skills Matter)
See http://www.rubypal.com for details and updates!
 
V

Victor Reyes

[Note: parts of this message were removed to make it a legal post.]

Hi Team,

First, thank you for all your replies. I truly appreciate each and everyone
of them!
Generally speaking I have problems explaining in writing an idea or what I
intent to do.
But, let me try to explain what I would like to do.

I am trying to implement a sudoku algorithm.
Given an initial set of values which I represent as the following example:

@ga = [
[0,0,0,0,1,9,0,4,0],
[0,0,4,8,0,0,6,0,0],
[7,5,0,0,0,0,0,0,2],
[0,9,0,1,0,2,0,0,4],
[0,0,0,0,0,3,0,0,0],
[5,0,0,4,0,6,0,3,0],
[8,0,0,0,0,0,0,7,3],
[0,0,6,0,0,8,4,0,0],
[0,1,0,2,9,0,0,0,0]
]

I use the above array to propagate the given values to a "master" array
which contains ALL the ORIGINAL valid and possible entries for a location.
At the start all numbers from 1..9:
@aa = [

[123456789,123456789,123456789,123456789,123456789,123456789,123456789,123456789,123456789],

[123456789,123456789,123456789,123456789,123456789,123456789,123456789,123456789,123456789],

[123456789,123456789,123456789,123456789,123456789,123456789,123456789,123456789,123456789],

[123456789,123456789,123456789,123456789,123456789,123456789,123456789,123456789,123456789],

[123456789,123456789,123456789,123456789,123456789,123456789,123456789,123456789,123456789],

[123456789,123456789,123456789,123456789,123456789,123456789,123456789,123456789,123456789],

[123456789,123456789,123456789,123456789,123456789,123456789,123456789,123456789,123456789],

[123456789,123456789,123456789,123456789,123456789,123456789,123456789,123456789,123456789],

[123456789,123456789,123456789,123456789,123456789,123456789,123456789,123456789,123456789]
]

But I don't want to propagate the zeroes (0) from the given array. I use
zeroes (0) for convenience only.
So, for instance, from the given array please notice that there is a one (1)
at location @ga = [0][4].
Knowing the index of that non-zero value (1 in this case) I would then use
the same index on the so called master array to place the 1.
I will then proceed to eliminate all the ones (1) from the same row and
column, since, as I am sure you know, the rule of sudoku only allows a
particular number once in a given row and column.

Well, that's why I need the index, so I can a bit easier manipulate the
arrays and their contents.

Again, thank you for all your help.

Victor


Hi --


On Apr 29, 2008, at 3:46 PM, Victor Reyes wrote:

[5,0,0,4,0,6,0,3,0],
# Output: 0 0 0 0 1 9 0 4 0
puts
nonzeroIndex
#
Output: *nil*

Any help will be greatly appreciated, as usual!

Thank you

Victor




irb> require 'code/ruby/ext/enumerable.rb'
=> true
irb> @ga[0]
=> [0, 0, 0, 0, 1, 9, 0, 4, 0]
irb> @ga[0].map_with_index {|e,i| e.zero? ? nil : i}
=> [nil, nil, nil, nil, 4, 5, nil, 7, nil]
irb> @ga[0].map_with_index {|e,i| e.zero? ? nil : i}.compact
=> [4, 5, 7]

Then you just need Enumerable#map_with_index

module Enumerable
# Like each_with_index, but the value is the array of block results.
def map_with_index
a = []
each_with_index { |e,i| a << yield(e, i) }
a
end
end

-Rob

Rob Biedenharn http://agileconsultingllc.com
(e-mail address removed)

It works without the 'require' here.(VERSION=1.8.6). I like the
map_with_index method (new for me), but isn't it overkill here?

@ga.each do |sub_arr|
sub_arr.each_with_index do |value,index|
print index.to_s + " " unless value == 0
end
puts
end

If all you need is side-effects, like printing, then you can used
#each (with_ or without index). #map_with_index, like #map itself,
returns a second collection.


David

--
Rails training from David A. Black and Ruby Power and Light:
INTRO TO RAILS June 9-12 Berlin
ADVANCING WITH RAILS June 16-19 Berlin
INTRO TO RAILS June 24-27 London (Skills Matter)
See http://www.rubypal.com for details and updates!
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,754
Messages
2,569,528
Members
45,000
Latest member
MurrayKeync

Latest Threads

Top