Capitalização de câmbio

35

Dadas duas cadeias de letras, transfira o padrão de maiúsculas de cada cadeia para a outra. Menos bytes ganha.

Input:   CodeGolf xxPPCGxx  
Output:  coDEGOlf XxppCgxx
  • Ambas as strings terão o mesmo comprimento e não serão vazias, com apenas letras a..ze A..Z.
  • Você pode emitir as duas seqüências resultantes em qualquer ordem em relação às entradas.
  • Você pode representar um par de cadeias como uma cadeia com um separador de caracteres únicos que não seja a letra para entrada e / ou saída.
  • Você pode representar uma string como uma lista de caracteres ou de um caractere, mas não como uma sequência de valores de pontos de código, a menos que sejam simplesmente strings no seu idioma.
  • Sua entrada e saída podem representar cadeias de caracteres de maneira diferente.

Casos de teste:

CodeGolf xxPPCGxx -> coDEGOlf XxppCgxx
lower UPPER -> LOWER upper
MiXeD lower -> mixed LoWeR
A A -> A A
ABcd EfGh -> AbCd EFgh
xnor
fonte

Respostas:

14

Java (JDK 10) , 66 bytes

a->b->{for(int i=a.length,t;i-->0;b[i]^=t)a[i]^=t=(a[i]^b[i])&32;}

Experimente online!

Explicações

a->b->{                           // Curried lambda
 for(int i=a.length,t;i-->0;      //  Descending loop on i,
                                  //  Declare t
     b[i]^=t                      //   Apply the case difference to b[i]
   )
  a[i]^=t=(a[i]^b[i])&32;         //   Assign the case difference of the two letters to t, and apply it to a[i].
}
Olivier Grégoire
fonte
9
Completamente não relacionado a essa resposta, mas é mais fácil do que criar um bate-papo. ; p Você notou que o Java-10 TIO tem um erro ao usar array[i++%n]+=...;? array[t=i++%n]=array[t]+...;funciona bem; e array[i%n]+=...;i++;funciona bem também, mas usar i++ou ++icom um módulo e +=anexar a uma linha em uma matriz não funciona. Aqui um Java 10 TIO como exemplo para ver o problema. Isso é um bug (ou recurso: S) no Java 10 JDK ou no compilador Java 10 TIO?
Kevin Cruijssen
11
@KevinCruijssen Eu vejo o problema, mas parece estranho. Vejo que a versão usada no TIO é 10.0.0_46 (de 20-03-2018). A versão mais recente é 10.0.1. Provavelmente, devemos pedir ao TIO para atualizar sua versão do Java.
Olivier Grégoire
3
@KevinCruijssen Dennis atualizou a versão para 10.0.1 e o problema ainda está acontecendo (ainda não tenho o Java 10 instalado, por isso confio no TIO, assim como você). Eu perguntei no Stack Overflow porque simplesmente não sei o que acontece aqui ... É desconcertante!
Olivier Grégoire
5
@KevinCruijssen Tudo bem, não é como se esta resposta atraísse muitos votos: P De qualquer forma ... O problema é que você realmente encontrou um bug . Como a especificação diz que deve estar agindo como você pensa, continue escrevendo sua resposta dessa maneira, otimizada para Java 10, se necessário. Dessa forma, você tem uma resposta válida para Java 10, mas não pode ser testada por causa desse bug. Basta escrevê-lo e testá-lo no Java 8, depois faça as mudanças apropriadas no Java 10, como mudar Stringpara var.
Olivier Grégoire
6
Eu acho muito legal que você tenha encontrado um bug no JDK 10. Bom trabalho:]]
Puxa
13

C (gcc) , 86 58 55 53 bytes

c(a,s,e)char*a,*s;{for(;*s++^=e=(*s^*a)&32;)*a++^=e;}

Experimente online!

