Змішування символів у рядку


10

Ви повинні написати функцію / програму, яка приймає введення через stdinаргументи / командного рядка / аргументи функції, змішує символи в рядку, а потім виводить заключну рядок через stdout.

Спочатку введення міститиме рядок (не порожній або null), пробіл, а потім парне число невід’ємних чисел, усі розділені пробілами. Якщо введення здійснюється через аргументи функції, рядок буде одним з аргументів, тоді як цілі числа, відокремлені пробілом, будуть іншими. Ви повинні поміняти символи рядка на індекси, що відповідають послідовним парам чисел.

Наприклад:

Hello_world! 0 6

має призвести до

wello_Horld!

Припущення

  • Ви можете вибрати між індексацією на основі 0 та 1, і можна припустити, що вказані індекси завжди будуть в діапазоні.
  • Рядок не буде довше 100 символів і міститиме лише символи ASCII в діапазоні !до ~(коди символів 0x21 до 0x7E, включно). Для ознайомлення дивіться таблицю ASCII .
  • Два індекси в парі можуть бути однаковими (у цьому випадку на цьому кроці нічого не поміняється).

Оцінка балів

Це код гольфу, тому виграє найкоротше подання (у байтах).

Випробування

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~

2
Для майбутніх проблем дозвольте мені порекомендувати пісочницю, де ви можете отримати зворотній зв'язок та відшліфувати свою проблему, перш ніж розміщувати її на головній (це мінімізує ризик визнання недійсних відповідей, якщо хтось виявить серйозний недолік у вашому виклику, який потребує виправлення).
Мартін Ендер

Навіщо вимагати введення на stdin, а не, наприклад, як аргументи командного рядка?
lrn

@lrn, правильно. Додано ще 2 варіанти.
Spikatrix

Нижче я бачу купу рішень, які припускають, що вони можуть отримати список індексів як масив, який передається у функцію, яку вони реалізують. Те, як я читаю ваше визначення, вхід - це один рядок, який містить індекси, а також рядок, над яким вони працюють, а вилучення індексів із вхідного рядка є частиною коду, який потребує гольфу. Чи можете ви уточнити, яке тлумачення є правильним?
Рето Кораді

@RetoKoradi, Ні. Введення не є повною ланкою. У ньому є рядок, а потім числа. Числа не включаються в рядок.
Spikatrix

Відповіді:


6

CJam, 11 байт

rr{irie\r}h

Як це працює

Це дещо інший підхід, в якому я просто запускаю цикл виконання часу, поки у входу не залишиться пари чисел.

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

Спробуйте його онлайн тут


6

Пітон 3, 89 86 байт

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

Розпакуйте всі речі. (3 байти збережено завдяки @potato)


Збережіть кілька байтів і зробіть це: [*s],*L=input().split()ви можете взяти рядок після нього. Мені дуже подобається ваше рішення BTW, воно майже елегантне, навіть якщо воно дуже гольф.
картопля

@potato О, уау, я не знав, що ти можеш мати два розпакування разом (я думав, що ти можеш це зробити лише в 3.5). Дякую!
Sp3000

4

CJam, 13 байт

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

Тестуйте це тут.

Пояснення

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.

Вау. Не очікував відповіді так швидко!
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]);}}

Пояснення наближається ...

Аргументи

T = слово типу char * .

V = масив парного числа цілих елементів.

L = довжина V

Вихідні дані

змішана струна

Як це працює ? :

підмітає числа масиву V навпаки і ставить n-й елемент рядка після відстеження всього його прогресу до фактичної точки. Приклад

input = T = "Перший", V = {1,2,1,0,0,4}

V перевернутий = {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 ..

Спробуйте тут


1
@ Agawa001, Ви можете гольфувати це набагато більше. Тип повернення intне потрібен (може призвести до несподіваної поведінки), а intзмінні, які є параметрами, не потребують intзмінних, а замість оголошення в циклі можуть бути оголошені в одному місці поза циклом, використовувати putcharзамість printfтощо
Spikatrix

2

Пітон 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))

Гольф більше, обмінюючись деякими змінними та використовуючи, ;як у коментарі Тіма.

Я очікував, що це вийде виглядати гольф, тільки не дуже.


1
Ви можете багато в цьому гольфу. Змініть whileна while c<len(t):line1;line2;line3.... c=c+2іде доc+=2
Тім

