Exchange capitalization

35

5

Given two strings of letters, transfer the capitalization pattern of each string onto the other one. Fewest bytes wins.

Input:   CodeGolf xxPPCGxx  
Output:  coDEGOlf XxppCgxx
  • Both strings will be equal-length and nonempty, with only letters a..z and A..Z.
  • You may output the two resulting strings in either order relative to the inputs.
  • You may represent a pair of strings as one string with a non-letter single-character separator for input and/or output.
  • You may represent a string as a list of characters or one-character strings, but not as a sequence of code point values unless these are simply strings in your language.
  • Your input and output may represent strings differently.

Test cases:

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

xnor

Posted 2018-06-02T17:54:24.843

Reputation: 115 687

Answers

14

Java (JDK 10), 66 bytes

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

Try it online!

Explanations

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

Posted 2018-06-02T17:54:24.843

Reputation: 10 647

9

Completely unrelated to this answer of yours, but it's easier than creating a chat. ;p Did you notice the Java-10 TIO has a bug when using array[i++%n]+=...;? array[t=i++%n]=array[t]+...; works fine; and array[i%n]+=...;i++; works fine as well, but using i++ or ++i with a modulo and += to append to a row in an array doesn't work.. Here a Java 10 TIO as example to see the problem. Is this a bug (or feature :S) in the Java 10 JDK or in the Java 10 TIO compiler?

– Kevin Cruijssen – 2018-06-04T13:26:58.463

1@KevinCruijssen I see the issue, but it seems weird. I see that the version used on TIO is 10.0.0_46 (of 20-03-2018). The latest version is 10.0.1. We should probably ask TIO to update their version of Java. – Olivier Grégoire – 2018-06-04T13:42:19.780

3

@KevinCruijssen Dennis updated the version to 10.0.1 and the issue is still happening (I don't have Java 10 installed yet so I rely on TIO, just like you). I've asked on Stack Overflow as I just don't know what happens here... It's baffling!

– Olivier Grégoire – 2018-06-04T15:18:26.313

I've upvoted and favorited your SO question. It seems array[something] += a; is interpret by the compiler correctly as int temp = something; array[temp] = array[temp] + a; in Java 8, but incorrectly as array[something] = array[something] + a; in Java 10 (NOTE: This is just pseudo-code, no idea if the compiler is exactly like this). The test cone by @DidierL. is pretty good and seems to confirm this, though: String[] array = {""}; array[test()] += "a"; with static int test() { System.out.println("evaluated"); return 0; } will print evaluated twice. – Kevin Cruijssen – 2018-06-04T16:32:45.973

Ah, I see adding a counter for the iterations will result in 50 for the bugged Java 10 code, but 100 for the Java 8 code. So i++ (and everything else inside the block-quoted of [...] +=) is evaluated twice. PS: Sorry to spam this answer of yours. As soon as the "Move to chat" option appears it would be best to do so. ;) – Kevin Cruijssen – 2018-06-04T16:35:52.460

5

@KevinCruijssen It's ok, it's not like this answer attracts a lot of upvotes :P Anyways... The thing is that you actually found a bug. Since the spec says it should be acting as you would think it does, keep writing your answer that way, optimized for Java 10 if you require so. That way, you have a valid Java 10 answer, but untestable because of that bug. Just write it and test it in Java 8, then make the proper Java 10 changes like changing String to var.

– Olivier Grégoire – 2018-06-04T19:40:54.850

6I think it's really neat that you found a bug in JDK 10. Good job :] – Poke – 2018-06-05T19:42:13.850

@Poke It indeed is. :) And rofl at that 500 upvotes. XD Anyway, if anyone want to use it in their java 10 answers, as provided by the accepted answer on SO, adding the compiler-flag -XDstringConcat=inline seems to work. Try it online in Java 10.

– Kevin Cruijssen – 2018-06-08T11:54:05.503

@KevinCruijssen That post is crazy. It got featured on Hacker News, on Reddit, and the OpenJDK bug was raised from "Major loss of functionality" to "Crash, loss of data, major memory leak". Even my colleagues saw it and asked me if I was the one posting it. I've hit the rep-cap 4 days in a row now, and I think I might hit it again today. Personally, I don't think it's such a big deal given the corner case it is. Only codegolfers could have find it.

– Olivier Grégoire – 2018-06-08T12:07:54.403

I think it was mentioned in the SO post but the thing to remember is that JDK 9 and 10 are not LTS versions. If you're using java in a professional environment you're hopefully on JDK 8 waiting for 11 to be released in September. All that aside, though, it's a pretty big bug – Poke – 2018-06-08T15:30:18.450

13

C (gcc), 86 58 55 53 bytes

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

