30
\$\begingroup\$

Introduction:

Although we have a lot of challenges where swapping two items in a list is a subtask, like Single swaps of an array; Swap to Sort an Array; \$n\$ swaps into a nop; etc., we don't have the simple challenge of just swapping two items given a list and two indices.

Input:
A list with some positive integers \$L\$, and two indices \$a\$ and \$b\$.

Output:
The same list, with the two items at the given indices swapped.

Challenge rules:

  • The input-list is guaranteed to contain at least two items.
  • The input-list is guaranteed to only contain positive integers.
  • The input-indices can be either 0-based or 1-based (please specify in your answer which of the two you've used).
  • The input-indices are guaranteed to be valid indices based on the length of the input-list.
  • The input-indices are distinct, so will never be the same index. (The values in the input-list won't necessarily be distinct.)
  • You can assume \$a<b\$ (and you're allowed to take the inputs in reversed order if it helps).
  • I/O is flexible. You're allowed to take the input as a list/array/stream, from STDIN, as a delimited string, etc. You're allowed to modify the input-list directly, or return a new one with the two items swapped.

General rules:

  • This is , so the shortest answer in bytes wins.
    Don't let code-golf languages discourage you from posting answers with non-codegolfing languages. Try to come up with an as short as possible answer for 'any' programming language.
  • Standard rules apply for your answer with default I/O rules, so you are allowed to use STDIN/STDOUT, functions/method with the proper parameters and return-type, full programs. Your call.
  • Default Loopholes are forbidden.
  • If possible, please add a link with a test for your code (e.g. TIO).
  • Also, adding an explanation for your answer is highly recommended.

Test cases

All test cases use 0-based indices.

Inputs: L=[1,2,3,4,5,6,7,8,9,10], a=3, b=7
Output:   [1,2,3,8,5,6,7,4,9,10]

Inputs: L=[ 3, 8, 1, 4,10,10,10,10], a=0, b=5
Output:   [10, 8, 1, 4,10, 3,10,10]

Inputs: L=[5,1,4,2,3], a=0, b=4
Output:   [3,1,4,2,5]

Inputs: L=[5,6], a=0, b=1
Output:   [6,5]

Inputs: L=[2,2,2], a=0, b=1
Output:   [2,2,2]
\$\endgroup\$
7
  • \$\begingroup\$ For un-number-input-friendly languages can we take in chars? (Assumed no) \$\endgroup\$ Commented Oct 15, 2021 at 16:04
  • 2
    \$\begingroup\$ @null What are you using for the indices if your language of choice doesn't include numbers? \$\endgroup\$ Commented Oct 15, 2021 at 16:24
  • \$\begingroup\$ They probably meant that parsing a number from input is difficult, so they wanted to take input as the byte value of a character code. I think it is pretty common to allow this, but it technically restricts the values (not all of them will restrict to bytes, but there is usually some cap). \$\endgroup\$ Commented Oct 16, 2021 at 16:50
  • 1
    \$\begingroup\$ Duplicate? \$\endgroup\$
    – alephalpha
    Commented Jan 13, 2022 at 7:11
  • \$\begingroup\$ @alephalpha Oh.. Apparently it is. \$\endgroup\$ Commented Jan 13, 2022 at 7:16

49 Answers 49

1
2
2
\$\begingroup\$

Perl 5, 42 bytes

Updated TIO link to show positive indices only per challenge instructions (thanks, Kevin!)

sub a{($a,$b,$l)=@_;@$l[$a,$b]=@$l[$b,$a]}

Try it online!

Takes arguments as (first index, second index, 0-bound array). Mutates array in-place. Works with arrays containing any valid values, not just positive integers!

\$\endgroup\$
1
  • 1
    \$\begingroup\$ The input-list will only contain positive integers, so you might want to change your TIO-link. But since it does work when I replace the qw(foo bar baz) with qw(1 2 3), I've already upvoted your answer. :) \$\endgroup\$ Commented Oct 15, 2021 at 21:01
2
\$\begingroup\$

Clojure, 27 bytes

#(assoc % %2(% %3)%3(% %2))

The first argument % is a vector of numbers (not a list!) so that we don't need to use the function nth.

Edit: TIO

Edit 2: And actually you cannot assoc a list anyway.

\$\endgroup\$
0
2
\$\begingroup\$

Raku, 19 18 bytes

{@^a[@^i].=rotate}

Try it online!

0-based indexing. Modifies the list in-place. Takes the indices as a two-element list.

Edit: rotate has the same effect as reverse and is one character shorter. D'oh!

\$\endgroup\$
2
\$\begingroup\$

Desmos, 49 bytes

l=[1...L.length]
f(L,a,b)=\{l=a:L[b],l=b:L[a],L\}

Try It On Desmos!

Try It On Desmos! - Prettified

Surprisingly readable (if you know a bit of Desmos) even after I code golfed it.

Python Equivalent (switching to 0-based)

def f(L,a,b):
    returnList = []
    for l in range(len(L)):
        if l == a:
            returnList.append(L[b])
        elif l == b:
            returnList.append(L[a])
        else:
            returnList.append(L[l])
    return returnList
\$\endgroup\$
1
\$\begingroup\$

Charcoal, 14 bytes

IEθ⎇№ηκ§θ⁻Σηκι

Try it online! Link is to verbose version of code. Takes the 0-indexed indices as a 2-element array. Explanation:

  θ             Input array
 E              Map over elements
    №           Count of
      κ         Current index in
     η          Input indices
   ⎇            If found then
        θ       Input array
       §        Indexed by
           η    Input indices
          Σ     Take the sum
         ⁻      Minus
            κ   Current index
             ι  Else current element
I               Cast to string
                Implicitly print
\$\endgroup\$
1
\$\begingroup\$

C++, 51 46 38 bytes

#define f(a,i,j)a[i]^=a[j]^(a[j]=a[i])

Saved 5 bytes thanks to Kevin Cruijssen.

Saved 8 bytes thanks to AZTECCO.

Try it online!

\$\endgroup\$
1
1
\$\begingroup\$

Python 3, 49 bytes

lambda l,a,b:l[:a]+[l[b]]+l[a+1:b]+[l[a]]+l[b+1:]

Try it online!

The very simple way.

\$\endgroup\$
1
\$\begingroup\$

Python 2, 52 49 bytes

(longer than the approach by @pxeger, but doesn't mutate in-place

lambda a,b,l:l[:a]+[l[b]]+l[a+1:b]+[l[a]]+l[b+1:]

Try it Online!

EDIT: Thanks @Stephen Universe for saving me few bytes!


56 bytes by using list.pop and list.insert:

def f(a,b,l):l.insert(b,l.pop(a)),l.insert(a,l.pop(b-1))

Try it online!

\$\endgroup\$
4
1
\$\begingroup\$

Icon, 43 34 bytes

-9 bytes thanks to Kevin Cruijssen

procedure s(l,a,b)
l[a]:=:l[b]
end

Try it online!

1-indexed

\$\endgroup\$
2
  • 1
    \$\begingroup\$ Can Icon modify the input-list directly, so you possibly won't need the return l? \$\endgroup\$ Commented Oct 16, 2021 at 12:15
  • 1
    \$\begingroup\$ @KevinCruijssen Yes, of course, lists are passed by reference. I relied on the value returned by the function to print the result, which was stupid :). Thanks! \$\endgroup\$ Commented Oct 16, 2021 at 18:51
1
\$\begingroup\$

Pari/GP, 34 bytes

f(l,a,b)=[l[a],l[b]]=[l[b],l[a]];l

Try it online!

1-indexed

\$\endgroup\$
1
\$\begingroup\$

x86-16 machine code, 7 bytes

00000000: 8a01 8600 8801 c3                        .......

Listing

8A 01   MOV  AL, BYTE PTR[BX][DI]       ; put 'b' value into AL 
86 00   XCHG AL, BYTE PTR[BX][SI]       ; swap 'b' value with 'a' position 
88 01   MOV  BYTE PTR[BX][DI], AL       ; put 'a' value into 'b' position 
C3      RET                             ; return to caller 

Input \$L\$ at [BX], indices \$a\$ in SI, \$b\$ in DI, 0-based.

A test with our old friend DOS DEBUG:

enter image description here

\$\endgroup\$
1
\$\begingroup\$

Ruby, 30 bytes

->(l,a,b){l[a],l[b]=l[b],l[a]}

Mutates the input in-place. Direct port of @pxeger's approach including the link below:

Attempt This Online!

\$\endgroup\$
1
\$\begingroup\$

Tcl, 75 bytes

proc S {L a b} {set x [lindex $L $a]
lset L $a [lindex $L $b]
lset L $b $x}

Try it online!

\$\endgroup\$
1
\$\begingroup\$

C++ (gcc), 36 bytes

#define f(a,i,j)std::swap(a[i],a[j])

Try it online!

\$\endgroup\$
2
  • 1
    \$\begingroup\$ You can remove the space at )std for -1. \$\endgroup\$ Commented Dec 1, 2021 at 13:37
  • 1
    \$\begingroup\$ To my understanding, you are still needed to add #include<algorithm> or #include<utility> or any other libraries includes one of them in your byte count. \$\endgroup\$
    – tsh
    Commented Dec 27, 2021 at 12:45
1
\$\begingroup\$

AWK, 36 bytes

$$(NF-1)+=$$NF-($$NF=$$(NF-1)),NF-=2

Try it online!

Expected input

The input is a list of integers separated by spaces; the last two integers are the indexes of the values that must be swapped:

Input:
3 8 1 4 10 10 10 10 1 6
\_________________/ | |
 List of integers,  | L> Second index
starting index at 1 |
                    L> First index

Output:
10 8 1 4 10 3 10 10
|           |
\___________/
   Swapped

How it works

$$(NF-1)                        We take the integer which index is the value of the second-to-last integer,
        +=                      and add:
          $$NF                  the integer which index is the last integer
              -($$NF            minus itself,
                    =$$(NF-1))  except that it is now the integer which index is the second-to-last integer.
,NF-=2                          And let's remove the last two integers.
                                Phew! It should print the modified input, at last.

It uses this swapping oneliner: a+=b-(b=a).

For better understanding: NF is the variable for the number of fields, i.e, the number of integers in the input. $n is the nth integer in the input, so $NF is the last integer, and $(NF-1) the second-to-last integer. $$NF equals $($NF), that is the integer which index is the last integer.

NF-=2 reduces the number of fields by two, ignoring the two indexes.

\$\endgroup\$
1
\$\begingroup\$

MathGolf, 1 byte

µ

Apparently MathGolf has a builtin for this. Came across it in the docs when I was working on another challenge today. ¯\_(ツ)_/¯.

Takes the loose index-inputs before the list.

Try it online.

\$\endgroup\$
1
\$\begingroup\$

BQN, 18 10 bytes

Edit: -8 bytes thanks to Razetime

{⌽⌾(𝕨⊸⊏)𝕩}

Try it at BQN online REPL

Probably not the tersest code, but it works, which was no trivial accomplishment for my very limited BQN ability. Now quite short...
Will try to golf-down better as my abilities (gradually) improve. ...thanks to Razetime.

Swap ← {⌽⌾(𝕨⊸⊏)𝕩}          # define Swap function:
                            # list of 2 indices to swap on left = 𝕨
                            # array on right = 𝕩.
                            
         ⌾                  # 'under' = apply function on LHS
                            # to elements specified by RHS  
          (𝕨⊸⊏)            #   RHS: elements of 𝕩 at indices 𝕨
        ⌽                   #   LHS: reverse
\$\endgroup\$
4
  • 1
    \$\begingroup\$ {⌽⌾(𝕨⊸⊏)𝕩} reads as pick the elements, reverse the picked elements, and put them back in the same place in the array. \$\endgroup\$
    – Razetime
    Commented Dec 28, 2021 at 3:59
  • 1
    \$\begingroup\$ @Razetime - Ha ha. Well, that's how it should have been done. Thanks! \$\endgroup\$ Commented Dec 28, 2021 at 10:42
  • 1
    \$\begingroup\$ the idea of Under is to a) apply right function as a transformation, b) apply left function to transformed data, c) invert the transformation. With this understanding, you can do some very interesting things for golf. \$\endgroup\$
    – Razetime
    Commented Dec 28, 2021 at 12:50
  • \$\begingroup\$ @Razetime - That's a great explanation. Thanks. \$\endgroup\$ Commented Dec 28, 2021 at 13:17
