------art_17535_22666276.1188802265486
Content-Type: text/plain; charset=ISO-8859-1
Content-Transfer-Encoding: 7bit
Content-Disposition: inline

On 8/31/07, Ruby Quiz <james / grayproductions.net> wrote:
> This week's task is to implement the Rope data structure as a Ruby class.

My implementation is attached along with a modified test.  I made a
few changes to what was asked, but this also gave more flexibility.
Here is what I did:

* Just as the implementation in the paper referenced in this quiz, my
implementation gives immutable ropes.  #<< is non-destructive, so I
had to change the test to do << nstead of just <<.  Also, I didn't
implement #shift, because it must be destructive.  The same
functionality can be achieved with 2 calls to #slice (one could be #at
if you only need to shift one element).  There are very good reasons
to make ropes immutable.  I'd imagine almost every other
implementation with modifiable ropes will fail when someone starts
modifying a sub-rope that is shared.  You'd really need a good COW
(copy-on-write) scheme to allow both transparent sharing and
modification.  I didn't see that it was worth the
effort/complexity/risk.  I chose the simple functional programming
approach (immutable objects).

* I chose to automatically balance the ropes during concatenation (no
normalize).  I used the same tree rotations that are used with AVL
trees.  Another option could be to treat these as red-black trees
which might save on some rotations.  One reason I automatically
balanced is that it simplifies the interface.  The user of the API
doesn't have to worry about when to normalize.  A second reason is
that every other rope operation is O(log(n)), so there probably isn't
much benefit in making only concatenation O(1).

* I don't allow ropes to directly use Strings.  Instead, a StringRope
is used as a proxy for a String.  To use a String directly, I would
have had to check the class, use respond_to, modify String to look
like a rope, etc.  Instead, I just went with the pure duck-typing
approach and made multiple Rope-like classes that use different types
of data.  My basis for these is the class ArrayRope.  There is no
reason why a rope data-structure can't be used with any sequence of
objects instead of just characters.  ArrayRope takes an Array-like
object.  An rope built out of these is to Array as a conventional rope
is to String.  I also added an IORope class to lazily work with files.
 Using IORope you could make a text editor that didn't have to read
the whole file in at once.  There is no reason you can't mix and match
any of these leaf rope classes (depth 0) within a rope tree.

* #each iterates through elements (i.e. characters) in the rope.  It
annoys me that String#each (and IO#each for that matter) iterates over
lines - it should be characters (not necessarily bytes).  All of the
Enumerable methods are accessible too.

* I used #at instead of #index because #index is used for searching in
String/Array.  Array#at is an exact match.

The main thing I didn't do was implement any regex stuff.  I don't see
how this is doable since all of the regex methods are completely tied
to String (not duck-typed).  You'd have to convert the whole rope to
string to do anything (which defeats the purpose of the rope).

------art_17535_22666276.1188802265486
Content-Type: application/x-ruby; name=quiz137.rb
Content-Transfer-Encoding: base64
X-Attachment-Id: f_f64jpfn2
Content-Disposition: attachment; filename="quiz137.rb"

