Question about multi-demension hash initialization

Team,
Is there a quick (perhaps one liner) way to initialize the following
hashes
into just one hash?

def xwing(ia)

p ia

puts " "
p @xwing

r1 = {“1” => 0, “2” => 0, “3” => 0, “4” => 0, “5” => 0, “6” => 0, “7”
=>
0, “8” => 0, “9” => 0}
r2 = {“1” => 0, “2” => 0, “3” => 0, “4” => 0, “5” => 0, “6” => 0, “7”
=>
0, “8” => 0, “9” => 0}
r3 = {“1” => 0, “2” => 0, “3” => 0, “4” => 0, “5” => 0, “6” => 0, “7”
=>
0, “8” => 0, “9” => 0}
r4 = {“1” => 0, “2” => 0, “3” => 0, “4” => 0, “5” => 0, “6” => 0, “7”
=>
0, “8” => 0, “9” => 0}
r5 = {“1” => 0, “2” => 0, “3” => 0, “4” => 0, “5” => 0, “6” => 0, “7”
=>
0, “8” => 0, “9” => 0}
r6 = {“1” => 0, “2” => 0, “3” => 0, “4” => 0, “5” => 0, “6” => 0, “7”
=>
0, “8” => 0, “9” => 0}
r7 = {“1” => 0, “2” => 0, “3” => 0, “4” => 0, “5” => 0, “6” => 0, “7”
=>
0, “8” => 0, “9” => 0}
r8 = {“1” => 0, “2” => 0, “3” => 0, “4” => 0, “5” => 0, “6” => 0, “7”
=>
0, “8” => 0, “9” => 0}
r9 = {“1” => 0, “2” => 0, “3” => 0, “4” => 0, “5” => 0, “6” => 0, “7”
=>
0, “8” => 0, “9” => 0}

end

(0…8).each do |r|
xwing(@xwing[[r][0]]) # @xwing is defined previously
end

Actually, I wanted just one hash, @frequency, but I did not know how to
do
it.

Thank you

Ruby student

On 19.09.2008 20:21, Ruby S. wrote:

