(phixonline)--> with javascript_semantics constant perms = {"ABCD", "CABD", "ACDB", "DACB", "BCDA", "ACBD", "ADCB", "CDAB", "DABC", "BCAD", "CADB", "CDBA", "CBAD", "ABDC", "ADBC", "BDCA", "DCBA", "BACD", "BADC", "BDAC", "CBDA", "DBCA", "DCAB"} -- 1: sum of letters sequence r = repeat(0,4) for i=1 to length(perms) do r = sq_add(r,perms[i]) end for r = sq_sub(max(r)+'A',r) printf(1,"%s\n",{r}) -- based on the notion that missing = sum(full)-sum(partial) would be true, -- and that sum(full) would be like {M,M,M,M} rather than a mix of numbers. -- the final step is equivalent to eg {1528,1530,1531,1529} -- max-r[i] -> { 3, 1, 0, 2} -- to chars -> { D, B, A, C} -- (but obviously both done in one line) -- 2: the xor trick r = repeat(0,4) for i=1 to length(perms) do r = sq_xor_bits(r,perms[i]) end for printf(1,"%s\n",{r}) -- (relies on the missing chars being present an odd number of times, non-missing chars an even number of times) -- 3: find least frequent letters r = " " for i=1 to length(r) do sequence count = repeat(0,4) for j=1 to length(perms) do integer cdx = perms[j][i]-'A'+1 count[cdx] += 1 end for r[i] = smallest(count,1)+'A'-1 end for printf(1,"%s\n",{r}) -- (relies on the assumption that a full set would have each letter occurring the same number of times in each position) -- (smallest(count,1) returns the index position of the smallest, rather than it's value) -- 4: test all permutations for i=1 to factorial(4) do r = permute(i,"ABCD") if not find(r,perms) then exit end if end for printf(1,"%s\n",{r}) -- (relies on brute force(!) - but this is the only method that could be made to cope with >1 omission)