교환 대문자


35

두 줄의 문자열이 주어지면 각 문자열의 대문자 패턴을 다른 문자열로 옮깁니다. 가장 적은 바이트가 이깁니다.

Input:   CodeGolf xxPPCGxx  
Output:  coDEGOlf XxppCgxx
  • 두 문자열은 길이가 같고 비어 있지 않으며 문자 a..z및 만 A..Z있습니다.
  • 두 개의 결과 문자열을 입력과 관련하여 순서대로 출력 할 수 있습니다.
  • 입력 및 / 또는 출력을 위해 문자가 아닌 단일 문자 구분 기호를 사용하여 한 쌍의 문자열을 하나의 문자열로 나타낼 수 있습니다.
  • 문자열을 문자 목록 또는 한 문자 문자열로 나타낼 수 있지만 단순히 언어로 된 문자열이 아닌 한 일련의 코드 포인트 값으로 표현할 수는 없습니다.
  • 입력과 출력은 문자열을 다르게 나타낼 수 있습니다.

테스트 사례 :

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

답변:


14

자바 (JDK 10) , 66 바이트

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

온라인으로 사용해보십시오!

설명

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].
}

9
이 답변과는 전혀 관련이 없지만 채팅을 만드는 것보다 쉽습니다. ; p 사용할 때 Java-10 TIO에 버그가 있음을 알았 array[i++%n]+=...;습니까? array[t=i++%n]=array[t]+...;잘 작동합니다. 및 array[i%n]+=...;i++;도 잘 작동하지만, 사용 i++또는 ++i모듈러와 +=배열의 행에 추가하는 것은 작업 ..하지 않는 예로서, 여기에 10 자바 TIO 문제를보고. Java 10 JDK 또는 Java 10 TIO 컴파일러에서 버그 (또는 기능 : S)입니까?
Kevin Cruijssen

1
@KevinCruijssen 문제가 보이지만 이상하게 보입니다. TIO에 사용 된 버전은 10.0.0_46 (의 20-03-2018)입니다. 최신 버전은 10.0.1입니다. TIO에게 Java 버전을 업데이트하도록 요청해야 할 것입니다.
Olivier Grégoire

3
@KevinCruijssen Dennis는 버전을 10.0.1로 업데이트했지만 문제가 계속 발생합니다 (아직 Java 10이 설치되어 있지 않으므로 귀하와 마찬가지로 TIO에 의존합니다). 나는 여기에서 무슨 일이 일어나는지 알지 못하면서 Stack Overflow에 대해 물었습니다 ... 당황 스럽습니다!
Olivier Grégoire 2016 년

5
@KevinCruijssen 괜찮습니다.이 답변이 많은 찬사를 끄는 것은 아닙니다 : P 어쨌든 ... 문제는 실제로 버그를 발견 한 것입니다 . 스펙은 생각대로 작동해야한다고 말하므로 필요한 경우 Java 10에 최적화 된 방식으로 답변을 작성하십시오. 그렇게하면 유효한 Java 10 답변이 있지만 버그로 인해 테스트 할 수 없습니다. Java 8로 작성하여 테스트 한 다음로 변경하는 것과 같이 Java 10을 올바르게 변경 String하십시오 var.
Olivier Grégoire

6
JDK 10에서 버그를 발견 한 것이 정말 깔끔하다고 생각합니다. 좋은 직업 :]
Poke

13

C (gcc) , 86 58 55 53 바이트

  • Cows quack 덕분에 28 바이트를 절약했습니다 .
  • 3 바이트를 저장했습니다.
  • Olivier Grégoire 덕분에 2 바이트를 절약했습니다 .
c(a,s,e)char*a,*s;{for(;*s++^=e=(*s^*a)&32;)*a++^=e;}

온라인으로 사용해보십시오!



@Cowsquack 와우; 고마워
Jonathan Frech 2016 년


@ OlivierGrégoire 감사합니다.
Jonathan Frech 2016 년

8

젤리 , 9 바이트

O&32^/^OỌ

온라인으로 사용해보십시오!

작동 원리

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.

1
... 우리는 그것이 일어날 것이라는 것을 알았습니다 : D
Jonathan Allan

