g | x | w | all
Bytes Lang Time Link
072Wolfram Language Mathematica250424T082658Zatt
024Uiua 0.16.0dev.1250424T100607Zharana
131Python 3250401T133050ZJitse
144JavaScript ES6250401T103943ZArnauld
135Maple250401T185929Zdharr
205Python3250401T131455ZAjax1234
086Charcoal250401T221403ZNeil
016Jelly250401T183911ZJonathan
01705AB1E250401T081646ZKevin Cr

Wolfram Language (Mathematica), 72 bytes

<|D@@(p##)&@@Cycles@*List/@#->#&/@Permutations@Subsets[p=#,{2}]|>@{}&

Try it online!

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.

Pad link with tests

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):]])

Try it online!

-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

Try it online!

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)])]

Try it online!

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.

Try it online!

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)