Decifrar as seqüências de caracteres (muito) sensíveis a maiúsculas e minúsculas

53

Objetivo

Este é um desafio simples. Seu objetivo é decifrar uma string trocando cada letra pela próxima letra do mesmo caso, mantendo inalterados os caracteres que não são da letra.

exemplo

Explicação passo a passo

  1. O primeiro caractere é a E. Procuramos a próxima letra em maiúscula: é a C. Trocamos esses caracteres, o que leva a CdoE!.

  2. Avançamos para o próximo caractere: este é a d. Procuramos a próxima letra em minúscula: é a o. Trocamos esses caracteres, o que leva a CodE!.

  3. Avançamos para o próximo personagem: é disso que acabamos de mudar para cá. Nós o ignoramos, porque já foi processado.

  4. Nós avançamos para o próximo personagem: este foi o Eque foi movido aqui para o passo 1. Nós o ignoramos, porque já foi processado.

  5. Avançamos para o próximo caractere: este é a !. Nós o ignoramos, porque não é uma carta.

Regras

  • Você pode assumir que a sequência de entrada é composta exclusivamente de caracteres ASCII imprimíveis, no intervalo de 32 a 126.

  • Você pode escrever um programa completo ou uma função que imprima ou retorne o resultado.

  • Se a sequência de entrada contiver um número ímpar de letras, a última letra restante não poderá ser trocada por outra e deve permanecer no lugar, independentemente do seu caso. A mesma lógica se aplica se a sequência contiver um número par de letras, mas um número ímpar de letras maiúsculas e um número ímpar de letras minúsculas.

  • Isso é código-golfe, então a resposta mais curta em bytes vence. As brechas padrão são proibidas.

Casos de teste

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 teste não tão aleatórios:

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
fonte
Suponho que um comentário semelhante seja válido se a entrada contiver um número par de letras, mas um número ímpar de letras maiúsculas e um número ímpar de letras minúsculas.
Greg Martin
14
Esse é um desafio muito inteligente ... Também gosto do fato de que os casos de teste podem ser feitos digitando uma string em minúscula, alterando aleatoriamente algumas das letras para maiúsculas e executando o mesmo programa que resolve o problema!
Greg Martin
11
@GregMartin eu descobri que o problema é seu próprio inverso, pois ao tentar um caso de teste eu acidentalmente digitado na saída em vez da entrada :-)
Luis Mendo
Eu acho que você deve incluir casos de teste com mais de um caractere ASCII que não seja da letra ... Acho que algumas implementações podem alterná-las acidentalmente, quando isso não deveria acontecer.
Greg Martin
3
Os casos de teste provavelmente devem incluir uma sequência sem letras maiúsculas e uma sequência sem letras.
Dennis

Respostas:

4

Geléia , 21 20 19 18 bytes

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

Experimente online!

Como 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
fonte
18

Retina , 53 bytes

Não é realmente inteligente, mas uma solução limpa e bastante legível

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

Experimente online!

Leo
fonte
9

MATL , 22 bytes

2:"tttk<f2etAZ))P5M(Yo

Experimente online! Ou verifique todos os casos de teste .

Como 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
fonte
6

Utilitários 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 em stdin. Saída em stdout.

(Nesta última versão, o stderr também foi gravado, mas o consenso do PPCG parece ser bom - o stderr é simplesmente ignorado. )

Edição 1: Obrigado a @Dennis por 15 bytes! Melhorias: (a) Recebendo informações via stdin; (b) combinar 2 scripts sed em um; e (c) substituir tr pela substituição via expansão dos parâmetros do bash; (b) e (c) desapareceram no Edit 2.

Edit 2: Menor por 5 bytes adicionais. Utilizou uma chamada de função para substituir os itens (b) e (c) na Edição 1.

Editar 3: Mais um byte passado] como parte dos argumentos da função.

Editar 4: substituídas as duas chamadas de função por chamadas para o próprio programa quando ele não possui argumentos.

Testbed e saída da amostra:

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

Solução severamente reduzida com a ajuda de @Neil, @Arnauld e @ edc65

Explicação

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
fonte
6 bytes, os parênteses anexos são redundantes quando removemos a segunda instrução :) Nice.
Jan
2
Por favor, ignore meu último comentário. Aqui está o 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]]poderia sero[o[j]=o[b],b]=c
edc65 5/02
O verdadeiro golpe de mestre aqui é usar o verdadeiro eo falso como índices para um array
edc65
Obrigado pessoal, até 95 agora. Começa a ficar muito difícil documentar a solução de uma maneira que faça sentido. XD @ edc65 são armazenados como propriedades no objeto array, não como índices. Sim, Arnauld descobriu que eles estavam sendo armazenados na matriz de caracteres, mas acho que a reutilização do objeto foi mais um acidente de sorte que veio de uma sugestão separada. Inicialmente, ele era armazenado em um objeto separado, o que obviamente era completamente desnecessário para o escopo do desafio.
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'

