I'm defining a function in Mathematica where if the i-th value in a list in 1, and the i+1-th value is 0, the function switches those two values.
I've defined it as:
f[i_, x_] := (If[x[[i]] == 1 && x[[i + 1]] == 0, x[[i]] = 1; x[[i + 1]] = 0]);
However when I test it with i = 2
and x = {1,1,0,0}
I get the following error:
Set::setps: {1,1,0,0} in the part assignment is not a symbol. >>
I don't quite know what I'm doing wrong, as I thought I was calling everything correctly.
You seem to have found a solution but let's break this down anyway.
First you have a simple transcription error where your Set
s apply the original values rather than swapping them. With this change the basic code works:
i = 2;
x = {1, 1, 0, 0};
If[
x[[i]] == 1 && x[[i + 1]] == 0,
x[[i]] = 0; x[[i + 1]] = 1;
]
x
{1, 0, 1, 0}
So we have successfully changed x
. To make this into a function we must pass the name of x
to this code rather than the value of x
. This is the source of your error:
{1, 1, 0, 0}[[2]] = 0;
Set::setps: {1,1,0,0} in the part assignment is not a symbol. >>
What you need is a Hold attribute on your function:
SetAttributes[f, HoldAll]
f[i_, x_] := If[x[[i]] == 1 && x[[i + 1]] == 0, x[[i]] = 0; x[[i + 1]] = 1;]
i = 2 ;
x = {1, 1, 0, 0};
f[2, x]
x
{1, 0, 1, 0}
Perhaps you did not intend to change the value of x
itself but this technique will surely come in handy in other applications. To modify the function above to manipulate a copy of the data we may use Module
, and we don't need the Hold attribute:
f2[i_, xImmutable_] :=
Module[{x = xImmutable},
If[x[[i]] == 1 && x[[i + 1]] == 0, x[[i]] = 0; x[[i + 1]] = 1];
x
]
i = 2 ;
x = {1, 1, 0, 0};
f2[2, x]
{1, 0, 1, 0}
Notice that x
within Module
is a local variable and not your global list x
, which remains unchanged.
For fun let's implement this in a different way.
f3[i_, x_] :=
If[
x[[i + {0, 1}]] == {1, 0},
ReplacePart[x, {i -> 0, i + 1 -> 1}],
x
]
f3[2, x]
{1, 0, 1, 0}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With