Reputation: 3327
a = RandomChoice[{a,2}]&
a[]
There are other ways to achieve this example, but I wish to do more complicated things similar to this using this method.
Can I get this to continue until there are no a
s left to resolve, without producing a stack overflow by trying to resolve {a,2}
before making the choice? Instead making the choice and resolving only the symbol chosen.
Upvotes: 0
Views: 118
Reputation: 6999
Here is a way to have RandomChoice
evaluate a function only when selected:
g := (Print["evaluate g"]; 42);
f = ( If[TrueQ[#], g, #] &@RandomChoice[{True, 1, 2, 3, 4}]) &
Table[f[], {10}]
this prints "evaluate g" just when randomly selected and outputs eg.
(* {2, 42, 3, 1, 3, 2, 4, 42, 2, 4} *)
This is another way, maybe a bit cleaner:
f = Unevaluated[{g, 1, 2, 3, 4}][[RandomInteger[{1, 5}]]] &
this works fine recursively:
a = Unevaluated[{a[], 2}][[RandomInteger[{1, 2}]]] &
Though as i said in comment it simply returns 2 every time since it recurses until 2 is chosen.
a[] (* 2 *)
I do not understand the entirety of the question and my guess is there is a better way to accomplish what you want.
Upvotes: 1
Reputation: 8680
Your request seems slightly contradictory: when the random choice selects a
you want it to recurse, but if it chooses a number you still want to continue until there are no a
's left.
The following code does this, but the recursion is technically unnecessary. Perhaps in your application it will be applicable.
The first part shows how you can recurse selections of a
by using Hold
:-
Clear[a]
list = {1, 2, a, 1, a, 3, a, 1, 4, 5};
heldlist = Hold /@ list;
a := Module[{z}, z = RandomChoice[heldlist];
Print["for information, choice was ", z];
If[MatchQ[z, Hold[_Symbol]],
heldlist = DeleteCases[heldlist, z, 1, 1];
If[MemberQ[heldlist, Hold[_Symbol]], ReleaseHold[z]]]]
a
On this occasion, calling a
recurses once, then picks a 4 and stops, as expected.
for information, choice was Hold[a]
for information, choice was Hold[4]
To make the process continue until there are no a
's While
can be used. There is recursion going on here too but While
keeps the process going when a number is picked.
While[MemberQ[heldlist, Hold[_Symbol]], a]
for information, choice was Hold[a]
for information, choice was Hold[1]
for information, choice was Hold[a]
These are the remaining items in the list :-
ReleaseHold /@ heldlist
{1, 2, 1, 3, 1, 4, 5}
Upvotes: 0