Remove values from list element, and add to other element

Basically what I need is to make a list of 400 elements, all have value 1. The next step is to create a function, that subtracts value (-1) from an element, and adds that to another element.

So: (1,1,1,1) could become (1,2,1,0).

Running the function 1 time is called a sweep. The sum of the list has to be 400 at all times, and an element needs to have minimum value 0.

The function needs to make all elements ''exchange'' 1's with each other randomly.

(1,2,1,0) could also become (0,4,0,0) for example.

• Sounds like a nice homework! Have you tried something? Sep 16 '14 at 22:32
• Look up Nest and ConstantArray. Sep 16 '14 at 22:33
• I tried f[a_] := list + RandomInteger[{-1, 1}, 400] + a - a Where list is a list of 400 elements with value 1. But it is obviously to simple to be correct.
– a-es
Sep 17 '14 at 7:53

Here is a rough stab at it that should help you get started:

f[x_List] := Module[{n, lis = Range @ Length @ x, len = Length @ x, d = x},
Do[(n = RandomChoice[lis, 2];
If[d[[First @ n]] > 0, d[[First @ n]] -= 1; d[[Last @ n]] += 1]), {len}];
d]


Now we generate our list of ones:

list = ConstantArray[1, 400];


Then:

res = f @ list

{0, 2, 2, 1, 1, 2, 3, 0, 0, 1, 1, 1, 1, 2, 0, 0, 2, 1, 0, 2, 0, 1, 3,
1, 1, 4, 2, 2, 0, 1, 0, 0, 2, 1, 0, 1, 2, 1, 1, 1, 1, 1, 0, 1, 0, 0,
1, 0, 0, 3, 2, 1, 1, 0, 2, 1, 0, 1, 1, 0, 0, 2, 0, 0, 1, 0, 1, 2, 1,
2, 1, 1, 1, 1, 1, 1, 0, 2, 1, 3, 0, 0, 1, 0, 1, 1, 2, 2, 0, 0, 0, 0,
2, 0, 2, 2, 0, 0, 1, 0, 0, 1, 3, 0, 1, 0, 1, 1, 1, 0, 2, 2, 0, 1, 2,
0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 2, 0, 0, 0, 1, 0, 3, 1, 2, 2, 1, 1, 1,
0, 0, 2, 1, 1, 0, 0, 1, 2, 0, 0, 3, 0, 1, 2, 3, 2, 2, 0, 3, 4, 1, 0,
0, 2, 0, 0, 0, 0, 0, 1, 2, 1, 4, 0, 0, 0, 0, 0, 0, 3, 0, 2, 1, 3, 2,
0, 1, 1, 0, 1, 2, 1, 0, 2, 1, 0, 0, 0, 0, 0, 3, 2, 0, 2, 0, 1, 0, 0,
1, 3, 1, 0, 2, 1, 0, 1, 1, 1, 3, 0, 1, 2, 1, 1, 0, 1, 2, 4, 0, 1, 2,
0, 2, 3, 3, 0, 0, 1, 2, 2, 0, 3, 1, 1, 0, 0, 1, 2, 0, 0, 1, 0, 0, 1,
0, 1, 2, 0, 1, 1, 1, 0, 3, 1, 1, 0, 2, 1, 0, 1, 0, 0, 2, 1, 1, 1, 1,
0, 0, 1, 1, 0, 1, 3, 0, 1, 1, 2, 0, 2, 1, 0, 2, 1, 0, 0, 0, 0, 0, 1,
3, 3, 0, 2, 2, 2, 1, 0, 2, 1, 3, 2, 0, 0, 0, 2, 0, 1, 3, 1, 2, 2, 2,
1, 3, 3, 1, 0, 1, 0, 2, 2, 1, 0, 1, 1, 1, 2, 1, 1, 0, 0, 2, 0, 2, 0,
1, 2, 2, 1, 2, 1, 0, 1, 2, 0, 3, 2, 2, 0, 2, 2, 2, 1, 0, 3, 0, 0, 2,
2, 0, 0, 4, 1, 2, 0, 1, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 2, 2, 1, 0,
0, 1, 1, 2, 0, 0, 1, 0, 1}


And:

Total @ res


400

• Thanks for your quick and satisfying response. I am trying to understand all the steps you've used in order to understand the algorithms. Could you elaborate a little bit?
– a-es
Sep 17 '14 at 7:47
• @a-es Sure. Assuming we use your smaller example with only 4 elements. lis = Range@Length@x creates a list from 1 to 4 (the length of the list). len = Length@x is the number of elements in the list. Now we pick randomly, the position of two elements from our list by n = RandomChoice[lis, 2]. Now the If statement does the subtraction of 1 from one element and addition to another element only if the first element is greater than 0, so that we keep to your requirement of minimum value of 0. The Do statement just repeats the process a certain number of times. Hope this helps. Sep 17 '14 at 8:57