| Bytes | Lang | Time | Link |
|---|---|---|---|
| 072 | Wolfram Language Mathematica | 250424T082658Z | att |
| 024 | Uiua 0.16.0dev.1 | 250424T100607Z | harana |
| 131 | Python 3 | 250401T133050Z | Jitse |
| 144 | JavaScript ES6 | 250401T103943Z | Arnauld |
| 135 | Maple | 250401T185929Z | dharr |
| 205 | Python3 | 250401T131455Z | Ajax1234 |
| 086 | Charcoal | 250401T221403Z | Neil |
| 016 | Jelly | 250401T183911Z | Jonathan |
| 017 | 05AB1E | 250401T081646Z | Kevin Cr |
Wolfram Language (Mathematica), 72 bytes
<|D@@(p##)&@@Cycles@*List/@#->#&/@Permutations@Subsets[p=#,{2}]|>@{}&
Brute force. is \[PermutationProduct]. Returns Missing["KeyAbsent", {}] if impossible.
D@@+p## (1 byte shorter than D@@(p##)) seems to be interpreted incorrectly on the version on TIO, as Times should have lower precedence than PermutationProduct.
Uiua 0.16.0-dev.1, 24 bytes (SBCS)
⍣⊢0▽≡⌟(≍⍆⤙⤚∧⍜⊏⇌)⧅≠∞⧅₂<°⊏
Input permutation as list. Returns a list of pairs or 0 if not possible.
Explanation:
⍣⊢0▽≡⌟(≍⍆⤙⤚∧⍜⊏⇌)⧅≠∞⧅₂<°⊏
°⊏ # Pushes the [0, input length) array to the top of the stack, keeping the input
⧅≠∞⧅₂< # Get all permutations of ordered pairs of indices
≡⌟( ) # For each permutation of pairs:
∧⍜⊏⇌ # Perform each swap on the input
⤚ # Keep the current permutation at the second position of the stack
≍⍆⤙ # Checks if the modified array is sorted and returns a boolean
▽ # Return an array of valid permutations of pairs
⍣ # Run the first function, if it errors, run the second function
⊢ # Returns the first list of pairs, or errors if there are none
0 # Outputs 0
Python 3, 131 bytes
f=lambda a,*p:max([f(a[:i]+[a[j]]+a[i+1:j]+[a[i]]+a[j+1:],*p,(i,j))for i in a for j in a if((i,j)in p)*j<j>i]or[[p][a>sorted(a):]])
-16 bytes thanks to Mukundan314
-1 byte thanks to l4m2
JavaScript (ES6), 144 bytes
Expects a 0-indexed input. Returns either a list of pairs "i,j" or 0.
f=(a,p=o=[],q=(n=a.length)*~-n)=>!q^a.some((x,i)=>q?a.some((y,j)=>i<j&!p.includes(k=i+[,j],d=[...a],d[i]=y,d[j]=x)&&f(d,o=[...p,k],q-2)):x-i)&&o
Maple, 135 bytes
proc(S)seq([(s:=<S>),seq((s[w]:=s[[w[2],w[1]]]),w=q),`if`(seq(s)={S[]}[],RETURN(q),0)],q=(c:=combinat):-permute(c:-choose(S,2)));0;end;
Input permutation as list. Output is list of lists, e.g., [[1, 2], [1, 3], [1, 4], [2, 4], [2, 3], [3, 4]], or 0 if not possible.
Ungolfed version:
f:=proc(S) # accepts a list
p:=(c:=combinat):-permute(c:-choose(S,2)); # all permutations of combinations of 2 things from input
for q in p do # for each list of swaps
s:=<S>; # make a Vector so can use smart indexing
seq((s[w]:=s[[w[2],w[1]]]),w=q); # do the swaps
if seq(s)={S[]}[] then return q fi # check the entries are 1,2,...,n; if so return list of swaps
od;
0 # return 0 if it can't be done.
end;
Python3, 205 bytes
def f(l):
q=[(l,{(i,I)for i in range(len(l))for I in range(i+1,len(l))},[])]
for l,o,p in q:
if l==sorted(l)and not o:return p
for i,I in o:L=[*l];A=L[i];L[i]=L[I];L[I]=A;q+=[(L,o-{(i,I)},p+[(i,I)])]
Charcoal, 86 bytes
FLθFι⊞υ⟦κι⟧≔⟦⟦θ⟦⟧⟧⟧ηFη¿¬ⅈ«≔⊟ιζF⁻υζ«≔E⌊ι⎇№κμ§⌊ι⁻Σκμλε≔⁺ζ⟦κ⟧δ¿⬤ε∨⁼λμ⊙⁻υδ№νμ¿⁻υδ⊞η⟦εδ⟧⭆¹δ
Try it online! Link is to verbose version of code. 0-indexed. Explanation:
FLθFι⊞υ⟦κι⟧
Generate a list of all the possible swaps.
≔⟦⟦θ⟦⟧⟧⟧ηFη¿¬ⅈ«
Start a breath-first search with the original list and no swaps yet, but stop if a solution is found.
≔⊟ιζF⁻υζ«
Loop over the remaining swaps.
≔E⌊ι⎇№κμ§⌊ι⁻Σκμλε
Make a new list of values with the relevant positions swapped.
≔⁺ζ⟦κ⟧δ
Make an updated list of swaps so far.
¿⬤ε∨⁼λμ⊙⁻υδ№νμ
If a solution is still potentially possible, then:
¿⁻υδ
If there are still some swaps left, then...
⊞η⟦εδ⟧
... save the new values and swaps to the search list, otherwise...
⭆¹δ
... output the found swaps.
Jelly, 16 bytes
Brute force version, I'm unsure if this is the best way to go here though.
ŒcŒ!żU$y@ƒJƑɗƇƊḢ
A monadic Link that accepts a permutation of \$[1,N]\$ and yields a list of pairs to swap or \$0\$ if not possible.
05AB1E, 18 17 bytes
ā<.Æœ.ΔvDyèRyǝ}āQ
-1 byte thanks to @l4m2
0-indexed. Outputs -1 if not result is possible.
Try it online or verify all test cases.
Explanation:
ā # Push a list in the range [1, (implicit) input-length]
< # Decrease each by 1 to the range [0,length)
.Æ # Get all 2-element combinations of these indices
œ # Get all permutations of these index-pairs
.Δ # Find the first permutation that's truthy by,
# or -1 if none is truthy
v # Pop and loop over each pair `y`:
D # Duplicate the current list
# (which will be the input-list in the first iteration)
yè # Get the values at index-pair `y`
R # Reverse the values in this pair
yǝ # Insert them back at index-pair `y`
}ā # After the inner loop: Push a list in the range [1,length] again
Q # Check that the two lists are equal (aka, the list is sorted)
# (after which the found result, or -1, is output implicitly)