Find the missing permutation: Difference between revisions
Content added Content deleted
Not a robot (talk | contribs) (Add 8086 assembly) |
(→{{header|Picat}}: Moved into subsections.) |
||
Line 2,557: | Line 2,557: | ||
=={{header|Picat}}== |
=={{header|Picat}}== |
||
Here are several approaches, including constraint modelling, sets (ordset), and permutations. |
Here are several approaches, including constraint modelling, sets (ordset), and permutations. |
||
<lang picat>import util. |
|||
import ordset. |
|||
import cp. |
|||
All assume that the variables P1 and/or Perms has been defined: |
|||
main => go. |
|||
<lang picat> P1 = ["ABCD","CABD","ACDB","DACB","BCDA","ACBD", |
|||
go => |
|||
P1 = ["ABCD","CABD","ACDB","DACB","BCDA","ACBD", |
|||
"ADCB","CDAB","DABC","BCAD","CADB","CDBA", |
"ADCB","CDAB","DABC","BCAD","CADB","CDBA", |
||
"CBAD","ABDC","ADBC","BDCA","DCBA","BACD", |
"CBAD","ABDC","ADBC","BDCA","DCBA","BACD", |
||
"BADC","BDAC","CBDA","DBCA","DCAB"], |
"BADC","BDAC","CBDA","DBCA","DCAB"], |
||
Perms = permutations("ABCD"), |
Perms = permutations("ABCD"), |
||
% ... |
|||
</lang> |
|||
===Very imperative=== |
|||
<lang Picat> % ... |
|||
Missing = _, |
|||
Missing = _, |
|||
foreach(P in Perms, Missing = _) |
|||
Found = false, |
|||
foreach(T in P1) |
|||
if P == T then |
|||
if P == T then |
|||
Found := true |
|||
end, |
|||
if not Found then |
|||
Missing := P |
|||
end |
end |
||
end, |
end, |
||
if not Found then |
|||
println(missing1=Missing), |
|||
Missing := P |
|||
end |
|||
end, |
|||
println(missing1=Missing).</lang> |
|||
===Somewhat less imperative=== |
|||
<lang Picat> % ... |
|||
Missing2 = _, |
|||
Missing2 = _, |
|||
foreach(P in Perms, Missing2 = _) |
|||
if not member(P,P1) then |
|||
if not member(P,P1) then |
|||
Missing2 := P |
|||
Missing2 := P |
|||
end |
end |
||
end, |
|||
println(missing2=Missing2), |
|||
println(missing2=Missing2).</lang> |
|||
===Using findall=== |
|||
<lang Picat> % ... |
|||
println(missing3=difference(Perms,P1)). |
|||
difference(Xs,Ys) = findall(X,(member(X,Xs),not(member(X,Ys)))).</lang> |
|||
% using findall (predicate) |
|||
println(missing3=difference(Perms,P1)), |
|||
===findall approach as a one-liner=== |
|||
<lang Picat> % ... |
|||
println(missing4=findall(X,(member(X,Perms),not(member(X,P1))))), |
|||
println(missing4=findall(X,(member(X,Perms),not(member(X,P1))))).</lang> |
|||
===Using ordsets=== |
|||
The module <code>ordsets</code> must be imported, |
|||
println(missing5=subtract(new_ordset(Perms),new_ordset(P1))), |
|||
<lang Picat>import ordsets. |
|||
% ... |
|||
println(missing5=subtract(new_ordset(Perms),new_ordset(P1))).</lang> |
|||
===List comprehension=== |
|||
List comprehension with <code>membchk/1</code> for the check) |
|||
println(missing6=[P:P in Perms,not member(P,P1)]), |
|||
<lang Picat> % ... |
|||
println(missing6=[P:P in Perms,not membchk(P,P1)])</lang> |
|||
===Using maps=== |
|||
<lang Picat> % ... |
|||
Map = new_map(), |
|||
Map = new_map(), |
|||
foreach(P in P1) Map.put(P,1) end, |
|||
foreach(P in P1) Map.put(P,1) end, |
|||
println(missing7=[P: P in Perms, not Map.has_key(P)]).</lang> |
|||
==="Merge sort" variants=== |
|||
"Merge sort" variants, using sorted lists. <code>zip/2</code> requires that the length of the two lists are the same, hence the "dummy". |
|||
<lang Picat> % ... |
|||
PermsSorted = Perms.sort(), |
|||
P1Sorted = P1.sort(), |
|||
Found2 = false, |
|||
foreach({P,PP} in zip(PermsSorted,P1Sorted ++ ["DUMMY"]), Found2 = false) |
|||
if P != PP then |
|||
println(missing8=P), |
|||
Found2 := true |
|||
end |
|||
end, |
|||
A = [cond(P == PP,1,0) : {P,PP} in zip(PermsSorted,P1Sorted ++ ["DUMMY"])], |
|||
% "merge sort" variant, using sorted lists |
|||
println(missing9=[PermsSorted[I] : I in 1..PermsSorted.length, A[I] = 0].first()), |
|||
% (zip/2 requires that the length of the two lists are the same, hence the dummy) |
|||
PermsSorted = Perms.sort(), |
|||
P1Sorted = P1.sort(), |
|||
Found2 = false, |
|||
foreach({P,PP} in zip(PermsSorted,P1Sorted ++ ["DUMMY"]), Found2 = false) |
|||
if P != PP then |
|||
println(missing8=P), |
|||
Found2 := true |
|||
end |
|||
end, |
|||
% shorter |
|||
% variant with list comprehension |
|||
println(missing10=[P:{P,PP} in zip(PermsSorted,P1Sorted ++ ["DUMMY"]), P != PP].first()),</lang> |
|||
println(missing9=[PermsSorted[I] : I in 1..PermsSorted.length, A[I] = 0].first()), |
|||
===Constraint modelling=== |
|||
% shorter |
|||
The <code>cp</code> module must be imported. |
|||
println(missing10=[P:{P,PP} in zip(PermsSorted,P1Sorted ++ ["DUMMY"]), P != PP].first()), |
|||
<lang Picat>import cp. |
|||
% ... |
|||
% CP variant |
|||
ABCD = new_map(['A'=1,'B'=2,'C'=3,'D'=4]), |
ABCD = new_map(['A'=1,'B'=2,'C'=3,'D'=4]), |
||
% convert to integers (for the table constraint) |
% convert to integers (for the table constraint) |
||
P1Table = [ [ABCD.get(C,0) : C in P].to_array() : P in P1], |
P1Table = [ [ABCD.get(C,0) : C in P].to_array() : P in P1], |
||
Line 2,643: | Line 2,654: | ||
solve(Missing3), |
solve(Missing3), |
||
ABCD2 = "ABCD", |
ABCD2 = "ABCD", |
||
println(missing11=[ABCD2[I] : I in Missing3]) |
println(missing11=[ABCD2[I] : I in Missing3]).</lang> |
||
===Matrix approach=== |
|||
<lang Picat> % ... |
|||
PermsLen = Perms.length, |
PermsLen = Perms.length, |
||
P1Len = P1.length, |
P1Len = P1.length, |
||
Line 2,653: | Line 2,664: | ||
A2[I,J] := 1 |
A2[I,J] := 1 |
||
end, |
end, |
||
println(missing12=[Perms[I] : I in 1..PermsLen, sum([A2[I,J] : J in 1..P1Len])=0]) |
println(missing12=[Perms[I] : I in 1..PermsLen, sum([A2[I,J] : J in 1..P1Len])=0]).</lang> |
||
===Xor variant=== |
|||
{{trans|Raku}} |
|||
<lang Picat> % ... |
|||
println(missing13=to_fstring("%X",reduce(^,[parse_term("0x"++P):P in P1]))).</lang> |
|||
===Count occurrences=== |
|||
% inspired by the Perl 6 xor variant |
|||
Count the character with the least occurrence (=5) for each positions (1..4). Some variants. |
|||
println(missing13=to_fstring("%X",reduce(^,[parse_term("0x"++P):P in P1]))), |
|||
{{trans|K}} |
|||
<lang Picat> % ... |
|||
% count the character with the least occurrence (=5) for each positions (1..4) |
|||
% (based on my K version) |
|||
println(missing14=[[O:O=5 in Occ]:Occ in [occurrences([P[I]:P in P1]):I in 1..4]]), |
println(missing14=[[O:O=5 in Occ]:Occ in [occurrences([P[I]:P in P1]):I in 1..4]]), |
||
% variant using sorting the occurrences |
% variant using sorting the occurrences |
||
println(missing15a=[C:C=_ in [sort2(Occ).first():Occ in [occurrences([P[I]:P in P1]):I in 1..4]]]), |
println(missing15a=[C:C=_ in [sort2(Occ).first():Occ in [occurrences([P[I]:P in P1]):I in 1..4]]]), |
||
% transpose instead of array index |
% transpose instead of array index |
||
println(missing15b=[C:C=_ in [sort2(O).first():T in transpose(P1),O=occurrences(T)]]), |
println(missing15b=[C:C=_ in [sort2(O).first():T in transpose(P1),O=occurrences(T)]]), |
||
% extract the values with first |
% extract the values with first |
||
println(missing15c=[sort2(O).first():T in transpose(P1),O=occurrences(T)].map(first)), |
println(missing15c=[sort2(O).first():T in transpose(P1),O=occurrences(T)].map(first)), |
||
println(missing15d=[sort2(O).first().first():T in transpose(P1),O=occurrences(T)]), |
println(missing15d=[sort2(O).first().first():T in transpose(P1),O=occurrences(T)]), |
||
println(missing15e=[S[1,1]:T in transpose(P1),S=sort2(occurrences(T))]), |
|||
println(missing15e=[S[1,1]:T in transpose(P1),S=sort2(occurrences(T))]). |
|||
% delete/2 |
|||
% return a map with the elements and the number of occurrences |
|||
occurrences(List) = Map => |
|||
Map = new_map(), |
|||
foreach(E in List) |
|||
Map.put(E, cond(Map.has_key(E),Map.get(E)+1,1)) |
|||
end, |
|||
Perms2 = Perms, |
Perms2 = Perms, |
||
foreach(P in P1) Perms2 := delete(Perms2,P) end, |
foreach(P in P1) Perms2 := delete(Perms2,P) end, |
||
Line 2,678: | Line 2,701: | ||
nl. |
nl. |
||
difference(Xs,Ys) = findall(X,(member(X,Xs),not(member(X,Ys)))). |
|||
% return a map with the elements and the number of occurrences |
|||
occurrences(List) = Map => |
|||
Map = new_map(), |
|||
foreach(E in List) |
|||
Map.put(E, cond(Map.has_key(E),Map.get(E)+1,1)) |
|||
end. |
|||
% sort a map according to values |
% sort a map according to values |
||
Line 2,693: | Line 2,706: | ||
</lang> |
</lang> |
||
Running all these snippets: |
|||
Output: |
|||
{{out}} |
|||
<pre> |
<pre> |
||
missing1 = DBAC |
missing1 = DBAC |
||
Line 2,715: | Line 2,728: | ||
missing15d = DBAC |
missing15d = DBAC |
||
missing15e = DBAC |
missing15e = DBAC |
||
missing16 = [DBAC] |
missing16 = [DBAC]</pre> |
||
</pre> |
|||
=={{header|PicoLisp}}== |
=={{header|PicoLisp}}== |