Try it online!

Jonathan Frech

Posted 2018-06-02T17:54:24.843

Reputation: 6 681

Bit manipulation gives f(S,Z)char*S,*Z;{for(int d;d=(*Z^*S)&32,*Z++^=d;)*S++^=d;}

– user41805 – 2018-06-02T18:55:28.720

@Cowsquack Wow; thanks a lot. – Jonathan Frech – 2018-06-02T18:58:59.507

c(a,s,e)char*a,*s;{for(;*s++^=e=(*s^*a)&32;)*a++^=e;} (53 bytes) – Olivier Grégoire – 2018-06-04T09:12:44.263

@OlivierGrégoire Thanks. – Jonathan Frech – 2018-06-04T10:03:28.353

8

Jelly, 9 bytes

O&32^/^OỌ

Try it online!

How it works

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

Posted 2018-06-02T17:54:24.843

Reputation: 196 637

1...we knew it was gonna happen :D – Jonathan Allan – 2018-06-02T20:01:55.780

7

APL (Dyalog Classic), 13 12 bytes

⊖⊖819⌶¨⍨∊∘⎕a

Try it online!

input and output is a 2×N character matrix

⎕a is the uppercase English alphabet 'ABC...Z'

∊∘⎕a returns a boolean matrix indicating which letters in the input are uppercase

819⌶ converts its right argument to uppercase or lowercase depending on its boolean left argument ("819" is leetspeak for "BIG")

819⌶¨⍨ does that for each (¨) character, swapping () the arguments

means reverse vertically; one acts as the left argument to 819⌶ and the other is the final action

ngn

Posted 2018-06-02T17:54:24.843

Reputation: 11 449

1"819" is leetspeak for "BIG" ... Seriously? That's the actual explanation for why it's 819? 0_o – DLosc – 2018-06-04T04:34:45.857

@DLosc yes :) see chat

– ngn – 2018-06-04T04:44:11.480

5

Pyth, 10 bytes

rVV_mmrIk1

Try it here!

Explanation & neat Pyth tricks used

  • rVV_mmrIk1 — Full program. Input is taken from STDIN as a list of two strings, and the output is written to STDOUT as a list of two lists of characters.

  • mm — For each character in each of the strings:

    • Ik — Check if it is invariant under...
    • r...1 — ... Converting to uppercase. Yields True for uppercase characters and False for lowercase ones.
  • _ — Reverse that list.

  • VV — And double-vectorize the following function over the two lists:

    • r — Convert to uppercase if the value is True (aka 1), else convert to lowercase.

This submission abuses the fact that r0 and r1 are the lowercase and uppercase functions in Pyth, and we use truth values (the values obtained by checking if each character is uppercase, reversed) yielding True for uppercase and False for lowercase. The fact that booleans are subclasses of integers in Python is very handy for the approach this answer is using. Porting Dennis and Jonathan's Jelly approaches both resulted in more than 18 bytes, so I am quite happy with the Pyth-specific tricks used here.

Mr. Xcoder

Posted 2018-06-02T17:54:24.843

Reputation: 39 774

4

MATL, 11 bytes

kG91<P32*-c

Try it online! Or verify all test cases.

Explanation

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

Posted 2018-06-02T17:54:24.843

Reputation: 87 464

4

Haskell, 78 bytes

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

Try it online!

user28667

Posted 2018-06-02T17:54:24.843

Reputation: 579

4isUpper x can be x<'a'. – Lynn – 2018-06-03T15:44:24.777

3

J, 36 31 27 bytes

-9 bytes thanks to FrownyFrog!

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

Try it online!

The previous solution was:

J, 36 31 bytes

-5 bytes thanks to FrownyFrog!

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

Try it online!

