Symmetric difference

Revision as of 22:15, 2 December 2009 by MikeMol (talk | contribs) (Create task. Initial example.)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)

Given two lists A and B, where list A is:

  • John
  • Bob
  • Mary
  • Serena
Task
Symmetric difference
You are encouraged to solve this task according to the task description, using any language you may know.

and list B is:

  • Jim
  • Mary
  • John
  • Bob

Find the elements in list A which are not in list B, as well as the elements in list B which are not in list A.

Perl

<lang perl>#!/usr/bin/perl -w

use strict;

our @listA = ("John", "Bob", "Mary", "Serena"); our @listB = ("Jim", "Mary", "John", "Bob");

  1. Present our initial data set

print "In list A: " . &formatList(@listA) . "\n"; print "In list B: " . &formatList(@listB) . "\n";

print "Not in list A: " . &formatList(&inLeftNotRight(\@listB, \@listA)) . "\n"; print "Not in list B: " . &formatList(&inLeftNotRight(\@listA, \@listB)) . "\n";


  1. Checks for elements in the first listref that aren't in the second listref.
  2. We call this for each list, so we can get the symmetric difference.

sub inLeftNotRight {

   # Our parameters; The referenced left list contains the elements we're searching for.
   # The referenced right list is what we're searching in.
   # We have to use list *references*, as Perl would otherwise collapse
   # both lists into a list, and we wouldn't know
   # which elements came from what list.
   my $leftList = shift;
   my $rightList = shift;
   # Convert to a hash; It makes it easier to search.
   my %rightHash = map {$_, "Some filler value that doesn't matter"} @$rightList;
   # We'll use this as our return value.
   my @notFound;
   foreach (@$leftList)
   {
       # Since each element in the "right" list is now a key in %rightHash
       # we can use Perl's "exists" keyword to quickly find out if our element
       # is in %rightHash, and therefor is in @$rightList.
       
       # If it's not found, add it to @notFound.
       push @notFound, ($_)
           unless exists $rightHash{$_};
   }
   return @notFound;

}

  1. Formats our list as a string that's a little nicer to look at.

sub formatList {

   my @listing = @_;
   my $last = pop @listing;
   my $listString;
   $listString .= "$_, "
       foreach (@listing);
   $listString .= $last;
   return $listString;

}</lang>

This outputs:

In list A: John, Bob, Mary, Serena
In list B: Jim, Mary, John, Bob
Not in list A: Jim
Not in list B: Serena