Forum: Ruby Fwd: Sudoku

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
James G. (Guest)
on 2005-12-30 16:17
(Received via mailing list)
Begin forwarded message:

> From: NILSSON Christer <removed_email_address@domain.invalid>
> Date: December 30, 2005 4:09:59 AM CST
> To: James Edward G. II <removed_email_address@domain.invalid>
> Subject: Re: Ruby Q. Suggestion
> Reply-To: NILSSON Christer <removed_email_address@domain.invalid>
>
> Hello James!

[snip]

> I found a short solution for Sudoku. It was originally written by
> Kevin Greer in JavaScript, but Ruby makes it look even nicer. I
> haven't seen the use of this data structure in Sudoku before.

[snip]
Craig D. (Guest)
on 2005-12-30 17:18
(Received via mailing list)
Greetings,

While it may be true that the Sudoku program below looks nicer in
Ruby than JavaScript, I don't find it very readable. Sure, it's
concise, but that doesn't help me understand it. The variable names
are horrible. As I learn Ruby, I'm seeing more and more of this poor
naming, favoring conciseness so much over clarity that some code
samples are outright frustrating to read for this "nuby." I hope that
I'm just stumbling on some bad examples and not the norm. I hope that
the more Ruby code I read, the more I'll find a pragmatic compromise
between conciseness and clarity.

Regards,
Craig
Christer N. (Guest)
on 2005-12-30 18:20
Craig D. wrote:
> The variable names are horrible.

Yes, you are correct. This is puzzle code, not production code. So part
of this is being puzzled! :-)

Joke aside, I considered using better variable names instead of a,b,c
and d, but did not find good candidates. Let me explain:

a, c = row.divmod(3) # row in 0..8
b, d = col.divmod(3) # col in 0..8

Maybe a=rowMajor, c=rowMinor, b=colMajor and d=colMinor would be more
helpful.

Fixing rowMajor and colMajor gives a 3x3 block:
  s[rowMajor][colMajor][x][y], x in 0..2, y in 0..2
Fixing rowMajor and rowMinor gives a row
  s[rowMajor][x][rowMinor][y]
Fixing colMajor and colMinor gives a column
  s[x][colMajor][y][colMinor]

I hope this clarifies the code.

Christer
Dirk M. (Guest)
on 2005-12-30 21:17
(Received via mailing list)
2005/12/30, Craig D. removed_email_address@domain.invalid:
>
> While it may be true that the Sudoku program below looks nicer in
> Ruby than JavaScript, I don't find it very readable. Sure, it's
> concise, but that doesn't help me understand it.


i wouldn't call it concise, it simply doesn't work.. probably an error
in
porting to Ruby..
the idea of simply going through every number and checking possibility
is
nice, but not enough, because a lot of numbers might fit, though only
one
will get you the proper solution.
Christer N. (Guest)
on 2005-12-30 21:29
Dirk M. wrote:
> i wouldn't call it concise, it simply doesn't work.. probably an error
> in porting to Ruby..

It works. This is the complete code.
Christer

# Author: Kevin Greer (JavaScript),   Date: Dec 25, 2005  --  Copyright
2005, All Rights Reserved
# Rewritten in Ruby by Christer N. 2005-12-29

class Sudoku

  def initialize s
    @s=s
  end

  def display
    for a in 0..2
      for b in 0..2
        for c in 0..2
          for d in 0..2
            print " " + @s[a][b][c][d].to_s
          end
			    print " |" if c<2
        end
        print "\n"
      end
      print "-------+-------+-------\n" if a<2
    end
  end

  def solve a, b, c, d
    return true if a==3
    return solve(a+1, 0, c, d) if b==3
    return solve(a, b+1, 0, d) if c==3
    return solve(a, b, c+1, 0) if d==3
    return solve(a, b, c, d+1) if @s[a][b][c][d]!=0

    for digit in 1..9
      if not occupied?(a, b, c, d, digit) then
        @s[a][b][c][d] = digit
        return true if solve(a, b, c, d+1)
        @s[a][b][c][d] = 0
      end
    end
    false
  end

  def occupied? a, b, c, d, digit
    for x in 0..2
      for y in 0..2
        return true if @s[a][b][x][y]==digit # block
        return true if @s[a][x][c][y]==digit # row
        return true if @s[x][b][y][d]==digit # column
      end
    end
    false
  end
end

