Buka kembali string case- (sangat) sensitif ini

53

Tujuan

Ini adalah tantangan sederhana. Tujuan Anda adalah menguraikan string dengan menukar setiap huruf dengan huruf berikutnya dari huruf yang sama, sambil membiarkan karakter non-huruf tidak berubah.

contoh

Penjelasan langkah demi langkah

  1. Karakter pertama adalah a E. Kami mencari huruf berikutnya dalam huruf besar: itu a C. Kami menukar karakter ini, yang mengarah ke CdoE!.

  2. Kami maju ke karakter berikutnya: ini adalah a d. Kami mencari huruf berikutnya dalam huruf kecil: itu a o. Kami menukar karakter ini, yang mengarah ke CodE!.

  3. Kami maju ke karakter berikutnya: ini adalah dbahwa kami baru saja pindah ke sini. Kami mengabaikannya, karena sudah diproses.

  4. Kami maju ke karakter berikutnya: ini adalah Eyang dipindahkan di sini di langkah # 1. Kami mengabaikannya, karena sudah diproses.

  5. Kami maju ke karakter berikutnya: ini adalah a !. Kami mengabaikannya, karena itu bukan surat.

Aturan

  • Anda dapat mengasumsikan bahwa string input dibuat secara eksklusif dari karakter ASCII yang dapat dicetak, dalam kisaran 32 - 126.

  • Anda dapat menulis program lengkap atau fungsi, yang mencetak atau mengembalikan hasilnya.

  • Jika string input berisi jumlah huruf ganjil, huruf terakhir yang tersisa tidak dapat ditukar dengan yang lain dan harus tetap di tempatnya, tidak peduli kasusnya. Logika yang sama berlaku jika string berisi angka genap, tetapi angka ganjil dari huruf besar dan jumlah ganjil dari huruf kecil.

  • Ini adalah kode-golf, jadi jawaban tersingkat dalam byte menang. Celah standar dilarang.

Uji kasus

Input : lLEhW OroLd!
Output: hELlO WorLd!

Input : rpGOZmaimgn uplRzse naC DEoO LdGf
Output: prOGRamming puzZles anD COdE GoLf

Input : eIt uqHKC RBWOO xNf ujPMO SzRE HTL EOvd yAg
Output: tHe quICK BROWN fOx juMPS OvER THE LAzy dOg

Input : NraWgCi: Nsas-eNEiTIsev rNsiTG!!
Output: WarNiNg: Case-sENsITive sTriNG!!

Kasus uji yang tidak terlalu acak:

Input : (^_^)
Output: (^_^)

Input : AWCTY HUOS RETP
Output: WATCH YOUR STEP

Input : hwn oeesd acsp nawyya
Output: who needs caps anyway

Input : SpMycaeIesKyBorekn
Output: MySpaceKeyIsBroken

Input : D's mroyr, Ivam. I'e faardi I act'n od htta.
Output: I'm sorry, Dave. I'm afraid I can't do that.
Arnauld
sumber
Saya berasumsi komentar yang sama berlaku jika inputnya berisi jumlah huruf genap, tetapi angka ganjil dari huruf besar dan jumlah ganjil dari huruf kecil.
Greg Martin
14
Ini adalah tantangan yang sangat pintar ... Saya juga menyukai kenyataan bahwa kasus uji dapat dibuat dengan mengetikkan string huruf kecil, secara acak mengubah beberapa huruf menjadi huruf besar, dan kemudian menjalankan program yang sama persis yang menyelesaikan masalah!
Greg Martin
1
@GregMartin Saya menemukan bahwa masalahnya adalah kebalikannya sendiri karena ketika mencoba sebuah test case saya tidak sengaja mengetikkan output daripada input :-)
Luis Mendo
Saya pikir Anda harus memasukkan kasus uji dengan lebih dari satu karakter ASCII non-huruf ... Saya pikir beberapa implementasi secara tidak sengaja dapat beralih satu sama lain, ketika itu tidak seharusnya terjadi.
Greg Martin
3
Kasing tes mungkin harus menyertakan string tanpa huruf besar dan string tanpa huruf sama sekali.
Dennis

Jawaban:

4

Jelly , 21 20 19 18 byte

s2UF,
nŒlTÇyJịŒsµ⁺

Cobalah online!

Bagaimana itu bekerja

nŒlTÇyJịŒsµ⁺  Main link. Argument: s (string)

 Œl           Convert to lowercase.