@Tim Дякую за допомогу!
ASCIIThenANSI

Чи не слід починати з 0?
Тім

@Tim Nope. cнасправді є індексування t(введення), щоб отримати позиції, які нам потрібно поміняти. Але оскільки t[0]це рядок, нам потрібно поміняти місцями t[1]і t[2]провести першу пару свопів.
ASCIIThenANSI

Ах, бачу, так. Вибачте, моє рішення розділило вхід, тому я здогадався, що ви зробили те саме :)
Тім

2

C, 109 107 102 байт

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

Примітка: sі aпотрібно оголошувати як глобальні масиви. sце рядок, на який ви хочете поміняти місцями, і aце масив intзі всіма значеннями числа.

Якщо вищевказаний код не працює, спробуйте використовувати void f(){...}замістьf(){...}

Невикористаний код:

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
}

Тестуйте це тут


хм ур-код менший :)
Abr001am

lol, де мінлива декларація? ось хитрий спосіб підтягнути ур-код: p
Abr001am

@ Agawa001, я не включав декларацію змінної, оскільки байти змінюватимуться в кожному тестовому випадку.
Spikatrix

Це не відповідає входу, визначеному в проблемі. Вхід - це один рядок. Якщо я повністю не зрозумів проблему, вам потрібно витягти значення індексу з вхідного рядка.
Рето Кораді

1

Пітон 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))

Пояснення:

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

1

C, 70 байт

Зважаючи на те, що вхідний рядок становить максимум довжину 100, я вирішив зробити байт 'NULL' із зазначенням кінця цілого масиву однозначним 0xFF. Імовірно, це не вважається додатковим входом, хоча за ціною (щонайбільше) 7 3 байтів його можна перетворити на індексацію на основі 1 та використовувати '\0'як кінець масиву.

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

В основному просто проводиться регулярний замін на змінну tmp і використовує те, що оператор кома вводить точки послідовності з визначеною поведінкою (на відміну від деяких проявів заміни xor, які мали б менший кількість символів, але призводять до не визначеної поведінки).

Редагувати: За бажанням ви можете перевірити це: http://rextester.com/OVOQ23313 .


Я не думаю, що ви можете припустити, що ви отримуєте масив з індексами, які потрібно міняти. Індекси є частиною вхідного рядка, і вам потрібно розібрати їх із рядка як частину розміщеного (і підрахованого) коду. З опису: "Введення спочатку буде містити рядок, пробіл, а потім парне число невід'ємних чисел, всі розділені пробілами."
Рето Кораді

1

Дартс - 123

Припускає, що введення в командному рядку автоматично розділяється на пробіли. В іншому випадку потрібно початкове x=x[0].split(' ');розділення рядка на текст та індекси.

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

З більшою кількістю пробілів:

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

Запустіть / протестуйте це на dartpad.dartlang.org .


Чи знаєте ви які-небудь онлайн-компілятори, де я міг би це перевірити?
Spikatrix

Додати посилання на DartPad.
lrn

1

Ребол - 71

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

Безголівки:

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

Як це перевірити? Чи є якийсь онлайн-компілятор для тестування цього?
Spikatrix

@CoolGuy - Так , ви можете перевірити його на try.rebol.nl The inputфункції не буде в змозі назвати STDIN звідти. Вирішення проблеми - це просто встановити inputзначення, яке ви хочете перевірити. Ось повний приклад першого тесту - 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 і натисніть Do у Rebol 3 NB. Rebol використовує індексацію на основі 1.
draegtun

@CoolGuy - Або ви можете завантажити Rebol 3 binaries з rebolsource.net
draegtun

0

C, 143 байти

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

Вищенаведена програма приймає дані з аргументів командного рядка, копіює рядок у масив, замінює відповідні символи та виводить модифіковану рядок.

Невикористаний код:

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
}

Ви припускаєте, що числа мають лише одну цифру? Враховуючи, що вхід може містити до 100 символів, я не думаю, що це буде дійсним. Подивіться також на 3-й приклад, який є 10одним із показників.
Рето Коради

@RetoKoradi, Дякую, що помітили це. Я виправив код.
Spikatrix

0

JavaScript (ES6), 95

95 байт з одним рядовим входом (функція f нижче)

75 байт з 2 параметрами, рядком та масивом (функція g нижче)

(Лише 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>

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.