Lebih asyik dengan string case ((sangat) sensitif)

28

Terinspirasi oleh tantangan ini (atau, lebih khusus lagi, dengan salah baca), saya datang dengan tantangan berikut:

Diberikan string input S, membalikkan urutan semua karakter huruf besar, dan semua karakter huruf kecil. Biarkan semua karakter non-huruf tetap di tempatnya. Contohnya:

Halo Dunia!

Perhatikan bahwa huruf besar W( huruf besar pertama) diganti dengan H(yang terakhir). Hal yang sama berlaku untuk huruf kecil: 'd' (yang pertama) ditukar dengan e(yang terakhir), l(kedua) diganti dengan l(pena-ultimate) ... Semua karakter non-huruf dibiarkan di tempatnya.

Memasukkan

  • Input adalah string dengan hanya karakter ASCII dalam kisaran 32-126.
  • Input dijamin paling panjang 1 karakter, dan tidak akan melebihi batas bahasa Anda.

Keluaran

  • String yang sama, dengan karakter yang ditukar seperti yang dijelaskan.

Aturan tambahan

  • Celah standar dilarang
  • Jawaban harus berupa program atau fungsi lengkap, bukan cuplikan atau entri REPL.
  • , jawaban terpendek dalam byte menang.

Uji kasus

A
A

Ok
Ok

OK
KO

Hello, World!
Wdlro, Holle!

0123456789
0123456789

The quick brown Fox jumps over the lazy doge
Feg odyza lehtr Tev ospmu jxon wor bkci uqeh

odd
ddo

racecar
racecar

EtOn Em OsN R AaToNsIsIhT!!1!
ThIs Is NoT A RaNsOmEnOtE!!1!
steenbergh
sumber
Anda mungkin ingin memasukkan testcase 2-char, solusi awal saya gagal pada awalnya. (Diperbaiki tanpa biaya dengan mengubah .+ke .*)
ETHproduk
"lazy doge" mengingatkan saya akan hal ini: youtube.com/watch?v=W-d6uUSY9hk
FinW

Jawaban:

5

MATL , 14 byte

2:"t@Y2myy)Pw(

Cobalah di MATL Online

Penjelasan

        % Impicitly grab input as a string