puts " "
r5 = {“1” => 0, “2” => 0, “3” => 0, “4” => 0, “5” => 0, “6” => 0, “7” =>
end

(0…8).each do |r|
xwing(@xwing[[r][0]]) # @xwing is defined previously
end

Actually, I wanted just one hash, @frequency, but I did not know how to do
it.

Err, what? You know how to create nine hashes but you do not know how
to create one? I’m suspecting that there is something missing from your
posting.

Maybe you wanted something like this:

irb(main):004:0> require ‘pp’
=> true
irb(main):005:0> pp Array.new(9) { Hash[*(1…9).map
{|i|[i.to_s,0]}.flatten] }
[{“6”=>0, “7”=>0, “8”=>0, “9”=>0, “1”=>0, “2”=>0, “3”=>0, “4”=>0,
“5”=>0},
{“6”=>0, “7”=>0, “8”=>0, “9”=>0, “1”=>0, “2”=>0, “3”=>0, “4”=>0,
“5”=>0},
{“6”=>0, “7”=>0, “8”=>0, “9”=>0, “1”=>0, “2”=>0, “3”=>0, “4”=>0,
“5”=>0},
{“6”=>0, “7”=>0, “8”=>0, “9”=>0, “1”=>0, “2”=>0, “3”=>0, “4”=>0,
“5”=>0},
{“6”=>0, “7”=>0, “8”=>0, “9”=>0, “1”=>0, “2”=>0, “3”=>0, “4”=>0,
“5”=>0},
{“6”=>0, “7”=>0, “8”=>0, “9”=>0, “1”=>0, “2”=>0, “3”=>0, “4”=>0,
“5”=>0},
{“6”=>0, “7”=>0, “8”=>0, “9”=>0, “1”=>0, “2”=>0, “3”=>0, “4”=>0,
“5”=>0},
{“6”=>0, “7”=>0, “8”=>0, “9”=>0, “1”=>0, “2”=>0, “3”=>0, “4”=>0,
“5”=>0},
{“6”=>0, “7”=>0, “8”=>0, “9”=>0, “1”=>0, “2”=>0, “3”=>0, “4”=>0,
“5”=>0}]
=> nil
irb(main):006:0>

However, given the structure of your Hashes I wonder why you do not want
to use Arrays instead. E.g.

irb(main):001:0> pp Array.new(9) { Array.new(9, 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, 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, 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, 0, 0, 0, 0]]
=> nil

Or even use a Matrix.

irb(main):006:0> require ‘matrix’
=> true
irb(main):007:0> pp Matrix.zero 9
Matrix[[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, 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, 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, 0, 0, 0]]
=> nil
irb(main):008:0> pp Matrix.zero(9).to_a
[[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, 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, 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, 0, 0, 0]]
=> nil
irb(main):009:0>

Kind regards

robert

On Sat, Sep 20, 2008 at 10:47 AM, Robert K.
[email protected]wrote:

def xwing(ia)
r3 = {“1” => 0, “2” => 0, “3” => 0, “4” => 0, “5” => 0, “6” => 0, “7” =>
0, “8” => 0, “9” => 0}

irb(main):004:0> require ‘pp’
{“6”=>0, “7”=>0, “8”=>0, “9”=>0, “1”=>0, “2”=>0, “3”=>0, “4”=>0, “5”=>0},
[0, 0, 0, 0, 0, 0, 0, 0, 0],
irb(main):006:0> require ‘matrix’
[0, 0, 0, 0, 0, 0, 0, 0, 0],
Kind regards

   robert

Robert,
First, thank you for your help and sample code.

What I need to do is to pass an integer compose of minimum 2 digits and
maximum of 8 and count the how many time a digit appears.
For example, I have a multidimensional array (9x9), which I then take
each
row and each column at a time.

For instance, the following are two rows extracted from the 9x9 array:

r1 = [345, 8, 459, 125679, 123, 45679, 379, 679, 79]
r8 = [9, 4, 6789, 356, 1, 357, 2356, 257, 67]

So, for row r1:
1s = 2, 2s = 2, 3s = 3, 4s = 3, 5s = 4, 6s = 3, 7s = 5, 8s = 1, 9s = 6

The same reasoning follows for r8.
So the 9x9 hash represents the 9x9 array for Sudoku, but instead of
representing a Sudoku element, the key = the number while the value is
the
count (frequency) of that key.
I am not sure if I am explaining myself clearly.

I need this information in order to successfully implement one of the
Sudoku
rules, the so called x-wing rule, which explanation can be found at:
http://www.sudokuoftheday.com/pages/techniques-8.php

I can find my way around with arrays, but with hashes I am not familiar
at
all.

Again, thank you for your help.

Ruby S.

On 20.09.2008 21:30, Ruby S. wrote:

On Sat, Sep 20, 2008 at 10:47 AM, Robert K.
[email protected]wrote:

On 19.09.2008 20:21, Ruby S. wrote:
First, thank you for your help and sample code.

You’re welcome.

What I need to do is to pass an integer compose of minimum 2 digits and
maximum of 8 and count the how many time a digit appears.

That’s easy.

irb(main):006:0> i = rand 100000000
=> 3976173
irb(main):007:0> h = Hash.new 0
=> {}
irb(main):008:0> i.to_s(10).scan(/\d/) {|dg| h[dg] += 1}
=> “3976173”
irb(main):009:0> h
=> {“6”=>1, “7”=>2, “9”=>1, “1”=>1, “3”=>2}
irb(main):010:0>

For example, I have a multidimensional array (9x9), which I then take each
row and each column at a time.

This is a two dimensional Array.

representing a Sudoku element, the key = the number while the value is the
count (frequency) of that key.
I am not sure if I am explaining myself clearly.

Me, too. :wink: Given the fact that you are dealing with Sudoku it is a
complete mystery to me why you want to count “digits”. It seems, a
Sudoku can have numbers in all locations and you want to make sure
that no number appears twice in a row and in a column. Basically there
are many ways to do this, one would be a bit set (you can use an integer
for that, see at end).

I need this information in order to successfully implement one of the Sudoku
rules, the so called x-wing rule, which explanation can be found at:
http://www.sudokuoftheday.com/pages/techniques-8.php

I can find my way around with arrays, but with hashes I am not familiar at
all.

Since you are indexing by number (or more precisely: digit) anyway what
do you gain by using a Hash?

Cheers

robert

A half baked example to illustrate what I mean with the bit set check:

#!/bin/env ruby

require ‘pp’

class Sudoku
def initialize(size)
raise ArgumentError unless 2 <= size
@size = size
@dat = Array.new(size * size)
@rows = Array.new(size, 0)
@cols = Array.new(size, 0)
end

def
@dat[pos(x,y)]
end

def []=(x,y,v)
raise “Not allowed” if @rows[x][v] == 1 || @cols[y][v] == 1
@dat[pos(x,y)] = v
@rows[x] |= 1 << v
@cols[y] |= 1 << v
end

def to_s
s = “”
@size.times do |i|
s << “[” << @dat[i * @size, @size].join(", ") << “]\n”
end
s
end

private
def pos(x,y)
raise ArgumentError unless [x,y].all? {|a| Integer === a}
x * @size + y
end
end

s = Sudoku.new 9

s[2,0] = 1
puts s

s[1,0] = 1

On Sun, Sep 21, 2008 at 4:47 AM, Robert K.
[email protected]wrote:

You’re welcome.
=> {}
This is a two dimensional Array.

So the 9x9 hash represents the 9x9 array for Sudoku, but instead of

you gain by using a Hash?
require ‘pp’
def
def to_s
x * @size + y
Robert,
Again, thanks a bunch.
You have given me enough material for a good few days to digest.
I’ll play and learn from your sample code.

Thanks again,

Ruby S.