# A Capital Cipher

Your task is to decipher a non-empty string consisting of printable ASCII characters in the range [32..126].

Reading the string character per character:

• each time you encounter a letter in lowercase, associate it with the next letter in uppercase, starting with 'A'
• each time you encounter a letter in uppercase, replace it with the letter in lowercase it's associated with
• other characters do not require any special processing and are just left unchanged

## Example

For the input string "endlAsEBAEE":

• Associate e to A, n to B, d to C and l to D
• Replace A with e
• Associate s to E
• Replace EBAEE with sness

The final output is "endlessness".

## Clarifications and rules

• The input string is guaranteed to contain each lowercase letter at most once. All further instances will be replaced with the corresponding capital letter.
• The input string is guaranteed to be valid. (You will not encounter a capital letter that is not yet associated with a lowercase letter.)
• Once a capital letter has been associated to a lowercase letter, it may or may not be used later in the string. For instance, C and D are not used in the above example.
• This is , so the shortest answer in bytes wins!

## Test cases

Inputs:

abcd
honk! ABCD!
endlAsEBAEE
helCo wDrCd!
dermatoglyphics
progBamFinD AuzJles & cCdL DCKf
sphinx of black quKrtz, jOdge my vGw. K NODLM IPGZE HGF SOWBA GYVP QCV JKRX TGU.
petBr AiABD AEckBd a ABFG of AEFGlBH ABAABDs. hJw mIny AEFGLBH ABAABDM HEH ABCBD AEABD AEFG?


abcd
honk! honk!
endlessness
hello world!
dermatoglyphics
programming puzzles & code golf
sphinx of black quartz, judge my vow. a quick brown fox jumps over the lazy dog.
peter piper picked a peck of pickled peppers. how many pickled peppers did peter piper pick?

• I think the inverse of this task - encoding a string of lowercase + punctuation - would also make an interesting challenge. Jun 10, 2018 at 7:25

# Jelly, 8 7 bytes

fØaØA,y


Try it online!

### How it works

fØaØA,y  Main link. Argument: s (string)

Øa      Yield the lowercase alphabet.
f        Filter; keep only characters that appear in the lowercase alphabet.
Call the result r.
ØA    Yield the uppercase alphabet (u).
,   Pair; yield [u, r].
y  Translate s, using the substitutions in [u, r].


# 05AB1E, 6 bytes

Code:

AÃAus‡


Uses the 05AB1E encoding. Try it online!

• Your answers put me to shame usually ʒ.l}Aus‡. Jun 12, 2018 at 18:06

# JavaScript (ES6), 62 bytes

s=>s.replace(/[A-Z]/g,c=>s.match(/[a-z]/g)[parseInt(c,36)-10])


Each capital letter is converted to its base 36 value, less 10.

We then match on the lowercase letter that's at that index.

let f=

s=>s.replace(/[A-Z]/g,c=>s.match(/[a-z]/g)[parseInt(c,36)-10])

console.log(f('abcd'))
console.log(f('endlAsEBAEE'))
console.log(f('helCo wDrCd!'))
console.log(f('progBamFinD AuzJles & cCdL DCKf'))
console.log(f('sphinx of black quKrtz, jOdge my vGw. K NODLM IPGZE HGF SOWBA GYVP QCV JKRX TGU.'))
console.log(f('petBr AiABD AEckBd a ABFG of AEFGlBH ABAABDs. hJw mIny AEFGLBH ABAABDM HEH ABCBD AEABD AEFG?'))

# Pyth, 36 bytes

JKr1GVQI&}NG!}NH=XHNhK=tK)p?}NJ@_HNN


Try it here

### Explanation

JKr1GVQI&}NG!}NH=XHNhK=tK)p?}NJ@_HNN
JKr1G                                  Let J and K be the uppercase alphabet.
VQ                                For each character in the input...
I&}NG!}NH         )             ... if the character is lowercase and not
yet in H, ...
=XHNhK                 ... add the letter and the next uppercase
letter to H...
=tK              ... and move to the next uppercase letter.
p?}NJ@_HNN   Print either the next character or the
letter it represents.


# Stax, 11 bytes

Ñ·í=Üò°f1èb


Run and debug it

# R, 79 bytes

function(x){s=utf8ToInt(x)
s[j]=s[s>96&s<123][s[j<-s>64&s<91]-64]
intToUtf8(s)}


Try it online!

• Very nice ! You can probably save a few bytes by using scan(,""  to make it a full program instead of a function, apart from that I am struggling to find any improvement... Jun 11, 2018 at 1:09

## Perl 5 with -p, 27 bytes

eval"y/A-Z/".y/a-z//cdr."/"


Try it online!

• Save a couple of bytes by replacing the s///gr with y///cdr. Jun 10, 2018 at 23:09
• @breadbox of course, thank you! Jun 11, 2018 at 15:26

# Z80Golf, 37 bytes

00000000: 2505 cd03 8030 0176 fe7b 300c fe61 3011  %....0.v.{0..a0.
00000010: fe5b 3004 fe41 3003 ff18 e7d6 414f 0a18  .[0..A0.....AO..
00000020: f777 2318 f3                             .w#..


Try it online!

z80 does pretty good at this! Here is a disassembly:

  dec h         ; HL = cipher write pointer
dec b         ; BC = cipher read pointer
; meaning of 'A'..'Z' is written to $ff00~$ff19
next:
call $8003 ; getchar jr nc, ok ; not EOF? halt ok: cp '{' jr nc, other ; a ≥ '{' cp 'a' jr nc, lower ; 'a' ≤ a ≤ 'z' cp '[' jr nc, other ; '[' ≤ a ≤ '' cp 'A' jr nc, upper ; 'A' ≤ a ≤ 'Z' other: rst$38
jr next
upper:
sub 'A'
ld c, a
ld a, (bc)
jr other
lower:
ld (hl), a
inc hl
jr other


We point both HL and BC at the $ff00 range with dec, and use rst$38 as a short alternative to call $8000, but otherwise there isn't much trickery going on. # Retina, 25 bytes ~["TL"|""L$[a-z]
$&-$&


Try it online! Explanation:

[a-z]


Match lowercase letters.

$$&-\$&


Replace each letter with a degenerate range of itself. (This prevents the later transliteration from treating it as a character class; backslash can't be used because some lower case letters have a special meaning after a backslash.)

["TL"|""L


List the degenerate ranges, but without line separators, and with a preceding TL.

~


Evaluate the resulting transliteration program on the original input.

# Python 2, 78 bytes

lambda s:''.join('@'<c<'['and filter(str.islower,s)[ord(c)-65]or c for c in s)


Try it online!

# Java (JDK 10), 109 bytes

s->{var r=s.replaceAll("[^a-z]","");for(char i=64;i++<64+r.length();)s=s.replace(i,r.charAt(i-65));return s;}


Try it online!

# C (gcc), 105 bytes

C;f(char*Z){for(char*z=--Z,c,*s;c=*++z;putchar(c))for(C=64,s=Z;*z>64&91>*z&&C^*z;c=*s)C+=*++s>96&*s<123;}


Try it online!

# Jelly, 11 bytes

ØAi
Çị¥¹Ç?€


Try it online!

# Pyth, 7 bytes

XQr1G@G
`

All testcases.