2:      % Push the array [1, 2] to the stack
"       % For each value in this array
  t     % Duplicate the top element of the stack (S)
  @     % Get the current loop index
  Y2    % Load the predefined literal 1Y2 ('ABC...Z') on the first loop
        % and the predefined literal 2Y2 ('abc...z') on the second loop (M)
  m     % Create a logical array the length of S that is TRUE when a character is in the
        % array M and FALSE otherwise (B)
  yy    % Make a copy of both S and B
  )     % Grab just the letters of S that were in M using B as an index
  P     % Reverse this array
  w     % Flip the top two stack elements
  (     % Assign them back into the string
        % Implicit end of for loop and implicit display
Suever
sumber
1
Kerja bagus! Saya memiliki 2:"tttXk>f)5MP(Yo17 byte
Luis Mendo
11

Retina , 19 byte

Retina tidak memiliki cara langsung untuk membalikkan string, tetapi kita bisa melakukannya dengan mengeksploitasi tahap penyortiran:

O^#`[a-z]
O^#`[A-Z]

Sortir ( O), bacalah sebagai angka ( #), lalu balik urutan ( ^), dari semua string yang cocok dengan regex yang diberikan (huruf kecil untuk baris pertama, dan huruf besar untuk yang kedua).

Ini berfungsi karena ketika kita mencoba membaca string tanpa karakter angka sebagai angka mereka diperlakukan 0, sehingga semua karakter memiliki nilai yang sama untuk pengurutan. Karena penyortiran stabil mereka dibiarkan dalam urutan yang sama, dan membalikkannya mengembalikan string asli terbalik.

Cobalah online!

Leo
sumber
10

Perl , 45 byte

44 byte kode + -pbendera.

for$c(u,l){@T=/\p{L$c}/g;s/\p{L$c}/pop@T/ge}

Cobalah online!

Unicode karakter mengklasifikasikan \p{Lu}dan \p{Ll}mencocokkan huruf besar dan kecil.
Jadi /\p{L$c}/akan mengembalikan daftar semua huruf besar (atau lebih rendah) (dan menyimpannya di dalam @T).
Dan kemudian, regex s/\p{$c}/pop@T/geakan mengganti setiap huruf (atas, bawah) dengan huruf terakhir @Tsaat menghapusnya @T.

Dada
sumber
7

JavaScript (ES6), 74 73 71 70 byte

f=
s=>(g=r=>s=s.replace(r,_=>a.pop(),a=s.match(r)))(/[A-Z]/g,g(/[a-z]/g))
<input oninput=o.textContent=f(this.value)><pre id=o>

Sunting: Disimpan 1 byte berkat @Arnauld.

Neil
sumber
4
Saya tahu ada cara yang lebih baik ...
ETHproduksi
5

JavaScript (ES6), 92 byte

s=>(F=(r,s)=>s.replace(r,([x],a,y)=>y+F(r,a)+x))(/[a-z](.*)([a-z])/,F(/[A-Z](.*)([A-Z])/,s))

Ada mendapat menjadi cara untuk mengambil keuntungan dari kesamaan antara regexes ...

Cuplikan tes

Produksi ETH
sumber
Apakah ini menganggap bahwa fungsi tersebut ditugaskan ke variabel yang disebut f? Bukankah seharusnya dalam hitungan byte?
steenbergh
@steenbergh Fungsi ini anonim, bisa disebut apa pun yang Anda inginkan
Kritixi Lithos
1
@steenbergh Tidak, ini merupakan fungsi anonim yang membuat fungsi lain Flalu memanggilnya dua kali secara rekursif. Fungsi luar sebenarnya tidak menyebut dirinya sendiri pada titik mana pun.
ETHproduk
Mengapa Anda menggunakan tanda kurung di .*dalam regex?
Luke
@ Lukas untuk menangkap karakter-karakter tersebut ( adalam ([x],a,y)=>)
ETHproduk
4

Perl 6 , 75 69 byte

{my @a=.comb;@(grep $_,@a).&{@$_=[R,] $_} for /<:Lu>/,/<:Ll>/;[~] @a}

Bagaimana itu bekerja

  1. my @a=.comb;
    Membagi string menjadi karakter, dan menyimpannya dalam array.

  2. for /<:Lu>/,/<:Ll>/
    Untuk dua regex yang cocok dengan huruf besar dan kecil, masing-masing ...

    • @(grep $_,@a)
      Dapatkan sepotong semua entri array yang cocok dengan regex.

    • .&{@$_=[R,] $_}
      Tetapkan kebalikan dari irisan itu sendiri.

  3. [~] @a
    Menggabungkan array yang dimodifikasi untuk membentuk string lagi, dan mengembalikannya.


-6 byte dengan mencuri ide untuk menggunakan kelas Unicode alih-alih rentang karakter, dari solusi @ Dada.

seseorang
sumber
3

Jelly , 14 byte

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.
    ,Ṛ$         Pair with its reverse. 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.
Dennis
sumber
bukan untuk menjadi nitpicky tapi .. 14 karakter! = 23 byte :) mothereff.in/byte-counter
Gizmo
@Gizmo Jelly menggunakan codepage . Lihat posting meta ini untuk informasi lebih lanjut.
Suever
@Suever Oh itu rapi, pelajari sesuatu hari ini ^. ^
Gizmo
3

Utilitas Bash + Unix, 122 121 byte

f()(p=[^$1*
v="\)\([$1\)\("
for((n=99;n;n--)){
q="$q;s/^\($p$v.*$v$p\)$/\1\4\3\2\5/"
p=[^$1*[$1$p
}
sed $q)
f a-z]|f A-Z]

Cobalah online!

Tidak terlalu pendek; mungkin seseorang bisa bermain golf lebih jauh.

Input pada stdin, output pada stdout.

Ini akan bekerja dengan benar pada input kurang dari 200 karakter.

(Sebenarnya itu benar menangani string apa pun dengan kurang dari 200 huruf kecil dan kurang dari 200 huruf besar.)

Jika Anda menambah 99 dalam kode menjadi 102 (dengan biaya satu byte tambahan), ia akan menangani string hingga 205 karakter.

Namun, Anda tidak dapat meningkatkan 99 dalam kode di atas 102 karena Anda kemudian akan melebihi panjang argumen maksimum sed.

Ini adalah versi tanpa batasan ukuran input tertentu, tetapi hitungannya sedikit lebih lama, 137 byte. (Versi yang lebih panjang ini menulis ke file bantu bernama t.)

f()(p=[^$1*
v="\)\([$1\)\("
for((n=`wc -c<t`;n;n--)){
sed -i "s/^\($p$v.*$v$p\)$/\1\4\3\2\5/" t
p=[^$1*[$1$p
})
cat>t
f a-z]
f A-Z]
cat t

Tes berjalan:

for x in A Ok OK 'Hello, World!' 0123456789 'The quick brown Fox jumps over the lazy doge' odd racecar 'EtOn Em OsN R AaToNsIsIhT!!1!'
  do
    echo "$x"
    ./swapping3 <<<"$x"
    echo
  done

A
A

Ok
Ok

OK
KO

Hello, World!
Wdlro, Holle!

0123456789
0123456789

The quick brown Fox jumps over the lazy doge
Feg odyza lehtr Tev ospmu jxon wor bkci uqeh

odd
ddo

racecar
racecar

EtOn Em OsN R AaToNsIsIhT!!1!
ThIs Is NoT A RaNsOmEnOtE!!1!
Mitchell Spector
sumber
Menarik bahwa gagal di TIO. ☹ Dapat bergantung pada sedimplementasi yang diinstal pada sistem Anda, tetapi untuk GNU sedAnda dapat menambahkan -ropsi dan menghapus \pelolosan semua tanda kurung.
manatwork
2

Python 2 , 115 byte

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

Cobalah online!

Dennis
sumber
Bisakah Anda mengganti \ n dengan;?
Tim
Sayangnya tidak ada. Argumen execdiuraikan seperti kode Python biasa, jadi untuk loop harus pada barisnya sendiri.
Dennis
2

Java (OpenJDK 8) , 271 byte

s->new String(new Error(){char[]o=s.toCharArray();char c;int b;{while(b++<2)for(int l=0,r=o.length;l<r;l++){for(--r;r>l&&f(r);r--);for(;l<r&&f(l);l++);if(l<r){o[l]=o[r];o[r]=c;}}}boolean f(int i){c=o[i];return b>1?!Character.isUpperCase(c):!Character.isLowerCase(c);}}.o)

Cobalah online!

DmitrySamoylenko
sumber
Anda bisa menyimpan beberapa byte dengan membuatnya menjadi lambda. s->new String...
NonlinearFruit
1
@NonlinearFruit terima kasih! 294 -> 272, juga memperbaiki kesalahan ketika r a l digunakan kembali tanpa inisialisasi.
DmitrySamoylenko
Selamat datang di PPCG! Beberapa hal yang Anda masih bisa bermain golf: char[]o=s.toCharArray();char c;int b;untuk char o[]=s.toCharArray(),c,b;; dan keduanya &&untuk &'; dan c=o[i];return b>1?!Character.isUpperCase(c):!Character.isLowerCase(c);hingga c=o[i];Character x=c;return b>1?!x.isUpperCase(c):!x.isLowerCase(c);( total 259 byte ). Dan saya mungkin melewatkan beberapa hal untuk golf lebih banyak. Juga, jika Anda belum melihatnya, tips untuk bermain golf di Jawa mungkin menarik untuk dibaca.
Kevin Cruijssen
1

R , 107 byte

u=utf8ToInt(scan(,''));for(i in c(65,97)){l=which(u%in%i:(i+25));u[l]=u[rev(l)]};cat(intToUtf8(u,T),sep="")

Diadaptasi dari tanggapan saya terhadap tantangan terkait. Ini jauh lebih mudah daripada hanya bertukar pasangan. Saya ingin tahu apakah saya bisa mendapatkan sub 100 dengan beberapa golf ...

Cobalah online!

Sumner18
sumber