Mais divertido com seqüências sensíveis a maiúsculas e minúsculas

28

Inspirado por esse desafio (ou, mais especificamente, por interpretá-lo mal), eu vim com o seguinte desafio:

Dada uma sequência de entrada S, inverta a ordem de todos os caracteres maiúsculos e minúsculos. Deixe todos os caracteres não alfabéticos no lugar. Por exemplo:

Olá Mundo!

Observe que a maiúscula W(a primeira letra maiúscula) foi substituída por H(a última). O mesmo vale para as letras minúsculas: 'd' (o primeiro) é trocado por e(o último), l(segundo) é substituído por l(caneta final) ... Todos os caracteres que não são letras são deixados no lugar.

Entrada

  • Entrada é uma sequência com apenas caracteres ASCII no intervalo 32-126.
  • É garantido que a entrada tenha pelo menos 1 caractere e não excederá o limite do seu idioma.

Saída

  • Essa mesma sequência, com os caracteres trocados conforme descrito.

Regras adicionais

  • As brechas padrão são proibidas
  • A resposta deve ser um programa ou uma função completa, não um trecho de texto ou uma entrada REPL.
  • , a resposta mais curta em bytes vence.

Casos de teste

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
fonte
Convém incluir um caso de teste de 2 caracteres. Minha solução original falhou nisso primeiro. (Fixo, sem qualquer custo, alterando .+a .*)
ETHproductions
"preguiçoso doge" me lembrou disso: youtube.com/watch?v=W-d6uUSY9hk
FinW

Respostas:

5

MATL , 14 bytes

2:"t@Y2myy)Pw(

Experimente no MATL Online

Explicação

        % 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
fonte
1
Bom trabalho! Eu tive 2:"tttXk>f)5MP(Yopor 17 bytes
Luis Mendo
11

Retina , 19 bytes

O Retina não tem uma maneira direta de reverter uma string, mas podemos fazer isso explorando o estágio de classificação:

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

Sort ( O), lendo-os como números ( #) e, em seguida, inverta a ordem ( ^) de todas as strings correspondentes ao regex fornecido (letras minúsculas para a primeira linha e letras maiúsculas para a segunda).

Isso funciona porque, quando tentamos ler cadeias sem caracteres numéricos como números, elas são tratadas como 0, portanto, todos os caracteres têm o mesmo valor para classificação. Como a classificação é estável, elas são deixadas na mesma ordem e a reversão retorna a string original invertida.

Experimente online!

Leo
fonte
10

Perl , 45 bytes

44 bytes de código + -psinalizador.

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

Experimente online!

Os caracteres Unicode classificam \p{Lu}e \p{Ll}correspondem respectivamente às letras maiúsculas e minúsculas.
Portanto /\p{L$c}/, retornará a lista de todas as letras maiúsculas (ou minúsculas) (e armazenará dentro @T).
E então, o regex s/\p{$c}/pop@T/gesubstituirá cada letra (maiúscula e minúscula) pela última letra @Tao removê-la @T.

dada
fonte
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: salvou 1 byte graças a @Arnauld.

Neil
fonte
4
Eu sabia que havia uma maneira melhor ...
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))

Tem tem que haver uma maneira de tirar proveito da semelhança entre as expressões regulares ...

Snippet de teste

ETHproductions
fonte
Isso pressupõe que a função está atribuída a uma variável chamada f? Isso não deveria estar na contagem de bytes?
21417 stanbergh
@steenbergh A função é anônima, pode ser chamada como você quiser que seja #
Kritixi Lithos
1
@steenbergh Não, é uma função anônima que cria outra função Fe a chama recursivamente duas vezes. A função externa não se chama de fato a qualquer momento.
ETHproductions
Por que você usa parênteses .*nas regexes?
11557 Luke
@ Lucas para capturar esses personagens (the ain ([x],a,y)=>)
ETHproductions
4

Perl 6 , 75 69 bytes

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

Como funciona

  1. my @a=.comb;
    Divida a string em caracteres e armazene-os em uma matriz.

  2. for /<:Lu>/,/<:Ll>/
    Para duas regexes correspondentes às letras maiúsculas e minúsculas, respectivamente ...

    • @(grep $_,@a)
      Obtenha uma fatia de todas as entradas da matriz que correspondem ao regex.

    • .&{@$_=[R,] $_}
      Atribua o reverso da fatia a si próprio.

  3. [~] @a
    Concatene a matriz modificada para formar uma sequência novamente e retorne-a.


-6 bytes, roubando a ideia de usar classes Unicode em vez de intervalos de caracteres, da solução da @ Dada.

smls
fonte
3

Gelatina , 14 bytes

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.
    ,Ṛ$         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
fonte
para não ser exigente, mas .. 14 caracteres! = 23 bytes :) mothereff.in/byte-counter
Gizmo
@Gizmo Jelly usa uma página de código . Consulte esta meta postagem para obter mais informações.
Suever
@Suever Oh, isso é puro, aprendi alguma coisa hoje ^ ^.
Gizmo
3

Utilitários Bash + Unix, 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]

Experimente online!

Não é realmente muito curto; talvez alguém possa jogar mais.

Entrada em stdin, saída em stdout.

Isso funcionará corretamente em entradas com menos de 200 caracteres.

(Na verdade, ele manipula corretamente qualquer sequência com menos de 200 letras minúsculas e menos de 200 letras maiúsculas.)

Se você aumentar o 99 no código para 102 (ao custo de um byte adicional), ele manipulará seqüências de caracteres até 205 caracteres.

No entanto, não é possível aumentar o 99 no código além de 102, pois você excederá o tamanho máximo do argumento do sed.

Aqui está uma versão sem qualquer limitação de tamanho de entrada específica, mas a contagem é um pouco mais longa, 137 bytes. (Esta versão mais longa grava em um arquivo auxiliar chamado 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

Execuções de teste:

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
fonte
Interessante que ele falhe no TIO. ☹ Pode depender da sedimplementação instalada no seu sistema, mas no GNU sedvocê pode adicionar -ropções e remover os \escapes de todos os parênteses.
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

Experimente online!

Dennis
fonte
Você pode substituir \ n por;?
Tim
Infelizmente não. O argumento de execé analisado como o código Python usual, portanto, o loop for deve estar em sua própria linha.
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)

Experimente online!

DmitrySamoylenko
fonte
Você pode salvar alguns bytes transformando isso em um lambda. s->new String...
NonlinearFruit
1
@NonlinearFruit thank you! 294 -> 272, também corrigiu um erro quando r r foi reutilizado sem inicialização.
DmitrySamoylenko
Bem-vindo ao PPCG! Algumas coisas que você ainda pode jogar golfe: char[]o=s.toCharArray();char c;int b;para char o[]=s.toCharArray(),c,b;; e ambos &&para &'; e c=o[i];return b>1?!Character.isUpperCase(c):!Character.isLowerCase(c);para c=o[i];Character x=c;return b>1?!x.isUpperCase(c):!x.isLowerCase(c);( 259 bytes no total ). E provavelmente perdi algumas coisas para jogar mais. Além disso, se você ainda não o viu, pode ser interessante ler dicas de golfe em Java .
Kevin Cruijssen 15/02
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 da minha resposta ao desafio vinculado. Isso é consideravelmente mais fácil do que apenas trocar pares. Gostaria de saber se eu poderia obter sub 100 com alguns golfe ...

Experimente online!

Sumner18
fonte