Más diversión con cuerdas sensibles a mayúsculas y minúsculas


28

Inspirado por este desafío (o, más específicamente, al interpretarlo mal), se me ocurrió el siguiente desafío:

Dada una cadena de entrada S, invierta el orden de todos los caracteres en mayúscula y todos los caracteres en minúscula. Deje todos los caracteres que no sean letras en su lugar. Por ejemplo:

¡Hola Mundo!

Tenga en cuenta que la mayúscula W(la primera letra mayúscula) se reemplazó por H(la última). Lo mismo ocurre con las letras minúsculas: 'd' (la primera) se intercambia con e(la última), l(la segunda) se reemplaza con l(pen-ultimate) ... Todos los caracteres que no son letras se dejan en su lugar.

Entrada

  • La entrada es una cadena con solo caracteres ASCII en el rango 32-126.
  • Se garantiza que la entrada tendrá al menos 1 carácter y no excederá el límite de su idioma.

Salida

  • Esa misma cadena, con los caracteres intercambiados como se describe.

Reglas adicionales

  • Las lagunas estándar están prohibidas
  • La respuesta debe ser un programa completo o una función, no un fragmento o una entrada REPL.
  • , la respuesta más corta en bytes gana.

Casos de prueba

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!

Es posible que desee incluir un caso de prueba de 2 caracteres, mi solución original falló al principio. (Fijo sin costo cambiando .+a .*)
ETHproductions

"Dogo perezoso" me recordó esto: youtube.com/watch?v=W-d6uUSY9hk
FinW

Respuestas:


5

MATL , 14 bytes

2:"t@Y2myy)Pw(

Pruébalo en MATL Online

Explicación

        % 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

1
¡Gran trabajo! Tenía 2:"tttXk>f)5MP(Yopara 17 bytes
Luis Mendo

11

Retina , 19 bytes

La retina no tiene una forma directa de invertir una cadena, pero podemos hacerlo explotando la etapa de clasificación:

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

Ordenar ( O), leerlos como números ( #) y luego invertir el orden ( ^) de todas las cadenas que coinciden con la expresión regular dada (letras minúsculas para la primera línea y letras mayúsculas para la segunda).

Esto funciona porque cuando intentamos leer cadenas sin caracteres numéricos como números a los que se las trata 0, por lo que todos los caracteres tienen el mismo valor para la ordenación. Dado que la ordenación es estable, se dejan en el mismo orden, y al invertirlos se devuelve la cadena original.

Pruébalo en línea!


10

Perl , 45 bytes

44 bytes de código + -pbandera.

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

Pruébalo en línea!

Clases de caracteres Unicode \p{Lu}y \p{Ll}coincide con letras mayúsculas y minúsculas respectivamente.
Por /\p{L$c}/lo tanto , devolverá la lista de todas las letras mayúsculas (o minúsculas) (y la almacenará dentro @T).
Y luego, la expresión regular s/\p{$c}/pop@T/gereemplazará cada letra (mayúscula y luego minúscula) por la última letra de @Tmientras la elimina @T.


7

JavaScript (ES6), 74 73 71 70 bytes

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>

Editar: guardado 1 byte gracias a @Arnauld.


44
Yo sabía que había una manera mejor ...
ETHproductions

5

JavaScript (ES6), 92 bytes

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

No ha llegado a ser una forma de aprovechar la similitud entre las expresiones regulares ...

Fragmento de prueba


¿Asume esto que la función está asignada a una variable llamada f? ¿No debería estar en el conteo de bytes?
steenbergh

@steenbergh La función es anónima, se puede llamar como quieras que sea
Kritixi Lithos

1
@steenbergh No, es una función anónima que crea otra función y Fluego la llama recursivamente dos veces. La función externa no se llama a sí misma en ningún momento.
ETHproductions

¿Por qué usas paréntesis .*en las expresiones regulares?
Lucas

@Luke para capturar esos personajes (el ade ([x],a,y)=>)
ETHproductions

4

Perl 6 , 75 69 bytes

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

Cómo funciona

  1. my @a=.comb;
    Divide la cadena en caracteres y guárdalos en una matriz.

  2. for /<:Lu>/,/<:Ll>/
    Para dos expresiones regulares que coinciden con letras mayúsculas y minúsculas, respectivamente ...

    • @(grep $_,@a)
      Obtenga una porción de todas las entradas de matriz que coincidan con la expresión regular.

    • .&{@$_=[R,] $_}
      Asigne el reverso del corte a sí mismo.

  3. [~] @a
    Concatene la matriz modificada para formar una cadena nuevamente y devuélvala.


-6 bytes al robar la idea de usar clases Unicode en lugar de rangos de caracteres, de la solución de @ Dada.


3

Jalea , 14 bytes

nŒlT,Ṛ$yJịŒsµ⁺

Pruébalo en línea!

Cómo funciona

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.

no ser quisquilloso pero ... 14 caracteres! = 23 bytes :) mothereff.in/byte-counter
Gizmo

