34
\$\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\$ Commented Jan 13, 2022 at 7:11
  • \$\begingroup\$ @alephalpha Oh.. Apparently it is. \$\endgroup\$ Commented Jan 13, 2022 at 7:16

56 Answers 56

14
\$\begingroup\$

Java, 27 bytes

java.util.Collections::swap

Try it online!

\$\endgroup\$
3
  • \$\begingroup\$ Huh, something actually has a builtin for this. A little on the long side, but I guess a lambda would be longer still. \$\endgroup\$ Commented Oct 16, 2021 at 19:50
  • 3
    \$\begingroup\$ @Neil A lambda without using the builtin would be 31 bytes: (a,i,j)->a[i]^=a[j]^(a[j]=a[i]) \$\endgroup\$ Commented Oct 17, 2021 at 13:19
  • \$\begingroup\$ Hmm, in JShell java.util.* is imported by default. I wonder if you can leverage that by calling your language Java+JShell? \$\endgroup\$ Commented Oct 18, 2021 at 22:24
11
\$\begingroup\$

Python 2, 32 bytes

def f(a,b,l):l[a],l[b]=l[b],l[a]

Attempt This Online!

Mutates the input in-place.


26 bytes with a NumPy array:

def f(l,a):l[a[::-1]]=l[a]

Try it online!

\$\endgroup\$
5
  • \$\begingroup\$ Blazingly fast 2! \$\endgroup\$ Commented Oct 15, 2021 at 15:13
  • 2
    \$\begingroup\$ You're allowed to modify the input-list, so 32 bytes is possible with this approach. \$\endgroup\$ Commented Oct 15, 2021 at 15:14
  • \$\begingroup\$ @KevinCruijssen thanks! \$\endgroup\$ Commented Oct 15, 2021 at 15:17
  • \$\begingroup\$ The solution isn't specific to python 2 btw — it works just as well in python 3 \$\endgroup\$ Commented Oct 15, 2021 at 18:26
  • 1
    \$\begingroup\$ @AlexWaygood It's in Python 2 here because originally it had ;print l, which was shorter in 2 than 3 \$\endgroup\$ Commented Oct 15, 2021 at 19:37
9
\$\begingroup\$

Brain-Flak, 122 bytes

(([{}]{()<({}[()]<({}<>)<>>)>}{})<(({}({}))([{}]{})<{({}()<<>({}<>)>)}{}>)>())<>({}<<>{({}[()]<({}<>)<>>)}{}>){<>({}<>)}{}

Try it online!

Works with all integers, 138 bytes

(([{}]{()<({}[()]<({}<>)<>>)>}{})<(({}({}))([{}]{})<{({}()<<>({}<>)>)}{}>)>())<>({}<<>{({}[()]<({}<>)<>>)}{}>)<>([]){({}[()]<({}<>)<>>)}<>

Try it online!

The difference here is that while the first uses

{<>({}<>)}{}

To pull all the items from the off stack onto the on stack this one has to use

<>({}){({}[()]<({}<>)<>>)}<>

The first one pulls until it hits a zero and then stops, so this will fail to produce the correct result when there is a zero before the first swapped value. The second checks the height and pulls that many times, thus it will work for any list.

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

R, 31 bytes

Or R>=4.1, 24 bytes by replacing the word function with \.

function(L,A){L[A]=L[rev(A)];L}

Try it online!

Takes input as a vector and a vector of two 1-based indices.

\$\endgroup\$
7
\$\begingroup\$

Rust, 11 bytes

<[_]>::swap

Modify the input in-place.

Try it online!

\$\endgroup\$
1
  • \$\begingroup\$ shortest non-golfing language so far, isn't it? \$\endgroup\$ Commented Oct 18, 2021 at 18:35
7
\$\begingroup\$

Factor, 21 bytes

[ [ exchange ] keep ]

Try it online!

It's almost a built-in, but exchange has stack effect ( m n seq -- ) so we need keep to actually keep the sequence around on the data stack. 0-indexed.

\$\endgroup\$
6
\$\begingroup\$

Jelly, 7 5 bytes

œPżịF

Try it online!

Takes indexes as 1 indexed and reversed (so [b, a]), the Footer on TIO does this for you.

How it works

œPżịF - Main link. Takes indices I on the left, array A on the right
œP    - Partition A at the indices in I, not keeping the borders
   ị  - Retrieve the elements of A at the indices in I; [A[b], A[a]]
  ż   - Zip together
    F - Flatten
\$\endgroup\$
6
\$\begingroup\$

