11
\$\begingroup\$

I can't think of a better name. This is similar to this challenge, but a lot easier.

Read three strings which contain only uppercase letters. The length of the first and second strings are the same. The second string and the third string are encrypted using Caesar cipher using the same key. The original string of the second string is the first string. You have to decrypt the third string. Obviously, there is exactly one possible original string of the third string.

You are allowed to output in any case (e.g.: lowercase, uppercase or capitalized), but the input is guaranteed to be uppercase.

Examples

AAA BBB CCC -> BBB
I U TQXXAIADXP -> HELLOWORLD
HELLO FCJJM QRPGLE -> STRING

Rule

This is , so code in the fewest bytes.

\$\endgroup\$
10
  • 8
    \$\begingroup\$ It seems like the last test case gives STRINO rather than STRING. \$\endgroup\$
    – Arnauld
    May 15 at 14:37
  • 2
    \$\begingroup\$ Can you add a test case where the letters in string 2 are sometimes before string 1 in the alphabet and sometimes after? Something like MNOP YZAB. \$\endgroup\$
    – DLosc
    May 15 at 17:14
  • 1
    \$\begingroup\$ May the key actually consist of several shift offsets as @DLosc is assuming? \$\endgroup\$
    – Arnauld
    May 15 at 18:40
  • 1
    \$\begingroup\$ @Arnauld I'm not sure what you mean by "several shift offsets." The MNOP YZAB example uses a shift of +12 (or, equivalently, -14). \$\endgroup\$
    – DLosc
    May 15 at 20:41
  • 1
    \$\begingroup\$ @int21h--GlorytoUkraine-- It is allowed \$\endgroup\$
    – None1
    May 16 at 12:37

20 Answers 20

7
\$\begingroup\$

Ruby, 31 29 bytes

-2 bytes thanks to @AZTECCO!

->a,b,c{c.tr b+w='-ZA-Z',a+w}

Attempt This Online!

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

Jelly,  13  10 bytes

-3 using transliterate as prompted by Kevin Cruijssen' answer

O_/ḢØA,ṙ¥y

A dyadic Link that accepts the known plaintext, ciphertext pair on the left and the ciphertext to be decrypted on the right and yields the plaintext.

Try it online! Or see the test-suite.

How?

O_/ḢØA,ṙ¥y - Link: [P=Plaintext, K=KnownCiphertext]; C=Ciphertext
O          - convert {[P, K]} to ordinals
 _/        - reduce by subtraction
   Ḣ       - head -> CeaserShift
    ØA     - uppercase alphabet
        ¥  - last two links as a dyad - f(Alphabet, CeaserShift)
       ṙ   -   rotate {Alphabet} left by {CeaserShift}
      ,    -   {Alphabet} pair {RotatedAlphabet} -> Mapping
         y - transliterate {C} as per {Mapping}
\$\endgroup\$
4
\$\begingroup\$

05AB1E, 12 11 10 bytes

ÇøÆнAu._Au‡

Inputs \$a,b,c\$ taken as two separated inputs in the format \$[b,a]\$ and \$c\$, where \$a\$ and \$b\$ are lists of characters.
Output as a lowercase string.

-1 byte by outputting in lowercase (OP allowed outputting in lowercase, but input is mandatory in uppercase, otherwise another byte could be saved by removing the u)

Try it online or verify all test cases.

Explanation:

Ç           # Map all inner characters of the first (implicit) input-pair to their
            # codepoint-integers
 ø          # Zip/transpose; swapping rows/columns
  Æ         # Reduce each inner pair by subtraction
   н        # Pop and leave just the first item
    Au      # Push the uppercase alphabet
      ._    # Rotate it the earlier calculated value amount towards the left
        A   # Push the lowercase alphabet
         ‡  # Transliterate all characters in the second (implicit) input
            # (after which the result is output implicitly)
\$\endgroup\$
3
\$\begingroup\$

Python, 134 115 85 bytes

  • -19 bytes thanks to @TheThonnu (converting def to lambda)
  • -30 bytes thanks to @Jitse by replacing the list comprehension
