Misturando caracteres em uma sequência

10

Você precisa escrever uma função / programa que receba entrada por meio dos stdin/ argumentos da linha de comando / argumentos da função, mescla caracteres em uma sequência e depois produza a sequência final via stdout.

A entrada primeiro conterá uma sequência (não vazia ou null), um espaço e, em seguida, um número par de números não negativos, todos separados por espaços. Se a entrada for obtida através de argumentos de função, a sequência será um dos argumentos, enquanto os números inteiros, separados por um espaço, serão o outro. Você deve trocar os caracteres da sequência nos índices correspondentes aos pares consecutivos de números.

Por exemplo:

Hello_world! 0 6

deve resultar em

wello_Horld!

Premissas

  • Você pode escolher entre indexação com base em 0 e com base em 1 e pode assumir que os índices fornecidos sempre estarão dentro do intervalo.
  • A cadeia não terá mais de 100 caracteres e conterá apenas caracteres ASCII no intervalo !de ~(códigos de caracteres 0x21 a 0x7E, inclusive). Consulte a tabela ASCII para referência.
  • Os dois índices em um par podem ser idênticos (nesse caso, nada é trocado nessa etapa).

Pontuação

Isso é código de golfe, então a submissão mais curta (em bytes) vence.

Casos de teste

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
fonte
2
Para desafios futuros, deixe-me recomendar a caixa de proteção onde você pode obter feedback e aprimorar seu desafio antes de publicá-lo no modo principal (isso minimiza o risco de invalidar respostas existentes se alguém descobrir uma falha séria no seu desafio que precise ser corrigida).
Martin Ender
Por que exigir entrada no stdin, e não, por exemplo, como argumentos de linha de comando?
LRN
@lrn, Certo. Adicionado mais 2 opções.
Spikatrix
Vejo um monte de soluções abaixo que pressupõem que eles podem obter a lista de índices como uma matriz que é passada para a função que implementam. Da maneira como leio sua definição, a entrada é uma sequência única, que contém os índices e a sequência em que eles operam, e extrair os índices da sequência de entrada faz parte do código que precisa ser jogado. Você pode esclarecer qual interpretação está correta?
Reto Koradi
@RetoKoradi, Não. A entrada não é uma sequência completa. Ele tem uma string e depois números. Os números não estão incluídos na string.
Spikatrix 18/05/19

Respostas:

6

CJam, 11 bytes

rr{irie\r}h

Como funciona

Essa é uma abordagem um pouco diferente, na qual eu simplesmente executo um loop do while, até que eu tenha pares de números restantes na 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

Experimente online aqui

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

Descompacte todas as coisas. (3 bytes salvos graças a @potato)

Sp3000
fonte
Salve alguns bytes e faça o seguinte: [*s],*L=input().split()você pode retirar a linha depois dela. Eu realmente gosto da sua solução, é quase elegante, mesmo que seja muito golfista.
potato
@ batata Oh, uau, eu não sabia que você poderia ter duas desempacotar juntas assim (eu pensei que você só poderia fazer isso na versão 3.5). Obrigado!
Sp3000
4

CJam, 13 bytes

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

Teste aqui.

Explicação

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
fonte
Uau. Não esperava uma resposta tão 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]);}}

A explicação está chegando ...

Argumentos

T = uma palavra do tipo char * .

V = uma matriz de um número par de elementos inteiros.

L = comprimento de V

Resultado

corda mista

Como funciona ? :

varre os números da matriz V vice-versa e coloca o enésimo elemento da sequência depois de acompanhar todo o seu progresso até o ponto real. Exemplo

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

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

Experimente aqui

Abr001am
fonte
11
@ Agawa001, você pode jogar muito mais isso. O tipo de retorno intnão é necessário (pode resultar em comportamento inesperado) e as intvariáveis ​​que são parâmetros não precisam de uma intvariável, em vez de declarar no loop pode ser declarada em um local fora do loop, use em putcharvez 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))

Jogou golfe trocando algumas variáveis ​​e usando ;como no comentário de Tim.

Eu esperava que saísse parecendo golfe, mas não tanto assim.