APL (Dyalog Unicode), 5 bytes

1-indexed. Reverse the sublist at the indices given by the second input of the first input.

⌽@⎕⊢⎕

Try it online!

\$\endgroup\$
6
\$\begingroup\$

Lean, 211 205 bytes

Helper:

notation `L`:=list ℕ
structure R:=m::(A:L)(B:ℕ)(C:L)
def r:L->L->ℕ->R
|p(h::t)0:=R.m p h t
|p(h::t)(n+1):=r(p++[h])t n
|_[]_:=R.m[]0[]

Actual function:

λl a b,let f:=r[]l a,z:=r[]f.C(b-a-1)in f.A++z.B::z.A++f.B::z.C

Try it online!

There's got to be a way to make product types and define type aliases easily, but I couldn't find it.

\$\endgroup\$
5
\$\begingroup\$

Jelly, 7 bytes

,U$yJ}ị

Try It Online!

A totally different Jelly 7-byter, so I figured I'd post this too. This is 1-indexed.

,U$yJ}ị    Main link; take indices on the left
,U$        Pair the indices with the reverse of itself ([[a, b], [b, a]])
   y       Apply this as a translation to
    J}     The indices of the right list (J takes a list of length L and returns [1, 2, ..., L])
      ị    Index back into the original list
\$\endgroup\$
5
\$\begingroup\$

Kotlin, 34 bytes

{l,x,y->l[x]=l[y].also{l[y]=l[x]}}

Ungolfed:

{ l, x, y ->
    l[x] = l[y].also { l[y] = l[x] }
}

This answer is a bit of an idiom in Kotlin.

Any#also() basically executes the given function, but then returns the receiver. In this case, the outer l[y] is evaluated, then .also() runs the lambda { l[y] = l[x] }, and returns the old value of l[y].

Try it online!

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

Haskell, 56 bytes

(?)=splitAt
(x!y)z|(q,d:e)<-y?z,(a,b:c)<-x?q=a++d:c++b:e

Try it online!

splitAt breaks the list into two parts at the particular index. This is useful because unlike (!!) we can get all the parts first.

To start we split at the second element, then the first. Splitting at the second first means we don't have to do extra arithmetic do calculate the offset which is required if we split at the first.

We use a pattern match to then get the first element of various pieces.

\$\endgroup\$
1
  • \$\begingroup\$ Blazingly fast! \$\endgroup\$ Commented Oct 15, 2021 at 15:12
4
\$\begingroup\$

Julia 1.0, 20 bytes

L*i=L[i]=L[i[[2,1]]]

Try it online!

1-indexed

expects L*[a,b] and mutates L

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

JavaScript, 31 bytes

l=>a=>b=>l[a]^=l[b]^(l[b]=l[a])

Only works for integers.

Try it online!

Thanks to Arnauld.

JavaScript, 32 bytes

l=>a=>b=>[l[a],l[b]]=[l[b],l[a]]

Try it online!

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

stacked, 5 bytes

$exch

Try it online!

You can remove the $ if input is allowed to be taken from the stack for 4 bytes. Convenient builtin to be sure.

22 bytes

[@j@i[i j nswap]apply]

Function. nswap performs a stack operation of swapping the ith and jth members, so we simply pop i and j and treat the stack at the top of the stack as the stack for nswap.

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

CJam, 4 bytes

{e\}

Code block (analogous to a function) that pops three elements from the stack: L, a, b, and pushes the swapped version of L. Indices a, b are 0-based.

Try it online!

Explanation

{  }  e# Define code block
 e\   e# Swap elements in array

Header:

q     e# Read all input as an unevaluated string, and push it to the stack
 ~    e# Evaluate string. Gives an array and two numbers, that are pushed

Footer:

~     e# Execute block
 p    e# Print string representation of the top of the stack
\$\endgroup\$
3
  • 1
    \$\begingroup\$ CJam is winning \o/ \$\endgroup\$ Commented Oct 15, 2021 at 19:56
  • 1
    \$\begingroup\$ Nice to see CJam beating Jelly for a to-the-point challenge like this. :) I'm actually surprised Jelly is 5 bytes. When I prepared my 4-byter 05AB1E program (which I will post if no one else will), I was expecting Jelly to have a 3-byte variant, but apparently not. \$\endgroup\$ Commented Oct 15, 2021 at 21:03
  • \$\begingroup\$ Apparently not only because Dennis is not around :-D \$\endgroup\$ Commented Oct 15, 2021 at 21:10
4
\$\begingroup\$

