Descifra esas cadenas sensibles a mayúsculas y minúsculas

53

Gol

Este es un desafío simple. Su objetivo es descifrar una cadena intercambiando cada letra con la siguiente letra del mismo caso, sin modificar los caracteres que no sean letras.

ejemplo

Explicación paso a paso

  1. El primer personaje es a E. Buscamos la siguiente letra en mayúscula: es a C. Intercambiamos estos caracteres, lo que conduce a CdoE!.

  2. Avanzamos al siguiente personaje: este es un d. Buscamos la siguiente letra en minúscula: es a o. Intercambiamos estos caracteres, lo que conduce a CodE!.

  3. Avanzamos al siguiente personaje: este es el dque acabamos de mudar aquí. Lo ignoramos porque ya ha sido procesado.

  4. Avanzamos al siguiente personaje: este es el Eque se movió aquí en el paso 1. Lo ignoramos porque ya ha sido procesado.

  5. Avanzamos al siguiente personaje: este es un !. Lo ignoramos, porque no es una carta.

Reglas

  • Puede suponer que la cadena de entrada está hecha exclusivamente de caracteres ASCII imprimibles, en el rango de 32 a 126.

  • Puede escribir un programa completo o una función, que imprime o devuelve el resultado.

  • Si la cadena de entrada contiene un número impar de letras, la última letra restante no se puede intercambiar con otra y debe permanecer en su lugar, sin importar su caso. La misma lógica se aplica si la cadena contiene un número par de letras, pero un número impar de letras mayúsculas y un número impar de letras minúsculas.

  • Este es el código de golf, por lo que gana la respuesta más corta en bytes. Las lagunas estándar están prohibidas.

Casos de prueba

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

Casos de prueba no tan aleatorios:

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
fuente
Supongo que se mantiene un comentario similar si la entrada contiene un número par de letras, pero un número impar de letras mayúsculas y un número impar de letras minúsculas.
Greg Martin
14
Este es un desafío realmente inteligente ... ¡También me gusta el hecho de que los casos de prueba se pueden hacer escribiendo una cadena en minúsculas, cambiando aleatoriamente algunas letras a mayúsculas y luego ejecutando exactamente el mismo programa que resuelve el problema!
Greg Martin
1
@ GregMartin Descubrí que el problema es su propio inverso porque al intentar un caso de prueba escribí accidentalmente la salida en lugar de la entrada :-)
Luis Mendo
Creo que debería incluir casos de prueba con más de un carácter ASCII que no sea letra ... Creo que algunas implementaciones podrían cambiarlos accidentalmente entre sí, cuando se supone que eso no sucederá.
Greg Martin
3
Los casos de prueba probablemente deberían incluir una cadena sin letras mayúsculas y una cadena sin letras.
Dennis

Respuestas:

4

Jalea , 21 20 19 18 bytes

s2UF,
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.
    Ç         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
fuente
18

Retina , 53 bytes

No es realmente inteligente, pero es una solución limpia y bastante legible

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

Pruébalo en línea!

León
fuente
9

MATL , 22 bytes

2:"tttk<f2etAZ))P5M(Yo

Pruébalo en línea! O verificar todos los casos de prueba .

Cómo funciona

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
fuente
6

Utilidades Bash + Unix, 77 62 57 56 54 bytes

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

Entrada en stdin. Salida en stdout.

(En esta última versión, stderr también está escrito, pero el consenso de PPCG parece ser que está bien, simplemente se ignora stderr ) .

Edición 1: ¡Gracias a @Dennis por 15 bytes! Mejoras: (a) Tomar entrada a través de stdin; (b) combinar 2 scripts sed en uno; y (c) reemplazar tr con sustitución mediante expansión de parámetros bash; (b) y (c) desaparecieron en Edit 2.

Edición 2: más corta en 5 bytes adicionales. Usó una llamada de función para reemplazar tanto (b) como (c) en Editar 1.

Edición 3: Un byte más pasado] como parte de los argumentos de la función.

Edición 4: reemplazó las dos llamadas de función con llamadas al programa en sí cuando no tiene argumentos.

Testbed y salida de muestra:

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
fuente
6

ES6, 185 95 bytes

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

Solución severamente acortada con la ayuda de @Neil, @Arnauld y @ edc65

Explicación

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

ene
fuente
6 bytes, los paréntesis adjuntos son redundantes cuando eliminamos la segunda declaración :) Niza.
Jan
2
Por favor ignora mi último comentario. Aquí está el 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]]podría sero[o[j]=o[b],b]=c
edc65
El golpe maestro real aquí está utilizando verdadero y falso como índices de un array
edc65
Gracias chicos, hasta 95 ahora. Comienza a ser realmente difícil documentar la solución de una manera que tenga sentido. XD @ edc65 se almacenan como propiedades en el objeto de matriz, no como índices. Sí, Arnauld descubrió que estaban siendo almacenados en la matriz de personajes, pero la reutilización del objeto fue más que un accidente afortunado, creo que surgió de una sugerencia separada. Inicialmente se almacenó en un objeto separado que, por supuesto, era completamente innecesario para el alcance del desafío.
Jan
3

