15
\$\begingroup\$

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! abrAcAdABCA 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? 

Answers:

abcd honk! honk! abracadabra 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? 
\$\endgroup\$
1
  • 1
    \$\begingroup\$ I think the inverse of this task - encoding a string of lowercase + punctuation - would also make an interesting challenge. \$\endgroup\$ Commented Jun 10, 2018 at 7:25

14 Answers 14

8
\$\begingroup\$

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]. 
\$\endgroup\$
4
\$\begingroup\$

05AB1E, 6 bytes

Code:

AÃAus‡ 

Uses the 05AB1E encoding. Try it online!

\$\endgroup\$
1
  • \$\begingroup\$ Your answers put me to shame usually ʒ.l}Aus‡. \$\endgroup\$ Commented Jun 12, 2018 at 18:06
3
\$\begingroup\$

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('abrAcAdABCA')) 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?'))

\$\endgroup\$
2
\$\begingroup\$

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. 
\$\endgroup\$
2
\$\begingroup\$

Stax, 11 bytes

Ñ·í=Üò°f1èb 

Run and debug it

\$\endgroup\$
2
\$\begingroup\$

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!

\$\endgroup\$
1
  • \$\begingroup\$ 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... \$\endgroup\$ Commented Jun 11, 2018 at 1:09
2
\$\begingroup\$

Perl 5 with -p, 27 bytes

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

Try it online!

-2 bytes thanks to @breadbox!

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

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.

\$\endgroup\$
1
\$\begingroup\$

Retina, 25 bytes

~["T`L`"|""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.)

["T`L`"|""L 

List the degenerate ranges, but without line separators, and with a preceding T`L`.

~ 

Evaluate the resulting transliteration program on the original input.

\$\endgroup\$
0
1
\$\begingroup\$

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!

\$\endgroup\$
1
\$\begingroup\$

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!

\$\endgroup\$
1
\$\begingroup\$

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!

\$\endgroup\$
0
\$\begingroup\$

Jelly, 11 bytes

ØAi Çị¥¹Ç?€ 

Try it online!

\$\endgroup\$
0
\$\begingroup\$

Pyth, 7 bytes

Fork of Dennis' brilliant Jelly answer

XQr1G@G 

All testcases.

\$\endgroup\$

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.