ASCIIThenANSI
fonte
11
Você pode jogar muito isso. Mude whilepara while c<len(t):line1;line2;line3.... c=c+2vai parac+=2
Tim
@ Tim Obrigado pela sua ajuda!
ASCIIThenANSI
C não deve começar em 0?
Tim
@ Tim Nope. cna verdade, é indexar t(a entrada) para obter as posições que precisamos trocar. Mas como t[0]é a corda, precisamos trocar t[1]e t[2]segurar o primeiro par de swaps.
ASCIIThenANSI
Ahh entendo sim. Desculpe, minha solução cisão da entrada, então eu imaginei que você tinha feito o mesmo :)
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: se aprecisa ser declarado como matrizes globais. sé a string que você deseja trocar e aé uma matriz intcom todos os valores numéricos.

Se o código acima não funcionar, tente usar em void f(){...}vez def(){...}

Código não destruído:

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
}

Teste aqui

Spikatrix
fonte
hmm código ur é menor :)
Abr001am
lol onde está declaração variável? isso é uma maneira cheaty para apertar código ur: p
Abr001am
@ Agawa001, não incluí a declaração da variável, pois os bytes variam com cada caso de teste.
Spikatrix 17/05/19
Isso não corresponde à entrada conforme definido no problema. A entrada é uma única sequência. A menos que eu tenha entendido completamente o problema, é necessário extrair os valores do índice da sequência de entrada.
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))

Explicação:

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

C, 70 bytes

Dado que a string de entrada tem no máximo 100, decidi tornar o byte 'NULL' indicando que o final da matriz inteira é inequívoco 0xFF. Presumivelmente, isso não conta como entrada extra, embora por um custo de (no máximo) 7 3 bytes possa ser transformado em indexação baseada em 1 e usado '\0'como o final da matriz.

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

Praticamente apenas faz trocas regulares com uma variável tmp e usa que o operador vírgula introduz pontos de sequência para ter um comportamento definido (diferente de algumas manifestações de xor swaps que teriam uma contagem mais baixa de caracteres, mas que levariam a um comportamento indefinido).

Edit: Conforme solicitado, você pode testá-lo: http://rextester.com/OVOQ23313 .

CL-
fonte
Eu não acho que você pode assumir que você obtém uma matriz com os índices a serem trocados. Os índices fazem parte da sequência de entrada e você precisa analisá-los como parte do código publicado (e contado). Na descrição: "A entrada primeiro conterá uma sequência, um espaço e, em seguida, um número par de números não negativos, todos separados por espaços".
Reto Koradi
1

Dardo - 123

Supõe que a entrada na linha de comando seja dividida automaticamente em espaços. Caso contrário, ele precisa de uma inicial x=x[0].split(' ');para dividir a sequência em 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());}

Com mais espaço em branco:

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

Execute / teste isso em dartpad.dartlang.org .

lrn
fonte
Você conhece algum compilador on-line onde eu possa testar isso?
Spikatrix 17/05/19
Adicionar link ao 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

Ungolfed:

s: take i: split input " " 
foreach [a b] i [swap at s do a at s do b]
print s
draegtun
fonte
Como faço para testar isso? Existe algum compilador online para testar isso?
Spikatrix 17/05/19
@CoolGuy - Sim, você pode testá-lo em try.rebol.nl A inputfunção não poderá chamar STDIN a partir daí. A solução alternativa é definir de forma simples inputo valor que você deseja testar. Aqui está um exemplo completo do primeiro teste - 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 e clique em Fazer no Rebol 3 NB. Rebol usa indexação baseada em 1.
Draegtun 17/05
@CoolGuy - Alternativamente, você pode baixar Rebol 3 binários de 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);}

O programa acima recebe entrada dos argumentos da linha de comando, copia a sequência em uma matriz, troca os caracteres correspondentes e, em seguida, gera a sequência modificada.

Código não destruído:

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
fonte
Você está assumindo que os números têm apenas um dígito? Considerando que a entrada pode ter até 100 caracteres, não acho que seja válido. Veja também o terceiro exemplo, que possui 10um dos índices.
Reto Koradi
@RetoKoradi, Obrigado por descobrir isso. Eu consertei o código.
Spikatrix 18/05/19
0

JavaScript (ES6), 95

95 bytes com uma entrada de sequência única (função f abaixo)

75 bytes com 2 parâmetros, sequência de caracteres e matriz numérica (função g abaixo)

(Somente EcmaScript 6, 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
fonte