1
\$\begingroup\$

Uiua, 3 bytes

⍜⊏⇌

Try it!

0-indexed.

\$\endgroup\$
0
\$\begingroup\$

C# (Visual C# Compiler), 75 bytes

List<int> f(List<int> L,int a,int b){var x=L[a];L[a]=L[b];L[b]=x;return L;}

Try it online!

Working only for int's. Thinking about evolving it to generics after.

\$\endgroup\$
5
  • \$\begingroup\$ 34 bytes (only works for ints). \$\endgroup\$ Commented Dec 1, 2021 at 13:40
  • \$\begingroup\$ In that case, I am in doubt if I should or not taking into the byte count the Action part or not. \$\endgroup\$
    – sergiol
    Commented Dec 1, 2021 at 13:45
  • \$\begingroup\$ No, you don't have to count them for lambda functions. Let me see if I can find the relevant meta-discussion for it. \$\endgroup\$ Commented Dec 1, 2021 at 13:48
  • \$\begingroup\$ Took a while to find, but here is one of the many discussions. The top-voted answer allowing it without types has 17 upvotes, and the others against it are in the negative. (Small note: recursive lambdas, or using multiple lambdas isn't allowed, so those should still be in the full-written style in C#/Java.) \$\endgroup\$ Commented Dec 1, 2021 at 14:06
  • \$\begingroup\$ Anyway, if you prefer to keep your current style instead of the lambda, it could be: 55 bytes. 🤷 \$\endgroup\$ Commented Dec 1, 2021 at 14:10
1
2

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.