Trộn các ký tự trong một chuỗi


10

Bạn phải viết một hàm / chương trình nhận đầu vào thông qua stdin/ đối số dòng lệnh / đối số hàm, trộn các ký tự trong một chuỗi và sau đó xuất chuỗi cuối cùng thông qua stdout.

Đầu vào trước tiên sẽ chứa một chuỗi (không trống hoặc null), một khoảng trắng và sau đó là một số chẵn các số không âm được phân tách bằng khoảng trắng. Nếu đầu vào được lấy thông qua các đối số hàm, chuỗi sẽ là một trong các đối số trong khi các số nguyên, được phân tách bằng dấu cách, sẽ là một đối số khác. Bạn phải hoán đổi các ký tự của chuỗi tại các chỉ số tương ứng với các cặp số liên tiếp.

Ví dụ:

Hello_world! 0 6

phải dẫn đến

wello_Horld!

Giả định

  • Bạn có thể chọn giữa lập chỉ mục dựa trên 0 và dựa trên 1 và có thể cho rằng các chỉ mục đã cho sẽ luôn nằm trong phạm vi.
  • Chuỗi sẽ không dài hơn 100 ký tự và sẽ chỉ chứa các ký tự ASCII trong phạm vi !tới ~(mã ký tự 0x21 đến 0x7E, đã bao gồm). Xem bảng ASCII để tham khảo.
  • Hai chỉ số trong một cặp thể giống hệt nhau (trong trường hợp đó, không có gì được hoán đổi trong bước đó).

Chấm điểm

Đây là mã golf, vì vậy bài nộp ngắn nhất (tính bằng byte) sẽ thắng.

Các trường hợp thử nghiệm

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
Đối với các thử thách trong tương lai, hãy để tôi giới thiệu hộp cát nơi bạn có thể nhận phản hồi và đánh bóng thử thách của mình trước khi đăng lên chính (điều này giảm thiểu rủi ro vô hiệu hóa các câu trả lời hiện có nếu ai đó phát hiện ra lỗ hổng nghiêm trọng trong thử thách của bạn cần khắc phục).
Martin Ender

Tại sao yêu cầu đầu vào trên stdin, và không, ví dụ, như các đối số dòng lệnh?
LRN

@lrn, phải rồi. Đã thêm 2 tùy chọn.
Spikatrix

Tôi thấy một loạt các giải pháp dưới đây cho rằng họ có thể lấy danh sách các chỉ mục dưới dạng một mảng được truyền vào hàm họ thực hiện. Cách tôi đọc định nghĩa của bạn, đầu vào là một chuỗi đơn, chứa các chỉ số cũng như chuỗi chúng hoạt động và trích xuất các chỉ mục từ chuỗi đầu vào là một phần của mã cần được đánh gôn. Bạn có thể làm rõ cách giải thích nào là đúng?
Reto Koradi

@RetoKoradi, số Đầu vào không phải là một chuỗi đầy đủ. Nó có một chuỗi, và sau đó là số. Các số không được bao gồm trong chuỗi.
Spikatrix

Câu trả lời:


6

CJam, 11 byte

rr{irie\r}h

Làm thế nào nó hoạt động

Đây là một cách tiếp cận hơi khác, trong đó tôi chỉ cần chạy một vòng lặp do-while cho đến khi tôi có các cặp số còn lại trong đầu vào.

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

Dùng thử trực tuyến tại đây


6

Python 3, 89 86 byte

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

Giải nén tất cả mọi thứ. (3 byte được lưu nhờ @potato)


Lưu một vài byte và làm điều này: [*s],*L=input().split()sau đó bạn có thể lấy dòng sau khi nó đi. Tôi thực sự thích giải pháp của bạn btw, nó gần như thanh lịch mặc dù nó rất golf.
khoai tây

@potato Ôi chà, tôi không biết bạn có thể có hai lần giải nén như vậy (tôi nghĩ bạn chỉ có thể làm điều đó trong 3.5). Cảm ơn!
Sp3000

4

CJam, 13 byte

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

Kiểm tra nó ở đây.

Giải trình

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.

Ái chà. Không mong đợi một câu trả lời nhanh như vậy!
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]);}}

Giải thích đang đến ...

Tranh luận

T = một từ loại char * .

V = một mảng gồm một số phần tử nguyên chẵn.

L = chiều dài của V

Đầu ra

chuỗi hỗn hợp

Làm thế nào nó hoạt động ?:

quét các số của mảng V ngược lại và đặt phần tử thứ n của chuỗi sau khi theo dõi tất cả tiến trình của nó cho đến điểm thực tế. Thí dụ

đầu vào = T = "Đầu tiên", V = {1,2,1,0,0,4}

V đảo ngược = {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 ..

Hãy thử nó ở đây


1
@ Agawa001, bạn có thể chơi golf này nhiều hơn nữa. Loại trả về intlà không cần thiết (có thể dẫn đến hành vi không mong muốn) và intcác biến là tham số không cần intbiến, thay vì khai báo trong vòng lặp có thể được khai báo ở một nơi bên ngoài vòng lặp, sử dụng putcharthay vì printfvv
Spikatrix

2

Con trăn 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))

Chơi gôn nhiều hơn bằng cách hoán đổi xung quanh một số biến và sử dụng ; như trong nhận xét của Tim.

Tôi dự kiến ​​nó sẽ ra sân chơi golf, chỉ là không nhiều như vậy.


1
Bạn có thể chơi golf này rất nhiều. Thay đổi whilethành while c<len(t):line1;line2;line3.... c=c+2đi đếnc+=2
Tim

