Mieszanie znaków w ciągu

10

Musisz napisać funkcję / program, który pobiera dane wejściowe za pomocą stdinargumentów / wiersza poleceń / argumentów funkcji, miesza znaki w ciągu, a następnie wyprowadza końcowy ciąg przez stdout.

Dane wejściowe będą najpierw zawierać ciąg znaków (nie pusty lub null), spację, a następnie parzystą liczbę liczb nieujemnych, wszystkie oddzielone spacjami. Jeśli dane wejściowe są pobierane za pomocą argumentów funkcyjnych, ciąg będzie jednym z argumentów, podczas gdy liczby całkowite, które są oddzielone spacją, będą drugim. Musisz zamienić znaki ciągu na indeksy odpowiadające kolejnym parom liczb.

Na przykład:

Hello_world! 0 6

musi skutkować

wello_Horld!

Założenia

  • Możesz wybrać między indeksowaniem opartym na 0 i opartym na 1 i możesz założyć, że podane indeksy zawsze będą w zakresie.
  • Ciąg nie będzie dłuższy niż 100 znaków i będzie zawierać tylko znaki ASCII w zakresie !od ~(kody znaków od 0x21 do 0x7E włącznie). Zobacz tabelę ASCII w celach informacyjnych.
  • Dwa wskaźniki w parze mogą być identyczne (w takim przypadku nic nie jest zamieniane na tym etapie).

Punktacja

To jest kod golfowy, więc wygrywa najkrótsze przesłanie (w bajtach).

Przypadki testowe

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
źródło
2
W przypadku przyszłych wyzwań pozwól mi polecić piaskownicę, w której możesz uzyskać informacje zwrotne i dopracować swoje wyzwanie przed opublikowaniem go na stronie głównej (minimalizuje to ryzyko unieważnienia istniejących odpowiedzi, jeśli ktoś odkryje poważną wadę w wyzwaniu, która wymaga naprawy).
Martin Ender
Po co wymagać wejścia na standardowe wejście, a nie np. Jako argumenty wiersza poleceń?
LRN
@ lrn, racja. Dodano 2 dodatkowe opcje.
Spikatrix
Widzę kilka rozwiązań poniżej, które zakładają, że mogą uzyskać listę indeksów jako tablicę, która jest przekazywana do implementowanej funkcji. Sposób, w jaki czytam twoją definicję, jest pojedynczym ciągiem, który zawiera zarówno indeksy, jak i ciąg, na którym operują, a wyodrębnianie indeksów z ciągu wejściowego jest częścią kodu, który należy zagrać w golfa. Czy możesz wyjaśnić, która interpretacja jest poprawna?
Reto Koradi
@RetoKoradi, Nie. Dane wejściowe nie są ciągiem pełnym. Ma ciąg, a następnie liczby. Liczby nie są zawarte w ciągu.
Spikatrix

Odpowiedzi:

6

CJam, 11 bajtów

rr{irie\r}h

Jak to działa

Jest to nieco inne podejście, w którym po prostu uruchamiam pętlę „do-while”, dopóki nie pozostaną pary liczb na wejściu.

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

Wypróbuj online tutaj

Optymalizator
źródło
6

Python 3, 89 86 bajtów

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

Rozpakuj wszystkie rzeczy. (3 bajty zapisane dzięki @potato)

Sp3000
źródło
Zaoszczędź kilka bajtów i zrób to: [*s],*L=input().split()możesz następnie zabrać linię po niej. Naprawdę podoba mi się twoje rozwiązanie, bo jest prawie eleganckie, mimo że jest bardzo golfa.
ziemniak
@potato O rany, nie wiedziałem, że możesz mieć tak dwa rozpakowania razem (myślałem, że możesz to zrobić tylko w wersji 3.5). Dzięki!
Sp3000,
4

CJam, 13 bajtów

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

Sprawdź to tutaj.

Wyjaśnienie

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
źródło
Whoa. Nie spodziewałem się tak szybkiej odpowiedzi!
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]);}}

Wyjaśnienie nadchodzi ...

Argumenty

T = słowo typu char * .

V = tablica parzystej liczby elementów całkowitych.

L = długość V

Wynik

mieszany sznurek

Jak to działa ? :

zamiata liczby z tablicy V na odwrót i umieszcza n-ty element ciągu po śledzeniu całego jego postępu do faktycznego punktu. Przykład

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

V odwrócone = {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 ..

Wypróbuj tutaj

Abr001am
źródło
1
@ Agawa001, Możesz zagrać w golfa o wiele więcej. Typ zwracany intnie jest potrzebny (może powodować nieoczekiwane zachowanie), a intzmienne, które są parametrami, nie wymagają intzmiennej, zamiast deklarować w pętli, można zadeklarować w jednym miejscu poza pętlą, użyć putcharzamiast printfitp.
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))

Grał w golfa, zamieniając niektóre zmienne i używając ;jak w komentarzu Tima.

Spodziewałem się, że będzie wyglądać na golfa, ale nie aż tak bardzo.