Python , 82 bytes

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

Pruébalo en línea!

Dennis
fuente
¿como funciona? ¿se llama incluso la lambda?
Sarge Borsch
La lambda es la presentación real (función). Todo lo demás es solo un código de acompañamiento que debe ejecutarse antes de llamar a la lambda.
Dennis
3

QBasic, 229 bytes

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$

Estrategia

Recorremos la cadena de entrada. Cuando encontramos una letra mayúscula, la almacenamos y su posición. La segunda vez que encontramos una letra mayúscula, usamos esos valores almacenados para intercambiarla con la anterior. Lo mismo para minúsculas.

(Estaba a punto de publicar una versión bastante más larga que usaba una matriz, porque pensé que las cadenas QBasic eran inmutables. Luego me topé con el hecho de que MID$(strng$, index, length) = replacement$funciona bien. Vive y aprende).

Ungolfed + comentó

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
fuente
2

C ++ 11 (GCC), 154 149 bytes

#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;}
vaultah
fuente
1
También debe #include<string>o cambiar a C ++ 14 y declarar un lambda genérico [](auto s)y asumir sque es de std::string. Además, la declaración [](auto&s)evita que devuelva la cadena, ya que se permite modificar los argumentos de entrada para que sirvan como salida.
Karl Napf
2

Qbasic, 436 408 bytes

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$

Guardado un byte gracias a DLosc. Se ahorraron varios más al cambiar el manejo de los caracteres que no son letras.

Esto consiste básicamente en tres partes:

  • Dividir la entrada en 3 cadenas (mayúsculas, minúsculas y un mapa (que también contiene los otros caracteres))
  • Voltear las letras mayúsculas y minúsculas
  • Usando el mapa para (re) construir la salida.

Una explicación más detallada (tenga en cuenta que se trata de una versión anterior del código, pero el principio todavía se aplica):

' --- 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
fuente
2

PHP, 108 93 83 bytes

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

Versión anterior (93 bytes)

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

Gracias a @ user59178 por recordarme que preg_replace()puede tomar matrices de cadenas como argumentos.


La respuesta original (108 bytes)

$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]));

El código se envuelve aquí para adaptarse al espacio disponible.
Se puede ejecutar desde la línea de comando:

$ 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!'

Es posible una versión más corta de 1 byte en PHP 7 apretando la asignación de $fdentro de su primera llamada:

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

Ambas soluciones, con casos de prueba y versiones no protegidas, se pueden encontrar en Github .

axiac
fuente
1
preg_replacepuede tomar una variedad de reemplazos para hacerlo, por lo que solo necesita una llamada. Además, es más corto de usar <?=que echo. Con estos, es simple obtener su respuesta a 93 bytes.
user59178
Tienes razón sobre eso preg_replace(). Me habia olvidado de eso. No me gusta <?=(en mi opinión <?no es parte del lenguaje, es solo un marcador) y me gusta escribir programas cortos de una línea que se puedan ejecutar desde la línea de comandos usando php -r. Pero para el propósito del código golf tienes razón otra vez. Puedo guardar 1 byte usando <?=.
axiac
1

Mathematica, 96 bytes

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

Un puerto de respuesta de Retina de Leo , que utiliza expresiones regulares.

Greg Martin
fuente
Estoy sinceramente sorprendido de que Mathica no tenga una construcción para eso, quiero decir, si "¿Cuándo es el domingo de Pascua", "Cuándo es la puesta de sol" y "¿Cuál es la forma de Francia" se construye, esta también debería tenerla!
sagiksp
1

Bean , 83 bytes

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 equivalente:

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

Explicación:

Toma implícitamente la primera línea de entrada sin formatear como a(ya que las nuevas líneas no pueden ser parte de una cadena codificada), y genera implícitamente una cadena sin codificar reemplazando secuencialmente los pares en mayúscula y luego en minúscula.

Prueba la demo aquí.

Prueba el paquete de prueba aquí.

Patrick Roberts
fuente
1

Ruby, 81 bytes

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

JavaScript (ES6), 80 bytes

Basado en la respuesta de Leo Retina .

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

Esto funciona porque los únicos caracteres en mayúscula en el código .replace(/([A-Z])([^A-Z]*)([A-Z])/g,'$3$2$1')son Ay Z, que se utilizan para describir los rangos de caracteres. Esto es precisamente lo que necesitamos transformar en minúsculas para procesar el segundo paso.

Casos de prueba

Arnauld
fuente
En realidad, resulta ser muy similar a esta respuesta de Python de Dennis.
Arnauld
1

ES6 155 - 195 bytes

Sé que ya hay una mejor respuesta, pero quería probar sin expresiones regulares. Este también funciona en la puntuación, pero parece violar la (^_^)prueba. En ese caso tengo otra c()función, dada a continuación.

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("(^_^)")     //> (^_^)

