Mezclando caracteres en una cadena

10

Debe escribir una función / programa que tome datos a través de los stdinargumentos de línea de comandos / argumentos de función, mezcle los caracteres en una cadena y luego envíe la cadena final a través de stdout.

La entrada contendrá primero una cadena (no vacía o null), un espacio, y luego un número par de números no negativos, todos separados por espacios. Si la entrada se toma a través de argumentos de función, la cadena será uno de los argumentos, mientras que los enteros, que están separados por un espacio, serán el otro. Debe intercambiar los caracteres de la cadena en los índices correspondientes a pares consecutivos de números.

Por ejemplo:

Hello_world! 0 6

debe resultar en

wello_Horld!

Supuestos

  • Puede elegir entre indexación basada en 0 y basada en 1, y puede suponer que los índices dados siempre estarán dentro del rango.
  • La cadena no tendrá más de 100 caracteres y solo contendrá caracteres ASCII en el rango !de ~(códigos de caracteres 0x21 a 0x7E, inclusive). Consulte la tabla ASCII para referencia.
  • Los dos índices en un par pueden ser idénticos (en cuyo caso, no se intercambia nada en ese paso).

Puntuación

Este es el código de golf, por lo que gana el envío más corto (en bytes).

Casos de prueba

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
fuente
2
Para desafíos futuros, permítame recomendarle el entorno limitado donde puede obtener comentarios y pulir su desafío antes de publicarlo en main (esto minimiza el riesgo de invalidar las respuestas existentes si alguien descubre una falla grave en su desafío que necesita solución).
Martin Ender
¿Por qué requerir entrada en stdin, y no, por ejemplo, como argumentos de línea de comando?
lrn
@lrn, correcto. Se agregaron 2 opciones más.
Spikatrix
Veo un montón de soluciones a continuación que suponen que pueden obtener la lista de índices como una matriz que se pasa a la función que implementan. La forma en que leo su definición, la entrada es una sola cadena, que contiene los índices, así como la cadena en la que operan, y la extracción de los índices de la cadena de entrada es parte del código que debe jugarse. ¿Puedes aclarar qué interpretación es la correcta?
Reto Koradi
@RetoKoradi, No. La entrada no es una cadena completa. Tiene una cadena y luego números. Los números no están incluidos en la cadena.
Spikatrix

Respuestas:

6

CJam, 11 bytes

rr{irie\r}h

Cómo funciona

Este es un enfoque ligeramente diferente, en el que simplemente ejecuto un bucle do-while hasta que me quedan pares de números en la entrada.

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

Pruébalo en línea aquí

Optimizador
fuente
6

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

Descomprime todas las cosas. (3 bytes guardados gracias a @potato)

Sp3000
fuente
Guarde unos pocos bytes y haga esto: [*s],*L=input().split()luego puede quitar la línea después. Por cierto, me gusta su solución, es casi elegante a pesar de que es muy golfista.
papa
@potato Oh, wow, no sabía que podrías tener dos desempaques juntos de esa manera (pensé que solo podías hacer eso en 3.5). ¡Gracias!
Sp3000
4

CJam, 13 bytes

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

Pruébalo aquí.

Explicación

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
fuente
Whoa ¡No esperaba una respuesta tan rápida!
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]);}}

Se acerca la explicación ...

Argumentos

T = una palabra de tipo char * .

V = una matriz de un número par de elementos enteros.

L = longitud de V

Salida

cadena mixta

Como funciona ? :

barre los números de la matriz V y viceversa, y coloca el enésimo elemento de la cadena después de seguir todo su progreso hasta el punto real. Ejemplo

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

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

Pruébalo aquí

Abr001am
fuente
1
@ Agawa001, puedes jugar al golf mucho más. El tipo de retorno intno es necesario (puede dar lugar a un comportamiento inesperado), y las intvariables que son parámetros no necesitan una intvariable, en lugar de declarar en el bucle se puede declarar en un lugar fuera del bucle, usar en putcharlugar 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))

Jugó más al cambiar algunas variables y usar ;como en el comentario de Tim.

Esperaba que saliera con aspecto de golf, pero no tanto.