7

APL (Dyalog Classic) , 13 12 바이트

⊖⊖819⌶¨⍨∊∘⎕a

온라인으로 사용해보십시오!

입력과 출력은 2 × N 문자 매트릭스입니다

⎕a 대문자 영어 알파벳입니다 'ABC...Z'

∊∘⎕a 입력에서 어떤 문자가 대문자인지를 나타내는 부울 행렬을 반환합니다.

819⌶ 부울 왼쪽 인수에 따라 오른쪽 인수를 대문자 또는 소문자로 변환합니다 ( "819"는 "BIG"에 대해 leetspeak입니다).

819⌶¨⍨각 ( ¨) 문자에 대해 인수를 교환 ( )

수직으로 뒤집는 수단; 하나 는 왼쪽 주장으로 작용 819⌶하고 다른 하나는 최종 행동입니다


1
"819" is leetspeak for "BIG"... 진심으로? 그것이 왜 819인지에 대한 실제 설명입니까? 0_o
DLosc

@DLosc yes :) 채팅보기
ngn

5

Pyth , 10 바이트

rVV_mmrIk1

여기 사용해보십시오!

설명 및 깔끔한 Pyth 트릭 사용

  • rVV_mmrIk1— 전체 프로그램. STDIN에서 두 개의 문자열 목록으로 입력을 가져오고 출력은 두 개의 문자 목록으로 STDOUT에 기록됩니다.

  • mm — 각 문자열의 각 문자에 대해 :

    • Ik — 아래에서 변하지 않는지 확인하십시오.
    • r...1— ... 대문자로 변환. 수익률 진정한 대문자 및 거짓 소문자 사람을위한.
  • _ — 그 목록을 반대로하십시오.

  • VV — 두 목록에서 다음 기능을 두 번 벡터화합니다.

    • r— 값이 True(일명 1) 이면 대문자 로 변환하고 그렇지 않으면 소문자로 변환합니다.

이 제출 남용은 사실 r0r1Pyth에서 소문자와 대문자 기능, 그리고 우리가 진리 값 (각 문자가 대문자 인 경우 확인하여 얻은 값, 반전) 사용은 항복 True대문자과 False소문자을 위해. 부울이 파이썬에서 정수의 서브 클래스라는 사실은이 답변이 사용하는 접근법에 매우 유용합니다. 포팅 데니스와 조나단의 젤리 접근 방식은 모두 18 바이트 이상이되었으므로 여기서 사용 된 Pyth 고유의 트릭에 매우 만족합니다.




3

J , 36 31 27 바이트

FrownyFrog 덕분에 -9 바이트!

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

온라인으로 사용해보십시오!

이전 솔루션은 다음과 같습니다.

J , 36 31 바이트

FrownyFrog 덕분에 -5 바이트!

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

온라인으로 사용해보십시오!