Explicación

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
fuente
1

Perl 6 , 56 bytes

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

Toma una variable de cadena como argumento y la modifica in situ para que después de llamar a lambda la variable contenga el resultado.

Más largo de lo que sería en Perl, porque:

  • La nueva sintaxis de expresiones regulares es más detallada, por ejemplo, escribir las clases de caracteres se vería en <[A..Z]>lugar de [A-Z].
  • Las expresiones regulares son código fuente de primera clase analizado en tiempo de compilación, y una cadena solo se puede interpolar en ellas en tiempo de ejecución si consiste en un subregex autónomo (es decir, no se puede interpolar una cadena en una clase de caracteres).
  • Explict EVAL, que permitiría una mayor flexibilidad, requiere el use MONKEY-SEE-NO-EVAL;pragma hostil al golf .

En el lado positivo, una matriz en una @variable se puede referenciar directamente en una expresión regular, y se trata como una alternancia.


Perl 6 , 65 bytes

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

Versión funcional (genera el resultado como el valor de retorno de la lambda).

smls
fuente
1

R, 343 bytes

Solución R terriblemente torpe:

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 .
contar
fuente
1

Python 2, 181 bytes

Mucho más de lo que debería ser, pero de todos modos:

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

Esto crea primero dos listas: uno de los índices de los caracteres en mayúscula y otro para los caracteres en minúscula. Cada una de estas listas se repite en pares de índices, y los caracteres en esos índices se cambian.

Mañana jugaré golf , pero por ahora es hora de dormir .

Daniel
fuente
1

Pip , 28 bytes

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

Toma entrada como argumento de línea de comando. Pruébalo en línea!

Explicación

Esta es una solución de expresiones regulares, utilizando las variables de expresión regular incorporadas XL(letras minúsculas `[a-z]`) y XU(letras mayúsculas `[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)

Cuando el segundo argumento Res una lista, los reemplazos se realizan en serie; por lo tanto, el reemplazo en minúsculas y el reemplazo en mayúsculas no interfieren entre sí.

DLosc
fuente
1

AWK , 121 129 bytes

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

Pruébalo en línea! Nota: el enlace tiene 8 bytes adicionales para permitir la entrada multilínea

El uso es bastante típico, pero requiere una versión AWKque acepte una cadena vacía como separador de campo (la mayoría de las versiones de, gawkpero estoy bastante seguro de que el original AWKfallará :()

Es muy sencillo, ya que simplemente itera sobre cada personaje y comprueba si ha encontrado uno de esos casos antes. Si es así, intercambia los caracteres y restablece el índice marcado. En el lado del aprendizaje, nunca antes había usado una declaración de asignación dentro de una declaración de asignación AWK. Por alguna razón, nunca había surgido. :)

Podría ser capaz de reducir un par de bytes diciendo que asigne OFS y FS fuera de un BEGINbloque mediante la asignación de línea de comando o similar, pero es "más limpio" de esta manera.

Agregar el enlace TIO me mostró que tenía un error de transcripción que requería 8 bytes para solucionarlo :( (lo dejé fuera 0*(U=a):)

Robert Benson
fuente
1

C (gcc) , 212 206 bytes

  • Gracias a ceilingcat por jugar al golf seis bytes.
#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);}

Pruébalo en línea!

Jonathan Frech
fuente
@ceilingcat Gracias.
Jonathan Frech
1

Stax , 18 bytes

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

Ejecutar y depurarlo

El enfoque general se basa en expresiones regulares.

  • Dos veces hacen:
  • Encuentra todos los partidos para [a-z].*?[a-z].
  • Intercambia el primer y el último personaje en los partidos.
  • Caso invertido.
recursivo
fuente
1

R , 223163 bytes 148 bytes

EDITAR: -60 bytes implementando un bucle for

EDITAR: -15 bytes de 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="")

Pruébalo en línea!

Funciona probando si el carácter es minúscula o mayúscula, los coloca en una matriz, invierte la matriz para extraer los valores en un formato intercambiado. Luego salida con cat. Pruébelo en línea con problemas scan(,'')si el código es más de una línea, por lo tanto, los puntos y comas en toda la línea de código.

Sumner18
fuente
Tengo 168 en su enlace, pero este golf es 163
Giuseppe
Y esto lo lleva a 162.
Giuseppe
esto probablemente funciona; el xviolín es el bit inteligente, pero eliminarlo también m=matrixera de 4 bytes.
Giuseppe
¿Qué hay del scan(,'')problema? ¡Y reduciendo el "iLEhW OroLd!" en TIO scan(,'')o de alguna otra manera para obtener información?
Sumner18
0

Java 7, 117 bytes

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

EDITAR: Acabo de notar que tengo una respuesta similar a la respuesta Retina de @Leo , a pesar de que lo he pensado de forma independiente.

Sin golf:

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

Código de prueba:

Pruébalo aquí

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

Salida:

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
fuente