f=lambda a,b,c:c and chr((s:=ord(a[0])-ord(b[0])+ord(c[0]))+26-s//65*26)+f(a,b,c[1:])

Attempt This Online!

My first golf in Python made by translation of my R golf.

\$\endgroup\$
6
  • 1
    \$\begingroup\$ Convert into a lambda for 115 bytes \$\endgroup\$
    – The Thonnu
    May 16 at 11:54
  • 1
    \$\begingroup\$ Nice first Python golf! You don't need to iterate over a and b, and you can make it recursive for 85 bytes \$\endgroup\$
    – Jitse
    May 16 at 14:38
  • \$\begingroup\$ @Jitse a huge improvement! Would you like to post it and take the credit? \$\endgroup\$ May 16 at 14:53
  • 1
    \$\begingroup\$ this one is all yours \$\endgroup\$
    – Jitse
    May 16 at 14:55
  • \$\begingroup\$ 79 bytes you don't need to have s stored in a variable. You can use a modulo \$\endgroup\$
    – Jakque
    May 17 at 9:48
3
\$\begingroup\$

R, 68 bytes

\(L,N=Map(utf8ToInt,L),S=el(N)-N[[2]]+N[[3]])LETTERS[S-38-S%/%65*26]

Attempt This Online!

This outputs vectors of single characters:

[1] "B" "B" "B"
[1] "H" "E" "L" "L" "O" "W" "O" "R" "L" "D"
[1] "S" "T" "R" "I" "N" "G"

R, 82 70 bytes

\(L,N=Map(utf8ToInt,L),S=el(N)-N[[2]]+N[[3]])intToUtf8(S+26-S%/%65*26)

Attempt This Online!

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

Jelly, 17 bytes

O_/Ḣ+O}_65%26+65Ọ

Try It Online!

I don't think this is optimal, especially the number of bytes wasted on _65%26+65.

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

Acc!!, 120 bytes

N
Count i while N-10 {
}
N-_
Count i while N-10 {
}
_*91+N
Count i while _%91-10 {
Write (_%91-_/91+13)%26+65
_-_%91+N
}

Try it online!

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

JavaScript (Node.js), 62 bytes

(a,b,c)=>(B=Buffer)(c).map(n=>(n-13+B(a)[0]-B(b)[0])%26+65)+""

Try it online!

Or 41 bytes by using Buffers for I/O:

(a,b,c)=>c.map(n=>(n-13+a[0]-b[0])%26+65)

Try it online!

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

Perl 5 -pla, 45 bytes

$q=<>;chop$q;$_=<>;eval"y/$q-ZA-$q/@F-ZA-@F/"

Try it online!

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

Uiua SBCS, 15 bytes

+@A◿26-:-@A:-∩⊢

Try it!

\$\endgroup\$
1
  • 1
    \$\begingroup\$ 11 bytes \$\endgroup\$
    – Tbw
    May 15 at 19:26
2
\$\begingroup\$

BQN, 19 bytes

{26|𝕩+⊑-´𝕨}⌾(-⟜'A')

Takes a list of the first two strings as left argument and the third string as right argument. Try it at BQN online!

Explanation

Rough port of my FunStack solution.

{26|𝕩+⊑-´𝕨}⌾(-⟜'A')
              -⟜'A'   Subtract 'A' to convert all letters to numbers 0-25
           ⌾(      )  After applying the below function, undo that operation
{          }
         𝕨            Left argument
       -´              Fold on subtraction
      ⊑               Get first element
    𝕩+                Add to each element of right argument
 26|                  Take each element mod 26
\$\endgroup\$
1
\$\begingroup\$

APL+WIN 39 bytes

Prompts for nested vector of strings.

⎕av[n+26×66>n←∊n[3]+↑-/↑¨2↑n←(⊂⎕av)⍳¨⎕]

Try it online! Thanks to Dyalog Classic

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

FunStack alpha, 39 bytes

Plus 65 Mod 26 Plus 13 Minus Head Minus

Tested using the initial proof-of-concept version of FunStack, but should work in the GitHub version too. Try it online!

Explanation

                   Minus  # Subtract (each character of) first argument from second
                 Head     # Get the first number in the resulting list
              Minus       # Subtract that from (each character of) third argument
         Plus 13          # Add 13 to each (turning A into something that's 0 mod 26)
     Mod 26               # Take each mod 26
Plus 65                   # Add 65, turning '\0' into 'A', etc.

We save a few bytes over the more self-explanatory Plus 'A' Mod 26 Minus 'A' by staying with characters rather than converting to integers and back again.

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

Google Sheets, 85 bytes

=sort(join(,char(65+mod(code(mid(A3,sequence(len(A3)),1))-65+code(A1)-code(A2),26))))

Put the strings in cells A1:A3 and the formula in cell B1.

screenshot

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

brainfuck, 201 bytes