CmNsYXNzIFJvcGUKICAgIGluY2x1ZGUgRW51bWVyYWJsZQogICAgIyBmb3JtIGEgYmluYXJ5IHRy
ZWUgZnJvbSB0d28gcm9wZXMgKHBvc3NpYmx5IHN1Yi10cmVlcykKICAgIGRlZiBpbml0aWFsaXpl
KGxlZnQscmlnaHQpCiAgICAgICAgQGxlZnQgPSBsZWZ0CiAgICAgICAgQHJpZ2h0ID0gcmlnaHQK
ICAgICAgICBAbGxlbmd0aCA9IEBsZWZ0Lmxlbmd0aAogICAgICAgIEBsZW5ndGggPSBAbGxlbmd0
aCtAcmlnaHQubGVuZ3RoCiAgICAgICAgQGRlcHRoID0gW2xlZnQuZGVwdGgsIHJpZ2h0LmRlcHRo
XS5tYXgrMQogICAgZW5kCiAgICAjIG51bWJlciBvZiBlbGVtZW50cyBpbiB0aGlzIHJvcGUKICAg
IGRlZiBsZW5ndGgKICAgICAgICBAbGVuZ3RoCiAgICBlbmQKICAgICMgZGVwdGggb2YgdGhlIHRy
ZWUgKHRvIGhlbHAga2VlcCB0aGUgdHJlZSBiYWxhbmNlZCkKICAgIGRlZiBkZXB0aAogICAgICAg
IEBkZXB0aAogICAgZW5kCiAgICAjIGxlZnQgcm9wZSAobm90IG5lZWRlZCB3aGVuIGRlcHRoPT0w
KQogICAgZGVmIGxlZnQKICAgICAgICBAbGVmdAogICAgZW5kCiAgICAjIHJpZ2h0IHJvcGUgKG5v
dCBuZWVkZWQgd2hlbiBkZXB0aD09MCkKICAgIGRlZiByaWdodAogICAgICAgIEByaWdodAogICAg
ZW5kCiAgICAjIGFwcGVuZGVkIHJvcGUgKG5vbi1tb2RpZnlpbmcpCiAgICBkZWYgPDwob3RoZXIp
CiAgICAgICAgIyBiYWxhbmNlIGFzIGFuIEFWTCB0cmVlCiAgICAgICAgYmFsYW5jZSA9IG90aGVy
LmRlcHRoLUBkZXB0aAogICAgICAgIGlmIGJhbGFuY2U+KzEKICAgICAgICAgICAgbGVmdCA9IG90
aGVyLmxlZnQKICAgICAgICAgICAgcmlnaHQgPSBvdGhlci5yaWdodAogICAgICAgICAgICBpZiBs
ZWZ0LmRlcHRoPnJpZ2h0LmRlcHRoCiAgICAgICAgICAgICAgICAjIHJvdGF0ZSBvdGhlciB0byBy
aWdodCBiZWZvcmUgcm90YXRpbmcgc2VsZitvdGhlciB0byBsZWZ0CiAgICAgICAgICAgICAgICAo
c2VsZiA8PCBsZWZ0LmxlZnQpIDw8IChsZWZ0LnJpZ2h0IDw8IHJpZ2h0KQogICAgICAgICAgICBl
bHNlCiAgICAgICAgICAgICAgICAjIHJvdGF0ZSBzZWxmK290aGVyIHRvIGxlZnQKICAgICAgICAg
ICAgICAgIChzZWxmIDw8IGxlZnQpIDw8IHJpZ2h0CiAgICAgICAgICAgIGVuZAogICAgICAgIGVs
c2lmIGJhbGFuY2U8LTEKICAgICAgICAgICAgaWYgQHJpZ2h0LmRlcHRoPkBsZWZ0LmRlcHRoCiAg
ICAgICAgICAgICAgICAjIHJvdGF0ZSBzZWxmIHRvIGxlZnQgYmVmb3JlIHJvdGF0aW5nIHNlbGYr
b3RoZXIgdG8gcmlnaHQKICAgICAgICAgICAgICAgIChAbGVmdCA8PCBAcmlnaHQubGVmdCkgPDwg
KEByaWdodC5yaWdodCA8PCBvdGhlcikKICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAg
IyByb3RhdGUgc2VsZitvdGhlciB0byByaWdodAogICAgICAgICAgICAgICAgQGxlZnQgPDwgKEBy
aWdodCA8PCBvdGhlcikKICAgICAgICAgICAgZW5kCiAgICAgICAgIyB1bmNvbW1lbnQgdGhpcyB0
byBhbGxvdyBzaG9ydCBzdHJpbmdzIHRvIGNvbmNhdCBmbGF0CiAgICAgICAgI2Vsc2lmIG90aGVy
LmRlcHRoLnplcm8/CiAgICAgICAgIyAgICAjIGFsbG93IEByaWdodCBhbmQgb3RoZXIgdG8gYmUg
bWVyZ2VkICh3aGVuIHRoZSBsZW5ndGggaXMgc2hvcnQpCiAgICAgICAgIyAgICBAbGVmdCA8PCAo
QHJpZ2h0IDw8IG90aGVyKQogICAgICAgIGVsc2UKICAgICAgICAgICAgc2VsZi5jbGFzcy5uZXco
c2VsZiwgb3RoZXIpCiAgICAgICAgZW5kCiAgICBlbmQKICAgICMgc2xpY2Ugb2YgdGhlIHJvcGUK
ICAgIGRlZiBzbGljZShzdGFydCwgbGVuKQogICAgICAgIHJldHVybiBzZWxmIGlmIHN0YXJ0Lnpl
cm8/IGFuZCBsZW49PUBsZW5ndGgKICAgICAgICByc3RhcnQgPSBzdGFydC1AbGxlbmd0aAogICAg
ICAgIHJldHVybiBAcmlnaHQuc2xpY2UocnN0YXJ0LCBsZW4pIGlmIHJzdGFydD4wCiAgICAgICAg
bGxlbiA9IEBsbGVuZ3RoLXN0YXJ0CiAgICAgICAgcmxlbiA9IGxlbi1sbGVuCiAgICAgICAgaWYg
cmxlbj4wCiAgICAgICAgICAgIEBsZWZ0LnNsaWNlKHN0YXJ0LCBsbGVuKSA8PCBAcmlnaHQuc2xp
Y2UoMCwgcmxlbikKICAgICAgICBlbHNlCiAgICAgICAgICAgIEBsZWZ0LnNsaWNlKHN0YXJ0LCBs
ZW4pCiAgICAgICAgZW5kCiAgICBlbmQKICAgICMgZWxlbWVudCBhdCBhIGNlcnRhaW4gcG9zaXRp
b24gaW4gdGhlIHJvcGUKICAgIGRlZiBhdChzdGFydCkKICAgICAgICByc3RhcnQgPSBzdGFydC1A
bGxlbmd0aAogICAgICAgIGlmIHJzdGFydDwwCiAgICAgICAgICAgIEBsZWZ0LmF0KHN0YXJ0KQog
ICAgICAgIGVsc2UKICAgICAgICAgICAgQHJpZ2h0LmF0KHJzdGFydCkKICAgICAgICBlbmQKICAg
IGVuZAogICAgIyBpdGVyYXRlIHRocm91Z2ggdGhlIGVsZW1lbnRzIGluIHRoZSByb3BlCiAgICBk
ZWYgZWFjaAogICAgICAgIEBsZWZ0LmVhY2ggeyB8eHwgeWllbGQgeCB9CiAgICAgICAgQHJpZ2h0
LmVhY2ggeyB8eHwgeWllbGQgeCB9CiAgICBlbmQKICAgICMgZmxhdHRlbiB0aGUgcm9wZSBpbnRv
IGEgc3RyaW5nIChvcHRpb25hbGx5IHN0YXJ0aW5nIHdpdGggYSBwcmVmaXgpCiAgICBkZWYgdG9f
cyhzPSIiKQogICAgICAgIEByaWdodC50b19zKEBsZWZ0LnRvX3MocykpCiAgICBlbmQKZW5kCgpF
bXB0eVJvcGUgPSBPYmplY3QubmV3CmNsYXNzIDw8IEVtcHR5Um9wZQogICAgaW5jbHVkZSBFbnVt
ZXJhYmxlCiAgICBkZWYgbGVuZ3RoCiAgICAgICAgMAogICAgZW5kCiAgICBkZWYgZGVwdGgKICAg
ICAgICAwCiAgICBlbmQKICAgIGRlZiA8PChvdGhlcikKICAgICAgICBvdGhlcgogICAgZW5kCiAg
ICBkZWYgPj4ob3RoZXIpCiAgICAgICAgb3RoZXIKICAgIGVuZAogICAgZGVmIHNsaWNlKHN0YXJ0
LCBsZW4pCiAgICAgICAgc2VsZgogICAgZW5kCiAgICBkZWYgZWFjaAogICAgZW5kCiAgICBkZWYg
dG9fcwogICAgICAgICIiCiAgICBlbmQKZW5kCgpjbGFzcyBBcnJheVJvcGUKICAgIGluY2x1ZGUg
RW51bWVyYWJsZQogICAgZGVmIHNlbGYubmV3KCphcmdzKQogICAgICAgIGlmIGFyZ3MuZW1wdHk/
CiAgICAgICAgICAgIEVtcHR5Um9wZQogICAgICAgIGVsc2UKICAgICAgICAgICAgc3VwZXIKICAg
ICAgICBlbmQKICAgIGVuZAogICAgZGVmIGluaXRpYWxpemUoZGF0YSkKICAgICAgICBAZGF0YSA9
IGRhdGEKICAgIGVuZAogICAgZGVmIGxlbmd0aAogICAgICAgIEBkYXRhLmxlbmd0aAogICAgZW5k
CiAgICBkZWYgZGVwdGgKICAgICAgICAwCiAgICBlbmQKICAgIGRlZiA8PChvdGhlcikKICAgICAg
ICBiYWxhbmNlID0gb3RoZXIuZGVwdGgKICAgICAgICBpZiBiYWxhbmNlPjEKICAgICAgICAgICAg
bGVmdCA9IG90aGVyLmxlZnQKICAgICAgICAgICAgcmlnaHQgPSBvdGhlci5yaWdodAogICAgICAg
ICAgICBpZiBsZWZ0LmRlcHRoPnJpZ2h0LmRlcHRoCiAgICAgICAgICAgICAgICAjIHJvdGF0ZSBv
dGhlciB0byByaWdodCBiZWZvcmUgcm90YXRpbmcgc2VsZitvdGhlciB0byBsZWZ0CiAgICAgICAg
ICAgICAgICAoc2VsZiA8PCBsZWZ0LmxlZnQpIDw8IChsZWZ0LnJpZ2h0IDw8IHJpZ2h0KQogICAg
ICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAjIHJvdGF0ZSBzZWxmK290aGVyIHRvIGxlZnQK
ICAgICAgICAgICAgICAgIChzZWxmIDw8IGxlZnQpIDw8IHJpZ2h0CiAgICAgICAgICAgIGVuZAog
ICAgICAgIGVsc2lmIG90aGVyLmxlbmd0aD09MAogICAgICAgICAgICAjIG5vdGhpbmcgdG8gYXBw
ZW5kLCBzZWxmIHdpbGwgZG8KICAgICAgICAgICAgc2VsZgogICAgICAgIGVsc2UKICAgICAgICAg
ICAgUm9wZS5uZXcoc2VsZiwgb3RoZXIpCiAgICAgICAgZW5kCiAgICBlbmQKICAgIGRlZiBzbGlj
ZShzdGFydCwgbGVuKQogICAgICAgIHJldHVybiBzZWxmIGlmIHN0YXJ0Lnplcm8/IGFuZCBsZW49
PUBkYXRhLmxlbmd0aAogICAgICAgICMgZGVwZW5kIG9uIHJ1YnkncyBDT1cgbWVjaGFuaXNtIHRv
IGp1c3QgcmVmZXJlbmNlIHRoZSBzbGljZSBkYXRhCiAgICAgICAgc2VsZi5jbGFzcy5uZXcoQGRh
dGEuc2xpY2Uoc3RhcnQsIGxlbikpCiAgICBlbmQKICAgIGRlZiBhdChzdGFydCkKICAgICAgICBA
ZGF0YS5hdChzdGFydCkKICAgIGVuZAogICAgZGVmIGVhY2gKICAgICAgICBAZGF0YS5lYWNoIHsg
fHh8IHlpZWxkIHggfQogICAgZW5kCiAgICBkZWYgdG9fcyhzPSIiKQogICAgICAgIHMuY29uY2F0
KEBkYXRhLnRvX3MpCiAgICBlbmQKZW5kCgpjbGFzcyBTdHJpbmdSb3BlIDwgQXJyYXlSb3BlCiAg
ICAjIHVuY29tbWVudCB0aGlzIHRvIGFsbG93IHNob3J0IHN0cmluZ3MgdG8gY29uY2F0IGZsYXQK
ICAgICNTSE9SVCA9IDY0CiAgICAjZGVmIDw8KG90aGVyKQogICAgIyAgICBpZiBvdGhlci5sZW5n
dGg9PTAKICAgICMgICAgICAgIHNlbGYKICAgICMgICAgZWxzaWYgQGRhdGEubGVuZ3RoK290aGVy
Lmxlbmd0aDw9U0hPUlQKICAgICMgICAgICAgICMganVzdCBtZXJnZSB0aGUgc3RyaW5ncyBpZiB0
aGUgdG90YWwgbGVuZ3RoIGlzIHNob3J0CiAgICAjICAgICAgICBzZWxmLmNsYXNzLm5ldyhAZGF0
YStvdGhlci50b19zKQogICAgIyAgICBlbHNlCiAgICAjICAgICAgICBzdXBlcgogICAgIyAgICBl
bmQKICAgICNlbmQKICAgIGRlZiBhdChzdGFydCkKICAgICAgICBAZGF0YVtzdGFydF0KICAgIGVu
ZAogICAgZGVmIGVhY2gKICAgICAgICBAZGF0YS5lYWNoX2NoYXIgeyB8eHwgeWllbGQgeCB9CiAg
ICBlbmQKZW5kCgpjbGFzcyBJT1JvcGUgPCBBcnJheVJvcGUKICAgIGluY2x1ZGUgRW51bWVyYWJs
ZQogICAgZGVmIGluaXRpYWxpemUoaW8sIHN0YXJ0PTAsIGxlbmd0aD0oaW8uc2VlaygwLElPOjpT
RUVLX0VORCk7aW8ucG9zLXN0YXJ0KSkKICAgICAgICBAaW8gPSBpbwogICAgICAgIEBzdGFydCA9
IHN0YXJ0CiAgICAgICAgQGxlbmd0aCA9IGxlbmd0aAogICAgZW5kCiAgICBkZWYgbGVuZ3RoCiAg
ICAgICAgQGxlbmd0aAogICAgZW5kCiAgICBkZWYgc2xpY2Uoc3RhcnQsIGxlbikKICAgICAgICBy
ZXR1cm4gc2VsZiBpZiBzdGFydC56ZXJvPyBhbmQgbGVuPT1AbGVuZ3RoCiAgICAgICAgIyBqdXN0
IHJlZmVyZW5jZSBhIGRpZmZlcmVudCBwYXJ0IG9mIHRoZSBJTwogICAgICAgIHNlbGYuY2xhc3Mu
bmV3KEBpbywgQHN0YXJ0K3N0YXJ0LCBsZW4pCiAgICBlbmQKICAgIGRlZiBhdChzdGFydCkKICAg
ICAgICBAaW8ucG9zID0gQHN0YXJ0K3N0YXJ0CiAgICAgICAgQGlvLmdldGMKICAgIGVuZAogICAg
ZGVmIGVhY2gKICAgICAgICBAaW8ucG9zID0gQHN0YXJ0CiAgICAgICAgQGxlbmd0aC50aW1lcyB7
IHlpZWxkIEBpby5nZXRjIH0KICAgIGVuZAogICAgZGVmIHRvX3Mocz0iIikKICAgICAgICBAaW8u
cG9zID0gQHN0YXJ0CiAgICAgICAgcy5jb25jYXQoQGlvLnJlYWQoQGxlbmd0aCkpCiAgICBlbmQK
ZW5kCgoKcmVxdWlyZSAnYmVuY2htYXJrJwoKI1RoaXMgY29kZSBtYWtlIGEgU3RyaW5nL1JvcGUg
b2YgIENIVU5LUyBjaHVua3Mgb2YgdGV4dAojZWFjaCBjaHVuayBpcyBTSVpFIGJ5dGVzIGxvbmcu
ICBFYWNoIGNodW5rIHN0YXJ0cyB3aXRoCiNhbiA4IGJ5dGUgbnVtYmVyLiAgSW5pdGlhbGx5IHRo
ZSBjaHVua3MgYXJlIHNodWZmbGVkIHRoZQojcXNvcnQgbWV0aG9kIHNvcnRzIHRoZW0gaW50byBh
c2NlbmRpbmcgb3JkZXIuCiMKI3Bhc3MgdGhlIG5hbWUgb2YgdGhlIGNsYXNzIHRvIHVzZSBhcyBh
IHBhcmFtZXRlcgojcnVieSAtciByb3BlLnJiIHRoaXNfZmlsZSBSb3BlCgpwdXRzICdwcmVwYXJp
bmcgZGF0YS4uLicKVGV4dENsYXNzID0gT2JqZWN0LmNvbnN0X2dldChBUkdWLnNoaWZ0IHx8IDpT
dHJpbmcpCgpkZWYgcXNvcnQodGV4dCkKIHJldHVybiBUZXh0Q2xhc3MubmV3IGlmIHRleHQubGVu
Z3RoID09IDAKIHBpdm90ID0gdGV4dC5zbGljZSgwLDgpLnRvX3MudG9faQogbGVzcyA9IFRleHRD
bGFzcy5uZXcKIG1vcmUgPSBUZXh0Q2xhc3MubmV3CiBvZmZzZXQgPSA4K1NJWkUKIHdoaWxlIChv
ZmZzZXQgPCB0ZXh0Lmxlbmd0aCkKICAgaSA9IHRleHQuc2xpY2Uob2Zmc2V0LDgpLnRvX3MudG9f
aQogICBpZiBpIDwgcGl2b3QKICAgICAgIGxlc3MgPDw9IHRleHQuc2xpY2Uob2Zmc2V0LDgrU0la
RSkKICAgZWxzZQogICAgICAgbW9yZSA8PD0gdGV4dC5zbGljZShvZmZzZXQsOCtTSVpFKQogICBl
bmQKICAgb2Zmc2V0ID0gb2Zmc2V0ICsgOCtTSVpFCiBlbmQKIHByaW50ICIqIgogcmV0dXJuIHFz
b3J0KGxlc3MpIDw8IHRleHQuc2xpY2UoMCw4K1NJWkUpIDw8IHFzb3J0KG1vcmUpCmVuZAoKc3Jh
bmQoMTIzNDU2Nzg5KQpTSVpFICA9IDUxMiAqIDEwMjQKQ0hVTktTID0gMTI4CkNIQVJTID0gJXdb
UiBPIFAgRV0KYnVsa19zdHJpbmcgPSBBcnJheS5uZXcoU0laRSkgeyBDSEFSU1tyYW5kKDQpXSB9
LmpvaW4KYnVsa190ZXh0ID0gVGV4dENsYXNzLm5ldyhidWxrX3N0cmluZykKYnVpbGQgPSBbXQpk
YXRhID0gbmlsCjgudGltZXMgewpwdXRzICdCdWlsZGluZyBUZXh0Li4uJwpHQy5zdGFydApidWls
ZCA8PCBCZW5jaG1hcmsubWVhc3VyZSBkbwogZGF0YSA9IFRleHRDbGFzcy5uZXcKICgwLi5DSFVO
S1MpLnNvcnRfYnkgeyByYW5kIH0uZWFjaCBkbyB8bnwKICAgZGF0YSA8PD0gVGV4dENsYXNzLm5l
dyhzcHJpbnRmKCIlMDhpIixuKSkgPDwgYnVsa190ZXh0CiBlbmQKIGRhdGEubm9ybWFsaXplICBp
ZiBkYXRhLnJlc3BvbmRfdG8/IDpub3JtYWxpemUKZW5kCn0KYnVpbGQgPSBidWlsZC5pbmplY3Qg
eyB8bWluLGN1cnwgY3VyLnRvdGFsPG1pbi50b3RhbCA/IGN1ciA6IG1pbiB9CgoKIyBzZWxmLWNo
ZWNrIHRoYXQgdGhlIGluZGljZXMgYWRkIHVwCnN1bSA9IDAKMC5zdGVwKGRhdGEubGVuZ3RoLTEs
IDgrU0laRSkgeyB8b2Zmc2V0fAogICAgc3VtICs9IGRhdGEuc2xpY2Uob2Zmc2V0LDgpLnRvX3Mu
dG9faQogICAgYnVsa19kYXRhID0gZGF0YS5zbGljZShvZmZzZXQrOCxTSVpFKS50b19zCiAgICBy
YWlzZSgiI3tidWxrX2RhdGFbMCwxMF19Li4uLiAhPSAje2J1bGtfc3RyaW5nWzAsMTBdfS4uLi4i
KSBpZiBidWxrX2RhdGEhPWJ1bGtfc3RyaW5nCn0KZXhwZWN0ZWRfc3VtID0gKENIVU5LUyooQ0hV
TktTKzEpKS8yCnJhaXNlKCIje3N1bX0hPSN7ZXhwZWN0ZWRfc3VtfSIpIGlmIHN1bSE9ZXhwZWN0
ZWRfc3VtCgpzb3J0ID0gW10Kc29ydGVkX2RhdGEgPSBuaWwKOC50aW1lcyB7CkdDLnN0YXJ0CnNv
cnQgPDwgQmVuY2htYXJrLm1lYXN1cmUgZG8KIHB1dHMgIlNvcnRpbmcgVGV4dC4uLiIKIHNvcnRl
ZF9kYXRhID0gcXNvcnQoZGF0YSkKIHB1dHMiXG4iCmVuZAp9CnNvcnQgPSBzb3J0LmluamVjdCB7
IHxtaW4sY3VyfCBjdXIudG90YWw8bWluLnRvdGFsID8gY3VyIDogbWluIH0KCnB1dHMgIkJ1aWxk
OiAje2J1aWxkfVNvcnQ6ICN7c29ydH0iCgojIHNlbGYtY2hlY2sgdGhhdCB0aGUgaW5kaWNlcyBh
cmUgc29ydGVkCmkgPSAwCjAuc3RlcChzb3J0ZWRfZGF0YS5sZW5ndGgtMSwgOCtTSVpFKSB7IHxv
ZmZzZXR8CiAgICBkYXRhaSA9IHNvcnRlZF9kYXRhLnNsaWNlKG9mZnNldCw4KS50b19zCiAgICBy
YWlzZSgiI3tkYXRhaX0hPSN7aX0iKSBpZiBkYXRhaS50b19pIT1pCiAgICBidWxrX2RhdGEgPSBz
b3J0ZWRfZGF0YS5zbGljZShvZmZzZXQrOCxTSVpFKS50b19zCiAgICByYWlzZSgiI3tidWxrX2Rh
dGFbMCwxMF19Li4uLiAhPSAje2J1bGtfc3RyaW5nWzAsMTBdfS4uLi4iKSBpZiBidWxrX2RhdGEh
PWJ1bGtfc3RyaW5nCiAgICBpICs9IDEKfQoKCg------art_17535_22666276.1188802265486--