작동 방식 :

                          (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

[:0이 (22 b.)될 수 있습니다 XOR. &.(3&u:)1 바이트를 저장합니다.
FrownyFrog

@FrownyFrog 아주 좋은 골프, 감사합니다! 당신은 정말 좋습니다!
Galen Ivanov


트윗 담아 가기 당신의 사용을 설명 할 수 "$? 감사!
Galen Ivanov

입력은로 이루어지며 ,:왼쪽에 2 개의 행이 있습니다. 우리는 약자를 의미하기 때문에 필요 "(1)하지만 "$작동합니다 "1 _. $ b.0$의 순위를 부여합니다 (모나 딕, 왼쪽, 왼쪽 오른쪽).
FrownyFrog

3

R , 118 94 75 72 바이트

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

온라인으로 사용해보십시오!

훨씬 더 골퍼가 있어야합니다. Luis Mendo의 MATL 솔루션 을 지적한 Giuseppe 덕분에 -43 바이트 . TIO 링크에는 동일한 바이트 수에 대한 함수 솔루션이 포함되어 있습니다.

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

보너스 : 출력은 이름이 원래 입력 문자열 인 명명 된 벡터입니다!


다른 곳에서는 a<-사용하지 않기 때문에 떨어 뜨릴 수 있어야합니다 a.
주세페

@ 주세페 내 마음을 읽고 있었습니까? ;)
JayCe

3

x86-64 머신 코드, 14 바이트

이 프로토 타입을 사용하여 C (x86-64 SysV 호출 규칙)에서 호출 할 수 있습니다.

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

길이가 명시 적 길이 인 버전 rcx은 크기가 같습니다. void casexchg(char *rdi, char *rsi, int dummy, size_t len);


이것은 C 및 Java 응답과 동일한 비트 교환 알고리즘을 사용합니다. 두 문자가 모두 같은 경우 변경하지 않아도됩니다. 반대의 경우에는 둘 다 변경해야합니다.

XOR을 사용하여 두 문자열의 대소 문자를 구분하십시오. mask = (a XOR b) AND 0x20같으면 0, 차이는 0x20입니다. a ^= mask; b ^= maskcaseflip은 대소 문자가 다르면 두 글자를 모두 씁니다. (상한 및 하한의 ASCII 문자 코드는 비트 5에서만 다릅니다.)

NASM 목록 (부터 nasm -felf64 -l/dev/stdout). 사용 cut -b 26- <casexchg.lst >casexchg.lst이 조립 수있는 일에이 등을 돌릴 수 있습니다.

   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

느린 loop명령어도 short와 같은 2 바이트 jcc입니다. scasb여전히 rdi1 바이트 명령어 로 증분하는 가장 좋은 방법 입니다. 나는 우리가 할 수 추측 xor al, [rdi]/ stosb. 그것은 같은 크기이지만 아마도 더 빠를 것입니다 loop(memory src + store는 memory dst + reload보다 저렴합니다). 그리고 암시 적 길이의 경우에도 ZF를 적절하게 설정합니다!

온라인으로 사용해보십시오! argv [1], argv [2]에서 호출하고 결과에 sys_write를 사용하는 _start





2

Q 기본, 133 바이트

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$

두 문자열을 쉼표로 구분하여 결과를 줄 바꿈으로 출력합니다. Dennis 's Jelly answer의 비트 인증 알고리즘을 사용합니다 . 그 이외의 주요 골프 트릭은 첫 번째 결과 문자열이 한 번에 한 문자 씩 직접 인쇄되므로 결과 문자열을 변수에 저장하고 루프 외부에 인쇄하는 것보다 약간 짧습니다.


2

자바 스크립트, 77 74 73 바이트

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

char 배열의 배열을 취하고 char 배열의 배열을 출력합니다.

-1 바이트 ( @Arnauld ) : c>'Z'c>{}


1
로 바이트를 저장할 수 있습니다 c>{}.
Arnauld

1

망막 , 75 바이트

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

온라인으로 사용해보십시오! 설명 : 줄 바꾸기는 처리 된 문자열의 양을 판별하기위한 마커로 사용됩니다. 정규식은 대문자 또는 일치하지 않는 문자를 찾습니다. 대문자가 일치하면 다른 문자는 대문자가되고, 그렇지 않으면 소문자가되고 그 반대의 경우도 개행은 다음 문자로 진행됩니다.



1

어셈블리 (nasm, x64, Linux) , 25 바이트 (123 바이트 소스)

16 진 바이트 :

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

함수 진입 점은 at a이며 문자열은 RDIand 를 사용하여 전달됩니다 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

온라인으로 사용해보십시오!


방금 기계 코드 크기가 아닌 asm 소스를 골프로 칠하고 있음을 깨달았습니다. 실생활에서 가끔 유용하기 때문에 일반적으로 더 재미 있습니다. (다른 모든 것이 같으면 작을수록 일반적으로 프론트 엔드 및 uop 캐시 밀도가 더 좋습니다.) x86 / x64 머신 코드에서의 골프 팁 .
Peter Cordes

@PeterCordes 팁 주셔서 감사합니다. 16 진수 바이트를 추가했습니다. 어셈블리가 약간 녹슬 었습니다 (마지막으로 DOS 3.3 용으로 작은 장치 드라이버를 작성해야했습니다!). 그러나 대부분의 최적화가 이루어 졌다고 생각합니다.
ErikF

예, 이거 꽤 좋아 보입니다. 흥미로운 부분 레지스터 핵. and al,32대부분의 ALU 명령어에있는 특수 AL, imm8 인코딩을 사용하는 2 바이트입니다. RCX에서 문자열 길이가 필요할 수 있으며 사용할 수 있습니다 loop. 나는 그것이 당신이 같은 길이 인 동안 보다 더 효율적test ah,ah 이기 때문에 당신이 말해야한다고 말 했지만, 그것은 asm 소스에서 더 길기 때문에 피 각질의 오래된 관용구는 실제로 asm 소스 코드 골프에 대한 장점을 가지고 있습니다 : Por
Peter Cordes

메모리 대상 xor와보다 엄격한 루프 구조를 사용하여 내 버전은 14 바이트의 x86-64 머신 코드로 들어 왔습니다 . 카운트 암시 적 길이 또는 명시 적 길이 문자열에 대해서도 동일합니다. NASM 소스는 123 바이트보다 짧아 질 수도 있습니다. Skylake 또는 Ryzen과 같은 최신 CPU에서 어느 것이 더 빨리 실행 될지 확실하지 않습니다 (Ryzen은 DX를 읽을 때 DH를 병합하는 데 추가 비용이 없지만 SKL은 병합 UOP를 삽입하는 데 추가주기가 필요합니다)
Peter Cordes


0

, 17 바이트

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

온라인으로 사용해보십시오! 링크는 자세한 버전의 코드입니다. 입력을 두 문자열의 배열로 가져옵니다. 설명:

 θ                  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

0

F #, 120 바이트

도청 전문가.

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

온라인으로 사용해보십시오!

이 함수 g는 두 문자열을 매개 변수로 사용합니다. 문자열의 각 요소 ( 및 )에 Seq.fold2누산기 ( a)가 있는 함수를 적용합니다 . 처음에는 빈 문자열이며 각 반복에서 변환 된 문자를 추가합니다.xya

b주요 기능입니다. 먼저 f에 대해 변환 s한 다음 s에 대해 변환 합니다 f. 그런 다음 두 값이 모두있는 튜플을 반환합니다.



0

루비 , 74 69 바이트

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

온라인으로 사용해보십시오!

입력 및 출력은 문자 배열이므로 바닥 글은 문자열에서 앞뒤로 변환을 수행합니다.

이것이 이것이 문제에 대한 좋은 접근 방법인지 확실하지 않지만이 과제는 swapcase방법에 대한 훌륭한 사용 시나리오처럼 보입니다 .


0

PHP 4.1.2 , 40 바이트

따옴표 쌍을 바이트 A0 (ISO-8859-1 또는 Windows-1252에서 NBSP)으로 바꾸면 표시된 바이트 수를 얻은 다음 웹 브라우저 (또는 명령 행)에서 다음과 같이 문자열을 제공합니다. 쿼리 문자열 인수 (또는 환경 변수) ab.

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

이 PHP 버전에서 register_globals 는 기본적으로 켜져 있으므로 문자열이 변수 $a및에 자동으로 할당됩니다 $b. 2e5필요한 경우 값 (200000)을 늘리십시오 .

PHP 7.1 이상, 58 바이트

다음을 사용하여 명령 행에서 실행하십시오 php -r 'code here' string1 string2.

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

3e5가능한 입력 문자열의 문제를 피하기 위해 대부분의 Linux 시스템 (특히 x86 및 PAGE_SIZE가 4096이고 MAX_ARG_STRLEN이 131072 인 기타 아키텍처)에서 값 (300000)이 (MAX_ARG_STRLEN * 2 + 1)을 초과하도록 선택됩니다. 필요한 경우 늘리십시오.

온라인으로 사용해보십시오!


0

Stax , 10 바이트

▌Ö↑o╓→ì]yç

실행 및 디버깅

다음은 작동 방식을 보여주기 위해 동일한 프로그램을 골고루 표현한 것입니다.

        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

이것을 실행


0

Crystal , 108 바이트

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

온라인으로 사용해보십시오!

어떻게 작동합니까?

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
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.