Смешивание символов в строке


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, верно. Добавлено еще 2 варианта.
Спикатрикс

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

@RetoKoradi, Нет. Ввод не является полной строкой. У него есть строка, а затем цифры. Числа не включены в строку.
Spikatrix

Ответы:


6

CJam, 11 байт

rr{irie\r}h

Как это работает

Это немного другой подход, в котором я просто запускаю цикл do-while, пока на входе не останется пар чисел.

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

Python 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()затем вы можете убрать строку после нее. Мне очень нравится ваше решение, кстати, оно почти элегантно, хотя и очень гольфы.
картошка

@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

С (137 б)

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-й элемент строки после отслеживания всего ее хода до фактической точки. пример

входные = T = "First", 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вместо printfetc
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
Вы можете играть в гольф много. Изменение whileTo while c<len(t):line1;line2;line3.... c=c+2идетc+=2
Тим

@ Тим Спасибо за вашу помощь!
ASCIIThenANSI

Разве не должен начинаться с 0?
Тим

@ Тим Нет. 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(){...}

Код Ungolfed:

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 .


Вы знаете какие-нибудь онлайн-компиляторы, где я мог бы это проверить?
Спикатрикс

Добавить ссылку на DartPad.
января

1

Реболь - 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

Как мне это проверить? Есть ли онлайн-компилятор для тестирования этого?
Спикатрикс

@CoolGuy - Да, вы можете проверить это на try.rebol.nl . 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 с 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);}

Вышеуказанная программа принимает входные данные из аргументов командной строки, копирует строку в массив, заменяет соответствующие символы и затем выводит измененную строку.

Код Ungolfed:

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.