n             Test for inequality.
   T          Truth; yield all indices of 1's.
    Ç         Call the helper link. Yields [A, B] (pair of lists).
      J       Indices; yield I := [1, ..., len(s)].
     y        Translate; replace the integers of I that occur in A with the
              corresponding integers in B.
        Œs    Swapcase; yield s with swapped case.
       ị      Use the translated index list to index into s with swapped case.
          µ   Combine all links to the left into a chain.
           ⁺   Duplicate the chain, executing it twice.


s2UF,         Helper link. Argument: J (list of indices)

s2            Split J into pairs. If the length is odd, the last list will be
              a singleton list.
  U           Upend; reverse each pair. This is a no-op for singletons lists.
   F          Flatten, concatenating the pairs.
    ,          Pair the previous result with J.
Dennis
sumber
18

Retina , 53 byte

Tidak terlalu pintar, tetapi solusi yang bersih dan cukup mudah dibaca

([a-z])(.*?)([a-z])
$3$2$1
([A-Z])(.*?)([A-Z])
$3$2$1

Cobalah online!

Leo
sumber
9

MATL , 22 byte

2:"tttk<f2etAZ))P5M(Yo

Cobalah online! Atau verifikasi semua kasus uji .

Bagaimana itu bekerja

2:"       % Do the following twice
  ttt     %   Input string (implicit). Push three more copies
  k       %   Convert to lowercase
  <f      %   Indices of characters that had their code point increased by
          %   the lowercase conversion, i.e. that were uppercase letters
  2e      %   Convert to 2-row matrix. This pads a zero in the lower-right 
          %   corner if necessary
  tAZ)    %   Keep only columns that don't contain zeros. Thus if there
          %   was a character that can't be swapped it will be ignored             
  )       %   Get 2-row matrix of characters at those positions
  P       %   Flip vertically. This does the swapping
  5M      %   Push matrix of original indices again
  (       %   Write the swapped characters onto their original positions
  Yo      %   Change case. In the first iteration, this prepares the
          %   string so the second iteration will process the letters that
          %   were originally lowercase. In the second iteration, it
          %   undoes the change of case 
          % End (implicit)
          % Display (implicit)
Luis Mendo
sumber
6

Utilitas Bash + Unix, 77 62 57 56 54 byte

sed -r "s/([$1)([^$1*)([$1)/\3\2\1/g"||$0 a-z]|$0 A-Z]

Masukan di stdin. Output di stdout.

(Dalam versi terakhir ini, stderr kebetulan ditulis juga, tetapi konsensus PPCG tampaknya tidak masalah - stderr diabaikan begitu saja. )

Sunting 1: Terima kasih kepada @Dennis selama 15 byte! Perbaikan: (a) Mengambil input melalui stdin; (B) menggabungkan 2 skrip sed menjadi satu; dan (c) mengganti tr dengan substitusi melalui ekspansi parameter bash; (b) dan (c) menghilang di Edit 2.

Sunting 2: Lebih pendek dengan 5 byte tambahan. Menggunakan panggilan fungsi untuk mengganti (b) dan (c) pada Edit 1.

Sunting 3: Satu byte lagi - berlalu] sebagai bagian dari argumen fungsi.

Sunting 4: Mengganti dua panggilan fungsi dengan panggilan ke program itu sendiri ketika tidak memiliki argumen.

Output testbed dan sampel:

for x in 'lLEhW OroLd!' 'rpGOZmaimgn uplRzse naC DEoO LdGf' 'eIt uqHKC RBWOO xNf ujPMO SzRE HTL EOvd yAg' 'NraWgCi: Nsas-eNEiTIsev rNsiTG!!' '(^_^)' 'AWCTY HUOS RETP' 'hwn oeesd acsp nawyya' 'SpMycaeIesKyBorekn' "D's mroyr, Ivam. I'e faardi I act'n od htta."; do ./swapping <<<"$x" 2>/dev/null; done

hELlO WorLd!
prOGRamming puzZles anD COdE GoLf
tHe quICK BROWN fOx juMPS OvER THE LAzy dOg
WarNiNg: Case-sENsITive sTriNG!!
(^_^)
WATCH YOUR STEP
who needs caps anyway
MySpaceKeyIsBroken
I'm sorry, Dave. I'm afraid I can't do that.
Mitchell Spector
sumber
6

ES6, 185 95 byte

i=>(o=[...i]).map((c,j)=>/[a-z]/i.test(c)?o[e=c>"Z"]=1/(b=o[e])?o[o[j]=o[b],b]=c:j:0)&&o.join``