@Gizmo Jelly usa una página de códigos . Vea esta meta publicación para más información.
Suever

@Suever Oh, eso está bien, aprendí algo hoy ^. ^
Gizmo

3

Bash + Unix utilidades, 122 121 bytes

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]

Pruébalo en línea!

Realmente no muy corto; tal vez alguien pueda jugar más golf.

Entrada en stdin, salida en stdout.

Esto funcionará correctamente en entradas de menos de 200 caracteres.

(En realidad, maneja correctamente cualquier cadena con menos de 200 letras minúsculas y menos de 200 letras mayúsculas).

Si aumenta el 99 en el código a 102 (a costa de un byte adicional), manejará cadenas de hasta 205 caracteres.

Sin embargo, no puede aumentar el 99 en el código más allá de 102 ya que luego excederá la longitud máxima de argumento de sed.

Aquí hay una versión sin ninguna limitación de tamaño de entrada particular, pero el recuento es un poco más largo, 137 bytes. (Esta versión más larga escribe en un archivo auxiliar llamado 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

Pruebas de funcionamiento:

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!

Interesante que falle en TIO. ☹ Puede depender de la sedimplementación instalada en su sistema, pero a GNU sedpuede agregar una -ropción y eliminar el \escape de todos los paréntesis.
manatwork

2

Python 2 , 115 bytes

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

Pruébalo en línea!


¿Puedes reemplazar \ n con;?
Tim

Lamentablemente no. El argumento de execse analiza como el código Python habitual, por lo que el bucle for debe estar en su propia línea.
Dennis

2

Java (OpenJDK 8) , 271 bytes

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)

Pruébalo en línea!


Puede guardar algunos bytes convirtiéndolo en una lambda. s->new String...
NonlinearFruit

1
@NonlinearFruit gracias! 294 -> 272, también corrigió el error cuando r y l se reutilizaba sin inicialización.
DmitrySamoylenko

Bienvenido a PPCG! Algunas cosas que aún puedes jugar char[]o=s.toCharArray();char c;int b;al golf: a char o[]=s.toCharArray(),c,b;; y ambos &&a &'; y c=o[i];return b>1?!Character.isUpperCase(c):!Character.isLowerCase(c);a c=o[i];Character x=c;return b>1?!x.isUpperCase(c):!x.isLowerCase(c);( 259 bytes en total ). Y probablemente me perdí algunas cosas para jugar más al golf. Además, si aún no lo ha visto, los consejos para jugar al golf en Java pueden ser interesantes de leer.
Kevin Cruijssen

1

R , 107 bytes

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="")

Adaptado de mi respuesta al desafío vinculado. Esto es considerablemente más fácil que simplemente intercambiar pares. Me pregunto si podría obtener sub 100 con algunos campos de golf ...

Pruébalo en línea!

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.