Replace a randomly chosen part of an expression

Here's one way:

expr = a x^3 + 2 y Cos[x] - Tanh[x^(y + 3)]/(x^4 - Sqrt[b]);
pos = Position[expr, x];
thisPos = RandomChoice[pos]; 
ReplacePart[expr, Drop[thisPos, -RandomInteger[{0, Length[thisPos] - 1}]] -> u]

Each time you execute it, you select a random term containing x from the expression and replace it with u.


Depending on your definition of random the method from bill s might have a problem in that some elements can be selected in more than one way. For example in your expr the element at position {3} can be selected from either {3, 2, 1, 2, 1} or {3, 3, 1, 1}. If we use Position to find all elements directly (rather than Dropping afterward) we avoid this.

expr = a x^3 + 2 y Cos[x] - Tanh[x^(y + 3)]/(x^4 - Sqrt[b]);

pos = Most @ Position[expr, s_ /; ! FreeQ[s, x]]

ReplacePart[expr, RandomChoice[pos] -> u]

This never seems to replace the whole expression with $u$, even if I run it 100,000 times. Shouldn't that happen, as the Plus in the top of the TreeForm is eligible for replacement too?

I did not consider the whole expression to be a part. The term {} in the return of Position represents the whole expression, but I dropped it using Most because ReplacePart cannot use this specification.

If you want to include that as a possibility I propose this instead:

pos = Position[expr, s_ /; ! FreeQ[s, x]]

Module[{x = expr}, x[[## & @@ RandomChoice @ pos]] = u; x]