Обмінна капіталізація


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

Java (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з по модулю і +=для додавання до рядка в масиві не працює .. Ось Java 10 TIO в якості прикладу , щоб побачити проблему. Це помилка (або функція: S) у Java 10 JDK або у компіляторі Java 10 TIO?
Кевін Кройсейсен

1
@KevinCruijssen Я бачу проблему, але це здається дивним. Я бачу, що версія TIO використовується 10.0.0_46 (20-03-2018). Остання версія - 10.0.1. Ми, мабуть, повинні попросити TIO оновити їх версію Java.
Олів’є Грегоар

3
@KevinCruijssen Dennis оновив версію до 10.0.1, і проблема все ще відбувається (у мене ще не встановлена ​​Java 10, тому я покладаюся на TIO, як і ви). Я запитав про Stack Overflow, оскільки я просто не знаю, що тут відбувається ... Це неприємно!
Олів'є Грегоар

5
@KevinCruijssen Це нормально, це не так, як ця відповідь приваблює багато оновлень: P У будь-якому випадку ... Справа в тому, що ви насправді знайшли помилку . Оскільки специфікація говорить, що вона повинна діяти так, як ви вважаєте, що це робить, продовжуйте писати свою відповідь таким чином, оптимізованим для Java 10, якщо цього вам потрібно. Таким чином, у вас є дійсна відповідь Java 10, але незаперечна через цю помилку. Просто напишіть його і протестуйте в Java 8, а потім внесіть відповідні зміни у Java 10, як-от зміни Stringна var.
Олів'є Грегоар

6
Я думаю, що це дійсно охайно, що ти знайшов помилку в JDK 10. Хороша робота:]
Poke

13

C (gcc) , 86 58 55 53 байт

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

Спробуйте в Інтернеті!



@Cowsquack Wow; дуже дякую.
Джонатан Фрех


@ OlivierGrégoire Дякую
Джонатан Фрех

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
Джонатан Аллан

7

APL (Dyalog Classic) , 13 12 байт

⊖⊖819⌶¨⍨∊∘⎕a

Спробуйте в Інтернеті!

вхід і вихід - це матриця символів 2 × N

⎕a є великим англійським алфавітом 'ABC...Z'

∊∘⎕a повертає булева матриця із зазначенням, які букви у введенні є великими літерами

819⌶ перетворює його правий аргумент у верхній чи нижній регістр залежно від його бульного лівого аргументу ("819" - це літовизначення для "BIG")

819⌶¨⍨робить це для кожного ( ¨) символу, замінюючи ( ) аргументами

означає реверс вертикально; один виступає лівим аргументом, 819⌶а другий - завершальною дією


1
"819" is leetspeak for "BIG"... Серйозно? Це власне пояснення, чому це 819? 0_o
DLosc

@DLosc так :) див. Чат
ngn

5

Pyth , 10 байт

rVV_mmrIk1

Спробуйте тут!

Пояснення та акуратні використані трюки Pyth

  • rVV_mmrIk1- Повна програма. Вхід береться з STDIN як список двох рядків, а вихід записується в STDOUT у вигляді списку з двох списків символів.

  • mm - Для кожного символу в кожному з рядків:

    • Ik - Перевірте, чи він інваріантний під ...
    • r...1- ... Перетворення у великі регістри. Врожайність " Істинна" для великих літер та " Неправильна" для малих символів .
  • _ - Поверніть цей список.

  • VV - І подвійно векторизуйте наступну функцію над двома списками:

    • r- Перетворити у великі регістри, якщо значення True(ака 1), інше перетворити на малі.

Це підпорядкування зловживає той факт , що r0і r1є малими та великими функціями в Pyth, і ми використовуємо значення істинності (значення , отримані з допомогою перевірки , якщо кожен символ у верхньому регістрі, в зворотному порядку ) з отриманням Trueв верхній регістр , і Falseдля нижніх регістрів. Те, що булеви є підкласами цілих чисел у Python, дуже зручно для підходу, який використовується у цій відповіді. Перенесення підходів Денніса та Джонатана до Jelly призвело до більш ніж 18 байт, тому я цілком задоволений певними трюками, що використовуються тут.




3

J , 36 31 27 байт

-9 байт завдяки FrownyFrog!

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

Спробуйте в Інтернеті!

Попереднє рішення:

J , 36 31 байт

-5 байт завдяки FrownyFrog!

