x86-64 machine code, 14 bytes
Callable from C (x86-64 SysV calling convention) with this prototype:
void casexchg(char *rdi, char *rsi); // modify both strings in place
An explicit-length version with length in rcx
is the same size. void casexchg(char *rdi, char *rsi, int dummy, size_t len);
This uses the same bit-exchange algo as the C and Java answers: If both letters are the same case, neither needs to change. If they're opposite case, they both need to change.
Use XOR to diff the case bit of the two strings. mask = (a XOR b) AND 0x20
is 0 for same or 0x20 for differing. a ^= mask; b ^= mask
caseflip both letters iff they were opposite case. (Because the ASCII letter codes for upper and lower differ only in bit 5.)
NASM listing (from nasm -felf64 -l/dev/stdout
). Use cut -b 26- <casexchg.lst >casexchg.lst
to turn this back into something you can assemble.
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
The slow loop
instruction is also 2 bytes, same as a short jcc
. scasb
is still the best way to increment rdi
with a one-byte instruction. I guess we could xor al, [rdi]
/ stosb
. That would be the same size but probably faster for the loop
case (memory src + store is cheaper than memory dst + reload). And would still set ZF appropriately for the implicit-length case!
Try it online! with a _start that calls it on argv[1], argv[2] and uses sys_write on the result
array[i++%n]+=...;
?array[t=i++%n]=array[t]+...;
funktioniert gut; undarray[i%n]+=...;i++;
funktioniert auch, aber die Verwendung voni++
oder++i
mit einem Modulo und+=
das Anhängen an eine Zeile in einem Array funktioniert nicht. Hier ein Java 10 TIO als Beispiel, um das Problem zu sehen. Handelt es sich um einen Fehler (oder eine Funktion: S) im Java 10 JDK oder im Java 10 TIO-Compiler?