Solusi sangat singkat dengan bantuan @Neil, @Arnauld dan @ edc65

Penjelasan

f = i =>
  // Get array of characters from input string
  (o = [...i])
    .map((c, j) => 
      // Check if it's a text character, otherwise skip it
      /[a-z]/i.test(c) ? 
        // Get last character position for case
        // merged with setting a variable for if the character is lowercase
        // merged with storing the current case character position,  
        // under properties on the array (with keys "true" or "false")
        o[e = c>"Z"] =
          // Check if there exists a character position to switch with
          // merged with storing the current position for quick access
          1/(b=o[e]) ? 
            // This statement will end up returning the Array subset, 
            // which will be falsy in the above conditional since (1/[])==false
            o[
              // Switch left character to the right
              o[j]=o[b]
            // Switch right character to the left
            ,b]=c : 
            // No character exists for case, so return current character position
            j
         // It was not a text character, so do nothing
         :0
      )
  // Join array and return as result
  && o.join``;

`lLEhW OroLd!
NraWgCi: Nsas-eNEiTIsev rNsiTG!!
rpGOZmaimgn uplRzse naC DEoO LdGf
eIt uqHKC RBWOO xNf ujPMO SzRE HTL EOvd yAg
(^_^)
AWCTY HUOS RETP
hwn oeesd acsp nawyya
SpMycaeIesKyBorekn
D's mroyr, Ivam. I'e faardi I act'n od htta`
  .split`\n`
  .map(testCase => console.log(f(testCase)));

Jan
sumber
6 byte, parens terlampir adalah berlebihan ketika kita menghapus pernyataan kedua :) Bagus.
Jan
2
Tolong abaikan komentar terakhir saya. Inilah 99:/[a-z]/i.test(c)?o[e=c>"Z"]=1/(b=o[e])?[o[b],o[j]]=[c,o[b]]:j:0
Arnauld
2
[o[b],o[j]]=[c,o[b]]bisao[o[j]=o[b],b]=c
edc65
Masterstroke yang sebenarnya di sini menggunakan benar dan salah sebagai indeks untuk array
edc65
Terima kasih kawan, turun ke 95 sekarang. Mulai menjadi sangat sulit untuk mendokumentasikan solusi dengan cara yang masuk akal. XD @ edc65 mereka disimpan sebagai properti pada objek array, bukan indeks. Ya Arnauld menemukan bahwa mereka sedang disimpan pada array karakter, tetapi penggunaan kembali objek itu lebih merupakan kecelakaan beruntung saya pikir itu berasal dari saran yang terpisah. Awalnya itu disimpan pada objek terpisah yang tentu saja sama sekali tidak perlu untuk lingkup tantangan.
Jan
3

Python , 82 byte

lambda s:S(r.lower(),t,S(r,t,s))
import re
S=re.sub
r='([A-Z])(.*?)'*2
t=r'\3\2\1'

Cobalah online!

Dennis
sumber
bagaimana cara kerjanya? Apakah lambda itu disebut?
Sarge Borsch
Lambda adalah pengiriman (fungsi) yang sebenarnya. Semua yang lain hanya kode yang menyertainya yang harus dieksekusi sebelum lambda dipanggil.
Dennis
3

QBasic, 229 byte

LINE INPUT s$
FOR i=1TO LEN(s$)
c$=MID$(s$,i,1)
IF"@"<c$AND"[">c$THEN
IF u THEN MID$(s$,u,1)=c$:MID$(s$,i,1)=u$
u=-i*(u=0)
u$=c$
ELSEIF"`"<c$AND"{">c$THEN
IF l THEN MID$(s$,l,1)=c$:MID$(s$,i,1)=l$
l=-i*(l=0)
l$=c$
END IF
NEXT
?s$

Strategi

Kami mengulang melalui string input. Ketika kami menemukan huruf besar, kami menyimpannya dan posisinya. Kali kedua kami menjumpai huruf besar, kami menggunakan nilai yang tersimpan itu untuk menukar dengan yang sebelumnya. Sama untuk huruf kecil.

(Saya akan memposting versi yang lebih panjang yang menggunakan array, karena saya pikir string QBasic tidak dapat diubah. Kemudian saya menemukan fakta yang MID$(strng$, index, length) = replacement$berfungsi dengan baik. Langsung dan pelajari.)

+ Ungolfed berkomentar

LINE INPUT text$

