SPUG: swapping two numbers

Michael R. Wolf MichaelRWolf at att.net
Fri Jun 23 13:39:15 PDT 2006

I was digging through some old code and came across a proof that I had done
that you can swap two numbers in place (i.e. without using an external
temporary value).

Of course, in Perl, we can just do this:
 ($x, $y) = ($y, $x)

But I was challenged (at a GSLUG meeting) to do it in a language-independent
way.  Since the guy mentioned he had known the solution for 20+ years, I
descended into bit-flipping land and came up with a solution.

(BTW:  I'm not sure why my first gut reaction was right.  I guess I've been
in the business long enough.  There's no way my conscious mind came up with
this solution!!!  Nevertheless, my subconscious came up with this solution
within about 3 seconds.  Brains are amazing!!!)

I present it here as an interesting piece of code:

#! /usr/bin/perl -w

use warnings;
use strict;

my $iterations = shift @ARGV || 10;

for (my $i = 0; $i < $iterations; $i++) {
    my ($orig_a, $a) = (int(rand 1000)) x 2;
    my ($orig_b, $b) = (int(rand 1000)) x 2;

    # Original solution:
    #    $a = $a ^ $b;
    #    $b = $b ^ $a;
    #    $a = $a ^ $b;

    # Refined to use op=
    #    $a ^= $b;
    #    $b ^= $a;
    #    $a ^= $b;

    # Utilizing op= value, factored onto one line
    #    $a ^= ($b ^= ($a ^= $b));

    # Refined to remove unnecessary parens
    $a ^= $b ^= $a ^= $b;

    printf("%3d %3d %s\n" =>
	   $a, $b,
	   $a == $orig_b && $b == $orig_a ? "passed" : "failed: a was
$orig_a, b was $orig_b");

Michael R. Wolf
    All mammals learn by playing!
        MichaelRWolf at att.net

More information about the spug-list mailing list