Take the 2-minute tour ×
Programming Puzzles & Code Golf Stack Exchange is a question and answer site for programming puzzle enthusiasts and code golfers. It's 100% free, no registration required.

You have to write a function/program that takes input via the stdin/command-line arguments/function arguments, mixes up characters in a string, and then output the final string via the stdout.

Input will first contain a string (not empty or null), a space, and then an even number of non-negative numbers all separated by spaces. You must swap the characters of the string at the indices corresponding to consecutive pairs of numbers.

For instance:

Hello_world! 0 6

must result in

wello_Horld!

Assumptions

  • You may choose between 0-based and 1-based indexing, and may assume that the given indexes will always be in range.
  • The string will not be longer than 100 characters and will only contain ASCII characters in range ! to ~ (character codes 0x21 to 0x7E, inclusive). See ASCII table for reference.
  • The two indices in a pair may be identical (in which case, nothing is swapped in that step).

Scoring

This is code golf, so the shortest submission (in bytes) wins.

Test Cases

Hello_world! 0 6 => wello_Horld!
First 1 2 1 0 0 4 => tFisr
(Second!$$) 8 7 10 1 => ()econd$!$S
~Third~ 0 0 6 6 0 6 6 0 => ~Third~
share|improve this question
2  
For future challenges, let me recommend the sandbox where you can get feedback and polish your challenge before posting it on main (this minimises the risk of invalidating existing answers if someone discovers a serious flaw in your challenge that needs fixing). –  Martin Büttner yesterday
    
Why require input on stdin, and not, e.g., as command line arguments? –  lrn yesterday
    
@lrn , Right. Added 2 more options. –  Cool Guy yesterday
    
I see a bunch of solutions below that assume that they can get the list of indices as an array that gets passed into the function they implement. The way I read your definition, the input is a single string, which contains the indices as well as the string they operate on, and extracting the indices from the input string is part of the code that needs to be golfed. Can you clarify which interpretation is correct? –  Reto Koradi 1 hour ago

11 Answers 11

up vote 4 down vote accepted

CJam, 11 bytes

rr{irie\r}h

How it works

This is a slightly different approach, in which I simply run a do-while loop till I have pairs of numbers left in the input.

r                 e# Read the first string
 r                e# Read the first number of the first number pair in the input
  {      }h       e# Do a do-while loop
   i              e# Convert the first number from the pair to integer
    ri            e# Read the second number from the pair and convert to intger
      e\          e# String X Y e\ works by swapping the Xth index with the Yth index in the
                  e# String
        r         e# This is our exit condition of the do-while loop. If we still have
                  e# a number on the input left, that means there are more pairs to swap.
                  e# Otherwise, we exit the loop and the result is printed automatically

Try it online here

share|improve this answer

Python 3, 89 86 bytes

[*s],*L=input().split()
while L:a,b,*L=map(int,L);s[a],s[b]=s[b],s[a]
print(*s,sep="")

Unpack all the things. (3 bytes saved thanks to @potato)

share|improve this answer
    
Save a few bytes and do this: [*s],*L=input().split() you can then take the line after it away. I really like your solution btw, it's almost elegant even though it is very golfed. –  potato 11 hours ago
    
@potato Oh wow, I didn't know you could have two unpacks together like that (I thought you could only do that in 3.5). Thanks! –  Sp3000 2 hours ago

CJam, 13 bytes

r[q~]2/{~e\}/

Test it here.

Explanation

r             e# Read the first token, i.e. the string.
 [q~]         e# Read the rest of the input, eval it and wrap it in an array.
     2/       e# Split the array into pairs of consecutive elements.
       {   }/ e# For each pair.
        ~     e# Unwrap the array.
         e\   e# Swap the corresponding elements in the string.
share|improve this answer
    
Whoa. Did not expect an answer that fast! –  Cool Guy yesterday

C (137 b)

f(char*T,int*V,int L){int C=0;for(int j=0;j<strlen(T);C=++j){for(int i=L-1;i+1;i--)if(C==V[i]){C=V[i-i%2*2+1];i-=i%2;}printf("%c",T[C]);}}