,>+[,----------],[-<->]++++++++[->++++++++>+++<<]+[,----------]>+>++>,[<<[-<+>>>-<<]<[->+<]<[->+>>>+<<<<]>[-<+>]>>[-<<+>>>+>+<<]>[>->+<[>]>[<+>-]<<[<]>-]<<<[->>+<<]>[->>+>>+<<<<]>>[-<<+>>]>>.[-]<[-]<,]

Try it online!

Expanded:

, string1 char1 to cell0
>+[,----------] read until newline
, string2 char1 to cell1
[-<->] [shift for string3 (=cell0-cell1) to cell0, end cell1]

++++++++[->++++++++>+++<<] [64 to cell2, 24 to cell3, end cell1]
+[,----------] [read end of line 2, end cell1]
>+>++ 65 to cell2 / 26 to cell3 / end cell3

String 3 processing loop using cell 4
| cell 0 | cell 1 | cell 2 | cell 3 | cell 4 | cell 5 | cell 6 | cell 7 | cell 8 |
| shift  | tmp    | 26     | 65 'A' | inchar | tmp    | tmp    | tmp    | tmp    |
>,[

<<[-<+>>>-<<] [65 to cell1 and subtract from cell4, end cell2]
<[->+<] [65 back to cell2, end cell1]
<[->+>>>+<<<<] [shift to cell1 and add to cell4, end cell0]
>[-<+>] [shift back to cell0, end cell1]

26 (divisor) to cell1 and cell5 and add to cell4 (to fix possible underflow) / end cell4
>>[-<<+>>>+>+<<]>

| shift | 26copy | 65 | 0 | ^char | 26      | 0       | 0 | 0 |
[>->+<[>]>[<+>-]<<[<]>-] [get char mod 26]
| shift | 26copy | 65 | 0 | ^0    | garbage | char%26 | 0 | 0 |

<<<[->>+<<] [26 back to cell3, end cell1]
>[->>+>>+<<<<] [65 to cell4 and add to cell6, end cell2]
>>[-<<+>>] [65 back to cell2, end cell4]
>>. output cell6
[-]<[-]< clear cell6 and cell5 / end cell4

,]
\$\endgroup\$
1
\$\begingroup\$

Charcoal, 19 17 bytes

⭆ζ§α⁻⌕αι⁻℅§ηκ℅§θκ

Try it online! Link is to verbose version of code. Explanation:

 ζ                  Third input
⭆                   Map over characters and join
   α                Predefined variable uppercase alphabet
  §                 Cyclically indexed by
     ⌕              Index of
       ι            Current letter in
      α             Predefined variable uppercase alphabet
    ⁻               Minus
           η        Second input
          §         Cyclically indexed by
            κ       Current index
         ℅          Take the ordinal
        ⁻           Minus
               θ    First input
              §     Cyclically indexed by
                κ   Current index
             ℅      Take the ordinal
                    Implicitly print
\$\endgroup\$
1
\$\begingroup\$

R, 51 bytes

\(A,B,C,`+`=paste0)chartr(B+"-ZA-Z",A+"-ZA-ZA-Z",C)

Attempt This Online!

Inspired by @ovs's Ruby answer. Test suite adapted from @int 21h -- Glory to Ukraine --'s R answer.

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

Python 3,  79  74 bytes

lambda p,c,e:''.join(chr((ord(p[0])-ord(c[0])+ord(x)+13)%26+65)for x in e)

An unnamed function that accepts the plaintext, p, the ciphertext of p, c, and the encrypted message, e, and returns the decrypted message.

Try it online!

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

K(ngn/k) 22 bytes

`c$65+26!{-z+*x-y}.65-

Try it here

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

Piet + ascii-piet, 60 bytes (5×12=60 codels)

tuqmkjknnfeC    m??m??lI fbnnfer  sU d n aiicccSlleqaaiiqqfa

Try Piet online!

Uses Piet's convenient i/o, where inputted characters are automatically converted to an ordinals, and outputted ordinals can be converted to characters.

Only works with a specific format of input, where the first two strings must be of length 1, each on their own line. The third string can be infinite, but each character of it must be inputted one per line. Use the link above to see a set up example.

This program terminates when no input remains.

Also, it's pretty uncommon for a Piet program to compete better than other languages such as Python and Ruby (even though neither of those are golfing languages), so I'm happy with how it turned out. I would also say there is a slight chance you can shave off 5 bytes, since there are so many black codels. Feel free to give it a try.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.