FOR i = 1 TO LEN(text$)
  char$ = MID$(text$, i, 1)
  IF "A" <= char$ AND "Z" >= char$ THEN
    ' Uppercase
    IF upperIndex = 0 THEN
      ' This is the first of a pair of uppercase letters
      ' Store the letter and its index for later
      upperLetter$ = char$
      upperIndex = i
    ELSE
      ' This is the second of a pair of uppercase letters
      ' Put it at the position of the previous uppercase letter
      ' and put that letter at this letter's position
      MID$(text$, upperIndex, 1) = char$
      MID$(text$, i, 1) = upperLetter$
      upperIndex = 0
    END IF
  ELSEIF "a" <= char$ AND "z" >= char$ THEN
    ' Lowercase
    IF lowerIndex = 0 THEN
      ' This is the first of a pair of lowercase letters
      ' Store the letter and its index for later
      lowerLetter$ = char$
      lowerIndex = i
    ELSE
      ' This is the second of a pair of lowercase letters
      ' Put it at the position of the previous lowercase letter
      ' and put that letter at this letter's position
      MID$(text$, lowerIndex, 1) = char$
      MID$(text$, i, 1) = lowerLetter$
      lowerIndex = 0
    END IF
  END IF
NEXT i

PRINT text$
DLosc
sumber
2

C ++ 11 (GCC), 154 149 byte

#include<algorithm>
[](std::string s){int*p,u,l=u=-1;for(auto&c:s)(c|32)-97<26U?p=&(c&32?u:l),~*p?(std::swap(c,s[*p]),*p=-1):*p=&c-&s[0]:0;return s;}
kubah
sumber
1
Anda juga harus #include<string>beralih ke C ++ 14 dan mendeklarasikan lambda generik [](auto s)dan menganggapnya ssebagai std::string. Juga, mendeklarasikan [](auto&s)menyelamatkan Anda dari mengembalikan string sebagai memodifikasi argumen input untuk berfungsi sebagai output diizinkan.
Karl Napf
2

Qbasic, 436 408 byte

LINE INPUT a$:b=len(a$):FOR a=1TO b:t$=MID$(a$,a,1)
IF"@"<t$AND"[">t$THEN
b$=b$+"U":u$=u$+t$
ELSEIF"`"<t$AND"{">t$THEN
b$=b$+"L":l$=l$+t$
ELSE b$=b$+t$
END IF:NEXT
FOR x=1TO b STEP 2:g$=g$+MID$(u$,x+1,1)+MID$(u$,x,1):h$=h$+MID$(l$,x+1,1)+MID$(l$,x,1):NEXT
FOR x=1TO b:t$=MID$(b$,x,1)
IF"U"=t$THEN
u=u+1:z$=z$+MID$(g$,u,1)
ELSEIF"L"=t$THEN l=l+1:z$=z$+MID$(h$,l,1)
ELSE z$=z$+t$
END IF:NEXT:?z$

Disimpan satu byte berkat DLosc. Disimpan beberapa lagi dengan mengubah penanganan karakter non-huruf.

Ini pada dasarnya terdiri dari tiga bagian:

  • Membagi input menjadi 3 string (Huruf besar, Huruf kecil, dan peta (juga memegang karakter lainnya))
  • Membalik huruf besar dan kecil
  • Menggunakan peta untuk (kembali) membangun output.

Penjelasan yang lebih terperinci (perhatikan bahwa ini merupakan versi kode yang lebih lama, tetapi prinsipnya masih berlaku):

' --- Part I: Reading the input
LINE INPUT a$
'This FOR loop takes one character at a time
b=len(a$):FOR a=1TO b
' And checks in what category the character belongs
t$=MID$(a$,a,1):SELECT CASE t$
' For each group, char t$ is added to that group (u$ for uppercase, 
' l$ for lowercase. The map in b$ is updated with a U or L on this index,
' or with the non-letter char t$.
CASE"A"TO"Z":b$=b$+"U":u$=u$+t$
CASE"a"TO"z":b$=b$+"L":l$=l$+t$
CASE ELSE:b$=b$+t$
END SELECT:NEXT

' --- Part II: Swapping within case-groups
' Loop through u$ and l$ twp chars at a time, and add those chunks in reverse order
' to g$ and h$. Because mid$ doesn't fail past the end of a string (but returns ""), 
' this automatically compensates for odd-length groups.
FOR x=1TO b STEP 2:g$=g$+MID$(u$,x+1,1)+MID$(u$,x,1):h$=h$+MID$(l$,x+1,1)+MID$(l$,x,1):NEXT

