Wymiana wielkich liter

35

Biorąc pod uwagę dwa ciągi liter, przenieś wzór wielkich liter każdego łańcucha na drugi. Wygrywa najmniej bajtów.

Input:   CodeGolf xxPPCGxx  
Output:  coDEGOlf XxppCgxx
  • Oba ciągi będą jednakowej długości i niepuste, będą zawierać tylko litery a..zi A..Z.
  • Możesz wyprowadzić dwa wynikowe ciągi w dowolnej kolejności względem danych wejściowych.
  • Możesz reprezentować parę ciągów jako jeden ciąg z nieliterowym separatorem jednoznakowym dla danych wejściowych i / lub wyjściowych.
  • Możesz reprezentować ciąg jako listę znaków lub ciągi jednoznakowe, ale nie jako sekwencję wartości punktów kodowych, chyba że są to po prostu ciągi w twoim języku.
  • Twoje dane wejściowe i wyjściowe mogą reprezentować ciągi inaczej.

Przypadki testowe:

CodeGolf xxPPCGxx -> coDEGOlf XxppCgxx
lower UPPER -> LOWER upper
MiXeD lower -> mixed LoWeR
A A -> A A
ABcd EfGh -> AbCd EFgh
xnor
źródło

Odpowiedzi:

14

Java (JDK 10) , 66 bajtów

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

Wypróbuj online!

Objaśnienia

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
źródło
9
Zupełnie niezwiązane z twoją odpowiedzią, ale jest to łatwiejsze niż tworzenie czatu. ; p Czy zauważyłeś, że Java-10 TIO ma błąd podczas używania array[i++%n]+=...;? array[t=i++%n]=array[t]+...;działa w porządku; i array[i%n]+=...;i++;działa również dobrze, ale używanie i++lub ++iz modulo i +=dołączanie do wiersza w tablicy nie działa. Tutaj TIO Java 10 jako przykład, aby zobaczyć problem. Czy to błąd (lub funkcja: S) w JDK Java 10 lub w kompilatorze Java 10 TIO?
Kevin Cruijssen
1
@KevinCruijssen Widzę problem, ale wydaje się dziwny. Widzę, że wersja używana w TIO to 10.0.0_46 (z 20-03-2018). Najnowsza wersja to 10.0.1. Prawdopodobnie powinniśmy poprosić TIO o aktualizację ich wersji Java.
Olivier Grégoire
3
@KevinCruijssen Dennis zaktualizował wersję do 10.0.1 i problem nadal występuje (nie mam jeszcze zainstalowanej Java 10, więc polegam na TIO, tak jak ty). Zapytałem o przepełnienie stosu, ponieważ po prostu nie wiem, co się tutaj dzieje ... To zaskakujące!
Olivier Grégoire
5
@KevinCruijssen W porządku, to nie tak, że ta odpowiedź przyciąga wiele pozytywnych opinii: P W każdym razie ... Chodzi o to, że rzeczywiście znalazłeś błąd . Ponieważ specyfikacja mówi, że powinna ona działać tak, jak myślisz, dlatego nadal pisz swoją odpowiedź, zoptymalizowaną pod kątem Java 10, jeśli tego potrzebujesz. W ten sposób otrzymujesz prawidłową odpowiedź Java 10, ale niesprawdzalną z powodu tego błędu. Po prostu napisz i przetestuj w Javie 8, a następnie wprowadź odpowiednie zmiany w Javie 10, takie jak zmiana Stringnavar .
Olivier Grégoire
6
Myślę, że to naprawdę fajne, że znalazłeś błąd w JDK 10. Dobra robota:]
Poke
13

C (gcc) , 86 58 55 53 bajtów

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

Wypróbuj online!

Jonathan Frech
źródło
Bitowa manipulacja dajef(S,Z)char*S,*Z;{for(int d;d=(*Z^*S)&32,*Z++^=d;)*S++^=d;}
Kritixi Lithos
@Cowsquack Wow; wielkie dzięki.
Jonathan Frech
@ OlivierGrégoire Thanks.
Jonathan Frech,
8