|:@(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 Дуже гарні гольфи, дякую! Ти справді хороший!
Гален Іванов


@FrownyFrog Нічого собі! Чи можете ви пояснити використання "та $? Спасибі!
Гален Іванов

Введення робиться за допомогою ,:, на лівій стороні є 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)

Спробуйте в Інтернеті!

Має бути набагато гольфістичний спосіб. -43 байти завдяки Джузеппе, який вказав мені на рішення MATL Луїсом Мендо. 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ніде не користуєтесь .
Джузеппе

@Giuseppe Ви читали мою думку? ;)
JayCe

3

машинний код x86-64, 14 байт

Телефонується з C (x86-64 SysV convention Convention) з цим прототипом:

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

Версія з чіткою довжиною довжиною в rcx- однаковий розмір. void casexchg(char *rdi, char *rsi, int dummy, size_t len);


Для цього використовується той самий біт-обмінник algo, як і відповіді 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інструкція - також 2 байти, така ж, як і коротка jcc. scasbяк і раніше найкращий спосіб нарощування rdiза допомогою однобайтової інструкції. Я думаю, ми могли xor al, [rdi]/ stosb. Це був би той самий розмір, але, ймовірно, швидший для loopвипадку (src пам'яті src + store дешевше, ніж dst пам'яті + перезавантаження). І все-таки встановив би ZF належним чином для випадку неявної довжини!

Спробуйте в Інтернеті! з _start, який викликає його в argv [1], argv [2] і використовує sys_write в результаті





2

QBasic, 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$

Бере два рядки, розділені комами, і виводить результати, розділені новим рядком. Використовує алгоритм біт-нескінченності з відповіді Денніса Желе . Окрім цього, головний трюк із гольфу тут полягає в тому, що перша рядок результатів друкується безпосередньо, один символ за часом, що трохи коротше, ніж збереження обох рядків результатів у змінних та друк їх поза циклом.


2

JavaScript, 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>{}.
Арнольд

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 байти)

Шістнадцятковий байт:

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

Точка вводу функції знаходиться у a, при цьому рядки передаються при використанні RDIта 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

Спробуйте в Інтернеті!


Я щойно зрозумів, що ти займаєшся джерелом гофру, а не розміром машинного коду. Це, як правило, веселіше, адже це періодично корисно в реальному житті. (Якщо всі інші рівні, менші, як правило, краще для передньої та загальної щільності кешу.) Поради щодо гольфу в машинному коді x86 / x64 .
Пітер Кордес

@PeterCordes Дякую за пораду. Я додав шістнадцятковий байт Моя збірка трохи іржава (я востаннє повинен був написати трохи драйвера пристрою для DOS 3.3!), Але, думаю, я отримав більшість оптимізацій.
ErikF

Так, це виглядає досить добре. Цікаві часткові реєстри хаків. and al,32- це лише 2 байти, використовуючи спеціальне кодування AL, im8, яке має більшість інструкцій ALU. Ви можете зажадати довжини рядка в RCX і використовувати loop. Я збирався сказати, що ви повинні, test ah,ahтому що це більш ефективно, ніж уor той же самий довжина, але він довше в джерелі asm, тому стара стару ідіому насправді має заслуги для гольфу з кодом з джерелом тла: P
Пітер Кордес,

Використовуючи пам'ять xor призначення та більш жорстку структуру циклу, моя версія вийшла в 14 байт машинного коду x86-64 . Те ж саме для рядків неявної довжини або явної довжини. Його джерело NASM, ймовірно, також може бути внизу менше, ніж 123 байти. Я не впевнений, який би працював швидше на сучасному процесорі, як Skylake або Ryzen (Ryzen не мав би додаткових витрат на злиття DH при зчитуванні DX, але SKL знадобиться додатковий цикл, щоб вставити об'єднаний загальний пристрій.)
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) до кожного елемента ( xі y) у рядках. Спочатку aце порожній рядок, і він додає до нього перетворений символ у кожній ітерації.

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), щоб відобразити кількість байтів, а потім запустіть із веб-браузера (або з командного рядка), надаючи рядки як аргументи рядка запиту (або змінні середовища) aта b.

<?=$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 (300000) вибрано для перевищення (MAX_ARG_STRLEN * 2 + 1) у більшості систем Linux (зокрема, x86 та інших архітектур, для яких PAGE_SIZE - 4096, а MAX_ARG_STRLEN - 131072), щоб уникнути проблем з будь-яким можливим рядом введення. Збільшуйте при необхідності.

Спробуйте в Інтернеті!


0

Стакс , 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

Кристал , 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
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.