Experimente online!

Dennis
fonte
como funciona? o lambda é chamado?
Sarge Borsch
O lambda é a submissão real (função). Tudo o resto é apenas um código que deve ser executado antes que o lambda seja chamado.
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$

Estratégia

Passamos pela string de entrada. Quando encontramos uma letra maiúscula, a armazenamos e sua posição. Na segunda vez que encontramos uma letra maiúscula, usamos esses valores armazenados para trocá-la pela anterior. O mesmo para minúsculas.

(Eu estava prestes a publicar uma versão mais longa que usava uma matriz, porque achava que as strings QBasic eram imutáveis. Depois, me deparei com o fato de que MID$(strng$, index, length) = replacement$funciona muito bem. Viva e aprenda.)

Ungolfed + comentou

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
fonte
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
fonte
11
Você também deve #include<string>alternar para o C ++ 14 e declarar um lambda genérico [](auto s)e assumir scomo sendo std::string. Além disso, declarar [](auto&s)evita que você retorne a string, pois é permitido modificar argumentos de entrada para servir como saída.
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$

Economizou um byte graças ao DLosc. Economizou vários outros alterando o tratamento de caracteres não-letra.

Isso basicamente consiste em três partes:

  • Dividindo a entrada em 3 cadeias (Maiúsculas, Minúsculas e um mapa (também segurando os outros caracteres))
  • Inverter as letras maiúsculas e minúsculas
  • Usando o mapa para (re) construir a saída.

Uma explicação mais detalhada (observe que essa é uma versão anterior do código, mas o princípio ainda 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
fonte
2

PHP, 108 93 83 bytes

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

Versão anterior (93 bytes)

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

Obrigado a @ user59178 por me lembrar de que preg_replace()pode usar matrizes de strings como argumentos.


A resposta 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]));

O código é agrupado aqui para caber no espaço disponível.
Pode ser executado na linha 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!'

Uma versão mais curta de 1 byte é possível no PHP 7 pressionando a atribuição $fdentro de sua primeira chamada:

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 as soluções, com casos de teste e versões não destruídas, podem ser encontradas no Github .

axiac
fonte
11
preg_replaceVocê pode precisar de uma variedade de substituições para fazer isso, basta uma chamada. Além disso, é mais curto de usar <?=do que echo. Com estes, é simples reduzir sua resposta a 93 bytes.
User59178
Você está certo preg_replace(). Eu esqueci sobre isto. Não gosto <?=(na minha opinião, <?não faz parte da linguagem, é apenas um marcador) e gosto de escrever pequenos programas de uma linha que podem ser executados a partir da linha de comando php -r. Mas, para fins de código de golfe, você está certo novamente. Eu posso salvar 1 byte usando <?=.
axiac 6/02/17
1

Mathematica, 96 bytes

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

Um porto da resposta Retina de Leo , que usa expressões regulares.

Greg Martin
fonte
Sinceramente, estou surpreso que o mathematica não tenha uma estrutura para isso, quero dizer, se "Quando é domingo de Páscoa", "Quando é o pôr do sol" e "qual é a forma da França", isso também deve ser feito!
sagiksp
1

Python 2 , 124 bytes

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

Não é tão curto quanto a minha solução baseada em regex , mas acho que ainda é interessante.

Experimente online!

Dennis
fonte
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')

Explicação:

Pegar aimplicitamente a primeira linha de entrada não formatada como (como as novas linhas não podem fazer parte da cadeia codificada) e gera implicitamente a cadeia não codificada substituindo sequencialmente os maiúsculos e os minúsculos.

Experimente a demonstração aqui.

Experimente o conjunto de testes aqui.

Patrick Roberts
fonte
1

Ruby, 81 bytes

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

JavaScript (ES6), 80 bytes

Com base na resposta da retina de Leo .

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

Isso funciona porque os únicos caracteres maiúsculos no código .replace(/([A-Z])([^A-Z]*)([A-Z])/g,'$3$2$1')são Ae Z, que são usados ​​para descrever os intervalos de caracteres. É exatamente isso que precisamos transformar em minúsculas para processar a segunda passagem.

Casos de teste

Arnauld
fonte
Na verdade, parece muito semelhante a essa resposta de Dennis em Python .
Arnauld
1

ES6 155 - 195 bytes

Eu sei que já existe uma resposta melhor, mas eu queria tentar sem regex. Este também funciona com pontuação, mas isso parece violar o (^_^)teste. Nesse caso, tenho outra c()função, dada abaixo.

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