Galareta , 9 bajtów

O&32^/^OỌ

Wypróbuj online!

Jak to działa

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
źródło
1
... wiedzieliśmy, że to się stanie: D
Jonathan Allan
7

APL (Dyalog Classic) , 13 12 bajtów

⊖⊖819⌶¨⍨∊∘⎕a

Wypróbuj online!

wejście i wyjście jest macierzą znaków 2 × N.

⎕a jest wielkim alfabetem angielskim 'ABC...Z'

∊∘⎕a zwraca macierz logiczną wskazującą, które litery na wejściu są dużymi literami

819⌶ konwertuje prawy argument na wielkie lub małe litery w zależności od logicznego lewego argumentu („819” to leetspeak dla „BIG”)

819⌶¨⍨robi to dla każdego ¨znaku ( ), zamieniając ( ) argumenty

oznacza odwrócenie w pionie; jeden działa jako lewy argument do 819⌶drugiego, a drugi jest działaniem końcowym

ngn
źródło
1
"819" is leetspeak for "BIG"... Poważnie? To jest prawdziwe wytłumaczenie, dlaczego jest to 819? 0_o
DLosc
@DLosc tak :) patrz czat
ngn
5

Pyth , 10 bajtów

rVV_mmrIk1

Wypróbuj tutaj!

Wyjaśnienie i zgrabne sztuczki Pythona

  • rVV_mmrIk1- Pełny program. Dane wejściowe są pobierane ze STDIN jako lista dwóch ciągów, a dane wyjściowe są zapisywane do STDOUT jako lista dwóch list znaków.

  • mm - Dla każdego znaku w każdym z ciągów:

    • Ik - Sprawdź, czy jest niezmienny w ...
    • r...1- ... Konwersja na wielkie litery. Wydajność Prawda dla wielkich liter i Fałsz dla małych.
  • _ - Odwróć tę listę.

  • VV - I podwójnie wektoryzuj następującą funkcję na dwóch listach:

    • r- Konwertuj na wielkie litery, jeśli wartość to True(aka 1), w przeciwnym razie konwertuj na małe litery.

To przesłanie narusza fakt, że r0i r1są funkcjami małych i wielkich liter w Pyth, i używamy wartości prawdy (wartości uzyskane przez sprawdzenie, czy każdy znak jest pisany wielkimi literami, odwrócony), uzyskując Truewielkie i Falsemałe litery. Fakt, że booleany są podklasami liczb całkowitych w Pythonie, jest bardzo przydatny w podejściu stosowanym w tej odpowiedzi. Podejście do portowania Dennisa i Jonathana Jelly zaowocowało ponad 18 bajtami, więc jestem całkiem zadowolony z zastosowanych tutaj sztuczek specyficznych dla Pytha.

Pan Xcoder
źródło
4

MATL , 11 bajtów

kG91<P32*-c

Wypróbuj online! Lub sprawdź wszystkie przypadki testowe .

Wyjaśnienie

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
źródło
4

Haskell , 78 bajtów

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

Wypróbuj online!

użytkownik 28667
źródło
4
isUpper xmoże być x<'a'.
Lynn
3

J , 36 31 27 bajtów

-9 bajtów dzięki FrownyFrog!

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

Wypróbuj online!

Poprzednie rozwiązanie to:

J , 36 31 bajtów

-5 bajtów dzięki FrownyFrog!

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

Wypróbuj online!