' --- Part III: Read the map to put it all back together
FOR x=1TO b:t$=MID$(b$,x,1)
' See what group was in this spot, then read the next char from the flipped string.
' This keeps an index on those strings for the next lookup.
IF t$="U"THEN
u=u+1:z$=z$+MID$(g$,u,1)
ELSEIF t$="L"THEN l=l+1:z$=z$+MID$(h$,l,1)
' The map contains a non-letter char, just drop that in
ELSE z$=z$+t$
' And finally,display the end result.
END IF:NEXT:?z$
steenbergh
sumber
2

PHP, 108 93 83 byte

<?=preg_replace([$a="/([a-z])([^a-z]*)([a-z])/",strtoupper($a)],"$3$2$1",$argv[1]);

Versi sebelumnya (93 byte)

<?=preg_replace(["/([a-z])([^a-z]*)([a-z])/","/([A-Z])([^A-Z]*)([A-Z])/"],"$3$2$1",$argv[1]);

Terima kasih kepada @ user59178 untuk mengingatkan saya bahwa preg_replace()dapat menggunakan array string sebagai argumen.


Jawaban asli (108 byte)

$f=preg_replace;echo$f("/([a-z])([^a-z]*)([a-z])/",$r="$3$2$1",
$f("/([A-Z])([^A-Z]*)([A-Z])/",$r,$argv[1]));

Kode dibungkus di sini agar sesuai dengan ruang yang tersedia.
Itu dapat dieksekusi dari baris perintah:

$ php -d error_reporting=0 -r '$f=preg_replace;echo$f("/([a-z])([^a-z]*)([a-z])/",$r="$3$2$1",$f("/([A-Z])([^A-Z]*)([A-Z])/",$r,$argv[1]));' 'lLEhW OroLd!'

Versi 1 byte yang lebih pendek dimungkinkan pada PHP 7 dengan menekan penugasan $fdi dalam panggilan pertamanya:

echo($f=preg_replace)("/([a-z])([^a-z]*)([a-z])/",$r="$3$2$1",
$f("/([A-Z])([^A-Z]*)([A-Z])/",$r,$argv[1]));

Kedua solusi, dengan kasus uji dan versi tidak berjubah dapat ditemukan di Github .

aksioma
sumber
1
preg_replacedapat mengambil berbagai penggantian untuk melakukannya sehingga Anda hanya perlu satu panggilan. Selain itu lebih pendek untuk digunakan <?=daripada echo. Dengan ini mudah untuk mendapatkan jawaban Anda hingga 93 byte.
user59178
Anda benar tentang preg_replace(). Saya lupa tentang itu. Saya tidak suka <?=(menurut saya <?bukan bagian dari bahasa, itu hanya penanda) dan saya suka menulis program satu baris pendek yang dapat dieksekusi dari baris perintah menggunakan php -r. Tetapi untuk tujuan golf kode Anda benar lagi. Saya bisa menghemat 1 byte menggunakan <?=.
Aksioma
1

Mathematica, 96 byte

s[#,r="([a-z])(.*?)([a-z])"]~(s=StringReplace[#,RegularExpression@#2->"$3$2$1"]&)~ToUpperCase@r&

Port jawaban Retina Leo , yang menggunakan ekspresi reguler.

Greg Martin
sumber
Saya benar-benar terkejut bahwa Mathematica tidak memiliki builtin untuk itu, maksud saya, jika "Kapan hari Minggu Paskah", "Kapan matahari terbenam" dan "apa bentuk perancis" mendapatkan builtin, yang ini juga harus!
sagiksp
1

Python 2 , 124 byte

s=input();u=str.isupper
exec"r='';i=0\nfor c in s:r+=c[u(c):]or filter(u,s+s[::-1])[i^1];i+=u(c)\ns=r.swapcase();"*2
print s

Tidak sesingkat solusi berbasis regex saya , tapi saya pikir ini masih menarik.

Cobalah online!

Dennis
sumber
1

Bean , 83 byte

Hexdump:

00000000 26 53 d0 80 d3 d0 80 a0 5d 20 80 0a a1 81 81 00  &SÐ.ÓÐ. ] ..¡...
00000010 23 81 01 20 80 0a a1 81 81 02 23 81 01 a8 db c1  #.. ..¡...#..¨ÛÁ
00000020 ad da dd a9 a8 db de c1 ad da dd aa bf a9 a8 db  .ÚÝ©¨ÛÞÁ.Úݪ¿©¨Û
00000030 c1 ad da dd 29 a4 b3 a4 b2 a4 31 a8 db e1 ad fa  Á.ÚÝ)¤³¤²¤1¨Ûá.ú
00000040 dd a9 a8 db de e1 ad fa dd aa bf a9 a8 db e1 ad  Ý©¨ÛÞá.úݪ¿©¨Ûá.
00000050 fa dd 29                                         úÝ)
00000053

