g | x | w | all
Bytes Lang Time Link
036Python 3 + numpy240528T131301ZNone1
041Python 3.8 prerelease250130T235457ZV_R
034FunStack alpha240515T173852ZDLosc
nanNibbles240525T154935ZDLosc
nanPiet + asciipiet240520T213447ZSanguine
022Kngn/k240517T033351Zakamayu
074Python 3240516T181554ZJonathan
068R240515T182732Zint 21h
085Python240516T111305Zint 21h
01005AB1E240516T065855ZKevin Cr
010Jelly240515T161907ZJonathan
051R240516T120558Zpajonk
017Charcoal240515T150201ZNeil
201brainfuck240515T221719Zengineer
029Ruby240515T150829Zovs
085Google Sheets240515T201952Zdoubleun
019BQN240515T180437ZDLosc
015Uiua SBCS240515T170400Zchunes
039APL+WIN240515T163841ZGraham
045Perl 5 pla240515T163108ZXcali
062JavaScript Node.js240515T144214ZArnauld
120Acc!!240515T160705ZMukundan
017Jelly240515T144116Zhyperneu

Python 3 + numpy, 36 bytes

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

Python 3.8 (pre-release), 41 bytes

Inputs and outputs are lists of integers, with 0 for A and 25 for Z.

lambda a,b,d:[(x-b[0]+a[0])%26for x in d]

Try it online!

The question says lists of integers are fine for I/O, but if we want lists of strings it's 67 bytes.

Python 3.8 (pre-release), 67 bytes

lambda a,b,d:[chr((ord(x)-ord(b[0])+ord(a[0])-65)%26+65)for x in d]

Try it online!

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.

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

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.

K(ngn/k) 22 bytes

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

Try it here

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!

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!

Python, 134 115 85 bytes

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.

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)

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}

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.

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

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

,]

Ruby, 31 29 bytes

-2 bytes thanks to @AZTECCO!

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

Attempt This Online!

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

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

Uiua SBCS, 15 bytes

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

Try it!

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

Perl 5 -pla, 45 bytes

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

Try it online!

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!

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!

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.