Explanation is coming ...

Arguments

T = a word of type char*.

V = an array of an even number of integer elements.

L = length of V

Output

mixed string

How does it work ?:

sweeps numbers of array V vice versa , and puts the nth element of the string after tracking all its progress until the actual point . Example

input= T="First" , V={1,2,1,0,0,4}

V inversed={4,0,0,1,2,1}

V[0] = 4th element -> index 0
0 -> 1
1->2

4th element 't' receives the second = 'r'

V[1] = 0 -> index 4
4 isnt mentionned after so , no changes

0 element='F' receives the fourth= 't'

V[3] = 1st element -> index 0
no changes

V[4] = 2 -> index 1
no changes after ..

Try it here

share|improve this answer
    
@Agawa001 , You can golf this a lot more. Return type int is not needed(may result in unexpected behavior), and int variables which are parameters do not need an int, variables, instead of declaring in the loop can be declared in one place outside the loop, use putchar instead of printf etc –  Cool Guy yesterday

Python 3 - 161 149

import sys
t=sys.stdin.read().split()
q=list(t[0])
c=1
i=int
while c<len(t):n=q;a=i(t[c]);b=i(t[c+1]);n[a]=q[b];n[b]=q[a];q=n;c+=2;
print(''.join(q))

Golfed more by swapping around some variables, and using ; as in Tim's comment.

I expected it to come out looking golfed, just not this much.

share|improve this answer
1  
You can golf this a lot. Change the while to while c<len(t):line1;line2;line3.... c=c+2 goes to c+=2 –  Tim yesterday
    
@Tim Thanks for your help! –  ASCIIThenANSI yesterday
    
Shouldn't c start at 0? –  Tim yesterday
    
@Tim Nope. c actually is indexing t (the input) to get the positions we need to swap. But since t[0] is the string we need to swap around, t[1] and t[2] hold the first pair of swaps. –  ASCIIThenANSI yesterday
    
Ahh I see, yes. Sorry, my solution split off the input, so i guessed you'd done the same :) –  Tim yesterday

C, 109 107 102 bytes

i;f(l){l=sizeof(a)/sizeof(*a);char t;for(;i<l;i+=2){t=s[a[i]];s[a[i]]=s[a[i+1]];s[a[i+1]]=t;}puts(s);}

Note: s and a needs to be declared as global arrays. s is the string which you want to swap and a is an array of int with all the number values.

If the above code does not work, try using void f(){...} instead of f(){...}

Ungolfed code:

int a[]={1, 2, 1, 0, 0, 4};//Integer elements
char s[]="First";          //String to be swapped

i; //Auto initialized to 0 and defaults to type int
void f(l){ //Variables defaults to type int
  l=sizeof(a)/sizeof(*a); //Gets number of elements in array a
  char t;

  for(;i<l;i+=2){ 

    t=s[a[i]];
    s[a[i]]=s[a[i+1]];
    s[a[i+1]]=t;  //Swap each character

  }

  puts(s); //Print the final char array
}

Test it here

share|improve this answer
    
hmm ur code is smaller :) –  Agawa001 yesterday
    
lol where is variable declaration ? thats a cheaty way to tighten ur code :p –  Agawa001 yesterday
    
@Agawa001 , I didn't include the variable declaration as the bytes would vary with each test case. –  Cool Guy yesterday
    
This does not match the input as defined in the problem. The input is a single string. Unless I completely misunderstood the problem, you need to extract the index values from the input string. –  Reto Koradi 1 hour ago

Python 3, 135

x=input().split()
y=list(x[0])
z=[int(i)for i in x[1:]]
while z:p,c=y[z[0]],y[z[1]];y[z[0]],y[z[1]]=c,p;del z[0],z[0]
print(''.join(y))

Explanation:

x=input().split()         # Split the input into a list at each space
y=list(x[0])              # First item in list (the word) into a list of chars
z=[int(i)for i in x[1:]]  # Make the list of numbers, into integers
while z:                  # Loop untill the list z is empty
    p,c=y[z[0]],y[z[1]]   # Assign p to the first char and c to the second
    y[z[0]],y[z[1]]=c,p   # Swap around using p and c
    del z[0],z[0]         # Remove the first 2 items in the list of integers
