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.

You are allowed to use any unambiguous I/O format, including strings, string arrays, integer arrays.

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
    Commented 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
    Commented May 15 at 17:14
  • 1
    \$\begingroup\$ May the key actually consist of several shift offsets as @DLosc is assuming? \$\endgroup\$
    – Arnauld
    Commented 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
    Commented May 15 at 20:41
  • 1
    \$\begingroup\$ @int21h--GlorytoUkraine-- It is allowed \$\endgroup\$
    – None1
    Commented May 16 at 12:37

22 Answers 22

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
  • 2
    \$\begingroup\$ Convert into a lambda for 115 bytes \$\endgroup\$
    – The Thonnu
    Commented May 16 at 11:54
  • 2
    \$\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
    Commented May 16 at 14:38
  • 1
    \$\begingroup\$ @Jitse a huge improvement! Would you like to post it and take the credit? \$\endgroup\$ Commented May 16 at 14:53
  • 1
    \$\begingroup\$ this one is all yours \$\endgroup\$
    – Jitse
    Commented May 16 at 14:55
  • 2
    \$\begingroup\$ @Jakque thank you, but this is getting too similar to another Python golf here... maybe I can adapt your suggestion into my R answer. \$\endgroup\$ Commented May 17 at 13:29
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
    Commented 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\$

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\$
1
\$\begingroup\$

FunStack alpha, 39 34 bytes

Mod 26Plus'A'!tuck Head Minus!tuck

Works in version 0.0.3. The TIO link is to the initial proof-of-concept version of FunStack, where the same thing works as long as all tokens are separated with spaces. Try it online!

Explanation

Capitalized words like Mod push a function on the stack. Literals like 26 or 'A' bind an argument to the top function on the stack. The stack command !tuck inserts a copy of the top stack element below the second-from-top stack element.

After all these commands are executed, the stack contains six functions, which are then composed and applied to the argument:

                     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 'A'          # Add 65 to each and convert to numbers
      Mod 26                # Take each mod 26
Plus 'A'                    # Add 65 and convert back to characters

We save a few bytes over the more self-explanatory Plus 'A' Mod 26 Minus 'A' by adding 'A' twice. Since the charcode of 'A' is 65, which is congruent to 13 mod 26, adding it has the same result as subtracting it.

\$\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\$
0
\$\begingroup\$

Nibbles, 23 nibbles (11.5 bytes)

+'A'.+-/$$/@$+13_%$26

Takes the three strings as command-line arguments. Attempt This Online!

Explanation

Observe that the ASCII code of A is 65, which is congruent to 13 mod 26; thus, converting a character A-Z to 0-25 and taking it mod 26 is equivalent to adding 13 and taking it mod 26.

It was a bit annoying to work around the fact that + and * are the only arithmetic operations in Nibbles that work element-wise on lists.

+'A'.+-/$$/@$+13_%$26
        $              # First string
       / $             # Get first character
           @           # Second string
          / $          # Get first character
      -                # Subtract
                _      # Third string
             +13       # Add 13 to each character
     +                 # Add the difference calculated earlier
    .                  # Map to each:
                 %$26  #  Mod 26
+'A'                   # Add 'A' to each, converting from numbers back to letters
\$\endgroup\$
0
\$\begingroup\$

Python 3, 36 bytes

Requires the numpy package.

It is a lambda that accepts three numpy arrays of integers as the input, and returns a numpy array of integer as the output. Using numpy is a clever way to do batch operations.

k=lambda a,b,c:(c-(b-a)[0]+13)%26+65

Run all test cases

\$\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.