Jak to działa:

                          (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 Iwanow
źródło
[:Może wynosić 0, a (22 b.)może być XOR. &.(3&u:)oszczędza 1 bajt.
FrownyFrog,
@FrownyFrog Bardzo fajne golfa, dziękuję! Jesteś naprawdę dobry!
Galen Iwanow
27
FrownyFrog,
@FrownyFrog Wow! Czy możesz wyjaśnić użycie "i $? Dzięki!
Galen Iwanow
Wprowadzanie odbywa się za pomocą ,:, po lewej stronie znajdują się 2 rzędy. Potrzebujemy, "(1)ale "$też działa, ponieważ to oznacza "1 _. $ b.0daje rangę $ (monadyczna, dyadyczna lewa, dyadyczna prawa).
FrownyFrog,
3

R , 118 94 75 72 bajty

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

Wypróbuj online!

Musi być dużo bardziej golfowy sposób. -43 bajty dzięki Giuseppe, który wskazał mi rozwiązanie MATL autorstwa Luisa Mendo. Łącze TIO zawiera rozwiązanie funkcyjne dla tej samej liczby bajtów.

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

Premia: Wyjście to nazwany wektor, którego nazwy są oryginalnymi ciągami wejściowymi!

JayCe
źródło
Powinieneś być w stanie upuścić, a<-ponieważ nie używasz anigdzie indziej.
Giuseppe
@Giuseppe Czy czytałeś w moich myślach? ;)
JayCe
3

kod maszynowy x86-64, 14 bajtów

Wywoływany z C (konwencja wywoływania SysV x86-64) z tym prototypem:

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

Wersja o jawnej długości z długością w rcxma ten sam rozmiar. void casexchg(char *rdi, char *rsi, int dummy, size_t len);


Używa tego samego algo wymiany bitów, co odpowiedzi C i Java: Jeśli obie litery są takie same, żadna nie musi się zmienić. Jeśli są w przeciwnym przypadku, oboje muszą się zmienić.

Użyj XOR, aby różnicować bit wielkości dwóch ciągów. mask = (a XOR b) AND 0x20wynosi 0 dla tego samego lub 0x20 dla różnicy. a ^= mask; b ^= maskcaseflip obie litery, jeśli były przeciwne. (Ponieważ kody liter ASCII dla górnej i dolnej różnią się tylko bitem 5).

Lista NASM (od nasm -felf64 -l/dev/stdout). Użyj, cut -b 26- <casexchg.lst >casexchg.lstaby zmienić to z powrotem w coś, co możesz złożyć.

   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

Wolna loopinstrukcja ma również 2 bajty, tak samo jak krótka jcc. scasbjest wciąż najlepszym sposobem na zwiększenie rdiinstrukcji jednobajtowej. Chyba moglibyśmy xor al, [rdi]/ stosb. Byłby to ten sam rozmiar, ale prawdopodobnie szybszy dlaloop przypadku (pamięć src + sklep jest tańsza niż pamięć dst + przeładowanie). I nadal ustawiłby ZF odpowiednio dla przypadku o niejawnej długości!

Wypróbuj online! z _start, który wywołuje go na argv [1], argv [2] i używa sys_write na wyniku

Peter Cordes
źródło
2

Python 3 , 83 bajty

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)]

Wypróbuj online!

-3 bajty dzięki Mr. Xcoder
-3 bajty dzięki Chas Brown

HyperNeutrino
źródło
83 bajty z lekkim kręceniem.
Chas Brown,
@ChasBrown Oh cool, nice. Dzięki!
HyperNeutrino
2

QBasic, 133 bajty

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$

Pobiera dwa ciągi rozdzielone przecinkami i wyświetla wyniki rozdzielone znakiem nowej linii. Wykorzystuje algorytm kręcący bity z odpowiedzi Jelly'ego na Jelly . Poza tym główną sztuczką golfa jest to, że pierwszy ciąg wyniku jest drukowany bezpośrednio, po jednym znaku na raz, co jest nieco krótsze niż zapisywanie obu ciągów wyników w zmiennych i drukowanie ich poza pętlą.

DLosc
źródło
2

JavaScript, 77 74 73 bajtów

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

Pobiera tablicę char znaków, generuje tablicę char znaków.

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

darrylyeo
źródło
1
Możesz zapisać bajt za pomocą c>{}.
Arnauld
1

Siatkówka , 75 bajtów

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

Wypróbuj online! Objaśnienie: Znaki nowej linii są używane jako znaczniki do ustalenia, ile łańcucha zostało przetworzone. Wyrażenie regularne próbuje dopasować do wielkich liter lub zawieść, że dowolne znaki. Jeśli dopasowana jest wielka litera, wówczas drugi znak jest pisany wielkimi literami, w przeciwnym razie jest pisany małymi literami i odwrotnie, podczas gdy nowe linie są przenoszone do następnego znaku.

