On Sunday 06 April 2008, Victor Reyes wrote:
> Team,
>
> I am trying to print the content of array, which is "addressed?" by a
> variable.
> Instead of getting the content of the array, I am getting its name.
> I think it is better to take a look at the code bellow.
PLEEEEEEEEEEEEEASE
> Do not laugh at my code, I'm still a beginner!
>
> For example, for array @a1h, I expected to see: 1,0,0,0,7,0,0,0,4 but
> instead I see: @a1h.
>
> class SudokuBrute
> def initialize
>
> # The following sudoku is from:
> http://www.life.com/Life/sudoku/0,26379,,00.html
> # This puzzle is rated as: easy
> @a1h = [1,0,0,0,7,0,0,0,4]
> @a2h = [0,0,0,6,0,4,0,5,0]
> @a3h = [0,0,8,0,9,0,0,0,0]
> @a4h = [6,0,0,9,0,0,0,1,5]
> @a5h = [0,1,9,0,0,0,7,4,0]
> @a6h = [5,3,0,0,0,1,0,0,8]
> @a7h = [0,0,0,0,4,0,3,0,0]
> @a8h = [0,7,0,5,0,8,0,0,0]
> @a9h = [4,0,0,0,6,0,0,0,1]
> end # End method initialize
>
> def pGrid
> for
> x in 1…9 do
> for
> i in 1…9 do
> arr = "@a" + i.to_s + "h"
> puts arr
> end
> end
> end # End of method pGrid
> end # End Class
>
> class Array
> include Comparable
> end
>
> ##################
> ms = SudokuBrute.new
>
> # Output initial settings
> ms.pGrid
Well, it's doing what you're asking it to do. arr is not an array, it's a
string like "@a1h". To achieve what you want, you can use
instance_variable_get, which returns the content of the instance variable
whose name is passed as argument:
arr = "@a" + i.to_s + "h"
puts instance_variable_get(arr)
The above suggestion works and only requires a small change in your code.
Most
likely, though, you should rethink the design of your class, replacing the
nine instance variables with a single hash or array variable, like this:
@a = {
:a1h => [1,0,0,0,7,0,0,0,4],
:a2h => [0,0,0,6,0,4,0,5,0],
:a3h => [0,0,8,0,9,0,0,0,0],
:a4h => [6,0,0,9,0,0,0,1,5],
:a5h => [0,1,9,0,0,0,7,4,0],
:a6h => [5,3,0,0,0,1,0,0,8],
:a7h => [0,0,0,0,4,0,3,0,0],
:a8h => [0,7,0,5,0,8,0,0,0],
:a9h => [4,0,0,0,6,0,0,0,1]
}
This stores the content of the grid into a hash, where each entry
represents a
row. The keys are symbols (you can replace them with strings, if you like)
and
correspond to the names you gave to your instance variables. You can
access a
row with:
row = @a[:a3h]
The downside of using a hash is that entries aren't ordered. If you need
to
iterate on all the rows in order, this isn't the best solution. In this
case,
I'd use an array:
@a = [
[1,0,0,0,7,0,0,0,4],
[0,0,0,6,0,4,0,5,0],
[0,0,8,0,9,0,0,0,0],
[6,0,0,9,0,0,0,1,5],
[0,1,9,0,0,0,7,4,0],
[5,3,0,0,0,1,0,0,8],
[0,0,0,0,4,0,3,0,0],
[0,7,0,5,0,8,0,0,0],
[4,0,0,0,6,0,0,0,1]
]
This way, rows can be accessed sequentially in the correct order, using
@a.each or the for ... in syntax you used above . You can also access them
using the [] syntax:
@a[3]
The downside is that you can no longer associate a key with the items.
I hope this helps
Stefano