How it works:

                          (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 Ivanov

Posted 2018-06-02T17:54:24.843

Reputation: 13 815

The [: can be 0 and the (22 b.) can be XOR. &.(3&u:) saves 1 byte. – FrownyFrog – 2018-06-02T22:47:23.357

@FrownyFrog Very nice golfs, thank you! You are really good! – Galen Ivanov – 2018-06-03T07:12:45.440

27 – FrownyFrog – 2018-06-03T21:09:04.680

@FrownyFrog Wow! Can you explain the use of " and $? Thanks! – Galen Ivanov – 2018-06-04T18:52:10.193

The input is done with ,:, there are 2 rows on the left side. We need "(1) but "$ works too, because it stands for "1 _. $ b.0 gives the rank of $ (monadic, dyadic left, dyadic right). – FrownyFrog – 2018-06-04T22:02:18.283

I only know 3 useful ones, "$,"{,"#:. And &> for "0 0. – FrownyFrog – 2018-06-04T22:17:41.733

3

R, 118 94 75 72 bytes

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

Try it online!

There must be a much golfier way. -43 bytes thanks to Giuseppe who pointed me to the MATL solution by Luis Mendo. TIO link contains a function solution for the same byte count.

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

Bonus: The output is a named vector whose names are the original input strings!

JayCe

Posted 2018-06-02T17:54:24.843

Reputation: 2 655

You should be able to drop a<- since you don't use a anywhere else. – Giuseppe – 2018-06-05T18:03:02.177

@Giuseppe Were you reading my mind? ;) – JayCe – 2018-06-05T18:04:48.703

3

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

Peter Cordes

Posted 2018-06-02T17:54:24.843

Reputation: 2 810

2

Python 3, 83 bytes

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

Try it online!

-3 bytes thanks to Mr. Xcoder
-3 bytes thanks to Chas Brown

HyperNeutrino

Posted 2018-06-02T17:54:24.843

Reputation: 26 575

83 bytes with a bit of bit-twiddling. – Chas Brown – 2018-06-02T19:36:56.640

@ChasBrown Oh cool, nice. Thanks! – HyperNeutrino – 2018-06-03T00:50:04.587

2

JavaScript, 77 74 73 bytes

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

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

console.log(
    f([[...'CodeGolf'],[...'xxPPCGxx']])
)

Takes an array of char arrays, outputs an array of char arrays.

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

darrylyeo

Posted 2018-06-02T17:54:24.843

Reputation: 6 214

1You can save a byte with c>{}. – Arnauld – 2018-06-03T22:10:04.587

2

k, 14 bytes

{`c$l+|x-l:_x}

Try it online! Input/output is a list of two strings.

zgrep

Posted 2018-06-02T17:54:24.843

Reputation: 1 291

2

Haskell, 78 bytes

c!d=([c..'z']++[';'..])!!sum[32|(c>'Z')/=(d>'Z')]
(#)=zipWith(!)
s%t=(s#t,t#s)

Try it online!

Lynn

Posted 2018-06-02T17:54:24.843

Reputation: 55 648

2

QBasic, 133 bytes

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$

Takes the two strings comma-separated and outputs the results newline-separated. Uses the bit-fiddling algorithm from Dennis's Jelly answer. Other than that, the main golf trick here is that the first result string is printed directly, one character at a time, which is a little shorter than saving both result strings in variables and printing them outside the loop.

DLosc

Posted 2018-06-02T17:54:24.843

Reputation: 21 213

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

Posted 2018-06-02T17:54:24.843

Reputation: 8 959

(y>'Z')*32 -> ord(y)&32 – Jonathan Allan – 2018-06-02T20:29:09.013

1

Retina, 75 bytes

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

Try it online! Explanation: The newlines are used as markers to determine how much of the string has been processed. The regex tries to match against uppercase letters or failing that any characters. If an uppercase letter was matched then the other character is uppercased otherwise it is lowercased and vice versa, while the newlines are advanced to the next character.

Neil

Posted 2018-06-02T17:54:24.843

Reputation: 95 035

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

Posted 2018-06-02T17:54:24.843

Reputation: 2 149

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 – 2018-06-08T03:48:14.300

@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 – 2018-06-08T04:04:07.243

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 – 2018-06-08T04:11:35.383

Using memory-destination xor and a tighter loop structure, my version came in at 14 bytes of x86-64 machine code. Same for count implicit-length or explicit-length strings. Its NASM source could probably be golfed down shorter than 123 bytes, too. I'm not sure which would run faster on a modern CPU like Skylake or Ryzen (Ryzen wouldn't have any extra cost for merging DH when reading DX, but SKL would need an extra cycle to insert a merging uop.)

– Peter Cordes – 2018-06-08T11:00:32.150

0

Jelly, 13 bytes

=Œu=/ị"Ɱż"Œs$

Try it online!

Also 13: =ŒuṚ×32ạŒlO$Ọ (or =ŒuṚæ«5ạŒlO$Ọ)

Jonathan Allan

Posted 2018-06-02T17:54:24.843

Reputation: 67 804

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

Posted 2018-06-02T17:54:24.843

Reputation: 95 035

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

Posted 2018-06-02T17:54:24.843

Reputation: 689

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

Posted 2018-06-02T17:54:24.843

Reputation: 4 687

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

Posted 2018-06-02T17:54:24.843

Reputation: 8 616

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.

Posted 2018-06-02T17:54:24.843

Reputation: 6 693

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

Posted 2018-06-02T17:54:24.843

Reputation: 5 369

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

Posted 2018-06-02T17:54:24.843

Reputation: 101