From: Robert Klemme Date: 2008-09-21T17:47:00+09:00 Subject: Re: Question about multi-demension hash initialization On 20.09.2008 21:30, Ruby Student wrote: > On Sat, Sep 20, 2008 at 10:47 AM, Robert Klemme > wrote: >> On 19.09.2008 20:21, Ruby Student 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. > 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. Me, too. ;-) 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 [](x,y) @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