creating empty blocks
[1/3] from: gchiu:compkarori at: 21-Sep-2001 23:15
I want to add some empty blocks as follows:
rooms: copy []
create-room: has [ result ] [
result: to-string random/only 1000
either find rooms result
[ create-room ]
[ append rooms copy reduce [ result [] [] [] [] ]
]
return result
]
but after
create-room
create-room
the empty blocks after each result are actually the same
>> probe rooms
["127" [] [] [] [] "792" [] [] [] []]
>> insert rooms/2 "test"
== []
>> probe rooms
["127" ["test"] [] [] [] "792" ["test"] [] [] []]
How does one create unique empty blocks??
--
Graham Chiu
[2/3] from: joel::neely::fedex::com at: 21-Sep-2001 2:06
Hi, Graham,
Graham Chiu wrote:
> I want to add some empty blocks as follows:
> rooms: copy []
<<quoted lines omitted: 17>>
> ["127" ["test"] [] [] [] "792" ["test"] [] [] []]
> How does one create unique empty blocks??
By using COPY/DEEP, you get the behavior
I assume you're looking for, as shown below:
>> rooms: copy []
== []
>> create-room: has [ result ] [
[ result: to-string random/only 1000
[ either find rooms result
[ [ create-room ]
[ [ append rooms copy/deep reduce [ result [] [] [] [] ]
[ ]
[ return result
[ ]
>> create-room
== "380"
>> create-room
== "196"
>> rooms
== ["380" [] [] [] [] "196" [] [] [] []]
>> append rooms/2 "foo"
== ["foo"]
>> rooms
== ["380" ["foo"] [] [] [] "196" [] [] [] []]
If you don't mind the kibitzing, I have a couple of other
observations re the code. ;-)
1) The first line in the function body could use RANDOM
instead of RANDOM/ONLY. (I assume this is a simplified
test case from some more complicated code...)
2) I would use iteration instead of recursion. It seemed
to me that you wanted to prevent duplicate "keys" from
being added to the list, but the approach above is not the
best way to do so, for the reasons below:
2a) It seems clearer, since you really don't want to
re-invoke *all* of the behavior of CREATE-ROOM, but
just the part that tries to generate another key.
2b) As written, CREATE-ROOM will recursively evaluate itself
if a duplicate key is drawn randomly. Assuming that
the recursion eventually terminates (see next item), the
non-duplicate will be added to ROOMS, but then the recursive
evaluation will return to its caller, which (when the whole
recursive pile unwinds) will return to the original caller
the first (failed, duplicate) key and *not* the one just
added to ROOMS.
2c) Calling CREATE-ROOM sufficiently many times could cause
REBOL to crash. As you add more keys to ROOMS, the
probability of a duplicate on each draw increases, and
therefore the number of tries before finding a non-duplicate
increases on average. As the total number of calls grows
close to 1000 (if you ever get that far) you can get such
a high probability of duplication that you could crash the
stack, even though there are still unused keys.
With all of that said, you might try something like this:
create-room: has [ result ] [
result: to-string random 1000
while [find rooms result] [
result: to-string random 1000
]
append rooms copy/deep reduce [
result [] [] [] []
]
result
]
to address (2a) and (2b). If the limit of 1000 was *way*
overspecified, then I'd ignore (2c). If you actually might
evaluate CREATE-ROOM close to 1000 times (e.g. at least 900)
you might consider something like this to fix the delays
involved in (2c), even though the above will avoid a crash:
all-rooms: make block! 1000
repeat i 1000 [append all-rooms i]
all-rooms: random all-rooms
== [754 572 711 296 501 542 40 69 644 596 524 132 792 17 ...
then
create-room: has [result] [
result: first all-rooms
all-rooms: next all-rooms ;; or remove all-rooms
;; ... and so on
which also give you the option of inserting a "safety" check
that would throw an error if ALL-ROOMS were empty at the
beginning of CREATE-ROOM (since, in that case, there's no
possibility of finding a non-duplicate key).
HTH!
-jn-
--
------------------------------------------------------------
Programming languages: compact, powerful, simple ...
Pick any two!
joel'dot'neely'at'fedex'dot'com
[3/3] from: gchiu:compkarori at: 22-Sep-2001 8:00
On Fri, 21 Sep 2001 02:06:45 -0500
Joel Neely <[joel--neely--fedex--com]> wrote:
> With all of that said, you might try something like this:
> create-room: has [ result ] [
<<quoted lines omitted: 10>>
> overspecified, then I'd ignore (2c). If you actually
> might
Hi Joel,
That's just what I need :) I was only expecting to create
about 10 rooms max, but I guess any way to avoid crashing
Rebol must be a good thing!
Explanation much appreciated.
--
Graham Chiu
Notes
- Quoted lines have been omitted from some messages.
View the message alone to see the lines that have been omitted