JavaScript Setara:

a.replace(/([A-Z])([^A-Z]*?)([A-Z])/g,'$3$2$1').replace(/([a-z])([^a-z]*?)([a-z])/g,'$3$2$1')

Penjelasan:

Secara implisit mengambil baris pertama dari input yang tidak diformat sebagai a(karena baris baru tidak dapat menjadi bagian dari string yang diacak), dan secara implisit mengeluarkan string yang tidak diacak dengan secara berurutan mengganti huruf besar, kemudian pasangan huruf kecil.

Coba demo di sini.

Coba test suite di sini.

Patrick Roberts
sumber
1

Ruby, 81 byte

puts f=->(i,s){i.gsub /([#{s})([^#{s}*)([#{s})/,'\3\2\1'}[f[$*[0],'a-z]'],'A-Z]']
aksioma
sumber
1

JavaScript (ES6), 80 byte

Berdasarkan jawaban Retina Leo .

s=>eval("s"+(r=".replace(/([A-Z])([^A-Z]*)([A-Z])/g,'$3$2$1')")+r.toLowerCase())

Ini berfungsi karena satu-satunya karakter huruf besar dalam kode .replace(/([A-Z])([^A-Z]*)([A-Z])/g,'$3$2$1')adalah Adan Z, yang digunakan untuk menggambarkan rentang karakter. Inilah yang perlu kita ubah menjadi huruf kecil untuk memproses lintasan kedua.

Uji kasus

Arnauld
sumber
Sebenarnya, ternyata sangat mirip dengan jawaban Python ini oleh Dennis.
Arnauld
1

ES6 155 - 195 byte

Saya tahu sudah ada jawaban yang lebih baik, tetapi saya ingin mencoba tanpa regex. Yang ini bekerja dengan tanda baca juga, tetapi itu tampaknya melanggar (^_^)tes. Dalam hal ini saya memiliki c()fungsi lain , yang diberikan di bawah ini.

f=(s)=>{d={};s=[...s];for(i in s){b=s[i];for(j in s)if(i<j&!d[i]&c(s[j])==c(b)){d[j]=1;s[i]=s[j];s[j]=b;break}}return s.join('')}
c=c=>~(c.charCodeAt()/32)

f("M I'o DaG") //> I'M a GoD
f("(^_^)")     //> )_^^(

c=c=>((c!=c.toUpperCase())<<1|c!=c.toLowerCase())||c.charCodeAt()

f("M I'o DaG") //> I'M a GoD
f("(^_^)")     //> (^_^)

Penjelasan

f=(s)=>{
    d={};        //list of indexes already swapped
    s=[...s];        //string to array, stolen from above ES6 answer
    for(i in s){
        b=s[i];        //keep a note of what we are swapping
        for(j in s)        //iterate over the array again
            if( i<j & !d[i] & c(s[j])==c(b) ){
                        //only pay attention after we pass i'th
                        //only swap if this char hasn't been swapped
                        //only swap if both chars in same 'category'
                d[j]=1;        //note that the latter char has been swapped
                s[i]=s[j];
                s[j]=b;
                break        //avoid swapping on the same 'i' twice
            }
    }
    return s.join('')        //return as string
}
M3D
sumber
1

Perl 6 , 56 byte

{for "A".."Z","a".."z" ->@c {s:g/(@c)(.*?)(@c)/$2$1$0/}}

Mengambil variabel string sebagai argumen, dan memodifikasinya di tempat sehingga setelah memanggil lambda variabel berisi hasilnya.

Lebih lama daripada di Perl, karena:

  • Sintaks regex baru lebih bertele-tele, misalnya menuliskan kelas karakter akan terlihat seperti <[A..Z]>bukan [A-Z].
  • Regex adalah kode sumber kelas satu yang diuraikan pada waktu kompilasi, dan sebuah string hanya dapat diinterpolasi ke dalamnya pada saat run-time jika terdiri dari subregex mandiri (yaitu Anda tidak dapat menginterpolasi string ke dalam kelas karakter).
  • Explict EVAL, yang akan memungkinkan lebih banyak fleksibilitas, membutuhkan use MONKEY-SEE-NO-EVAL;pragma yang tidak ramah terhadap golf .

Di sisi positifnya, array dalam suatu @variabel dapat direferensikan secara langsung dalam regex, dan diperlakukan sebagai pergantian.


Perl 6 , 65 byte

{reduce ->$_,@c {S:g/(@c)(.*?)(@c)/$2$1$0/},$_,"A".."Z","a".."z"}

Versi fungsional (menampilkan hasilnya sebagai nilai pengembalian lambda).

seseorang
sumber
1

R, 343 Bytes

Solusi R yang sangat kikuk:

f <- function(x) {
        y=unlist(strsplit(x,""))
        z=data.frame(l=ifelse(y %in% letters,0,ifelse(y %in% LETTERS,1,2)),s=y)
        l <- list(which(z$l==0),which(z$l==1))
        v <- unlist(l)
        for(j in 1:2) for (i in seq(1,ifelse(length(l[[j]])%%2==1,length(l[[j]])-2,length(l[[j]])-1),2)) l[[j]][i:(i+1)] <- rev(l[[j]][i:(i+1)])
        z[v,] <- z[unlist(l),]
        return(z$s)
    }

f("D's mroyr, Ivam. I'e faardi I act'n od htta.")

# [1] I ' m   s o r r y ,   D a v e .   I ' m   a f r a i d   I   c a n ' t   d o   t h a t .
menghitung
sumber
1

Python 2, 181 byte

Jauh lebih lama dari yang seharusnya tetapi tetap:

def F(s):
 for l in[i for i,c in enumerate(s)if c.isupper()],[i for i,c in enumerate(s)if c.islower()]:
  for a,b in zip(l[0::2],l[1::2]):s=s[:a]+s[b]+s[a+1:b]+s[a]+s[b+1:]
 print s

Ini pertama membuat dua daftar: salah satu indeks karakter huruf besar dan satu untuk karakter huruf kecil. Masing-masing daftar ini dilingkarkan melalui pasangan indeks, dan karakter pada indeks tersebut dialihkan.

Saya akan bermain golf ini besok , tetapi untuk sekarang saatnya tidur .

Daniel
sumber
1

Pip , 28 byte

Y[XLXU]aRy.`.*?`.y{Sa@0a@va}

Mengambil input sebagai argumen baris perintah. Cobalah online!

Penjelasan

Ini adalah solusi regex, menggunakan variabel regin builtin XL(huruf kecil, `[a-z]`) dan XU(huruf besar, `[A-Z]`).

                              a is 1st cmdline arg; v is -1 (implicit)
Y[XLXU]                       Yank a list containing XL and XU into y
         y.`.*?`.y            Concatenate y, `.*?`, and y itemwise, giving this list:
                              [`[a-z].*?[a-z]`; `[A-Z].*?[A-Z]`]
       aR                     In a, replace matches of each regex in that list...
                  {        }  ... using this callback function:
                   Sa@0a@v     Swap the 0th and -1st characters of the match
                          a    and return the resulting string
                              Print (implicit)

Ketika argumen kedua Radalah daftar, penggantian dilakukan secara seri; dengan demikian, penggantian huruf kecil dan penggantian huruf besar tidak saling mengganggu.

DLosc
sumber
1

AWK , 121 129 byte

BEGIN{FS=OFS=""}{for(a=1;a<=NF;a++){if($a~/[A-Z]/?U>0?p=U+(U=0):0*(U=a):$a~/[a-z]/?L>0?p=L+(L=0):0*(L=a):0>0){t=$a;$a=$p;$p=t}}}1

Cobalah online! Catatan: Tautan memiliki 8 byte tambahan untuk memungkinkan input multiline

Penggunaannya cukup tipikal, tetapi memang membutuhkan versi AWKyang menerima string kosong sebagai pemisah bidang (sebagian besar versi gawktapi saya cukup yakin yang asli AWKakan gagal :()

Ini sangat mudah karena hanya mengulangi setiap karakter dan memeriksa jika sudah ditemukan salah satu dari kasus itu sebelumnya. Jika demikian, itu swap karakter dan mengatur ulang indeks yang diperiksa. Di sisi pembelajaran, saya tidak pernah menggunakan pernyataan tugas dalam pernyataan tugas AWKsebelumnya. Untuk beberapa alasan itu tidak pernah muncul. :)

Saya mungkin dapat mencukur beberapa byte dengan mengatakan untuk menetapkan OFS dan FS di luar BEGINblok melalui penugasan baris perintah atau serupa, tetapi "lebih bersih" dengan cara ini.

Menambahkan tautan TIO menunjukkan kepada saya bahwa saya memiliki kesalahan transkripsi yang membutuhkan 8 byte untuk memperbaiki :( (saya tidak tahu 0*(U=a):)

Robert Benson
sumber
1

C (gcc) , 212 206 byte

#define I(a,b)if(S[j=i]>=a&S[i]<-~b){for(;S[++j]<a|S[j]>b;);j<l?s[i]=S[j],s[j]=S[i]:0;}
i,j,l;f(char*S){char*s=calloc(l=-~strlen(S),1);for(i=~0;++i<strlen(S);)if(!s[i]){s[i]=S[i];I(65,90)I(97,'z')}puts(s);}

Cobalah online!

Jonathan Frech
sumber
@ceilingcat Terima kasih.
Jonathan Frech
1

Stax , 18 byte

âß:}\]ó☺æ■jφ╛jz/Φi

Jalankan dan debug itu

Pendekatan umum berbasis regex.

  • Dua kali lakukan:
  • Temukan semua kecocokan untuk [a-z].*?[a-z].
  • Tukar karakter pertama dan terakhir dalam pertandingan.
  • Balik kasus.
rekursif
sumber
1

R , 223 163 byte 148 byte

EDIT: -60 byte dengan menerapkan loop for

EDIT: -15 byte dari Giuseppe

u=utf8ToInt(scan(,''));for(i in c(65,97)){l=which(u%in%i:(i+25));x=sum(l|1)%/%2;u[l[1:(x*2)]]=u[c(matrix(l,2)[2:1,1:x])]};cat(intToUtf8(u,T),sep="")

Cobalah online!

Bekerja dengan menguji apakah karakter adalah huruf kecil atau huruf besar, menempatkannya dalam matriks, membalikkan matriks untuk mengekstraksi nilai-nilai dalam format yang ditukar. Kemudian output dengan cat. Cobalah online berjuang dengan scan(,'')jika kode lebih dari satu baris, maka titik koma di sepanjang baris kode tunggal.

Sumner18
sumber
Saya mendapatkan 168 pada tautan Anda, tetapi golf ini 163
Giuseppe
Dan ini membawanya ke 162.
Giuseppe
ini mungkin berhasil; yang xmengutak-atik adalah sedikit pintar, tapi menyingkirkan m=matrixadalah 4 byte juga.
Giuseppe
Bagaimana dengan scan(,'')masalahnya? Dan mengurangi "lLEhW OroLd!" di TIO ke scan(,'')atau cara lain untuk mendapatkan input?
Sumner18
0

Java 7, 117 byte

String c(String s){String x="([a-z])(.*?)([a-z])",y="$3$2$1";return s.replaceAll(x,y).replaceAll(x.toUpperCase(),y);}

EDIT: Hanya memperhatikan saya memiliki jawaban yang sama dengan jawaban Retina @Leo , meskipun saya sudah memikirkannya secara independen ..

Tidak Disatukan:

String c(final String s) {
  String x = "([a-z])(.*?)([a-z])",
         y = "$3$2$1";
  return s.replaceAll(x, y).replaceAll(x.toUpperCase(), y);
}

Kode uji:

Coba di sini.

class M{
  static String c(String s){String x="([a-z])(.*?)([a-z])",y="$3$2$1";return s.replaceAll(x,y).replaceAll(x.toUpperCase(),y);}

  public static void main(String[] a){
    System.out.println(c("lLEhW OroLd!"));
    System.out.println(c("rpGOZmaimgn uplRzse naC DEoO LdGf"));
    System.out.println(c("eIt uqHKC RBWOO xNf ujPMO SzRE HTL EOvd yAg"));
    System.out.println(c("NraWgCi: Nsas-eNEiTIsev rNsiTG!!"));
    System.out.println(c("(^_^)"));
    System.out.println(c("AWCTY HUOS RETP"));
    System.out.println(c("hwn oeesd acsp nawyya"));
    System.out.println(c("SpMycaeIesKyBorekn"));
    System.out.println(c("D's mroyr, Ivam. I'e faardi I act'n od htta."));
  }
}

Keluaran:

hELlO WorLd!
prOGRamming puzZles anD COdE GoLf
tHe quICK BROWN fOx juMPS OvER THE LAzy dOg
WarNiNg: Case-sENsITive sTriNG!!
(^_^)
WATCH YOUR STEP
who needs caps anyway
MySpaceKeyIsBroken
I'm sorry, Dave. I'm afraid I can't do that.
Kevin Cruijssen
sumber