------ art_78371_25250453.1179662733670
Content-Type: text/plain; charset=ISO-8859-1; format=flowed
Content-Transfer-Encoding: 7bit
Content-Disposition: inline
Hi
here goes my solution for Ruby Quiz #124.
This was quite tough, firstly to find the algorithms and secondly to
write concise code that still runs not too slowly.
I have therefore adapted my original solution (which runs 30% faster
and still is attached to this mail) to something more "readable", well
it is up to you to judge that :).
I know this is not DRY, but politeness cannot be ;). Ty again for the
great effort Ruby Quiz is.
BTW is there a book to be published one day about Ruby Quiz?
Cheers
Robert
Usage <-EOS
usage:
ruby #{$0} [-t|--test] [-h|--html] <Square Order List>
Prints Magic Squares for all indicated orders.
Indicating -t also tests the results.
EOS
loop do
case ARGV.first
when "-t", "--test"
require 'test-squares'
ARGV.shift
when "-h", "--html"
require 'html-output'
ARGV.shift
when "-?", "--help", nil
puts Usage
exit
when "--"
ARGV.shift && break
else
break
end
end
class Array
def lpos; first end
def cpos; self[1] end
end
#
# This is a default output module, another output
# module called HTMLOutput is provided as an example
# how to pull in an appropriate Output module
# as plugin.
#
module Output
def to_s decoration alse
l @order*@order).to_s.size
return @data.map{ |line|
line.map{ |cell|
"%#{l}d" % cell
}.join(" ")
}.join("\n") unless decoration
sep_line +" << ( "-" * l.succ.succ << "+" ) * @order
sep_line.dup << "\n" <<
@data.map{ | line | "| " << line.map{ |cell| "%#{l}d" % cell
}.join(" | ") << " |" }.
zip( [sep_line] * @order ).flatten.join("\n")
end
end
#
# The usage of cursors is slowing down the program a little
# bit but I feel it is still fast enough.
#
class Cursor
attr_reader :cpos, :lpos
def initialize order, lpos, cpos
@order rder
@lpos pos
@cpos pos
end
def move ldelta, cdelta
l lpos + ldelta
c cpos + cdelta
l % order
c % order
self.class.new @order, l, c
end
def next!
s up
@cpos +
return s if @cpos < @order
@cpos
@lpos +
@lpos % order
s
end
end
#
# This is where the work is done, like
# testing and outputting and what was it?
# Ah yes storing the data.
#
class SquareData
include Output
include HTMLOutput rescue nil
include TestSquare rescue nil
def initialize order
@order rder
@data rray.new( @order ){ Array.new( @order ) { nil } }
end
def [](c); @data[c.lpos][c.cpos] end
def []
, v); @data[c.lpos][c.cpos] end
def each_subdiagonal
(@order/4).times do
| line |
(@order/4).times do
| col |
4.times do
| l |
4.times do
| c |
yield [ 4*line + l, 4*col + c ] if
l
|| l+c 3
end
end # 4.times do
end # (@order/4).times do
end # (@order/4).times do
end
def siamese_order
model elf.class.new @order
last order*@order
@pos ursor.new @order, 0, @order/2
yield @pos.lpos, @pos.cpos, self[@pos]
model[ @pos ] rue
2.upto last do
npos pos.move -1, +1
npos pos.move +1, 0 if model[ npos ]
model[ @pos pos ] rue
yield @pos.lpos, @pos.cpos, self[@pos]
end # @last.times do
end
end # class SquareData
#
# The base class for Magic Squares it basically
# is the result of factorizing the three classes
# representing the three differnt cases, odd, even and
# double even.
#
# It's singleton class is used as a class Factory for
# the three implementing classes.
#
class Square
def to_s decoration alse
@data.to_s decoration
end
private
def initialize order
@order rder.to_i
@last order*@order
@data quareData.new @order
compute
@data.test rescue nil
end
end
#
# The simplest case, the Siamese Order algorithm
# is applied.
#
class OddSquare < Square
private
def compute
count
@data.siamese_order do
| lpos, cpos, _ |
@data[[ lpos, cpos]] ount
count +
end # @data.siamese_order do
end
end # class OddSquare
#
# The Double Cross Algorithm is applied
# to double even Squares.
#
class DoubleCross < Square
def compute
pos ursor.new @order, 0, 0
1.upto( @last ) do
| n |
@data[ pos.next! ]
end # 1.upto( @last ) do
@data.each_subdiagonal do
| lidx, cidx |
@data[[ lidx, cidx ]] last.succ - @data[[lidx, cidx]]
end
end
end
#
# And eventually we use the LUX algorithm of Conway for even
# squares.
#
class FiatLux < Square
L [0, 1], [1, 0], [1, 1], [0, 0] ]
U [0, 0], [1, 0], [1, 1], [0, 1] ]
X [0, 0], [1, 1], [1, 0], [0, 1] ]
def compute
half order / 2
lux_data quareData.new half
n alf/2
pos ursor.new half, 0, 0
n.succ.times do
half.times do
lux_data[ pos.next! ]
end # half.times do
end # n.succ.times do
half.times do
lux_data[ pos.next! ]
end # half.times do
lux_data[[ n, n ]]
lux_data[[ n+1, n]]
2.upto(n) do
half.times do
lux_data[ pos.next! ]
end
end # 2.upto(half) do
count
lux_data.siamese_order do
| siam_row, siam_col, elem |
elem.each do
| r, c |
@data[[ 2*siam_row + r, 2*siam_col + c ]] ount
count +
end # elem.each do
end # lux_data.siamese_order do
end
end # class FiatLux
class << Square
#
# trying to call the ctors with consistent values only
#
protected :new
def Factory arg
arg rg.to_i
case arg % 4
when 1, 3
OddSquare.new arg
when 0
DoubleCross.new arg
else
FiatLux.new arg
end
end
end
ARGV.each do
|arg|
puts Square::Factory( arg ).to_s( true )
puts
end
------ art_78371_25250453.1179662733670
Content-Type: application/x-ruby; name=124-magic-square-readable.rb
Content-Transfer-Encoding: base64
X-Attachment-Id: f_f1xd0x0c
Content-Disposition: attachment; filename="124-magic-square-readable.rb"
IyB2aW06IHN0cz0yIHN3PTIgZnQ9cnVieSBleHBhbmR0YWIgbnUgdHc9MDoKVXNhZ2UgPSA8PC1F
T1MKICB1c2FnZToKICAgICAgcnVieSAjeyQwfSBbLXR8LS10ZXN0XSBbLWh8LS1odG1sXSA8U3F1
YXJlIE9yZGVyIExpc3Q+CgogICAgICBQcmludHMgTWFnaWMgU3F1YXJlcyBmb3IgYWxsIGluZGlj
YXRlZCBvcmRlcnMuCiAgICAgIEluZGljYXRpbmcgLXQgYWxzbyB0ZXN0cyB0aGUgcmVzdWx0cy4K
RU9TCmxvb3AgZG8KICBjYXNlIEFSR1YuZmlyc3QKICAgIHdoZW4gIi10IiwgIi0tdGVzdCIKICAg
ICAgcmVxdWlyZSAndGVzdC1zcXVhcmVzJwogICAgICBBUkdWLnNoaWZ0CiAgICB3aGVuICItaCIs
ICItLWh0bWwiCiAgICAgIHJlcXVpcmUgJ2h0bWwtb3V0cHV0JwogICAgICBBUkdWLnNoaWZ0CiAg
ICB3aGVuICItPyIsICItLWhlbHAiLCBuaWwKICAgICAgcHV0cyBVc2FnZQogICAgICBleGl0CiAg
ICB3aGVuICItLSIKICAgICAgQVJHVi5zaGlmdCAmJiBicmVhawogICAgZWxzZQogICAgICBicmVh
awogIGVuZAplbmQKCmNsYXNzIEFycmF5CiAgZGVmIGxwb3M7IGZpcnN0IGVuZAogIGRlZiBjcG9z
OyBzZWxmWzFdIGVuZAplbmQKIwojIFRoaXMgaXMgYSBkZWZhdWx0IG91dHB1dCBtb2R1bGUsIGFu
b3RoZXIgb3V0cHV0CiMgbW9kdWxlIGNhbGxlZCBIVE1MT3V0cHV0IGlzIHByb3ZpZGVkIGFzIGFu
IGV4YW1wbGUKIyBob3cgdG8gcHVsbCBpbiBhbiBhcHByb3ByaWF0ZSBPdXRwdXQgbW9kdWxlCiMg
YXMgcGx1Z2luLgojCm1vZHVsZSBPdXRwdXQKICBkZWYgdG9fcyBkZWNvcmF0aW9uID0gZmFsc2UK
ICAgIGwgPSAoQG9yZGVyKkBvcmRlcikudG9fcy5zaXplCiAgICByZXR1cm4gIEBkYXRhLm1hcHsg
fGxpbmV8CiAgICAgICAgICAgICAgICAgICAgICAgIGxpbmUubWFweyB8Y2VsbHwgIAogICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICIlI3tsfWQiICUgY2VsbCAKICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICB9LmpvaW4oIiAiKQogICAgICAgICAgICAgICAgICAgICAgfS5q
b2luKCJcbiIpIHVubGVzcyBkZWNvcmF0aW9uCgogICAgc2VwX2xpbmUgPSAiKyIgPDwgKCAiLSIg
KiBsLnN1Y2Muc3VjYyA8PCAiKyIgKSAqIEBvcmRlcgogICAgc2VwX2xpbmUuZHVwIDw8ICJcbiIg
PDwgCiAgICBAZGF0YS5tYXB7IHwgbGluZSB8ICJ8ICIgPDwgbGluZS5tYXB7IHxjZWxsfCAiJSN7
bH1kIiAlIGNlbGwgfS5qb2luKCIgfCAiKSA8PCAiIHwiIH0uCiAgICAgIHppcCggW3NlcF9saW5l
XSAqIEBvcmRlciApLmZsYXR0ZW4uam9pbigiXG4iKQogIGVuZAplbmQKCiMKIyBUaGUgdXNhZ2Ug
b2YgY3Vyc29ycyBpcyBzbG93aW5nIGRvd24gdGhlIHByb2dyYW0gYSBsaXR0bGUKIyBiaXQgYnV0
IEkgZmVlbCBpdCBpcyBzdGlsbCBmYXN0IGVub3VnaC4KIwpjbGFzcyBDdXJzb3IKICBhdHRyX3Jl
YWRlciA6Y3BvcywgOmxwb3MKICBkZWYgaW5pdGlhbGl6ZSBvcmRlciwgbHBvcywgY3BvcwogICAg
QG9yZGVyID0gb3JkZXIKICAgIEBscG9zICA9IGxwb3MKICAgIEBjcG9zICA9IGNwb3MKICBlbmQK
CiAgZGVmIG1vdmUgbGRlbHRhLCBjZGVsdGEKICAgIGwgPSBAbHBvcyArIGxkZWx0YQogICAgYyA9
IEBjcG9zICsgY2RlbHRhCiAgICBsICU9IEBvcmRlcgogICAgYyAlPSBAb3JkZXIKICAgIHNlbGYu
Y2xhc3MubmV3IEBvcmRlciwgbCwgYwogIGVuZAogIGRlZiBuZXh0IQogICAgIHMgPSBkdXAKICAg
ICBAY3BvcyArPSAxCiAgICAgcmV0dXJuIHMgaWYgQGNwb3MgPCBAb3JkZXIKICAgICBAY3BvcyA9
IDAKICAgICBAbHBvcyArPSAxCiAgICAgQGxwb3MgJT0gQG9yZGVyCiAgICAgcwogIGVuZAplbmQK
CiMKIyBUaGlzIGlzIHdoZXJlIHRoZSB3b3JrIGlzIGRvbmUsIGxpa2UKIyB0ZXN0aW5nIGFuZCBv
dXRwdXR0aW5nIGFuZCB3aGF0IHdhcyBpdD8KIyBBaCB5ZXMgc3RvcmluZyB0aGUgZGF0YS4KIwpj
bGFzcyBTcXVhcmVEYXRhCiAgaW5jbHVkZSBPdXRwdXQKICBpbmNsdWRlIEhUTUxPdXRwdXQgcmVz
Y3VlIG5pbAogIGluY2x1ZGUgVGVzdFNxdWFyZSByZXNjdWUgbmlsCiAgZGVmIGluaXRpYWxpemUg
b3JkZXIKICAgIEBvcmRlciA9IG9yZGVyCiAgICBAZGF0YSA9IEFycmF5Lm5ldyggQG9yZGVyICl7
IEFycmF5Lm5ldyggQG9yZGVyICkgeyBuaWwgfSB9CiAgZW5kCiAgCiAgZGVmIFtdKGMpOyBAZGF0
YVtjLmxwb3NdW2MuY3Bvc10gZW5kCiAgZGVmIFtdPShjLCB2KTsgQGRhdGFbYy5scG9zXVtjLmNw
b3NdID0gdiBlbmQKCiAgZGVmIGVhY2hfc3ViZGlhZ29uYWwKICAgIChAb3JkZXIvNCkudGltZXMg
ZG8KICAgICAgfCBsaW5lIHwKICAgICAgKEBvcmRlci80KS50aW1lcyBkbwogICAgICAgIHwgY29s
IHwKICAgICAgICA0LnRpbWVzIGRvCiAgICAgICAgICB8IGwgfAogICAgICAgICAgNC50aW1lcyBk
bwogICAgICAgICAgICB8IGMgfAogICAgICAgICAgICB5aWVsZCBbIDQqbGluZSArIGwsIDQqY29s
ICsgYyBdIGlmCiAgICAgICAgICAgIGw9PWMgfHwgbCtjID09IDMKICAgICAgICAgIGVuZAogICAg
ICAgIGVuZCAjIDQudGltZXMgZG8KICAgICAgZW5kICMgKEBvcmRlci80KS50aW1lcyBkbwogICAg
ZW5kICMgKEBvcmRlci80KS50aW1lcyBkbwogIGVuZAoKICBkZWYgc2lhbWVzZV9vcmRlcgogICAg
bW9kZWwgPSBzZWxmLmNsYXNzLm5ldyBAb3JkZXIKICAgIGxhc3QgPSBAb3JkZXIqQG9yZGVyCiAg
ICBAcG9zID0gQ3Vyc29yLm5ldyBAb3JkZXIsIDAsIEBvcmRlci8yCiAgICB5aWVsZCBAcG9zLmxw
b3MsIEBwb3MuY3Bvcywgc2VsZltAcG9zXQogICAgbW9kZWxbIEBwb3MgXSA9IHRydWUKICAgIDIu
dXB0byBsYXN0IGRvCiAgICAgIG5wb3MgPSBAcG9zLm1vdmUgLTEsICsxCiAgICAgIG5wb3MgPSBA
cG9zLm1vdmUgKzEsIDAgaWYgbW9kZWxbIG5wb3MgXQogICAgICBtb2RlbFsgQHBvcyA9IG5wb3Mg
XSA9IHRydWUKICAgICAgeWllbGQgQHBvcy5scG9zLCBAcG9zLmNwb3MsIHNlbGZbQHBvc10KICAg
IGVuZCAjIEBsYXN0LnRpbWVzIGRvCiAgZW5kCmVuZCAjIGNsYXNzIFNxdWFyZURhdGEKCiMKIyBU
aGUgYmFzZSBjbGFzcyBmb3IgTWFnaWMgU3F1YXJlcyBpdCBiYXNpY2FsbHkKIyBpcyB0aGUgcmVz
dWx0IG9mIGZhY3Rvcml6aW5nIHRoZSB0aHJlZSBjbGFzc2VzCiMgcmVwcmVzZW50aW5nIHRoZSB0
aHJlZSBkaWZmZXJudCBjYXNlcywgb2RkLCBldmVuIGFuZAojIGRvdWJsZSBldmVuLgojCiMgSXQn
cyBzaW5nbGV0b24gY2xhc3MgaXMgdXNlZCBhcyBhIGNsYXNzIEZhY3RvcnkgZm9yCiMgdGhlIHRo
cmVlIGltcGxlbWVudGluZyBjbGFzc2VzLgojCmNsYXNzIFNxdWFyZQoKICBkZWYgdG9fcyBkZWNv
cmF0aW9uID0gZmFsc2UKICAgIEBkYXRhLnRvX3MgZGVjb3JhdGlvbgogIGVuZAogIHByaXZhdGUK
ICBkZWYgaW5pdGlhbGl6ZSBvcmRlcgogICAgQG9yZGVyID0gb3JkZXIudG9faQogICAgQGxhc3Qg
PSBAb3JkZXIqQG9yZGVyCiAgICBAZGF0YSA9IFNxdWFyZURhdGEubmV3IEBvcmRlcgogICAgY29t
cHV0ZQogICAgQGRhdGEudGVzdCByZXNjdWUgbmlsCiAgZW5kCgplbmQKCiMKIyBUaGUgc2ltcGxl
c3QgY2FzZSwgdGhlIFNpYW1lc2UgT3JkZXIgYWxnb3JpdGhtCiMgaXMgYXBwbGllZC4KIwpjbGFz
cyBPZGRTcXVhcmUgPCBTcXVhcmUKCiAgcHJpdmF0ZQogIGRlZiBjb21wdXRlCiAgICBjb3VudCA9
IDEKICAgIEBkYXRhLnNpYW1lc2Vfb3JkZXIgZG8KICAgICAgfCBscG9zLCBjcG9zLCBfIHwKICAg
ICAgQGRhdGFbWyBscG9zLCBjcG9zXV0gPSBjb3VudAogICAgICBjb3VudCArPSAxCiAgICBlbmQg
IyBAZGF0YS5zaWFtZXNlX29yZGVyIGRvCiAgZW5kCgplbmQgIyBjbGFzcyBPZGRTcXVhcmUKCiMK
IyBUaGUgRG91YmxlIENyb3NzIEFsZ29yaXRobSBpcyBhcHBsaWVkCiMgdG8gZG91YmxlIGV2ZW4g
U3F1YXJlcy4KIwpjbGFzcyBEb3VibGVDcm9zcyA8IFNxdWFyZQogIGRlZiBjb21wdXRlCiAgICBw
b3MgPSBDdXJzb3IubmV3IEBvcmRlciwgMCwgMAogICAgMS51cHRvKCBAbGFzdCApIGRvCiAgICAg
IHwgbiB8CiAgICAgIEBkYXRhWyBwb3MubmV4dCEgXSA9IG4KICAgIGVuZCAjIDEudXB0byggQGxh
c3QgKSBkbwogICAgQGRhdGEuZWFjaF9zdWJkaWFnb25hbCBkbwogICAgICB8IGxpZHgsIGNpZHgg
fAogICAgICBAZGF0YVtbIGxpZHgsIGNpZHggXV0gPSBAbGFzdC5zdWNjIC0gQGRhdGFbW2xpZHgs
IGNpZHhdXQogICAgZW5kCgogIGVuZAplbmQKCiMKIyBBbmQgZXZlbnR1YWxseSB3ZSB1c2UgdGhl
IExVWCBhbGdvcml0aG0gb2YgQ29ud2F5IGZvciBldmVuIAojIHNxdWFyZXMuCiMKY2xhc3MgRmlh
dEx1eCA8IFNxdWFyZQogIEwgPSBbIFswLCAxXSwgWzEsIDBdLCBbMSwgMV0sIFswLCAwXSBdCiAg
VSA9IFsgWzAsIDBdLCBbMSwgMF0sIFsxLCAxXSwgWzAsIDFdIF0KICBYID0gWyBbMCwgMF0sIFsx
LCAxXSwgWzEsIDBdLCBbMCwgMV0gXQogIGRlZiBjb21wdXRlCiAgICBoYWxmID0gQG9yZGVyIC8g
MgogICAgbHV4X2RhdGEgPSBTcXVhcmVEYXRhLm5ldyBoYWxmCiAgICBuID0gaGFsZi8yCiAgICBw
b3MgPSBDdXJzb3IubmV3IGhhbGYsIDAsIDAKICAgIG4uc3VjYy50aW1lcyBkbyAKICAgICAgaGFs
Zi50aW1lcyBkbwogICAgICAgIGx1eF9kYXRhWyBwb3MubmV4dCEgXSA9IEwKICAgICAgZW5kICMg
aGFsZi50aW1lcyBkbwogICAgZW5kICMgbi5zdWNjLnRpbWVzIGRvCiAgICBoYWxmLnRpbWVzIGRv
IAogICAgICBsdXhfZGF0YVsgcG9zLm5leHQhIF0gPSBVCiAgICBlbmQgIyBoYWxmLnRpbWVzIGRv
IAogICAgbHV4X2RhdGFbWyBuLCBuIF1dID0gVQogICAgbHV4X2RhdGFbWyBuKzEsIG5dXSA9IEwK
ICAgIDIudXB0byhuKSBkbwogICAgICBoYWxmLnRpbWVzIGRvCiAgICAgICAgbHV4X2RhdGFbIHBv
cy5uZXh0ISBdID0gWAogICAgICBlbmQKICAgIGVuZCAjIDIudXB0byhoYWxmKSBkbwogICAKICAg
IGNvdW50ID0gMQogICAgbHV4X2RhdGEuc2lhbWVzZV9vcmRlciBkbwogICAgICB8IHNpYW1fcm93
LCBzaWFtX2NvbCwgZWxlbSB8CiAgICAgIGVsZW0uZWFjaCBkbwogICAgICAgIHwgciwgYyB8CiAg
ICAgICAgQGRhdGFbWyAyKnNpYW1fcm93ICsgciwgMipzaWFtX2NvbCArIGMgXV0gPSBjb3VudAog
ICAgICAgIGNvdW50ICs9IDEKICAgICAgZW5kICMgZWxlbS5lYWNoIGRvCiAgICBlbmQgIyBsdXhf
ZGF0YS5zaWFtZXNlX29yZGVyIGRvCiAgZW5kCmVuZCAjIGNsYXNzIEZpYXRMdXgKCmNsYXNzIDw8
IFNxdWFyZQogICMKICAjIHRyeWluZyB0byBjYWxsIHRoZSBjdG9ycyB3aXRoIGNvbnNpc3RlbnQg
dmFsdWVzIG9ubHkKICAjCiAgcHJvdGVjdGVkIDpuZXcKICBkZWYgRmFjdG9yeSBhcmcKICAgIGFy
ZyA9IGFyZy50b19pCiAgICBjYXNlIGFyZyAlIDQKICAgICAgd2hlbiAxLCAzCiAgICAgICAgT2Rk
U3F1YXJlLm5ldyBhcmcKICAgICAgd2hlbiAwCiAgICAgICAgRG91YmxlQ3Jvc3MubmV3IGFyZwog
ICAgICBlbHNlCiAgICAgICAgRmlhdEx1eC5uZXcgYXJnCiAgICBlbmQKICBlbmQKZW5kCkFSR1Yu
ZWFjaCBkbwogIHxhcmd8CiAgcHV0cyBTcXVhcmU6OkZhY3RvcnkoIGFyZyApLnRvX3MoIHRydWUg
KQogIHB1dHMKZW5kCgo------ art_78371_25250453.1179662733670
Content-Type: application/x-ruby; name=124-magic-square.rb
Content-Transfer-Encoding: base64
X-Attachment-Id: f_f1xd1kgn
Content-Disposition: attachment; filename="124-magic-square.rb"
IyB2aW06IHN0cz0yIHN3PTIgZnQ9cnVieSBleHBhbmR0YWIgbnUgdHc9MDoKVXNhZ2UgPSA8PC1F
T1MKICB1c2FnZToKICAgICAgcnVieSAjeyQwfSBbLXR8LS10ZXN0XSBbLWh8LS1odG1sXSA8U3F1
YXJlIE9yZGVyIExpc3Q+CgogICAgICBQcmludHMgTWFnaWMgU3F1YXJlcyBmb3IgYWxsIGluZGlj
YXRlZCBvcmRlcnMuCiAgICAgIEluZGljYXRpbmcgLXQgYWxzbyB0ZXN0cyB0aGUgcmVzdWx0cy4K
RU9TCmxvb3AgZG8KICBjYXNlIEFSR1YuZmlyc3QKICAgIHdoZW4gIi10IiwgIi0tdGVzdCIKICAg
ICAgcmVxdWlyZSAndGVzdC1zcXVhcmVzJwogICAgICBBUkdWLnNoaWZ0CiAgICB3aGVuICItaCIs
ICItLWh0bWwiCiAgICAgIHJlcXVpcmUgJ2h0bWwtb3V0cHV0JwogICAgICBBUkdWLnNoaWZ0CiAg
ICB3aGVuICItPyIsICItLWhlbHAiLCBuaWwKICAgICAgcHV0cyBVc2FnZQogICAgICBleGl0CiAg
ICB3aGVuICItLSIKICAgICAgQVJHVi5zaGlmdCAmJiBicmVhawogICAgZWxzZQogICAgICBicmVh
awogIGVuZAplbmQKCiMKIyBUaGlzIGlzIGEgZGVmYXVsdCBvdXRwdXQgbW9kdWxlLCBhbm90aGVy
IG91dHB1dAojIG1vZHVsZSBjYWxsZWQgSFRNTE91dHB1dCBpcyBwcm92aWRlZCBhcyBhbiBleGFt
cGxlCiMgaG93IHRvIHB1bGwgaW4gYW4gYXBwcm9wcmlhdGUgT3V0cHV0IG1vZHVsZQojIGFzIHBs
dWdpbi4KIwptb2R1bGUgT3V0cHV0CiAgZGVmIHRvX3MgZGVjb3JhdGlvbiA9IGZhbHNlCiAgICBs
ID0gKEBvcmRlcipAb3JkZXIpLnRvX3Muc2l6ZQogICAgcmV0dXJuICBAZGF0YS5tYXB7IHxsaW5l
fAogICAgICAgICAgICAgICAgICAgICAgICBsaW5lLm1hcHsgfGNlbGx8ICAKICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAiJSN7bH1kIiAlIGNlbGwgCiAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgfS5qb2luKCIgIikKICAgICAgICAgICAgICAgICAgICAgIH0uam9pbigi
XG4iKSB1bmxlc3MgZGVjb3JhdGlvbgoKICAgIHNlcF9saW5lID0gIisiIDw8ICggIi0iICogbC5z
dWNjLnN1Y2MgPDwgIisiICkgKiBAb3JkZXIKICAgIHNlcF9saW5lLmR1cCA8PCAiXG4iIDw8IAog
ICAgQGRhdGEubWFweyB8IGxpbmUgfCAifCAiIDw8IGxpbmUubWFweyB8Y2VsbHwgIiUje2x9ZCIg
JSBjZWxsIH0uam9pbigiIHwgIikgPDwgIiB8IiB9LgogICAgICB6aXAoIFtzZXBfbGluZV0gKiBA
b3JkZXIgKS5mbGF0dGVuLmpvaW4oIlxuIikKICBlbmQKZW5kCgojCiMgVGhlIHVzYWdlIG9mIGN1
cnNvcnMgaXMgc2xvd2luZyBkb3duIHRoZSBwcm9ncmFtIGEgbGl0dGxlCiMgYml0IGJ1dCBJIGZl
ZWwgaXQgaXMgc3RpbGwgZmFzdCBlbm91Z2guCiMKY2xhc3MgQ3Vyc29yCiAgYXR0cl9yZWFkZXIg
OmNwb3MsIDpscG9zCiAgZGVmIGluaXRpYWxpemUgb3JkZXIsIGxwb3MsIGNwb3MKICAgIEBvcmRl
ciA9IG9yZGVyCiAgICBAbHBvcyAgPSBscG9zCiAgICBAY3BvcyAgPSBjcG9zCiAgZW5kCgogIGRl
ZiBtb3ZlIGxkZWx0YSwgY2RlbHRhCiAgICBsID0gQGxwb3MgKyBsZGVsdGEKICAgIGMgPSBAY3Bv
cyArIGNkZWx0YQogICAgbCAlPSBAb3JkZXIKICAgIGMgJT0gQG9yZGVyCiAgICBzZWxmLmNsYXNz
Lm5ldyBAb3JkZXIsIGwsIGMKICBlbmQKICBkZWYgbmV4dCEKICAgICBAY3BvcyArPSAxCiAgICAg
cmV0dXJuIGlmIEBjcG9zIDwgQG9yZGVyCiAgICAgQGNwb3MgPSAwCiAgICAgQGxwb3MgKz0gMQog
ICAgIEBscG9zICU9IEBvcmRlcgogIGVuZAplbmQKCiMKIyBUaGlzIGlzIHdoZXJlIHRoZSB3b3Jr
IGlzIGRvbmUsIGxpa2UKIyB0ZXN0aW5nIGFuZCBvdXRwdXR0aW5nIGFuZCB3aGF0IHdhcyBpdD8K
IyBBaCB5ZXMgc3RvcmluZyB0aGUgZGF0YS4KIwpjbGFzcyBTcXVhcmVEYXRhCiAgaW5jbHVkZSBP
dXRwdXQKICBpbmNsdWRlIEhUTUxPdXRwdXQgcmVzY3VlIG5pbAogIGluY2x1ZGUgVGVzdFNxdWFy
ZSByZXNjdWUgbmlsCiAgZGVmIGluaXRpYWxpemUgb3JkZXIKICAgIEBvcmRlciA9IG9yZGVyCiAg
ICBAZGF0YSA9IEFycmF5Lm5ldyggQG9yZGVyICl7IEFycmF5Lm5ldyggQG9yZGVyICkgeyBuaWwg
fSB9CiAgZW5kCiAgCiAgZGVmIHBlZWsoaSwgaik7IEBkYXRhW2ldW2pdIGVuZAogIGRlZiBwb2tl
KGksIGosIHYpOyBAZGF0YVtpXVtqXSA9IHYgZW5kCiAgZGVmIFtdKGMpOyBAZGF0YVtjLmxwb3Nd
W2MuY3Bvc10gZW5kCiAgZGVmIFtdPShjLCB2KTsgQGRhdGFbYy5scG9zXVtjLmNwb3NdID0gdiBl
bmQKCiAgZGVmIGVhY2hfc3ViZGlhZ29uYWwKICAgIChAb3JkZXIvNCkudGltZXMgZG8KICAgICAg
fCBsaW5lIHwKICAgICAgKEBvcmRlci80KS50aW1lcyBkbwogICAgICAgIHwgY29sIHwKICAgICAg
ICA0LnRpbWVzIGRvCiAgICAgICAgICB8IGwgfAogICAgICAgICAgNC50aW1lcyBkbwogICAgICAg
ICAgICB8IGMgfAogICAgICAgICAgICB5aWVsZCBbIDQqbGluZSArIGwsIDQqY29sICsgYyBdIGlm
CiAgICAgICAgICAgIGw9PWMgfHwgbCtjID09IDMKICAgICAgICAgIGVuZAogICAgICAgIGVuZCAj
IDQudGltZXMgZG8KICAgICAgZW5kICMgKEBvcmRlci80KS50aW1lcyBkbwogICAgZW5kICMgKEBv
cmRlci80KS50aW1lcyBkbwogIGVuZAoKICBkZWYgc2lhbWVzZV9vcmRlcgogICAgbW9kZWwgPSBz
ZWxmLmNsYXNzLm5ldyBAb3JkZXIKICAgIGxhc3QgPSBAb3JkZXIqQG9yZGVyCiAgICBAcG9zID0g
Q3Vyc29yLm5ldyBAb3JkZXIsIDAsIEBvcmRlci8yCiAgICB5aWVsZCBAcG9zLmxwb3MsIEBwb3Mu
Y3BvcywgcGVlayggQHBvcy5scG9zLCBAcG9zLmNwb3MgKQogICAgbW9kZWxbIEBwb3MgXSA9IHRy
dWUKICAgIDIudXB0byBsYXN0IGRvCiAgICAgIG5wb3MgPSBAcG9zLm1vdmUgLTEsICsxCiAgICAg
IG5wb3MgPSBAcG9zLm1vdmUgKzEsIDAgaWYgbW9kZWxbIG5wb3MgXQogICAgICBtb2RlbFsgQHBv
cyA9IG5wb3MgXSA9IHRydWUKICAgICAgeWllbGQgQHBvcy5scG9zLCBAcG9zLmNwb3MsIHBlZWso
IEBwb3MubHBvcywgQHBvcy5jcG9zICkKICAgIGVuZCAjIEBsYXN0LnRpbWVzIGRvCiAgZW5kCmVu
ZCAjIGNsYXNzIFNxdWFyZURhdGEKCiMKIyBUaGUgYmFzZSBjbGFzcyBmb3IgTWFnaWMgU3F1YXJl
cyBpdCBiYXNpY2FsbHkKIyBpcyB0aGUgcmVzdWx0IG9mIGZhY3Rvcml6aW5nIHRoZSB0aHJlZSBj
bGFzc2VzCiMgcmVwcmVzZW50aW5nIHRoZSB0aHJlZSBkaWZmZXJudCBjYXNlcywgb2RkLCBldmVu
IGFuZAojIGRvdWJsZSBldmVuLgojIEl0J3Mgc2luZ2xldG9uIGNsYXNzIGlzIHVzZWQgYXMgYSBj
bGFzcyBGYWN0b3J5IGZvcgojIHRoZSB0aHJlZSBpbXBsZW1lbnRpbmcgY2xhc3Nlcy4KIwpjbGFz
cyBTcXVhcmUKCiAgZGVmIHRvX3MgZGVjb3JhdGlvbiA9IGZhbHNlCiAgICBAZGF0YS50b19zIGRl
Y29yYXRpb24KICBlbmQKICBwcml2YXRlCiAgZGVmIGluaXRpYWxpemUgb3JkZXIKICAgIEBvcmRl
ciA9IG9yZGVyLnRvX2kKICAgIEBsYXN0ID0gQG9yZGVyKkBvcmRlcgogICAgQGRhdGEgPSBTcXVh
cmVEYXRhLm5ldyBAb3JkZXIKICAgIGNvbXB1dGUKICAgIEBkYXRhLnRlc3QgcmVzY3VlIG5pbAog
IGVuZAoKZW5kCgojCiMgVGhlIHNpbXBsZXN0IGNhc2UsIHRoZSBTaWFtZXNlIE9yZGVyIGFsZ29y
aXRobQojIGlzIGFwcGxpZWQuCiMKY2xhc3MgT2RkU3F1YXJlIDwgU3F1YXJlCgogIHByaXZhdGUK
ICBkZWYgY29tcHV0ZQogICAgQHBvcyA9IEN1cnNvci5uZXcgQG9yZGVyLCAwLCBAb3JkZXIvMgog
ICAgQGRhdGFbIEBwb3MgXSA9IDEgCiAgICAyLnVwdG8gQGxhc3QgZG8KICAgICAgfCBuIHwKICAg
ICAgbnBvcyA9IEBwb3MubW92ZSAtMSwgKzEKICAgICAgbnBvcyA9IEBwb3MubW92ZSArMSwgMCBp
ZiBAZGF0YVsgbnBvcyBdCiAgICAgIEBkYXRhWyBAcG9zID0gbnBvcyBdID0gbgogICAgZW5kICMg
QGxhc3QudGltZXMgZG8KICBlbmQKCmVuZCAjIGNsYXNzIE9kZFNxdWFyZQoKIwojIFRoZSBEb3Vi
bGUgQ3Jvc3MgQWxnb3JpdGhtIGlzIGFwcGxpZWQKIyB0byBkb3VibGUgZXZlbiBTcXVhcmVzLgoj
CmNsYXNzIERvdWJsZUNyb3NzIDwgU3F1YXJlCiAgZGVmIGNvbXB1dGUKICAgIHBvcyA9IEN1cnNv
ci5uZXcgQG9yZGVyLCAwLCAwCiAgICAxLnVwdG8oIEBsYXN0ICkgZG8KICAgICAgfCBuIHwKICAg
ICAgQGRhdGFbIHBvcyBdID0gbgogICAgICBwb3MubmV4dCEKICAgIGVuZCAjIDEudXB0byggQGxh
c3QgKSBkbwogICAgQGRhdGEuZWFjaF9zdWJkaWFnb25hbCBkbwogICAgICB8IGxpZHgsIGNpZHgg
fAogICAgICBAZGF0YS5wb2tlIGxpZHgsIGNpZHgsIEBsYXN0LnN1Y2MgLSBAZGF0YS5wZWVrKCBs
aWR4LCBjaWR4ICkKICAgIGVuZAoKICBlbmQKZW5kCgojCiMgQW5kIGV2ZW50dWFsbHkgd2UgdXNl
IHRoZSBMVVggYWxnb3JpdGhtIG9mIENvbndheSBmb3IgZXZlbiAKIyBzcXVhcmVzLgojCmNsYXNz
IEZpYXRMdXggPCBTcXVhcmUKICBMID0gWyBbMCwgMV0sIFsxLCAwXSwgWzEsIDFdLCBbMCwgMF0g
XQogIFUgPSBbIFswLCAwXSwgWzEsIDBdLCBbMSwgMV0sIFswLCAxXSBdCiAgWCA9IFsgWzAsIDBd
LCBbMSwgMV0sIFsxLCAwXSwgWzAsIDFdIF0KICBkZWYgY29tcHV0ZQogICAgaGFsZiA9IEBvcmRl
ciAvIDIKICAgIGx1eF9kYXRhID0gU3F1YXJlRGF0YS5uZXcgaGFsZgogICAgbiA9IGhhbGYvMgog
ICAgcG9zID0gQ3Vyc29yLm5ldyBoYWxmLCAwLCAwCiAgICBuLnN1Y2MudGltZXMgZG8gCiAgICAg
IGhhbGYudGltZXMgZG8KICAgICAgICBsdXhfZGF0YVsgcG9zIF0gPSBMCiAgICAgICAgcG9zLm5l
eHQhCiAgICAgIGVuZCAjIGhhbGYudGltZXMgZG8KICAgIGVuZCAjIG4uc3VjYy50aW1lcyBkbwog
ICAgaGFsZi50aW1lcyBkbyAKICAgICAgbHV4X2RhdGFbIHBvcyBdID0gVQogICAgICBwb3MubmV4
dCEKICAgIGVuZCAjIGhhbGYudGltZXMgZG8gCiAgICBsdXhfZGF0YS5wb2tlIG4sIG4sIFUKICAg
IGx1eF9kYXRhLnBva2UgbisxLCBuLCBMCiAgICAyLnVwdG8obikgZG8KICAgICAgaGFsZi50aW1l
cyBkbwogICAgICAgIGx1eF9kYXRhWyBwb3MgXSA9IFgKICAgICAgICBwb3MubmV4dCEKICAgICAg
ZW5kCiAgICBlbmQgIyAyLnVwdG8oaGFsZikgZG8KICAgCiAgICBjb3VudCA9IDEKICAgIGx1eF9k
YXRhLnNpYW1lc2Vfb3JkZXIgZG8KICAgICAgfCBzaWFtX3Jvdywgc2lhbV9jb2wsIGVsZW0gfAog
ICAgICBlbGVtLmVhY2ggZG8KICAgICAgICB8IHIsIGMgfAogICAgICAgIEBkYXRhLnBva2UgMipz
aWFtX3JvdyArIHIsIDIqc2lhbV9jb2wgKyBjLCBjb3VudAogICAgICAgIGNvdW50ICs9IDEKICAg
ICAgZW5kICMgZWxlbS5lYWNoIGRvCiAgICBlbmQgIyBsdXhfZGF0YS5zaWFtZXNlX29yZGVyIGRv
CiAgZW5kCmVuZCAjIGNsYXNzIEZpYXRMdXgKCmNsYXNzIDw8IFNxdWFyZQogICMKICAjIHRyeWlu
ZyB0byBjYWxsIHRoZSBjdG9ycyB3aXRoIGNvbnNpc3RlbnQgdmFsdWVzIG9ubHkKICAjCiAgcHJv
dGVjdGVkIDpuZXcKICBkZWYgRmFjdG9yeSBhcmcKICAgIGFyZyA9IGFyZy50b19pCiAgICBjYXNl
IGFyZyAlIDQKICAgICAgd2hlbiAxLCAzCiAgICAgICAgT2RkU3F1YXJlLm5ldyBhcmcKICAgICAg
d2hlbiAwCiAgICAgICAgRG91YmxlQ3Jvc3MubmV3IGFyZwogICAgICBlbHNlCiAgICAgICAgRmlh
dEx1eC5uZXcgYXJnCiAgICBlbmQKICBlbmQKZW5kCkFSR1YuZWFjaCBkbwogIHxhcmd8CiAgcHV0
cyBTcXVhcmU6OkZhY3RvcnkoIGFyZyApLnRvX3MoIHRydWUgKQogIHB1dHMKZW5kCgo------ art_78371_25250453.1179662733670
Content-Type: application/x-ruby; name=test-squares.rb
Content-Transfer-Encoding: base64
X-Attachment-Id: f_f1xd1vdn
Content-Disposition: attachment; filename="test-squares.rb"
IyB2aW06IHN0cz0yIHN3PTIgZnQ9cnVieSBleHBhbmR0YWIgbnUgdHc9MDoKCm1vZHVsZSBUZXN0
U3F1YXJlCiAgZGVmIGFzc2VydCBjZHQsIG1zZwogICAgcmV0dXJuICRzdGRlcnIucHV0cyggIiN7
bXNnfSAuIC4gLiAuIC4gb2siICkgaWYgY2R0CiAgICByYWlzZSBFeGNlcHRpb24sIG1zZyA8PCAi
XG4iIDw8IHRvX3MKICBlbmQKICBkZWYgdGVzdAogICAgZGlhMSA9IGRpYTIgPSAwCiAgICBAb3Jk
ZXIudGltZXMgZG8KICAgICAgfCBpZHggfAogICAgICBkaWExICs9IHBlZWsoIGlkeCwgaWR4ICkK
ICAgICAgZGlhMiArPSBwZWVrKCBpZHgsIC1pZHguc3VjYyApCiAgICBlbmQgIyBAbGluZXMuZWFj
aF93aXRoX2luZGV4IGRvCiAgICBhc3NlcnQgZGlhMT09ZGlhMiwgIkJvdGggZGlhZ29uYWxzIgog
ICAgQG9yZGVyLnRpbWVzIGRvIAogICAgICB8IGlkeDEgfAogICAgICBjb2xfbiA9IHJvd19uID0g
MAogICAgICBAb3JkZXIudGltZXMgZG8gCiAgICAgICAgfCBpZHgyIHwKICAgICAgICBjb2xfbiAr
PSBwZWVrIGlkeDIsIGlkeDEKICAgICAgICByb3dfbiArPSBwZWVrIGlkeDEsIGlkeDIKICAgICAg
ZW5kCiAgICAgIGFzc2VydCBkaWExID09IGNvbF9uLCAiQ29sICN7aWR4MX0iCiAgICAgIGFzc2Vy
dCBkaWExID09IHJvd19uLCAiUm93ICN7aWR4MX0iCiAgICBlbmQgIyBAbGluZXMuZWFjaF93aXRo
X2luZGV4IGRvCiAgZW5kICMgZGVmIHRlc3QKCiAgZGVmIGlzX29rPwogICAgZGlhMSA9IGRpYTIg
PSAwCiAgICBAb3JkZXIudGltZXMgZG8KICAgICAgfCBpZHggfAogICAgICBkaWExICs9IHBlZWso
IGlkeCwgaWR4ICkKICAgICAgZGlhMiArPSBwZWVrKCBpZHgsIC1pZHguc3VjYyApCiAgICBlbmQg
IyBAbGluZXMuZWFjaF93aXRoX2luZGV4IGRvCiAgICByZXR1cm4gZmFsc2UgdW5sZXNzIGRpYTE9
PWRpYTIKICAgIEBvcmRlci50aW1lcyBkbyAKICAgICAgfCBpZHgxIHwKICAgICAgY29sX24gPSBy
b3dfbiA9IDAKICAgICAgQG9yZGVyLnRpbWVzIGRvIAogICAgICAgIHwgaWR4MiB8CiAgICAgICAg
Y29sX24gKz0gcGVlayBpZHgyLCBpZHgxCiAgICAgICAgcm93X24gKz0gcGVlayBpZHgxLCBpZHgy
CiAgICAgIGVuZAogICAgICByZXR1cm4gZmFsc2UgdW5sZXNzIGRpYTEgPT0gY29sX24KICAgICAg
cmV0dXJuIGZhbHNlIHVubGVzcyBkaWExID09IHJvd19uCiAgICBlbmQgIyBAbGluZXMuZWFjaF93
aXRoX2luZGV4IGRvCiAgICB0cnVlCiAgICAKICBlbmQKCmVuZAo------ art_78371_25250453.1179662733670
Content-Type: application/x-ruby; name=html-output.rb
Content-Transfer-Encoding: base64
X-Attachment-Id: f_f1xd23gi
Content-Disposition: attachment; filename="html-output.rb"
IyB2aW06IHN0cz0yIHN3PTIgZnQ9cnVieSBleHBhbmR0YWIgbnUgdHc9MDoKbW9kdWxlIEhUTUxP
dXRwdXQKICBkZWYgdG9fcyBkZWNvcmF0aW9uID0gZmFsc2UKICAgICV7PGgxPkEgTWFnaWMgU3F1
YXJlIG9mIG9yZGVyICN7QG9yZGVyfTwvaDE+CiAgICA8dGFibGUje2RlY29yYXRpb24gPyAiIGJv
cmRlcj1cIjFcIiI6IiJ9IGNsYXNzPSJtYWdpYy1zcXVhcmUiPlxufSA8PAogICAgICAgIEBkYXRh
Lm1hcHsgfGxpbmV8CiAgICAgICAgICAgICAgICAgICAgICAgICV7ICAgPHRyPlxufSA8PCBsaW5l
Lm1hcHsgfGNlbGx8ICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAleyAgICAg
IDx0ZD4lZDwvdGQ+fSAlIGNlbGwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfS5q
b2luKCJcbiIpIDw8ICV7XG4gICAgICA8L3RyPn0KICAgICAgICAgICAgICAgICAgICAgIH0uam9p
bigiXG4iKSA8PCAiXG48L3RhYmxlPiIgCiAgZW5kCmVuZAo------ art_78371_25250453.1179662733670--