Explicação

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

Perl 6 , 56 bytes

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

Pega uma variável de cadeia como argumento e modifica-a no local para que, depois de chamar o lambda, a variável contenha o resultado.

Mais do que seria em Perl, porque:

  • A nova sintaxe regex é mais detalhada, por exemplo, escrever as classes de caracteres teria a aparência em <[A..Z]>vez de [A-Z].
  • Regexes são código-fonte de primeira classe analisados ​​em tempo de compilação, e uma cadeia de caracteres só pode ser interpolada neles em tempo de execução se consistir em um subregex independente (ou seja, você não pode interpolar uma cadeia de caracteres em uma classe de caracteres).
  • Explict EVAL, que permitiria mais flexibilidade, requer o use MONKEY-SEE-NO-EVAL;pragma hostil ao golfe .

No lado positivo, uma matriz em uma @variável pode ser referenciada diretamente em uma regex e é tratada como uma alternância.


Perl 6 , 65 bytes

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

Versão funcional (gera o resultado como o valor de retorno da lambda).

smls
fonte
1

R, 343 bytes

Solução R terrivelmente desajeitada:

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 .
contagem
fonte
1

Python 2, 181 bytes

Muito mais longo do que deveria, mas de qualquer maneira:

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

Isso primeiro cria duas listas: um dos índices dos caracteres maiúsculos e outro para os caracteres minúsculos. Cada uma dessas listas é repetida em pares de índices, e os caracteres nesses índices são alternados.

Amanhã vou jogar golfe , mas por enquanto é hora de dormir .

Daniel
fonte
1

Pip , 28 bytes

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

Recebe entrada como um argumento de linha de comando. Experimente online!

Explicação

Esta é uma solução de regex, usando as variáveis ​​de regex incorporadas XL(letras minúsculas `[a-z]`) e XU(letras maiú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)

Quando o segundo argumento para Ré uma lista, as substituições são executadas em série; portanto, a substituição em minúsculas e a substituição em maiúsculas não interferem entre si.

DLosc
fonte
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

Experimente online! Nota: O link possui 8 bytes extras para permitir entrada de várias linhas

O uso é bastante típico, mas requer uma versão AWKque aceite uma string vazia como separador de campos (na maioria das versões, gawkmas tenho certeza de que o original AWKfalharia :()

É muito simples, pois simplesmente itera sobre cada personagem e verifica se já foi encontrado um desses casos antes. Nesse caso, ele troca os caracteres e redefine o índice verificado. No lado da aprendizagem, eu nunca havia usado uma declaração de atribuição em uma declaração de atribuição AWKantes. Por alguma razão, isso nunca aconteceu. :)

Talvez eu consiga raspar alguns bytes dizendo para atribuir OFS e FS fora de um BEGINbloco via atribuição de linha de comando ou similar, mas é "mais limpo" dessa maneira.

A adição do link TIO me mostrou que havia um erro de transcrição que exigia 8 bytes para corrigir :( (deixei de fora 0*(U=a):)

Robert Benson
fonte
1

C (gcc) , 212 206 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);}

Experimente online!

Jonathan Frech
fonte
@ceilingcat Obrigado.
Jonathan Frech
1

Stax , 18 bytes

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

Execute e depure

A abordagem geral é baseada em regex.

  • Duas vezes:
  • Encontrar todas as correspondências para [a-z].*?[a-z].
  • Troque o primeiro e o último caractere nas partidas.
  • Caso invertido.
recursivo
fonte
1

R , 223 163 bytes 148 bytes

EDIT: -60 bytes implementando um loop for

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

Experimente online!

Funciona testando se o caractere é minúsculo ou maiúsculo, os coloca em uma matriz, inverte a matriz para extrair os valores em um formato trocado. Em seguida, imprima com cat. Experimente as dificuldades online scan(,'')se o código tiver mais de uma linha, daí o ponto e vírgula em toda a linha de código.

Sumner18
fonte
Eu recebo 168 no seu link, mas esse golfe é 163
Giuseppe
E isso leva a 162.
Giuseppe
isso provavelmente funciona; a xbrincadeira é a parte mais inteligente, mas livrar-se de m=matrix4 bytes também.
Giuseppe
E o scan(,'')problema? E reduzindo o "lLEhW OroLd!" no TIO para scan(,'')ou alguma outra maneira de obter entrada?
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);}

EDIT: Acabei de notar que tenho uma resposta semelhante à resposta Retina do @Leo , embora tenha pensado nisso de forma independente ..

Ungolfed:

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 do teste:

Experimente aqui.

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

Resultado:

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
fonte