```--Boundary_(ID_6svXY46JdpCkN+cKGpBBYA)
Content-type: text/plain; charset=ISO-8859-1; format=flowed
Content-transfer-encoding: 7BIT

This is my solution.  It makes use of my ArrayValue class which was
discussed on the list previously.  It calculate the placement of pieces
for a certain number without first calculating the placement of the
pieces for all numbers lower than it by using the following algorithm
(found at http://frcec.tripod.com/fischerrandomchessstartingpositions/):
1. id % 4 * 2  ight square bishop (counting left to right
2. (id / 4) % 4 * 2 + 1  ark square bishop ^ starting at 0)
3. (id / 4 / 6) % 6  ueen, number of vacant squares from the left
4. (id / 4 / 6)  eRN code of the other pieces (see the website for
more.  The KeRN codes do have a pattern but I hard coded it).

First, an explaination of the ArrayValue class.  The code is below:
daniel@daniel-desktop:~\$ cat arrayvalue.rb
class ArrayValue
instance_methods.each do |m|
undef_method(m) unless m
/^_*(method_missing|send|id)_*\$/
end

def initialize(origArray, origIndex)
@origArray, @origIndex  rigArray, origIndex
end

def set(newObj)
@origArray[@origIndex]  ewObj
end

def get
@origArray[@origIndex]
end

def method_missing(method, *args)
get.send(method, *args)
rescue
super
end

define_method(:' ) {|other| set(other)}
end

class Array
def to_av()
ret  ]
each_index {|x| ret << ArrayValue.new(self, x) }
ret
end
end

So, an ArrayValue stores the array and index it originally came from and
it can edit/get those values.  Otherwise, an ArrayValue inherits all of
the methods of the value it represents because of the method_missing
definition.  One thing missing from the ArrayValue class is what to do
if CRD (CRUD minus the U) operations are performed on the original
array.  Because of this, I recommend never actually storing an
ArrayValue but creating them again every time you need one.

Also, the array class is edited to provide a to_av method, which returns
an array of ArrayValues.  This is the only recommended way of creating
ArrayValues.

Note that Logan Capaldo wrote something with the same concept but that
uses some tricks with arrays and overriding [] o that calling
ArrayValue#Set is not necessary, you just go
ArrayOfArrayValues[0]mething and it changes the original array.

Some uses of ArrayValue:
daniel@daniel-desktop:~\$ irb -r arrayvalue.rb
irb(main):001:0> ary  1, 2, 3, "a", :b]
[1, 2, 3, "a", :b]
irb(main):002:0> ary.to_av[4].set("c")
"c"
irb(main):003:0> ary
[1, 2, 3, "a", "c"]
irb(main):005:0> ary.to_av.select{|x| x.kind_of?(Numeric)}.each{|x|
x.set(42)}
[42, 42, 42]
irb(main):006:0> ary
[42, 42, 42, "a", "c"]
irb(main):013:0> ary  "Skip me!", nil, nil, nil, 43]
["Skip me!", nil, nil, nil, 43]
irb(main):014:0> ary.to_av.select{|x| x.nil?}[1].set("The 2nd nil")
"The 2nd nil"
irb(main):015:0> ary
["Skip me!", nil, "The 2nd nil", nil, 43]

Now to the real code:
daniel@daniel-desktop:~\$ cat chess960short.rb
#! /usr/bin/ruby
require 'arrayvalue.rb'

KeRN  <-END.split("\n").collect{|x| x.split(" ")}
N N R K R
N R N K R
N R K N R
N R K R N
R N N K R
R N K N R
R N K R N
R K N N R
R K N R N
R K R N N
END

id  RGV[0].to_i % 960
out  rray.new(8)
1.downto(0) {|x| out[id % 4 *2 + x]  B"; id /  }
out.to_av.select{|x| x.nil?}[id % 6].set("Q"); id /
KeRN[id].each{ |currentPiece| out.to_av.select{|x|
x.nil?}.first.set(currentPiece) }

Another, commented and not written for brevity version will be posted
shortly.

Ruby Quiz wrote:
> The three rules of Ruby Quiz:
>
> 1.  Please do not post any solutions or spoiler discussion for this quiz until
> 48 hours have passed from the time on this message.
>
> 2.  Support Ruby Quiz by submitting ideas as often as you can:
>
> http://www.rubyquiz.com/
>
> 3.  Enjoy!
>
> Suggestion:  A [QUIZ] in the subject of emails about the problem helps everyone
> if you can.
>
> --------------------
>
> by Kieran Wild
>
> Chess960, is a chess variant produced by Grandmaster Bobby Fischer by
> formalizing the rules of Shuffle Chess. Its goal was to create a chess variant
> in which chess creativity and talent would be more important than memorization
> and analysis of opening moves. His approach was to create a randomized initial
> chess position, which would thus make memorizing chess opening move sequences
> far less helpful. The initial position is set up in a special way and there are
> 960 such positions, thus the name Chess960.
>
> The starting position for Chess960 must meet certain rules. White pawns are
> placed on the second rank as in chess. All remaining white pieces are placed
> randomly on the first rank, but with the following restrictions:
>
> 	* The king is placed somewhere between the two rooks.
> 	* The bishops are placed on opposite-colored squares.
>
> The black pieces are placed equal-and-opposite to the white pieces. For example,
> if the white king is placed on b1, then the black king is placed on b8. Note
> that the king never starts on file a or h, because there would be no room for a
> rook
>
> Can I suggest a nice little ruby program to generates all 960 possible starting
> positions and outputs a random one on request.
>
> Output could be as follows.
>
> 	Starting Position 432:
>
> 	White
>
> 	a1 b1 c1 d1 e1 f1 g1 h1
> 	N  B  B   R  K  R  Q  N
>
> 	Black
>
> 	a8 b8 c8 d8 e8 f8 g8 h8
> 	N  B  B   R  K  R  Q  N
>
> Or some better output.
>
>

--Boundary_(ID_6svXY46JdpCkN+cKGpBBYA)
Content-type: application/x-ruby; name=arrayvalue.rb
Content-transfer-encoding: base64
Content-disposition: inline; filename=arrayvalue.rb

Y2xhc3MgQXJyYXlWYWx1ZQoJaW5zdGFuY2VfbWV0aG9kcy5lYWNoIGRvIHxtfAoJCXVuZGVm
X21ldGhvZChtKSB1bmxlc3MgbSA9fiAvXl8qKG1ldGhvZF9taXNzaW5nfHNlbmR8aWQpXyok
LwoJZW5kCgkKCWRlZiBpbml0aWFsaXplKG9yaWdBcnJheSwgb3JpZ0luZGV4KQoJCUBvcmln
QXJyYXksIEBvcmlnSW5kZXggPSBvcmlnQXJyYXksIG9yaWdJbmRleAoJZW5kCgkKCWRlZiBz
ZXQobmV3T2JqKQoJCUBvcmlnQXJyYXlbQG9yaWdJbmRleF0gPSBuZXdPYmoKCWVuZAoJCglk
ZWYgZ2V0CgkJQG9yaWdBcnJheVtAb3JpZ0luZGV4XQoJZW5kCgkKCWRlZiBtZXRob2RfbWlz
c2luZyhtZXRob2QsICphcmdzKQoJCQlnZXQuc2VuZChtZXRob2QsICphcmdzKQoJCXJlc2N1
ZQoJCQlzdXBlcgoJZW5kCgkKCWRlZmluZV9tZXRob2QoOic9ICcpIHt8b3RoZXJ8IHNldChv
dGhlcil9CmVuZAoKY2xhc3MgQXJyYXkKCWRlZiB0b19hdigpCgkJcmV0ID0gW10KCQllYWNo
X2luZGV4IHt8eHwgcmV0IDw8IEFycmF5VmFsdWUubmV3KHNlbGYsIHgpIH0KCQlyZXQKCWVu
ZAplbmQKCl9fRU5EX18KJSBjYXQgdmlldy5yYgpjbGFzcyBBcnJheVZpZXcKICBjbGFzcyBB
cnJheUluZGV4UmVmCiAgICBkZWYgaW5pdGlhbGl6ZSggYXJyYXksIGluZGV4ICkKICAgICAg
QGFycmF5ID0gYXJyYXkKICAgICAgQGluZGV4ID0gaW5kZXgKICAgIGVuZAoKICAgIGRlZiB2
YWx1ZQogICAgICBAYXJyYXlbQGluZGV4XQogICAgZW5kCgogICAgZGVmIHZhbHVlPShuZXdf
dmFsdWUpCiAgICAgIEBhcnJheVtAaW5kZXhdID0gbmV3X3ZhbHVlCiAgICBlbmQKICBlbmQK
CiAgZGVmIGluaXRpYWxpemUoIGFycmF5ICkKICAgIEBhcnJheSA9IGFycmF5CiAgICBAcmVm
ZXJlbmNlcyA9IFtdCiAgZW5kCgogIGRlZiBbXSgqYXJncykKICAgIGlmIGFyZ3MubGVuZ3Ro
ID09IDEgYW5kIGFyZ3Mua2luZF9vZj8gUmFuZ2Ugb3IgYXJncy5sZW5ndGggPiAxCiAgICAg
IEByZWZlcmVuY2VzWyphcmdzXS5tYXAgeyB8eHwgeC52YWx1ZSB9CiAgICBlbHNlCiAgICAg
IEByZWZlcmVuY2VzWyphcmdzXS52YWx1ZQogICAgZW5kCiAgZW5kCgogIGRlZiBbXT0oaW5k
ZXgsIHZhbHVlKQogICAgQHJlZmVyZW5jZXNbaW5kZXhdLnZhbHVlID0gdmFsdWUKICBlbmQK
CiAgZGVmIGVhY2gKICAgIEByZWZlcmVuY2VzLmVhY2ggZG8gfHh8CiAgICAgIHlpZWxkIHgu
dmFsdWUKICAgIGVuZAogIGVuZAoKCiAgZGVmIGFkZF9yZWYoIGluZGV4ICkKICAgIEByZWZl
cmVuY2VzIDw8IEFycmF5SW5kZXhSZWYubmV3KCBAYXJyYXksIGluZGV4ICkKICBlbmQKZW5k
CgoKY2xhc3MgQXJyYXkKICBkZWYgc2VsZWN0X3ZpZXcKICAgIHIgPSBBcnJheVZpZXcubmV3
KCBzZWxmICkKICAgIGVhY2hfd2l0aF9pbmRleCBkbyB8aXRlbSwgaW5kZXh8CiAgICAgIHIu
YWRkX3JlZiggaW5kZXggKSBpZiB5aWVsZCggaXRlbSApICAgICBlbmQKICAgIHIKICBlbmQK
ZW5kCgphID0gKDEuLjEwKS50b19hCgpwIGEKYiA9IGEuc2VsZWN0X3ZpZXcgeyB8eHwgKHgg
JSAyKS56ZXJvPyB9CmJbMF0gPSA0MgpwIGEKCiUgcnVieSB2aWV3LnJiClsxLCAyLCAzLCA0
LCA1LCA2LCA3LCA4LCA5LCAxMF0KWzEsIDQyLCAzLCA0LCA1LCA2LCA3LCA4LCA5LCAxMF0g

--Boundary_(ID_6svXY46JdpCkN+cKGpBBYA)
Content-type: application/x-ruby; name=chess960short.rb
Content-transfer-encoding: base64
Content-disposition: inline; filename=chess960short.rb

IyEgL3Vzci9iaW4vcnVieQpyZXF1aXJlICdhcnJheXZhbHVlLnJiJwoKS2VSTiA9IDw8LUVO
RC5zcGxpdCgiXG4iKS5jb2xsZWN0e3x4fCB4LnNwbGl0KCIgIil9CglOIE4gUiBLIFIKCU4g
UiBOIEsgUgoJTiBSIEsgTiBSCglOIFIgSyBSIE4KCVIgTiBOIEsgUgoJUiBOIEsgTiBSCglS
IE4gSyBSIE4KCVIgSyBOIE4gUgoJUiBLIE4gUiBOCglSIEsgUiBOIE4KCUVORAoKaWQgPSBB
UkdWWzBdLnRvX2kgJSA5NjAKb3V0ID0gQXJyYXkubmV3KDgpCjEuZG93bnRvKDApIHt8eHwg
b3V0W2lkICUgNCAqMiArIHhdID0gIkIiOyBpZCAvPSA0IH0Kb3V0LnRvX2F2LnNlbGVjdHt8
eHwgeC5uaWw/fVtpZCAlIDZdLnNldCgiUSIpOyBpZCAvPSA2CktlUk5baWRdLmVhY2h7IHxj
dXJyZW50UGllY2V8IG91dC50b19hdi5zZWxlY3R7fHh8IHgubmlsP30uZmlyc3Quc2V0KGN1
cnJlbnRQaWVjZSkgfQpwdXRzIG91dC5qb2lu

--Boundary_(ID_6svXY46JdpCkN+cKGpBBYA)--

```