@Tim Cảm ơn sự giúp đỡ của bạn!
ASCIIThenANSI

Không nên bắt đầu từ 0?
Tim

@Tim Không. cthực sự là lập chỉ mục t(đầu vào) để có được các vị trí chúng ta cần trao đổi. Nhưng vì t[0]là chuỗi chúng ta cần trao đổi xung quanh,t[1]t[2]giữ cặp giao dịch hoán đổi đầu tiên.
ASCIIThenANSI

À tôi hiểu rồi, đúng vậy. Xin lỗi, giải pháp của tôi đã tách ra khỏi đầu vào, vì vậy tôi đoán bạn cũng đã làm như vậy :)
Tim

2

C, 109 107 102 byte

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

Lưu ý: sacần được khai báo là mảng toàn cầu. slà chuỗi mà bạn muốn trao đổi và alà một mảng củaint với tất cả các giá trị số.

Nếu đoạn mã trên không hoạt động, hãy thử sử dụng void f(){...}thay vìf(){...}

Mã bị đánh cắp:

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
}

Kiểm tra nó ở đây


Mã hmm của bạn nhỏ hơn :)
Abr001am

lol khai báo biến ở đâu? Đó là một cách gian lận để thắt chặt mã ur: p
Abr001am

@ Agawa001, tôi không bao gồm khai báo biến vì các byte sẽ thay đổi theo từng trường hợp kiểm tra.
Spikatrix 17/05/2015

Điều này không phù hợp với đầu vào như được xác định trong vấn đề. Đầu vào là một chuỗi đơn. Trừ khi tôi hoàn toàn hiểu sai vấn đề, bạn cần trích xuất các giá trị chỉ mục từ chuỗi đầu vào.
Reto Koradi

1

Tră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))

Giải trình:

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 byte

Cho rằng chuỗi đầu vào có độ dài tối đa 100, tôi quyết định tạo byte 'NULL' chỉ ra phần cuối của mảng số nguyên là không rõ ràng 0xFF. Có lẽ điều này không được tính là đầu vào thêm, mặc dù với chi phí (tối đa) 7 3 byte, nó có thể được lập thành lập chỉ mục dựa trên 1 và sử dụng '\0'làm phần cuối của mảng.

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

Khá nhiều việc hoán đổi thông thường với biến tmp và sử dụng toán tử dấu phẩy giới thiệu các điểm chuỗi để có hành vi xác định (không giống như một số biểu hiện của hoán đổi xor sẽ có số lượng ký tự thấp hơn nhưng dẫn đến hành vi không xác định).

Chỉnh sửa: Theo yêu cầu, bạn có thể kiểm tra nó: http://rextester.com/OVOQ23313 .


Tôi không nghĩ rằng bạn có thể giả định rằng bạn có được một mảng với các chỉ số được hoán đổi. Các chỉ mục là một phần của chuỗi đầu vào và bạn cần phân tích chúng ra khỏi chuỗi như một phần của mã được đăng (và được tính). Từ mô tả: "Đầu vào trước tiên sẽ chứa một chuỗi, một khoảng trắng và sau đó là một số chẵn các số không âm được phân tách bằng khoảng trắng."
Reto Koradi

1

Phi tiêu - 123

Giả sử đầu vào trên dòng lệnh được tự động phân tách tại các khoảng trắng. Nếu không, nó cần một chữ cái đầu x=x[0].split(' ');để phân tách chuỗi thành văn bản và chỉ mục.

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

Với nhiều khoảng trắng hơn:

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

Chạy / kiểm tra điều này trên dartpad.dartlang.org .


Bạn có biết bất kỳ trình biên dịch trực tuyến nào mà tôi có thể kiểm tra điều này không?
Spikatrix 17/05/2015

Thêm liên kết đến DartPad.
LRN

1

Nổi loạn - 71

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

Ung dung:

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

Làm thế nào để tôi kiểm tra điều này? Có bất kỳ trình biên dịch trực tuyến để thử nghiệm này?
Spikatrix 17/05/2015

@CoolGuy - Có bạn có thể kiểm tra nó ở try.rebol.nl Các inputchức năng sẽ không thể gọi STDIN từ đó. Cách giải quyết là đặt đơn giản thành inputgiá trị bạn muốn kiểm tra. Dưới đây là ví dụ đầy đủ về thử nghiệm đầu tiên - 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 và nhấp vào Do trong Rebol 3 NB. Rebol sử dụng lập chỉ mục dựa trên 1.
Drainegtun 17/05/2015

@CoolGuy - Hoặc bạn có thể tải về Rebol 3 mã nhị phân từ rebolsource.net
draegtun

0

C, 143 byte

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

Chương trình trên lấy đầu vào từ các đối số dòng lệnh, sao chép chuỗi thành một mảng, hoán đổi các ký tự tương ứng và sau đó, xuất chuỗi đã sửa đổi.

Mã bị đánh cắp:

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
}

Bạn có cho rằng các số chỉ có một chữ số? Xem xét rằng đầu vào có thể lên tới 100 ký tự, tôi không nghĩ rằng nó sẽ hợp lệ. Cũng xem ví dụ thứ 3, có 10một trong các chỉ số.
Reto Koradi

@RetoKoradi, Cảm ơn vì đã phát hiện ra điều đó. Tôi đã sửa mã.
Spikatrix

0

JavaScript (ES6), 95

95 byte với một chuỗi đầu vào (hàm f bên dưới)

75 byte với 2 tham số, chuỗi và mảng số (hàm g bên dưới)

(Chỉ 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>

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.