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 ^= mask
letras 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.lst
para 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 loop
instrução lenta também tem 2 bytes, o mesmo que um curto jcc
. scasb
ainda é a melhor maneira de incrementar rdi
com 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 loop
caso (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
array[i++%n]+=...;
?array[t=i++%n]=array[t]+...;
funciona bem; earray[i%n]+=...;i++;
funciona bem também, mas usari++
ou++i
com 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?