       Re: Challenge!

• To: mathgroup at christensen.cybernetics.net
• Subject: [mg926] Re: Challenge!
• From: villegas (Robert Villegas)
• Date: Wed, 3 May 1995 00:05:11 -0400
• Organization: Wolfram Research, Inc.

```> I have two lists of equal length M.
>
> I wish to generate a third list also of length M, where the i th element
> of this list is either the i th element of the first list, or the i th
> element of the second list.
>
> It should be equally probable that the new element be chosen from the
> first or second list.
>
> eg.  I have a list {a,b,c,d,e,f,g}
>      and another   {A,B,C,D,E,F,G}
>
>                    {a,B,C,d,e,F,G}
>                    {a,b,c,d,E,f,g}
>                    {A,B,C,D,e,f,G}
>                    etc.

Paul,

One way of looking at this is that you want to take corresponding
elements of the two lists, like a and A, and apply a function to
them, f[a, A], where f means "pick one of your arguments at random".
MapThread will do this:  take two lists, feed their first arguments
to f, then feed their second arguments to f, and so on, giving you the
list of f-results at the end.  A diagram makes it a little clearer
how you're gluing the two lists together with f:

{a1 , a2 , a3 , . . . , aM}

|    |    |            |
f    f    f            f
|    |    |            |

{b1 , b2 , b3 , . . . , bM}

So let's use "glue" f that picks a random element:

In:= list1 = {a, b, c, d, e, f, g}

Out= {a, b, c, d, e, f, g}

In:= list2 = {A, B, C, D, E, F, G}

Out= {A, B, C, D, E, F, G}

In:= MapThread[Part[{#1, #2}, 1 + Random[Integer] ]&, {list1, list2}]

Out= {A, B, c, d, E, F, G}

Note that Random[Integer] is a short way of generating a random integer
0 or 1 (related:  Random[Real] generates a random Real from 0 to 1, and
Random[Complex] generates a random Complex whose parts are real numbers
from 0 to 1).

We can make it easy to generate more random selections from the two by
making a delayed assignment to a variable 'randomSelection'.  Any time
we evaluate 'randomSelection', like in a Table, we get a different
random selection from the two lists.

In:= randomSelection := MapThread[Part[{#1, #2}, 1 + Random[Integer]
]&, {list1, list2}]

In:= Table[randomSelection, {6}] //TableForm

Out//TableForm= a   b   C   D   E   F   G

a   B   C   d   e   F   g

A   B   C   D   E   f   G

A   b   c   D   E   F   G

a   b   C   D   E   f   g

a   B   c   D   e   F   G

This method of storing a command or program in a symbol is given in
Roman Maeder's _Programming in Mathematica_ (2nd ed), section 5.5.3.

MapThread is happy to work with any number of lists, so we can use it to
randomly select from k lists instead of just 2, with essentially no
complications in the command.  Here's the same technique applied to
seven lists:

In:= lists = Array[a, {7, 5}] ; TableForm[lists]

Out//TableForm= a[1, 1]   a[1, 2]   a[1, 3]   a[1, 4]   a[1, 5]

a[2, 1]   a[2, 2]   a[2, 3]   a[2, 4]   a[2, 5]

a[3, 1]   a[3, 2]   a[3, 3]   a[3, 4]   a[3, 5]

a[4, 1]   a[4, 2]   a[4, 3]   a[4, 4]   a[4, 5]

a[5, 1]   a[5, 2]   a[5, 3]   a[5, 4]   a[5, 5]

a[6, 1]   a[6, 2]   a[6, 3]   a[6, 4]   a[6, 5]

a[7, 1]   a[7, 2]   a[7, 3]   a[7, 4]   a[7, 5]

In:= MapThread[Part[{##}, Random[Integer, {1, 7}]]&, lists]

Out= {a[3, 1], a[2, 2], a[3, 3], a[7, 4], a[2, 5]}

A different method from MapThread is Table, and gives a command that
is equally short:

In:= Table[Part[lists, Random[Integer, {1, 7}], i], {i, 5}]

Out= {a[4, 1], a[4, 2], a[2, 3], a[1, 4], a[4, 5]}

I'm not sure which one holds up better in timing tests for either a
large number of lists, or lists with a large number of elements.  It
would be interesting to do some tests.

Robby Villegas

```

• Prev by Date: Re: simplex tableau help wanted
• Next by Date: Re: Challenge!
• Previous by thread: Re: Challenge!
• Next by thread: Re: Challenge!