ASCIIThenANSI
fuente
1
Puedes jugar mucho al golf. Cambiar el whilea while c<len(t):line1;line2;line3.... c=c+2va ac+=2
Tim
@Tim ¡Gracias por tu ayuda!
ASCIIThenANSI
¿No debería c comenzar en 0?
Tim
@Tim Nope. cen realidad está indexando t(la entrada) para obtener las posiciones que necesitamos intercambiar. Pero dado que t[0]es la cadena que necesitamos intercambiar, t[1]y t[2]mantener el primer par de intercambios.
ASCIIThenANSI
Ahh ya veo, sí. Lo siento, mi solución dividió la entrada, así que supuse que habías hecho lo mismo :)
Tim
2

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

Nota: sy adebe declararse como matrices globales. ses la cadena que desea intercambiar y aes una matriz intcon todos los valores numéricos.

Si el código anterior no funciona, intente usarlo en void f(){...}lugar def(){...}

Código sin 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
}

Pruébalo aquí

Spikatrix
fuente
hmm tu código es más pequeño :)
Abr001am
lol donde esta la declaracion variable? esa es una manera engañosa de ajustar su código: p
Abr001am
@ Agawa001, no incluí la declaración de variable ya que los bytes variarían con cada caso de prueba.
Spikatrix
Esto no coincide con la entrada como se define en el problema. La entrada es una sola cadena. A menos que haya entendido completamente el problema, debe extraer los valores de índice de la cadena de entrada.
Reto Koradi
1

Pitón 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))

Explicación:

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
fuente
1

C, 70 bytes

Dado que la cadena de entrada tiene una longitud máxima de 100, decidí hacer que el byte 'NULL' que indica el final de la matriz de enteros sea inequívoco 0xFF. Presumiblemente, esto no cuenta como entrada adicional, aunque por un costo de (como máximo) 7 3 bytes se puede convertir en una indexación basada en 1 y usar '\0'como el final de la matriz.

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

Prácticamente solo hace un intercambio regular con una variable tmp y usa que el operador de coma introduce puntos de secuencia para tener un comportamiento definido (a diferencia de algunas manifestaciones de intercambios xor que tendrían un recuento de caracteres más bajo pero conducirían a un comportamiento indefinido).

Editar: según lo solicitado, puede probarlo: http://rextester.com/OVOQ23313 .

CL-
fuente
No creo que puedas asumir que obtienes una matriz con los índices para intercambiar. Los índices son parte de la cadena de entrada, y debe analizarlos fuera de la cadena como parte del código publicado (y contado). De la descripción: "La entrada contendrá primero una cadena, un espacio y luego un número par de números no negativos, todos separados por espacios".
Reto Koradi
1

Dart - 123

Asume que la entrada en la línea de comandos se divide automáticamente en espacios. De lo contrario, necesita una inicial x=x[0].split(' ');para dividir la cadena en texto e índices.

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

Con más espacios en blanco:

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

Ejecute / pruebe esto en dartpad.dartlang.org .

lrn
fuente
¿Conoces algún compilador en línea donde pueda probar esto?
Spikatrix
Añadir enlace a 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

Sin golf:

s: take i: split input " " 
foreach [a b] i [swap at s do a at s do b]
print s
draegtun
fuente
¿Cómo pruebo esto? ¿Hay algún compilador en línea para probar esto?
Spikatrix
@CoolGuy: sí, puede probarlo en try.rebol.nl La inputfunción no podrá llamar a STDIN desde allí. La solución alternativa es establecer de manera simple inputel valor que desea probar. Este es un ejemplo completo de la primera prueba 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 y haga clic en Hacer en Rebol 3 NB. Rebol usa indexación basada en 1.
draegtun
@CoolGuy - También puede descargar los binarios de Rebol 3 rebolsource.net
draegtun
0

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

El programa anterior toma datos de los argumentos de la línea de comandos, copia la cadena en una matriz, intercambia los caracteres correspondientes y luego genera la cadena modificada.

Código sin 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
fuente
¿Asume que los números tienen solo un dígito? Teniendo en cuenta que la entrada puede tener hasta 100 caracteres, no creo que sea válida. Observe también el tercer ejemplo, que tiene 10como uno de los índices.
Reto Koradi
@RetoKoradi, gracias por ver eso. Arreglé el código.
Spikatrix
0

JavaScript (ES6), 95

95 bytes con una sola entrada de cadena (función f a continuación)

75 bytes con 2 parámetros, cadena y matriz de números (función g a continuación)

(EcmaScript 6, solo Firefox)

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
fuente