ErrLess, 6 bytes

0m:r.M

A macro.

Explanation

0 { Push a 0 to the stack to identify the macro } 
m { Start macro definition }
: { (L a b) -> (L (a b)) }
r { Rotate }
. { Halt (Return) }
M { End macro definition }

You can test it with the following program:

0m
 :r.
M

{ Test cases: }

1,2x3x4x5x6x7x8x9xax 3 7
0" # a? { Outputs "(1 2 3 8 5 6 7 4 9 10)" and a newline }

3,8x1x4xaxaxaxax 0 5
0" # a? { Outputs "(10 8 1 4 10 3 10 10)" and a newline }

5,1x4x2x3x 0 4
0" # a? { Outputs "(3 1 4 2 5)" and a newline }

5,6x 0 1
0" # a? { Outputs "(6 5)" and a newline }

2,2x2x 0 1
0" # a? { Outputs "(2 2 2)" and a newline }
.

Try it online!

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

Uiua, 3 bytes

⍜⊏⇌

Try it!

0-indexed.

\$\endgroup\$
3
\$\begingroup\$

Zsh, 39 bytes

eval "t=$`<i`;`<i`=$`<j`;`<j`=$"t
<<<$@

Attempt This Online!

Takes the array on the command line, with the two indices in files called i and j.

A bit of quote trickery to avoid escapes.

\$\endgroup\$
3
\$\begingroup\$

C (clang), 34 bytes

f(*a,i,j){a[i]^=a[j]^(a[j]=a[i]);}

Try it online!

Port of Unmitigated's C++ answer

\$\endgroup\$
3
\$\begingroup\$

Wolfram Language (Mathematica), 24 21 bytes

1-based indices, input is a list and a tuple of indices to reverse

Reverse~SubsetMap~##&

Try it online!

-3 bytes thanks to att.

\$\endgroup\$
1
  • 2
    \$\begingroup\$ 21 bytes \$\endgroup\$ Commented Oct 16, 2021 at 4:03
3
\$\begingroup\$

TI-Basic, 39 33 bytes

Prompt L,A,B
ʟL(A→X
ʟL(B→ʟL(A
X→ʟL(B
ʟL

-6 bytes thanks to MarcMush.

Input indices are 1-based. Output is stored in Ans and is displayed.

\$\endgroup\$
0
3
\$\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\$
3
\$\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\$
3
\$\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\$
3
\$\begingroup\$

Pip -xp, 8 bytes

aRAba@Rb

Takes input as two command-line arguments: the list, and a list containing the two indices (0-based). Attempt This Online!

Explanation

The -x flag is for taking the arguments as lists rather than strings; the -p flag is for displaying the result as a list rather than concatenated together.

a         ; In the first argument
 RA       ; replace the items at indices given by
   b      ; the second argument
    a     ; with the values in the first argument
     @    ; at indices
      Rb  ; reverse(second argument)

The straightforward version, which takes the indices as separate arguments, comes in at 9 bytes:

a@b::a@ca
   ::      ; Swap
a@b        ; the item in a at index b
     a@c   ; with the item in a at index c
        a  ; Output the new value of a
\$\endgroup\$
3
\$\begingroup\$

J, 4 bytes

C.~<

Input is L f (a b). The function is a dyadic hook.

Attempt This Online!

C.~<
   <   NB. box y
C.~    NB. apply a permutation in cycle form (C.) with the arguments swapped (~)   

C. fills in the incomplete permutation according to the identity permutation, thus, the items are swapped and everything else is left alone.

I suppose if a b could be given as a boxed list, then an improvement could be made by allowing the answer to be C. alone (meaning the input is given as (<a b) f L).

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

Python 2, 49 bytes

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

Try it online!

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

PHP, 46 bytes

fn(&$a,$i,$j)=>[$a[$i],$a[$j]]=[$a[$j],$a[$i]]

Try it online!

changes the array in place, 0 indexing

My first shot was with list, but PHP has array destructuring since 7.1, so it ends up like the JS answer with lots of dollars (money money money!)

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

Vyxal, 7 bytes

İṘZ(n÷Ȧ

Try it Online!

This could almost certainly be a bit smaller, but I got smol brain and can't think of a good way to swap values.

Explanation:

İ        # Get the values at the indexes
 Ṙ       # Reverse the values
  Z      # Zip the values with the new indexes
   (n    # For each value/index pair:
     ÷   #  Split the value/index
      Ȧ  #  Put the value at that index
\$\endgroup\$

Your Answer

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.