Question

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 as 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.

Was it helpful?

Solution

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.

OTHER TIPS

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}

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top