Mélanger des caractères dans une chaîne

10

Vous devez écrire une fonction / un programme qui accepte les entrées via les stdinarguments de ligne de commande / arguments de fonction, mélange les caractères dans une chaîne, puis affiche la chaîne finale via stdout.

L'entrée contiendra d'abord une chaîne (non vide ou null), un espace, puis un nombre pair de nombres non négatifs, tous séparés par des espaces. Si l'entrée est prise via des arguments de fonction, la chaîne sera l'un des arguments tandis que les entiers, séparés par un espace, seront l'autre. Vous devez permuter les caractères de la chaîne aux indices correspondant aux paires consécutives de nombres.

Par exemple:

Hello_world! 0 6

doit se traduire par

wello_Horld!

Hypothèses

  • Vous pouvez choisir entre l'indexation basée sur 0 et celle basée sur 1, et pouvez supposer que les index donnés seront toujours dans la plage.
  • La chaîne ne sera pas plus de 100 caractères et ne contenir que des caractères ASCII dans la gamme !de ~(codes de caractères 0x21 à 0x7E, inclus). Voir le tableau ASCII pour référence.
  • Les deux indices d'une paire peuvent être identiques (auquel cas, rien n'est échangé à cette étape).

Notation

Il s'agit du code golf, donc la soumission la plus courte (en octets) l'emporte.

Cas de test

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~
Spikatrix
la source
2
Pour les défis futurs, permettez-moi de recommander le bac à sable où vous pouvez obtenir des commentaires et peaufiner votre défi avant de le publier sur main (cela minimise le risque d'invalider les réponses existantes si quelqu'un découvre une faille grave dans votre défi qui doit être corrigée).
Martin Ender
Pourquoi exiger une entrée sur stdin, et non, par exemple, comme arguments de ligne de commande?
lrn
@lrn, à droite. Ajout de 2 options supplémentaires.
Spikatrix
Je vois un tas de solutions ci-dessous qui supposent qu'ils peuvent obtenir la liste des indices sous forme de tableau qui est transmis à la fonction qu'ils implémentent. La façon dont je lis votre définition, l'entrée est une chaîne unique, qui contient les indices ainsi que la chaîne sur laquelle ils opèrent, et l'extraction des indices de la chaîne d'entrée fait partie du code qui doit être joué. Pouvez-vous préciser quelle interprétation est correcte?
Reto Koradi
@RetoKoradi, Non. L'entrée n'est pas une chaîne complète. Il a une chaîne, puis des nombres. Les chiffres ne sont pas inclus dans la chaîne.
Spikatrix

Réponses:

6

CJam, 11 octets

rr{irie\r}h

Comment ça fonctionne

Il s'agit d'une approche légèrement différente, dans laquelle je lance simplement une boucle do-while jusqu'à ce qu'il me reste des paires de nombres dans l'entrée.

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

Essayez-le en ligne ici

Optimiseur
la source
6

Python 3, 89 86 octets

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

Déballez toutes les choses. (3 octets enregistrés grâce à @potato)

Sp3000
la source
Enregistrez quelques octets et procédez comme [*s],*L=input().split()suit : vous pouvez ensuite retirer la ligne après. J'aime vraiment votre solution, elle est presque élégante même si elle est très golfée.
pomme de terre
@potato Oh wow, je ne savais pas que vous pouviez avoir deux déballages ensemble comme ça (je pensais que vous ne pouviez le faire qu'en 3.5). Merci!
Sp3000
4

CJam, 13 octets

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

Testez-le ici.

Explication

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.
Martin Ender
la source
Whoa. Je ne m'attendais pas à une réponse aussi rapide!
Spikatrix
2

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

L'explication vient ...

Arguments

T = un mot de type char * .

V = un tableau d'un nombre pair d'éléments entiers.

L = longueur de V

Production

chaîne mixte

Comment ça marche ? :

balaie les nombres du tableau V vice versa, et place le nième élément de la chaîne après avoir suivi toute sa progression jusqu'au point réel. Exemple

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

V inversé = {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 ..

Essayez-le ici

Abr001am
la source
1
@ Agawa001, vous pouvez jouer au golf beaucoup plus. Le type de retour intn'est pas nécessaire (peut entraîner un comportement inattendu), et les intvariables qui sont des paramètres n'ont pas besoin d'une intvariable, au lieu de déclarer dans la boucle peuvent être déclarées à un endroit en dehors de la boucle, utilisez à la putcharplace de printfetc
Spikatrix
2

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

Golfé plus en échangeant autour de certaines variables et en utilisant ;comme dans le commentaire de Tim.

Je m'attendais à ce qu'il sorte golfique, mais pas autant.

ASCIIThenANSI
la source
1
Vous pouvez beaucoup jouer au golf. Changez whilepour while c<len(t):line1;line2;line3.... c=c+2va àc+=2
Tim
@Tim Merci pour votre aide!
ASCIIThenANSI
Ne devrait-il pas commencer à 0?
Tim
@Tim Nope. cest en fait l'indexation t(l'entrée) pour obtenir les positions que nous devons échanger. Mais puisque t[0]c'est la chaîne que nous devons échanger t[1]et t[2]maintenir la première paire de swaps.
ASCIIThenANSI
Ahh je vois, oui. Désolé, ma solution a coupé l'entrée, donc j'ai deviné que vous aviez fait la même chose :)
Tim
2