Jonathan Frech
fonte
Manipulação de bits dáf(S,Z)char*S,*Z;{for(int d;d=(*Z^*S)&32,*Z++^=d;)*S++^=d;}
Kritixi Lithos
@Cowsquack Wow; Muito obrigado.
Jonathan Frech
@ OlivierGrégoire Obrigado.
Jonathan Frech
8

Geléia , 9 bytes

O&32^/^OỌ

Experimente online!

Como funciona

O&32^/^OỌ  Main link. Argument: [s, t] (pair of strings)

O          Ordinal; replace each character with its code point.
 &32       Perform bitwise AND with 32, yielding 32 for lowercase letters, 0 for
           uppercase ones.
    ^/     Reduce by XOR, yielding 32 for letter pairs with different 
           capitalizations, 0 for letter pair with matching capitalizations.
      ^O   XOR the result with each of the code points.
        Ọ  Unordinal; replace each code point with its character.
Dennis
fonte
11
... nós sabíamos que isso iria acontecer: D
Jonathan Allan
7

APL (Dyalog Classic) , 13 12 bytes

⊖⊖819⌶¨⍨∊∘⎕a

Experimente online!

entrada e saída é uma matriz de caracteres 2 × N

⎕a é o alfabeto inglês maiúsculo 'ABC...Z'

∊∘⎕a retorna uma matriz booleana indicando quais letras na entrada estão em maiúsculas

819⌶ converte seu argumento da direita em maiúsculas ou minúsculas, dependendo do argumento da esquerda booleana ("819" é leetspeak para "BIG")

819⌶¨⍨faz isso para cada ¨caractere ( ), trocando ( ) os argumentos

significa reverter verticalmente; um atua como argumento à esquerda 819⌶e o outro é a ação final

ngn
fonte
11
"819" is leetspeak for "BIG"... A sério? Essa é a explicação real do porquê de 819? 0_o
DLosc 4/18
@DLosc yes :) see chat
ngn
5

Pitão , 10 bytes

rVV_mmrIk1

Experimente aqui!

Explicação e truques de Pyth

  • rVV_mmrIk1- programa completo. A entrada é obtida de STDIN como uma lista de duas cadeias e a saída é gravada em STDOUT como uma lista de duas listas de caracteres.

  • mm - Para cada caractere em cada uma das strings:

    • Ik - Verifique se é invariável em ...
    • r...1- ... Convertendo para maiúsculas. Rendimentos True para caracteres maiúsculos e False para caracteres minúsculos.
  • _ - Inverta essa lista.

  • VV - Vetorize duas vezes a seguinte função nas duas listas:

    • r- Converta para maiúsculas se o valor for True(também conhecido como 1), ou então converta para minúsculas.

Esta submissão abusos o fato de que r0e r1são a letras minúsculas e maiúsculas funções em Pyth, e nós usamos valores de verdade (os valores obtidos, verificando se cada personagem é maiúscula, inverteu) dando Truepara maiúsculas e Falseem minúsculas. O fato de os booleanos serem subclasses de números inteiros no Python é muito útil para a abordagem que esta resposta está usando. Portar as abordagens de Dennis e Jonathan's Jelly resultou em mais de 18 bytes, por isso estou muito feliz com os truques específicos de Pyth usados ​​aqui.

Mr. Xcoder
fonte
4

MATL , 11 bytes

kG91<P32*-c

Experimente online! Ou verifique todos os casos de teste .

Explicação

k      % Implicit input: 2-row char matrix. Convert to lower-case
G      % Push input again 
91<    % Less than 91?, element-wise. Gives 1 for upper-case
P      % Flip vertically
32*    % Multiply by 32, element-wise
-      % Subtract, element-wise
c      % Convert to char. Implicit display
Luis Mendo
fonte
4

Haskell , 78 bytes

import Data.Char
c x|isUpper x=toUpper|1<2=toLower
(!)=zipWith c
x#y=(y!x,x!y)

Experimente online!