s =
 [[[[0,0,0],[0,7,1],[0,0,5]],
   [[5,0,0],[0,6,9],[0,7,1]],
   [[0,7,1],[8,5,3],[4,2,0]]],
  [[[0,1,0],[0,0,2],[0,0,0]],
   [[7,8,0],[1,5,4],[0,9,2]],
   [[0,4,0],[3,6,0],[1,8,0]]],
  [[[0,6,4],[0,2,3],[0,5,0]],
   [[9,0,5],[0,1,0],[0,0,0]],
   [[7,0,0],[5,9,0],[0,0,0]]]]
sudoku = Sudoku.new(s)
sudoku.display
print "\nsolving...\n\n"
if sudoku.solve(0,0,0,0) then
  sudoku.display
end


 0 0 0 | 0 7 1 | 0 0 5
 5 0 0 | 0 6 9 | 0 7 1
 0 7 1 | 8 5 3 | 4 2 0
-------+-------+-------
 0 1 0 | 0 0 2 | 0 0 0
 7 8 0 | 1 5 4 | 0 9 2
 0 4 0 | 3 6 0 | 1 8 0
-------+-------+-------
 0 6 4 | 0 2 3 | 0 5 0
 9 0 5 | 0 1 0 | 0 0 0
 7 0 0 | 5 9 0 | 0 0 0

solving...

 2 3 9 | 4 7 1 | 6 8 5
 5 4 8 | 2 6 9 | 3 7 1
 6 7 1 | 8 5 3 | 4 2 9
-------+-------+-------
 5 1 6 | 8 9 2 | 3 4 7
 7 8 3 | 1 5 4 | 6 9 2
 9 4 2 | 3 6 7 | 1 8 5
-------+-------+-------
 1 6 4 | 7 2 3 | 9 5 8
 9 2 5 | 8 1 6 | 4 3 7
 7 3 8 | 5 9 4 | 2 1 6

Program exited with code 0
Christer N. (Guest)
on 2005-12-30 21:31
Link to the original Javascript code by Kevin Greer:

http://www.peerbox.com:8668/space/start/2005-12-5/...

Christer
Christer N. (Guest)
on 2005-12-30 21:32
=?UTF-8?B?U2ltb24gS3LDtmdlcg==?= (Guest)
on 2005-12-30 21:50
(Received via mailing list)
Christer N. wrote:
> 2005, All Rights Reserved
>       for b in 0..2
>   end
>         @s[a][b][c][d] = digit
>         return true if @s[a][b][x][y]==digit # block
>    [[5,0,0],[0,6,9],[0,7,1]],
> if sudoku.solve(0,0,0,0) then
>  0 4 0 | 3 6 0 | 1 8 0
> -------+-------+-------
>  5 1 6 | 8 9 2 | 3 4 7
>  7 8 3 | 1 5 4 | 6 9 2
>  9 4 2 | 3 6 7 | 1 8 5
> -------+-------+-------
>  1 6 4 | 7 2 3 | 9 5 8
>  9 2 5 | 8 1 6 | 4 3 7
>  7 3 8 | 5 9 4 | 2 1 6
>
> Program exited with code 0

First Column has two 9's !

cheers

Simon
Dirk M. (Guest)
on 2005-12-30 22:27
(Received via mailing list)
>
> First Column has two 9's !


and it leaves my tests with zero's..
greetings, Dirk.
Christer N. (Guest)
on 2005-12-30 22:38
> First Column has two 9's !
> cheers
> Simon

Excellent observation, Simon!

The error is in the display definition:
-            print " " + @s[a][b][c][d].to_s
+            print " " + @s[a][c][b][d].to_s

New output:

 2 3 9 | 5 4 8 | 6 7 1
 4 7 1 | 2 6 9 | 8 5 3
 6 8 5 | 3 7 1 | 4 2 9
-------+-------+-------
 5 1 6 | 7 8 3 | 9 4 2
 8 9 2 | 1 5 4 | 3 6 7
 3 4 7 | 6 9 2 | 1 8 5
-------+-------+-------
 1 6 4 | 9 2 5 | 7 3 8
 7 2 3 | 8 1 6 | 5 9 4
 9 5 8 | 4 3 7 | 2 1 6

Sorry, I shouldn't have opened that bottle of champagne yet!

Christer
Christer N. (Guest)
on 2005-12-30 22:40
Dirk M. wrote:
> and it leaves my tests with zero's..
> greetings, Dirk.

Would you mind sending me your input, Dirk?

Christer
Dirk M. (Guest)
on 2005-12-30 23:21
(Received via mailing list)
Christer N. <removed_email_address@domain.invalid>:
>
> Would you mind sending me your input, Dirk?


it seems this was also a problem with the arrays,
i had entered the puzzle from left to right, i just found out it had to
be
done one block at the time..
anyway, sorry for the fuzz ;-)
greetings, Dirk.
This topic is locked and can not be replied to.