C, 109 107 102 octets

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);}

Remarque: set adoit être déclaré en tant que tableaux globaux. sest la chaîne que vous souhaitez échanger et aest un tableau intcontenant toutes les valeurs numériques.

Si le code ci-dessus ne fonctionne pas, essayez d'utiliser void f(){...}au lieu def(){...}

Code non golfé:

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
}

Testez-le ici

Spikatrix
la source
hmm ur code est plus petit :)
Abr001am
lol où est la déclaration de variable? c'est une façon astucieuse de resserrer votre code: p
Abr001am
@ Agawa001, je n'ai pas inclus la déclaration de variable car les octets varient avec chaque cas de test.
Spikatrix
Cela ne correspond pas à l'entrée définie dans le problème. L'entrée est une chaîne unique. Sauf si j'ai mal compris le problème, vous devez extraire les valeurs d'index de la chaîne d'entrée.
Reto Koradi
1

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

Explication:

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
Tim
la source
1

C, 70 octets

Étant donné que la chaîne d'entrée est au maximum de 100, j'ai décidé de faire de l'octet «NULL» indiquant la fin du tableau d'entiers univoque 0xFF. Vraisemblablement, cela ne compte pas comme entrée supplémentaire, bien que pour un coût de (au plus) 73 octets, il puisse être transformé en indexation basée sur 1 et utilisé '\0'comme fin du tableau.

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

À peu près, l'échange normal avec une variable tmp et utilise que l'opérateur de virgule introduit des points de séquence pour avoir un comportement défini (contrairement à certaines manifestations de swaps xor qui auraient un nombre de caractères inférieur mais conduiraient à un comportement non défini).

Edit: Comme demandé, vous pouvez le tester: http://rextester.com/OVOQ23313 .

CL-
la source
Je ne pense pas que vous puissiez supposer que vous obtenez un tableau avec les indices à échanger. Les indices font partie de la chaîne d'entrée et vous devez les analyser hors de la chaîne dans le cadre du code publié (et compté). D'après la description: "L'entrée contiendra d'abord une chaîne, un espace, puis un nombre pair de nombres non négatifs, tous séparés par des espaces."
Reto Koradi
1

Fléchette - 123

Suppose que l'entrée sur la ligne de commande est automatiquement divisée en espaces. Sinon, il a besoin d'une initiale x=x[0].split(' ');pour diviser la chaîne en texte et en index.

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());}

Avec plus d'espace:

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());
}

Exécutez / testez ceci sur dartpad.dartlang.org .

lrn
la source
Connaissez-vous des compilateurs en ligne où je pourrais tester cela?
Spikatrix
Ajoutez un lien vers DartPad.
lrn
1

Rebol - 71

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

Non golfé:

s: take i: split input " " 
foreach [a b] i [swap at s do a at s do b]
print s
draegtun
la source
Comment puis-je tester cela? Existe-t-il un compilateur en ligne pour tester cela?
Spikatrix
@CoolGuy - Oui, vous pouvez le tester sur try.rebol.nl La inputfonction ne pourra pas appeler STDIN à partir de là. La solution de contournement consiste à définir simplement inputla valeur que vous souhaitez tester. Voici un exemple complet du premier 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 et cliquez sur Do in Rebol 3 NB. Rebol utilise une indexation basée sur 1.
draegtun
@CoolGuy - Alternativement, vous pouvez télécharger les binaires Rebol 3 depuis rebolsource.net
draegtun
0

C, 143 octets

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);}

Le programme ci-dessus prend les entrées des arguments de ligne de commande, copie la chaîne dans un tableau, échange les caractères correspondants, puis sort la chaîne modifiée.

Code non golfé:

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
}
Spikatrix
la source
Supposez-vous que les chiffres ont un seul chiffre? Étant donné que l'entrée peut contenir jusqu'à 100 caractères, je ne pense pas que ce sera valide. Regardez également le 3e exemple, qui a l' 10un des indices.
Reto Koradi
@RetoKoradi, Merci d'avoir repéré cela. J'ai corrigé le code.
Spikatrix
0

JavaScript (ES6), 95

95 octets avec une seule entrée de chaîne (fonction f ci-dessous)

75 octets avec 2 paramètres, chaîne et tableau de nombres (fonction g ci-dessous)

(EcmaScript 6, Firefox uniquement)

f=i=>
(
  n=i.split(' '),
  s=[...n.shift()],
  n.map((v,i)=>i&1?[s[v],s[w]]=[s[w],s[v]]:w=v),
  s.join('')
)

g=(s,n)=>
  n.map((v,i)=>i&1?[s[v],s[w]]=[s[w],s[v]]:w=v,s=[...s])
  &&s.join('')

// TEST
out=x=>O.innerHTML+=x+'\n'

;[['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~']]
.forEach(t=>{
  u=f(t[0]),
  ok=u==t[1],
  out('Test '+(ok?'OK: ':'FAIL: ')+t[0]+'\n Result:' +u + '\n Check: '+t[1]+'\n')
})
<pre id=O></pre>

edc65
la source