user28667
fonte
4
isUpper xpode ser x<'a'.
Lynn
3

J , 36 31 27 bytes

-9 bytes graças ao FrownyFrog!

(XOR"$32*[:~:/97>])&.(3&u:)

Experimente online!

A solução anterior foi:

J , 36 31 bytes

-5 bytes graças ao FrownyFrog!

|:@(XOR 32*0~:/@|:97>])&.(3&u:)

Experimente online!

Como funciona:

                          (3&u:)  converts the strings to code points
   (                    )&.       then do the following and convert back to chars
                    97>]          check if they are uppercase letters 
             0~:/@|:              transpose and check if the two values are different
          32*                     multiply by 32 (32 if different, 0 otherwise)
      XOR                         xor the code point values with 32 or 0
 |:@                              and transpose
Galen Ivanov
fonte
O [:pode ser 0 e o (22 b.)pode ser XOR. &.(3&u:)salva 1 byte.
precisa saber é o seguinte
@FrownyFrog Golfinhos muito agradáveis, obrigado! Você é muito bom!
Galen Ivanov
27
FrownyFrog
@FrownyFrog Wow! Você pode explicar o uso de "e $? Obrigado!
Galen Ivanov
A entrada é feita com ,:, existem 2 linhas no lado esquerdo. Precisamos, "(1)mas "$também funciona, porque significa "1 _. $ b.0dá a classificação de $ (monádico, diádico esquerdo, diádico direito).
precisa saber é o seguinte
3

R , 118 94 75 72 bytes

m=sapply(scan(,""),utf8ToInt);w=m>96;apply(m-32*(w-w[,2:1]),2,intToUtf8)

Experimente online!

Deve haver uma maneira muito mais golfista. -43 bytes graças a Giuseppe, que me indicou a solução MATL de Luis Mendo. O link TIO contém uma solução de função para a mesma contagem de bytes.

m=sapply(a<-scan(,""),utf8ToInt)    # Turns input into a matrix of bytecode (2 columns)
w=m>96                              # Predicate : which chars are lower?
apply(m-32*(w-w[,2:1]),2,intToUtf8) # -32*w turns the string to UPPER
                                    # +32*w[,2:1] swaps capitalization
                                    # intToUtf8 turns bytecode to strings

Bônus: A saída é um vetor nomeado cujos nomes são as seqüências de entrada originais!

JayCe
fonte
Você deve soltar, a<-pois não usa em anenhum outro lugar.
Giuseppe
@ Giuseppe Você estava lendo minha mente? ;)
Jayce
3

código de máquina x86-64, 14 bytes

É possível chamar de C (convenção de chamada x86-64 SysV) com este protótipo:

void casexchg(char *rdi, char *rsi);  // modify both strings in place

Uma versão de comprimento explícito com comprimento rcxé do mesmo tamanho. void casexchg(char *rdi, char *rsi, int dummy, size_t len);


Isso usa o mesmo algo de troca de bits que as respostas C e Java: se as duas letras são o mesmo caso, nenhuma delas precisa mudar. Se for o caso oposto, ambos precisam mudar.

Use XOR para diferenciar o bit de maiúsculas e minúsculas das duas seqüências. mask = (a XOR b) AND 0x20é 0 para o mesmo ou 0x20 para diferente. a ^= mask; b ^= maskletras maiúsculas de minúsculas ambas as letras se elas eram o caso oposto. (Como os códigos de letras ASCII para superior e inferior diferem apenas no bit 5.)

Listagem NASM (de nasm -felf64 -l/dev/stdout). Use cut -b 26- <casexchg.lst >casexchg.lstpara transformar isso de volta em algo que você pode montar.

   addr    machine
 6         code          global casexchg
 7         bytes         casexchg:
 8                       .loop:
 9 00000000 AC               lodsb                ; al=[rsi] ; rsi++