Neil
źródło
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))

Try it online!

Outputs the result as one string with a single-character separator.

Thx to Jonathon Allan for 1 byte.

Chas Brown
źródło
(y>'Z')*32 -> ord(y)&32
Jonathan Allan
1

Assembly (nasm, x64, Linux), 25 bytes (123 bytes source)

Hex bytes:

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

The function entry point is at a, with the strings passed in using RDI and 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

Try it online!

ErikF
źródło
I just realized you're golfing the asm source, not the machine-code size. That's usually more fun, because it's occasionally useful in real life. (All else being equal, smaller is typically better for the front-end and uop cache density.) Tips for golfing in x86/x64 machine code.
Peter Cordes
@PeterCordes Thanks for the tip. I've added the hex bytes. My assembly is a little rusty (I last had to write a little device driver for DOS 3.3!) but I think I got most of the optimizations in.
ErikF
Yeah, this looks pretty good. Interesting partial-register hacks. and al,32 is only 2 bytes, using the special AL,imm8 encoding that most ALU instructions have. You could require the string length in RCX and use loop. I was going to say you should test ah,ah because that's more efficient than or while being the same length, but it's longer in asm source so the crusty old idiom actually has merit for asm-source code golfing :P
Peter Cordes
Używając miejsca docelowego pamięci xor i ściślejszej struktury pętli, moja wersja otrzymała 14 bajtów kodu maszynowego x86-64 . To samo dotyczy liczenia ciągów o niejawnej długości lub o jawnej długości. Prawdopodobnie jego źródło NASM może mieć również mniej niż 123 bajty. Nie jestem pewien, który z nich działałby szybciej na nowoczesnym procesorze, takim jak Skylake lub Ryzen (Ryzen nie musiałby ponosić żadnych dodatkowych kosztów za połączenie DH podczas czytania DX, ale SKL potrzebowałby dodatkowego cyklu, aby wstawić scalający uop.)
Peter Cordes
0

Charcoal, 17 bytes

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

Try it online! Link is to verbose version of code. Takes input as an array of two strings. Explanation:

 θ                  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
źródło
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

Try it online!

The function g takes the two strings as parameters. Seq.fold2 applies a function with an accumulator (a) to each element (x and y) in the strings. Initially a is an empty string, and it adds the converted character to it in each iteration.

b is the main function. It first converts f with respect to s, and then converts s with respect to f. It then returns a tuple with both values.

Ciaran_McCarthy
źródło
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.
_-_-[]-[].

Try it online!

ASCII-only
źródło
0

Ruby, 74 69 bytes

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

Try it online!

Input and output are arrays of chars, so the footer does back and forth transformations from strings.

I'm not yet sure whether this is a good approach to the problem, but this challenge definitely looks like a nice use scenario for swapcase method.

Kirill L.
źródło
0

PHP 4.1.2, 40 bytes

Replace the pair of quotation marks with byte A0 (in ISO-8859-1 or Windows-1252, this is NBSP) to get the byte count shown, then run from a web browser (or from the command line), providing the strings as the query string arguments (or environment variables) a and b.

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

In this version of PHP, register_globals is on by default, so the strings will automatically be assigned to the variables $a and $b. Increase the value 2e5 (200000) if necessary.

PHP 7.1+, 58 bytes

Run on the command line, using php -r 'code here' string1 string2:

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

The value 3e5 (300000) is chosen to exceed (MAX_ARG_STRLEN * 2 + 1) on most Linux systems (specifically, x86 and other architectures for which PAGE_SIZE is 4096, and MAX_ARG_STRLEN is thus 131072), to avoid problems with any possible input string. Increase if necessary.

Try it online!

PleaseStand
źródło
0

Stax, 10 bytes

▌Ö↑o╓→ì]yç

Run and debug it

Here's an ungolfed representation of the same program to show how it works.

        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

Run this one

recursive
źródło
0

Crystal, 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

Try it online!

How it works?

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
źródło