ASCIIThenANSI
źródło
1
Możesz dużo w golfa. Zmień whileTO while c<len(t):line1;line2;line3.... c=c+2idzie doc+=2
Tim
@Tim Dzięki za pomoc!
ASCIIThenANSI
Czy c nie powinno zaczynać się od 0?
Tim
@Tim Nope. cfaktycznie indeksuje t(dane wejściowe), aby uzyskać pozycje, które musimy zamienić. Ale ponieważ t[0]jest to ciąg, który musimy zamienić t[1]i t[2]zatrzymać pierwszą parę zamian .
ASCIIThenANSI
Ach, rozumiem, tak. Przepraszam, moje rozwiązanie podzieliło dane wejściowe, więc zgadłem, że zrobiłeś to samo :)
Tim
2

C, 109 107 102 bajtów

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

Uwaga: si anależy zadeklarować jako tablice globalne. sjest ciągiem, który chcesz zamienić i ajest tablicą intzawierającą wszystkie wartości liczbowe.

Jeśli powyższy kod nie działa, spróbuj użyć void f(){...}zamiastf(){...}

Nieskluczony kod:

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
}

Sprawdź to tutaj

Spikatrix
źródło
hmm
twój
lol gdzie jest deklaracja zmienna? to podstępny sposób na zaostrzenie twojego kodu: p
Abr001am
@ Agawa001, nie dołączałem deklaracji zmiennej, ponieważ bajty różniłyby się w każdym przypadku testowym.
Spikatrix
To nie pasuje do danych wejściowych zdefiniowanych w problemie. Dane wejściowe to pojedynczy ciąg. O ile całkowicie nie zrozumiałem problemu, musisz wyodrębnić wartości indeksu z ciągu wejściowego.
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))

Wyjaśnienie:

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
źródło
1

C, 70 bajtów

Biorąc pod uwagę, że łańcuch wejściowy ma co najwyżej 100, postanowiłem ustawić bajt „NULL” wskazujący, że koniec tablicy liczb całkowitych jest jednoznaczny 0xFF. Przypuszczalnie nie jest to liczone jako dodatkowe dane wejściowe, chociaż przy koszcie (najwyżej) 7 3 bajtów można go przekształcić w indeksowanie 1 i użyć '\0'jako końca tablicy.

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

Prawie tylko dokonuje regularnej zamiany ze zmienną tmp i wykorzystuje to, że operator przecinka wprowadza punkty sekwencji, aby mieć określone zachowanie (w przeciwieństwie do niektórych przejawów zamiany xor, które miałyby mniejszą liczbę znaków, ale prowadziłyby do nieokreślonego zachowania).

Edycja: zgodnie z prośbą możesz to przetestować: http://rextester.com/OVOQ23313 .

CL-
źródło
Nie sądzę, żebyś mógł założyć, że masz tablicę z indeksami, które chcesz zamienić. Indeksy są częścią ciągu wejściowego i należy je parsować poza ciąg jako część opublikowanego (i zliczonego) kodu. Z opisu: „Dane wejściowe będą najpierw zawierać ciąg znaków, spację, a następnie parzystą liczbę liczb nieujemnych, wszystkie oddzielone spacjami”.
Reto Koradi
1

Dart - 123

Zakłada, że ​​dane wejściowe w wierszu polecenia są automatycznie dzielone w spacjach. W przeciwnym razie potrzebuje inicjału, x=x[0].split(' ');aby podzielić ciąg na tekst i indeksy.

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

Z większą ilością białych znaków:

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

Uruchom / przetestuj to na dartpad.dartlang.org .

lrn
źródło
Czy znasz jakieś kompilatory online, w których mógłbym to przetestować?
Spikatrix
Dodaj link do DartPada.
LRN
1

Rebol - 71

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

Nie golfowany:

s: take i: split input " " 
foreach [a b] i [swap at s do a at s do b]
print s
draegtun
źródło
Jak to przetestować? Czy jest jakiś kompilator online do testowania tego?
Spikatrix
@CoolGuy - Tak można go przetestować w try.rebol.nl The inputfunkcji nie będzie mógł zadzwonić STDIN stamtąd. Obejściem tego problemu jest proste ustawienie inputwartości, którą chcesz przetestować. Oto pełny przykład pierwszego testu - 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 i kliknij Do w Rebol 3 NB. Rebol używa indeksowania 1.
draegtun
@CoolGuy - Alternatywnie możesz pobrać pliki binarne Rebol 3 z rebolsource.net
draegtun
0

C, 143 bajty

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

Powyższy program pobiera dane z argumentów wiersza poleceń, kopiuje ciąg do tablicy, zamienia odpowiednie znaki, a następnie wysyła zmodyfikowany ciąg.

Nieskluczony kod:

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
źródło
Czy zakładasz, że liczby mają tylko jedną cyfrę? Biorąc pod uwagę, że dane wejściowe mogą mieć do 100 znaków, nie sądzę, aby były poprawne. Zobacz także trzeci przykład, który ma 10jeden z indeksów.
Reto Koradi
@RetoKoradi, dziękuję za wykrycie tego. Naprawiłem kod.
Spikatrix
0

JavaScript (ES6), 95

95 bajtów z pojedynczym wejściem łańcuchowym (funkcja f poniżej)

75 bajtów z 2 parametrami, ciągiem znaków i tablicą liczb (funkcja g poniżej)

(EcmaScript 6, tylko 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
źródło