10 00000001 3207             xor   al, [rdi]
11 00000003 2420             and   al, 0x20       ; 0 if their cases were the same: no flipping needed
12                       
13 00000005 3007             xor   [rdi], al      ; caseflip both iff their cases were opposite
14 00000007 3046FF           xor   [rsi-1], al
15                       
16 0000000A AE               scasb                ; cmp al,[rdi] / inc rdi
17                           ; AL=0 or 0x20.
18                           ; At the terminating 0 in both strings, AL will be 0 so JNE will fall through.
19                           ; 0x20 is ASCII space, which isn't allowed, so AL=0x20 won't cause early exit
20 0000000B 75F3             jne  .loop
21                       ;    loop  .loop            ; caller passes explict length in RCX
22                       
23 0000000D C3               ret

  size = 0xe bytes = 14
24 0000000E 0E           db $ - casexchg_bitdiff

A loopinstrução lenta também tem 2 bytes, o mesmo que um curto jcc. scasbainda é a melhor maneira de incrementar rdicom uma instrução de um byte. Eu acho que poderíamos xor al, [rdi]/ stosb. Esse seria o mesmo tamanho, mas provavelmente mais rápido para o loopcaso (a memória src + store é mais barata que a memória dst + reload). E ainda definiria o ZF adequadamente para o caso de comprimento implícito!

Experimente online! com um _start que chama argv [1], argv [2] e usa sys_write no resultado

Peter Cordes
fonte
2

Python 3 , 83 bytes

lambda a,b:(g(a,b),g(b,a))
g=lambda*a:[chr(ord(x)&95|(y>'Z')<<5)for x,y in zip(*a)]

Experimente online!

-3 bytes graças ao Sr. Xcoder
-3 bytes graças ao Chas Brown

HyperNeutrino
fonte
83 bytes com um pouco de manipulação de bits.
Chas Brown
@ChasBrown Oh legal, legal. Obrigado!
HyperNeutrino
2

QBasic, 133 bytes

INPUT a$,b$
FOR i=1TO LEN(a$)
c=ASC(MID$(a$,i,1))
d=ASC(MID$(b$,i,1))
s=32AND(c XOR d)
?CHR$(c XOR s);
r$=r$+CHR$(d XOR s)
NEXT
?
?r$

Pega as duas cadeias separadas por vírgula e gera os resultados separados por nova linha. Usa o algoritmo de manipulação de bits da resposta de Dennis's Jelly . Fora isso, o principal truque de golfe aqui é que a primeira sequência de resultados é impressa diretamente, um caractere de cada vez, um pouco mais curto do que salvar as duas seqüências de resultados em variáveis ​​e imprimi-las fora do loop.

DLosc
fonte
2

JavaScript, 77 74 73 bytes

W=>W.map((w,x)=>w.map((c,i)=>W[+!x][i][`to${c>{}?'Low':'Upp'}erCase`]()))

Pega uma matriz de matrizes de caracteres, gera uma matriz de matrizes de caracteres.

-1 byte ( @Arnauld ): c>'Z'c>{}

darrylyeo
fonte
11
Você pode salvar um byte com c>{}.
Arnauld
1

Retina , 75 bytes

