15
\$\begingroup\$

Swapping two elements in a vector/matrix is very simple in Octave:

x='abcde';
x([4,1])=x([1,4])
x = 
   dbcae

Unfortunately, I have yet to find a way to do this inside an anonymous function. While the function below is syntactically correct, it only gives back the two elements that are swapped, not the entire x vector:

f=@(x)(x([4,1])=x([1,4]))
f(x)
ans = 
     ad

Is there a way to achieve the desired behavior using anonymous functions in a golfy way? Can several elements be swapped this way using an anonymous function?

I could create an indexing vector: f=@(x)x([4,2,3,1,5]), but creating such a vector dynamically will likely take a lot of bytes too.

\$\endgroup\$
21
\$\begingroup\$

Argument List

f=@(x,y=x([4 1])=x([1 4]))x;

Try it online!

\$\endgroup\$
  • 5
    \$\begingroup\$ Wait what? I never knew this was possible in Octave. This opens up so many new techniques.... \$\endgroup\$ – Sanchises Apr 23 '18 at 11:41
  • 4
    \$\begingroup\$ What in the...? \$\endgroup\$ – Stewie Griffin Apr 23 '18 at 11:43
  • 1
    \$\begingroup\$ Please post this in the Tips for Octave question! With this technique, you can basically do everything in the argument list, so you never need to choose between a 'full' and anonymous function again. I'm shocked. \$\endgroup\$ – Sanchises Apr 23 '18 at 11:47
  • 3
    \$\begingroup\$ Amazing. BTW, you can remove the final ; for the purposes of byte count \$\endgroup\$ – Luis Mendo Apr 23 '18 at 11:56
  • \$\begingroup\$ Thanks to all .@Sanchises It seems that Octave is a shocking language. Be careful! It is added to tips. \$\endgroup\$ – rahnema1 Apr 23 '18 at 12:16
11
\$\begingroup\$

Be eval

f=@(x)eval"x([4 1])=x([1 4])"

Try it online!


In Matlab the parentheses cannot be omitted:

f=@(x)eval('x([4 1])=x([1 4])')
\$\endgroup\$
  • 9
    \$\begingroup\$ Only on PPCG is eval the answer :-) \$\endgroup\$ – Stewie Griffin Apr 23 '18 at 9:27
  • \$\begingroup\$ Do you want to add this to the Octave tips question? for loop inside an anonymous function using eval saved a lot of bytes there, and can probably do it on many other challenges too,,, \$\endgroup\$ – Stewie Griffin Apr 23 '18 at 12:52
  • \$\begingroup\$ Not sure if it is ever golfier, but I suppose you can do it even without anonymous function: s='x([1 4])=x([4 1])';eval(s) -- I suppose this is mostly interesting if you already made a function to do eval with minimal chars. \$\endgroup\$ – Dennis Jaheruddin Apr 23 '18 at 13:07
  • 1
    \$\begingroup\$ Added :) \$\endgroup\$ – Stewie Griffin Apr 23 '18 at 13:26
  • 2
    \$\begingroup\$ I think this answer is the only one thusfar that is both valid Octave and Matlab. \$\endgroup\$ – Batman Apr 23 '18 at 23:34
8
\$\begingroup\$

Cell array

One option is to use a cell array, like this:

f=@(x){x([1,4])=x([4,1]);x}{2}

Try it online!

\$\endgroup\$
  • \$\begingroup\$ Nice one! Reminds me of this trick \$\endgroup\$ – Luis Mendo Apr 23 '18 at 9:15

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.