print(''.join(y))         # Print out the altered list as a string
share|improve this answer

C, 70 bytes

Given that the input string is at most length 100 I decided to make the 'NULL' byte indicating the end of the integer array be the unambiguous 0xFF. Presumably this doesn't count as extra input, though for a cost of (at most) 7 3 bytes it can be made into 1-based indexing and use '\0' as the end of the array.

f(s,i,t)char*s,*i;{for(;~*i;)t=s[*i],s[*i]=s[*++i],s[*i++]=t;puts(s);}

Pretty much just does regular swapping with a tmp variable and uses that the comma operator introduces sequence points to have defined behaviour (unlike some manifestations of xor swaps that would have a lower character count but lead to undefined behaviour).

Edit: As requested you can test it out: http://rextester.com/OVOQ23313.

share|improve this answer
    
I don't think you can assume that you get an array with the indices to be swapped. The indices are part of the input string, and you need to parse them out of the string as part of the posted (and counted) code. From the description: "Input will first contain a string, a space, and then an even number of non-negative numbers all separated by spaces." –  Reto Koradi 1 hour ago

Dart - 123

Assumes input on the command-line is automatically split at spaces. Otherwise it needs an initial x=x[0].split(' '); to split the string into text and indices.

main(x,{c,i:1,a,t}){c=x[0].split("");n()=>a=int.parse(x[i++]);for(;i<x.length;t=c[n()],c[a]=c[n()],c[a]=t);print(c.join());}

With more whitespace:

main(x,{c,i:1,a,t}){
  c=x[0].split("");
  n()=>a=int.parse(x[i++]);
  for(;i<x.length;t=c[n()],c[a]=c[n()],c[a]=t);
  print(c.join());
}

Run/test this on dartpad.dartlang.org.

share|improve this answer
    
Do you know of any online compilers where I could test this? –  Cool Guy yesterday
    
Add link to DartPad. –  lrn 17 hours ago

Rebol - 71

s: take i: split input" "foreach[a b]i[swap at s do a at s do b]print s

Ungolfed:

s: take i: split input " " 
foreach [a b] i [swap at s do a at s do b]
print s
share|improve this answer
    
How do I test this? Is there any online compiler for testing this? –  Cool Guy 17 hours ago
    
@CoolGuy - Yes you can test it at try.rebol.nl The input function won't be able to call STDIN from there. The workaround is to simple set input to be the value you wish to test. Here's full example of the first test - input: "hello_World 1 7" s: take i: split input" "foreach[a b]i[swap at s do a at s do b]print s and click on Do in Rebol 3 NB. Rebol uses 1-based indexing. –  draegtun 17 hours ago
    
@CoolGuy - Alternatively you can download Rebol 3 binaries from rebolsource.net –  draegtun 17 hours ago

C, 143 bytes

main(a,v,i)char** v;{i=2;char s[101],t;strcpy(s,v[1]);for(;i<a;i+=2){t=s[atoi(v[i])];s[atoi(v[i])]=s[atoi(v[i+1])];s[atoi(v[i+1])]=t;}puts(s);}

The above program takes input from command-line arguments, copies the string into an array, swaps corresponding characters and then, outputs the modified string.

Ungolfed code:

main(int a,char** v,int i){ //Arguments of main 
  i = 2;
  char s[101],t;

  strcpy(s,v[1]); //Copy string literal into an array

  for(;i<a;i+=2){
    t=s[atoi(v[i])];
    s[atoi(v[i])]=s[atoi(v[i+1])];
    s[atoi(v[i+1])]=t;  //Swap each character
  }

  puts(s); // Output the final string
}
share|improve this answer
    
Are you assuming that the numbers have only one digit? Considering that the input can be up to 100 characters, I don't think that will be valid. Also look at the 3rd example, which has 10 as one of the indices. –  Reto Koradi 1 hour ago
    
@RetoKoradi , Thanks for spotting that. I fixed the code. –  Cool Guy 19 mins ago

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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