^
¶
+`¶(([A-Z])|(.))(.*)¶(([A-Z])|(.))
$#6*$u$1$#7*$l$1¶$4$#2*$u$5$#3*$l$5¶

Experimente online! Explicação: As novas linhas são usadas como marcadores para determinar quanto da cadeia foi processada. O regex tenta corresponder contra letras maiúsculas ou com falha em qualquer caractere. Se uma letra maiúscula foi correspondida, o outro caractere é maiúsculo, caso contrário, é minúsculo e vice-versa, enquanto as novas linhas são avançadas para o próximo caractere.

Neil
fonte
1

Python 3 , 76 75 bytes

lambda a,b:''.join(chr(ord(x)&95|ord(y)&32)for x,y in zip(a+' '+b,b+'a'+a))

Experimente online!

Produz o resultado como uma sequência com um separador de caractere único.

Thx para Jonathon Allan por 1 byte.

Chas Brown
fonte
(y>'Z')*32->ord(y)&32
Jonathan Allan
1

Assembly (nasm, x64, Linux) , 25 bytes (fonte de 123 bytes)

Bytes hexadecimais:

0x88, 0xE6, 0x30, 0xC6, 0x80, 0xE6, 0x20, 0x88
0xF2, 0x66, 0x31, 0xD0, 0x88, 0x26, 0xAA, 0xAC
0x8A, 0x26, 0x8A, 0x07, 0x08, 0xE4, 0x75, 0xE8, 0xC3

O ponto de entrada da função é em a, com as cadeias passadas usando RDIe RSI.

b:MOV DH,AH
XOR DH,AL
AND DH,32
MOV DL,DH
XOR AX,DX
MOV [RSI],AH
STOSB
LODSB
a:MOV AH,[RSI]
MOV AL,[RDI]
OR AH,AH
JNZ b
RET

Experimente online!

ErikF
fonte
Acabei de perceber que você está jogando a fonte ASM, não o tamanho do código da máquina. Isso geralmente é mais divertido, porque ocasionalmente é útil na vida real. (Tudo o resto é igual, menor é geralmente melhor para a densidade de cache front-end e uop.) Dicas para jogar golfe no código de máquina x86 / x64 .
Peter Cordes
@ PeterCordes Obrigado pela dica. Eu adicionei os bytes hexadecimais. Meu montagem é um pouco enferrujado (I última teve que escrever um pequeno driver de dispositivo para DOS 3.3!), Mas eu acho que eu tenho a maioria das otimizações no.
ErikF
Sim, isso parece muito bom. Hackes de registro parcial interessantes. and al,32é de apenas 2 bytes, usando a codificação AL, imm8 especial que a maioria das instruções da ALU possui. Você pode exigir o comprimento da string no RCX e usá-lo loop. Eu diria que você deveria, test ah,ahporque é mais eficiente do queor ter o mesmo comprimento, mas é mais longo na fonte ASM, de modo que o idioma velho e duro tem mérito no golfe de código fonte: P
Peter Cordes
Usando xor de destino da memória e uma estrutura de loop mais rígida, minha versão chegou a 14 bytes de código de máquina x86-64 . O mesmo para contagem de comprimento implícito ou comprimento explícito. Provavelmente, sua fonte NASM também poderia ter menos de 123 bytes. Não sei ao certo o que seria mais rápido em uma CPU moderna como Skylake ou Ryzen (a Ryzen não teria nenhum custo extra para mesclar DH ao ler DX, mas a SKL precisaria de um ciclo extra para inserir um uop que se fundisse.)
Peter Cordes
0

Carvão , 17 bytes

Eθ⭆ι⎇№α§§θ¬κμ↥λ↧λ

Experimente online! Link é a versão detalhada do código. Recebe a entrada como uma matriz de duas seqüências. Explicação:

 θ                  Input array
E                   Map over strings
   ι                Current string
  ⭆                 Map over characters
         θ          Input array
           κ        Outer loop index
          ¬         Logical Not
        §           Index into array
            μ       Inner loop index
       §            Index into array
      α             Uppercase characters
     №              Count number of matches
              λ λ   Current character
             ↥      Uppercase
               ↧    Lowercase
    ⎇               Ternary
                    Implicitly print
Neil
fonte
0

F #, 120 bytes

Bugger.

open System
let g=Seq.fold2(fun a x y->a+string(x|>if y>'Z'then Char.ToLower else Char.ToUpper))""
let b f s=g f s,g s f

Experimente online!

A função gusa as duas strings como parâmetros. Seq.fold2aplica uma função com um acumulador ( a) a cada elemento ( xe y) nas cadeias. Inicialmente, aé uma sequência vazia e adiciona o caractere convertido a cada iteração.

bé a função principal. Ele primeiro converte fem relação a se depois converte sem relação a f. Em seguida, ele retorna uma tupla com os dois valores.

Ciaran_McCarthy
fonte
0

Prolog (SWI) , 121 bytes

[H|T]-[I|U]-[J|V]-[K|W]:-((H>96,I>96;H<92,I<92),J=H,K=I;H>96,J is H-32,K is I+32;J is H+32,K is I-32),T-U-V-W.
_-_-[]-[].

Experimente online!

Somente ASCII
fonte
0

Ruby , 74 69 bytes

->a,b{a.zip(b).map{|x|x.one?{|y|y>?_}?x.map(&:swapcase):x}.transpose}

Experimente online!

Entrada e saída são matrizes de caracteres, portanto, o rodapé faz as transformações das cadeias para frente e para trás.

Ainda não tenho certeza se essa é uma boa abordagem para o problema, mas esse desafio definitivamente parece um cenário de uso agradável para o swapcasemétodo.

Kirill L.
fonte
0

PHP 4.1.2 , 40 bytes

Substitua o par de aspas pelo byte A0 (em ISO-8859-1 ou Windows-1252, este é o NBSP) para obter a contagem de bytes mostrada e execute a partir de um navegador da Web (ou da linha de comando), fornecendo as strings como os argumentos da string de consulta (ou variáveis ​​de ambiente) ae b.

<?=$a^$c=($a^$b)&str_pad("",2e5),_,$b^$c;

Nesta versão do PHP, register_globals está ativado por padrão, portanto, as strings serão atribuídas automaticamente às variáveis $ae $b. Aumente o valor 2e5(200000), se necessário.

PHP 7.1 ou superior, 58 bytes

Execute na linha de comando, usando php -r 'code here' string1 string2:

[,$a,$b]=$argv;echo("$b $a"^$a.=" $b")&str_pad("",3e5)^$a;

O valor 3e5(300000) é escolhido para exceder (MAX_ARG_STRLEN * 2 + 1) na maioria dos sistemas Linux (especificamente, x86 e outras arquiteturas para as quais PAGE_SIZE é 4096 e MAX_ARG_STRLEN é, portanto, 131072), para evitar problemas com qualquer sequência de entrada possível. Aumente se necessário.

Experimente online!

PleaseStand
fonte
0

Stax , 10 bytes

▌Ö↑o╓→ì]yç

Execute e depure

Aqui está uma representação não destruída do mesmo programa para mostrar como ele funciona.

        Example
        ["Ab", "cd"]                    
:)      [["Ab", "cd"], ["cd", "Ab"]]    Get all rotations of input
m       ["cd", "Ab"]                    For each, run the rest of program; print result
  M     ["cA", "db"]                    Transpose matrix
  {     "cA"                            Begin block for mapping to result
    B   "A" 99                          "Pop" first element from string array; leave the rest
    96> "A" 1                           Is the character code > 96?
    :c  "a"                             Set case of string; 0 -> upper,  1 -> lower
  m     "ab"                            Perform the map using the block

Execute este

recursivo
fonte
0

Cristal , 108 bytes

def f(a,b)r=s=""
a.zip(b){|x,y|r+="`"<x<"{"?y.downcase: y.upcase
s+="`"<y<"{"?x.downcase: x.upcase}
{s,r}end

Experimente online!

Como funciona?

def f(a, b)                       # Strings as list of characters
r = s = ""                        # Strings buffers initialization
a.zip(b) do |x, y|                # Join two arrays to paired tuples and iterate
r+="`"<x<"{"?y.downcase: y.upcase # Check if character is downcase using triple
s+="`"<y<"{"?x.downcase: x.upcase # comparison and ascii table. Then apply it to
end                               # the other character using String methods
{s, r}                            # Return two new strings using a tuple
end                               # PS: Tuples are inmutable structures in Crystal
user80978
fonte