One-line variables swap in PHP, Ruby, Perl, Python and C

Joy in BlueToday’s fun and games: let’s swap a few variables without using more variables than necessary.

Let me know if you disagree with any of this…

$a = 1;
$b = 2;
list($a, $b) = array($b, $a);
print "a=$a, b=$b\n";
a = 1
b = 2
a, b = b, a
puts "a=#{a}, b=#{b}\n"
my $a = 1;
my $b = 2;
($a, $b) = ($b, $a);
print "a=$a, b=$b\n";
?View Code PYTHON
a=1
b=2
a, b = b, a
print 'a=%i, b=%i' % (a, b)

And now, good old C. Let’s use the only method that does not generate an overflow…first, for integer types:

int a=0, b=27;
a=(a^(b=(a=a^b)^b));
printf("a=%d, b=%d\n", a, b);

“Well,” you may say, “but what about pointers arithmetic? Any solution?”
Why, yes. That’s what I came up with after 15 minutes of fiddling:

char *a = "one", *b = "two";
a=(void *)(((long)a)^(long)(b=(void *)(((long)(a=(void *)((long)a^(long)b)))^(long)b)));
printf("a=%s, b=%s\n", a, b);

Note the use of void *, which allows me to ignore the pointer type. And, yes, I know, a C++ compiler may not really like this syntax. This may be doable using templates but I haven’t looked into that.
Sorry, I haven’t looked into Erlang or Haskell yet…

Similar Posts:

If you enjoyed this post, make sure you subscribe to my RSS feed!

If you enjoyed this post, please consider to leave a comment or subscribe to the feed and get future articles delivered to your feed reader.

Comments

On the PHP one, you could also do:
$a = 1;
$b = 2;
$x = $a
$y = $b
$a = $y
$b = $x

unset($x, $y);
echo ‘a=’,$a’, b=’,$b,”\n”;

Would be interesting to do a test of speed and memory usage between the two.

Of course that wouldn’t be a one liner thou.

I did a test with a 100K loop on each and yours is actually faster by .001 to .005 seconds. I did another test where I removed the unset out of mine and my was .040 – .042 seconds faster. Here’s my test code:

<?php
$time_start = microtime(true);
$i =0;

do
{
$a = 1;
$b = 2;
list($a, $b) = array($b, $a);
}while(++$i < 100000);

$time_end = microtime(true);
$time = $time_end – $time_start;

echo ‘Test 1: ‘,$time,”;

$time_start = microtime(true);
$i =0;

do
{
$a = 1;
$b = 2;
$x = $a;
$y = $b;
$a = $y;
$b = $x;
unset($x, $y);
}while(++$i < 100000);

$time_end = microtime(true);
$time = $time_end – $time_start;

echo ‘Test 2: ‘,$time,”;

$time_start = microtime(true);
$i =0;

do
{
$a = 1;
$b = 2;
$x = $a;
$y = $b;
$a = $y;
$b = $x;
}while(++$i < 100000);

$time_end = microtime(true);
$time = $time_end – $time_start;

echo ‘Test 3: ‘,$time,”;

@EllisGL

Ha! I do not think that I would have bothered writing a test harness for PHP’s assignment. And, apparently, I would have been wrong: your results are surprising since they show that parsing more code will, in the end, be as fast as calling a built-in function.

@admin

Hmf I realized, after re-reading your test harness, that the amount of parsing should be the same. Shame on me.

How about using the (little-known) comma operator in your C/C++ examples:

int a = 1;
int b = 27;

a = b – a, b = b – a, a = a + b;

Regarding Erlang, there is no way to do this I know of, as you can bind one variable name only once.

template
void inline swap(T &a, T &b) { T &tmp = a; a = b; b = tmp; }

@Mike M

Fun alternative. A tad dangerous, though, not because of your use of commas but because your code could suffer from integer overflows.

@manveru

Right. What was I thinking? I guess I could use an anonymous function to create a new scope but then the swapped result would only live in that other scope, right? (You may have guessed that my knowledge of Erlang is very superficial so far)

@anonymous

“But that’s cheating!” he whined ;)

Leave a comment

(required)

(required)


Data Recovery Software