Find the missing permutation

From Rosetta Code

These are all of the permutations of the symbols A, B, C and D, except for one that's not listed. Find that missing permutation.

ABCD
CABD
ACDB
DACB
BCDA
ACBD
ADCB
CDAB
DABC
BCAD
CADB
CDBA
CBAD
ABDC
ADBC
BDCA
DCBA
BACD
BADC
BDAC
CBDA
DBCA
DCAB

C

Much of this code duplicates code from Permutation Sort task. Here ElementType is a char instead of a char *. <lang c>#include <stdlib.h>

  1. include <stdio.h>
  2. include <string.h>

typedef struct pi *Permutations;

typedef char ElementType;

struct pi {

   short list_size;
   short *counts;
   ElementType *crntperm;

};

Permutations PermutationIterator( ElementType *list, short listSize) {

   int ix;
   Permutations p = (Permutations)malloc(sizeof(struct pi));
   p->list_size = listSize;
   p->counts = (short *)malloc( p->list_size * sizeof(short));
   p->crntperm = (ElementType *)malloc( p->list_size * sizeof(ElementType));
   for (ix=0; ix<p->list_size; ix++) {
       p->counts[ix] = ix;
       p->crntperm[ix] = list[ix];
   }
   return p;

}

void FreePermutations( Permutations p) {

   if (NULL == p) return;
   if (p->crntperm) free(p->crntperm);
   if (p->counts) free(p->counts);
   free(p);

}

  1. define FREE_Permutations(pi) do {\
   FreePermutations(pi); pi=NULL; } while(0)


ElementType *FirstPermutation(Permutations p) {

   return p->crntperm;

}

ElementType *NextPermutation( Permutations p) {

   int ix, j;
   ElementType *crntp, t;
   crntp = p->crntperm;
   ix = 1;
   do {
       t = crntp[0];
       for(j=0; j<ix; j++) crntp[j] = crntp[j+1];
       crntp[ix] = t;
       if (p->counts[ix] > 0) break;
       ix += 1;
   } while (ix < p->list_size);
   if (ix == p->list_size) return NULL;
   p->counts[ix] -= 1;
   while(--ix) {
       p->counts[ix] = ix;
   }
   return crntp;

}

static char *pmList[] = {

 "ABCD","CABD","ACDB","DACB",
 "BCDA","ACBD","ADCB","CDAB",
 "DABC","BCAD","CADB","CDBA",
 "CBAD","ABDC","ADBC","BDCA",
 "DCBA","BACD","BADC","BDAC",
 "CBDA","DBCA","DCAB" };
  1. define LISTSIZE (sizeof(pmList)/sizeof(pmList[0]))

int main( int argc, char *argv[] ) {

   short size =4;
   ElementType *prm;
   ElementType mx[] = "ABCD";
   int k;
   char ss[8];
   Permutations pi = PermutationIterator(mx, size);
   for ( prm = FirstPermutation(pi); prm; prm = NextPermutation(pi)) {
       strncpy(ss, prm, 4);  ss[4] = 0;
       for (k=0; k<LISTSIZE; k++) {
           if (0 == strcmp(pmList[k], ss)) break;
       }
       if (k==LISTSIZE) {
           printf("Permutation %s was not in list\n", ss);
           break;
       }
   }
   FreePermutations( pi);
   return 0;

}</lang>

Haskell

Works with: GHC version 6.10+

<lang haskell>import Data.List import Control.Monad import Control.Arrow

deficientPermsList =

 ["ABCD","CABD","ACDB","DACB",
 "BCDA","ACBD","ADCB","CDAB",
 "DABC","BCAD","CADB","CDBA",
 "CBAD","ABDC","ADBC","BDCA",
 "DCBA","BACD","BADC","BDAC",
 "CBDA","DBCA","DCAB"]

missingPerm :: (Eq a) => a -> a missingPerm = (\\) =<< permutations . nub. join</lang> Use:

missingPerm deficientPermsList

Python

Works with: Python version 2.6+

<lang python>from itertools import permutations

given = ABCD CABD ACDB DACB BCDA ACBD ADCB CDAB DABC BCAD CADB CDBA

          CBAD ABDC ADBC BDCA DCBA BACD BADC BDAC CBDA DBCA DCAB.split()

allPerms = [.join(x) for x in permutations(given[0])]

missing = list(set(allPerms) - set(given)) # ['DBAC']</lang>

Ruby

Works with: Ruby version 1.8.7+

<lang ruby>given = %w{

 ABCD CABD ACDB DACB BCDA ACBD ADCB CDAB DABC BCAD CADB CDBA
 CBAD ABDC ADBC BDCA DCBA BACD BADC BDAC CBDA DBCA DCAB

}

all = given[0].split(//).permutation.collect {|perm| perm.join()}

missing = all - given # ["DBAC"]</lang>

Tcl

Library: tcllib

<lang tcl>package require struct::list package require struct::set

  1. Make complete list of permutations of a string of characters

proc allCharPerms s {

   set perms {}
   set p [struct::list firstperm [split $s {}]]
   while {$p ne ""} {

lappend perms [join $p {}] set p [struct::list nextperm $p]

   }
   return $perms

}

  1. The set of provided permutations (wrapped for convenience)

set have {

   ABCD CABD ACDB DACB BCDA ACBD ADCB CDAB DABC BCAD CADB CDBA CBAD ABDC
   ADBC BDCA DCBA BACD BADC BDAC CBDA DBCA DCAB

}

  1. Get the real list of permutations...

set all [allCharPerms [lindex $have 0]]

  1. Find the missing one(s)!

set missing [struct::set difference $all $have] puts "missing permutation(s): $missing"</lang> Outputs

missing permutation(s): DBAC