# Newbie program

**URL:** <https://www.ruby-forum.com/t/newbie-program/95846>\
**Category:** Ruby\
**Created:** [June 15, 2006, 8:36pm UTC](https://www.ruby-forum.com/t/newbie-program/95846 "2006-06-15T20:36:24Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![Logesh\_Pillay](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/l/a8b319/32.png) [@Logesh\_Pillay](https://www.ruby-forum.com/u/Logesh_Pillay)\
**Post date:** [June 15, 2006, 8:36pm UTC](https://www.ruby-forum.com/t/newbie-program/95846/1 "2006-06-15T20:36:24Z")

</div>

I discovered Ruby this week. I was amazed at how easy it was to program  
in it without a book or any real manual.  
I’ve written the following program. It looks too much like the python  
original to be good idiomatic ruby. I’d appreciate suggestions how to  
improve it.  
Thanks.  
Logesh  
#returns the ways one can place n queens on a  
#chessboard of size n\*n so that no queen is attacking another  
#Ruby 1.8.3; 15 June 2006  
def nqueens  
$n = 8  
$board = [nil] \* ($n+1)  
def choose(k)  
if k \> $n  
print $board, “\n”  
else  
for i in 1…$n  
$board[k] = i  
choose(k + 1) if k == 1 or stillgood(k)  
end  
end  
end  
def stillgood(k)  
for i in 1…k  
return false if ($board[k] == $board[i]) or  
(k-i == ($board[k] - $board[i]).abs)  
end  
return true  
end  
end  
nqueens.choose(1)

---

<div class="post-metadata">

**Author:** ![Logesh\_Pillay](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/l/a8b319/32.png) [@Logesh\_Pillay](https://www.ruby-forum.com/u/Logesh_Pillay)\
**Post date:** [June 15, 2006, 11:08pm UTC](https://www.ruby-forum.com/t/newbie-program/95846/2 "2006-06-15T23:08:25Z")

</div>

On Jun 15, 2006, at 1:34 PM, Logesh Pillay wrote:

> I’d appreciate suggestions how to improve it.

Well, I’ve tried to Rubify the code a bit. I did these things;

- Stopped defining methods in methods.
- Used a class.
- Switched the global variables to instance variables.
- Used upto() iterators.
- Got rid of print().
- Made stillgood() method name more Rubish.
- Added the application code test at the end.

The thing I think you should still do:

- Pick more meaningful variable names than @n and k.

Here’s the code.

class NQueens  
def initialize  
@n = 8  
@board = [nil] \* (@n + 1)  
end

def choose(k)  
if k \> @n  
puts @board.join  
else  
1.upto(@n) do |i|  
@board[k] = i  
choose(k + 1) if k == 1 or still\_good?(k)  
end  
end  
end

def still\_good?(k)  
1.upto(k - 1) do |i|  
return false if (@board[k] == @board[i]) or  
(k-i == (@board[k] - @board[i]).abs)  
end  
true  
end  
end

if **FILE** == $PROGRAM\_NAME  
NQueens.new.choose(1)  
end

Hope that helps.

James Edward G. II

---

<div class="post-metadata">

**Author:** ![Logesh\_Pillay](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/l/a8b319/32.png) [@Logesh\_Pillay](https://www.ruby-forum.com/u/Logesh_Pillay)\
**Post date:** [June 15, 2006, 11:48pm UTC](https://www.ruby-forum.com/t/newbie-program/95846/3 "2006-06-15T23:48:51Z")

</div>

On Fri, 2006-06-16 at 06:05 +0900, James Edward G. II wrote:

> On Jun 15, 2006, at 1:34 PM, Logesh Pillay wrote:
> 
> > I’d appreciate suggestions how to improve it.
> 
> Well, I’ve tried to Rubify the code a bit.

If I could just make a couple of small extra suggestions,

> Here’s the code.
> 
> class NQueens

```
 class << self
   def choose(k)
     new.choose(k)
   end
 end

```

> ```
> @board[k] = i
> choose(k + 1) if k == 1 or still_good?(k)
> end
> end
> 
> ```
> 
> end

```
 # explicit returns are a pet peeve of mine :)
 def still_good(k)
   !(1...k).any? do |i|
     @board[k] == @board[i] or k-i == (@board[k] - @board[i]).abs
  end
end

```

> end
> 
> if **FILE** == $PROGRAM\_NAME  
> NQueens.choose(1)

---

<div class="post-metadata">

**Author:** ![Logesh\_Pillay](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/l/a8b319/32.png) [@Logesh\_Pillay](https://www.ruby-forum.com/u/Logesh_Pillay)\
**Post date:** [June 16, 2006, 3:49am UTC](https://www.ruby-forum.com/t/newbie-program/95846/4 "2006-06-16T03:49:39Z")

</div>

Just for another data point, here’s a version that I wrote ages ago  
that attempts to be as Ruby-ish as possible. The board is stored in  
such a way that a single line of Ruby can test if a new queen can be  
placed in a given square, and solutions are yielded to a block as  
they’re found. (Put a ‘break’ into the block if you only want the  
first solution.)

Pete Y.  
[http://9cays.com](http://9cays.com)

module Queens  
Queen = Struct.new(:x, :y)

class Board \< Array  
def to\_s  
map {|q| “.“_q.x + “X” + “.”_(size-q.x-1)}.join(”\n”) + “\n”  
end

```
 def add(*q)
   Board.new(self + q)
 end

```

end

def self.solve(size = 8, queens = Board.new, &block)  
if queens.size == size  
yield queens  
else  
y = queens.size  
for x in 0…size  
unless queens.any? {|q| x == q.x or (x-q.x).abs == (y-  
q.y).abs }  
solve(size, queens.add(Queen.new(x,y)), &block)  
end  
end  
end  
end

end

Queens::solve {|q| print q.to\_s, “\n” }
