26
\$\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\$
3
  • \$\begingroup\$ For un-number-input-friendly languages can we take in chars? (Assumed no) \$\endgroup\$
    – null
    Oct 15 at 16:04
  • 2
    \$\begingroup\$ @null What are you using for the indices if your language of choice doesn't include numbers? \$\endgroup\$ Oct 15 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\$ Oct 16 at 16:50

47 Answers 47

15
\$\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\$
    – Neil
    Oct 16 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\$ Oct 17 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\$ Oct 18 at 22:24
9
\$\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\$
    – null
    Oct 15 at 15:13
  • 2
    \$\begingroup\$ You're allowed to modify the input-list, so 32 bytes is possible with this approach. \$\endgroup\$ Oct 15 at 15:14
  • \$\begingroup\$ @KevinCruijssen thanks! \$\endgroup\$
    – pxeger
    Oct 15 at 15:17
  • \$\begingroup\$ The solution isn't specific to python 2 btw — it works just as well in python 3 \$\endgroup\$ Oct 15 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\$
    – pxeger
    Oct 15 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
7
\$\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\$
    – Tom
    Oct 18 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\$

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\$

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\$
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\$
    – null
    Oct 15 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\$

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\$
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\$

Pip -xp, 8 bytes

aRAba@Rb

Takes input as two command-line arguments: the list, and a list containing the two indices (0-based). Like this: [1;2;3;4] [1;3].

Replit! Or, here's a 9-byte equivalent (simulating the -x flag) in Pip Classic: Try it 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\$

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\$

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\$

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\$
    – Luis Mendo
    Oct 15 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\$ Oct 15 at 21:03
  • \$\begingroup\$ Apparently not only because Dennis is not around :-D \$\endgroup\$
    – Luis Mendo
    Oct 15 at 21:10
3
\$\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\$
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\$
2
\$\begingroup\$

Retina 0.8.2, 99 bytes

2`\d+
$*
1*(,1*);
$1,$&
(?<=(?=.*;(?<-2>\d+,)*(\d+))(1)*,(?(4)$)(?<-4>1)*(,1*)?;(\d+,)*)\d+
$1
.*;

Try it online! Link includes test cases. Takes input in the form a,b;L. Explanation:

2`\d+
$*

Convert the indices to unary.

1*(,1*);
$1,$&

Make a second copy of b so that we now have b,a,b;L.

(?<=(?=.*;(?<-2>\d+,)*(\d+))(1)*,(?(4)$)(?<-4>1)*(,1*)?;(\d+,)*)\d+
$1

Match an integer in L, with index $#4 equalling either a or b (using a .NET balancing group), then match the other index in $#2, and match the integer at that index as the replacement for this integer (also using a .NET balancing group).

.*;

Delete a and b.

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

Red, 33 bytes

func[l a b][swap at l a at l b l]

Try it online!

1-indexed

\$\endgroup\$
2
\$\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\$
    – att
    Oct 16 at 4:03
2
\$\begingroup\$

Core Maude, 158 bytes

mod S is pr ARRAY{Nat,Nat0}*(sort Array{Nat,Nat0}to A). var I J X Y : Nat . op
s : A Nat Nat -> A . eq s(A:A,I,J)= insert(I,A:A[J],insert(J,A:A[I],A:A)). endm

Example Session

             \||||||||||||||||||/
           --- Welcome to Maude ---
             /||||||||||||||||||\
         Maude 3.1 built: Oct 12 2020 20:12:31
         Copyright 1997-2020 SRI International
               Sat Oct 16 22:01:13 2021
Maude> mod S is pr ARRAY{Nat,Nat0}*(sort Array{Nat,Nat0}to A). var I J X Y : Nat . op
> s : A Nat Nat -> A . eq s(A:A,I,J)= insert(I,A:A[J],insert(J,A:A[I],A:A)). endm
Maude> red s(0 |-> 1 ; 1 |-> 2 ; 2 |-> 3 ; 3 |-> 4 ; 4 |-> 5 ; 5 |-> 6 ; 6 |-> 7 ;
>       7 |-> 8 ; 8 |-> 9 ; 9 |-> 10, 3, 7) .
result A: 0 |-> 1 ; 1 |-> 2 ; 2 |-> 3 ; 3 |-> 8 ; 4 |-> 5 ; 5 |-> 6 ; 6 |-> 7 ;
    7 |-> 4 ; 8 |-> 9 ; 9 |-> 10
Maude> red s(0 |-> 3 ; 1 |-> 8 ; 2 |-> 1 ; 3 |-> 4 ; 4 |-> 10 ; 5 |-> 10 ; 6 |-> 10 ;
>       7 |-> 10, 0, 5) .
result A: 0 |-> 10 ; 1 |-> 8 ; 2 |-> 1 ; 3 |-> 4 ; 4 |-> 10 ; 5 |-> 3 ; 6 |->
    10 ; 7 |-> 10
Maude> red s(0 |-> 5 ; 1 |-> 1 ; 2 |-> 4 ; 3 |-> 2 ; 4 |-> 3, 0, 4) .
result A: 0 |-> 3 ; 1 |-> 1 ; 2 |-> 4 ; 3 |-> 2 ; 4 |-> 5
Maude> red s(0 |-> 5 ; 1 |-> 6, 0, 1) .
result A: 0 |-> 6 ; 1 |-> 5
Maude> red s(0 |-> 2 ; 1 |-> 2 ; 2 |-> 2, 0, 1) .
result A: 0 |-> 2 ; 1 |-> 2 ; 2 |-> 2

Ungolfed

mod S is
    pr ARRAY{Nat,Nat0} * (sort Array{Nat,Nat0} to A).
    var I J X Y : Nat .
    op s : A Nat Nat -> A .
    eq s(A:A, I, J) = insert(I, A:A[J], insert(J, A:A[I], A:A)) .
endm

The answer is obtained by reducing the function s with the list, given as a Maude array (e.g., 0 |-> 1 ; 1 |-> 2 for [1, 2]), and the two indices, zero-indexed.

Maude does have lists (e.g., 0 1 for the same list [1, 2]), but this is one case where it's actually shorter to use arrays (which are generally very verbose) because we don't need to use an array literal syntax in the code, and because we need indexing. The FAQ says it's allowed to accept input as either an array or a list.

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

Javascript 38 bytes

(l,a,b)=>(l[a]=[l[b],l[b]=l[a]][0])&&l
\$\endgroup\$
2
\$\begingroup\$

05AB1E, 4 bytes

è¹Rǝ

Since no one posted an 05AB1E answer yet and it's been a couple of days, I'm gonna post my prepared 4-byter.

First input is a pair of indices \$[a,b]\$, second input is the list \$L\$.

Try it online or verify all test cases.

Explanation:

è    # Index the first (implicit) input into the second (implicit) input-list
 ¹   # Push the first input-indices again
  R  # Reverse them
   ǝ # Insert the values at those reversed indices into the (implicit) second input-list
     # (after which the result is output implicitly)
\$\endgroup\$
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\$ Oct 15 at 21:01

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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