Trifid Cipher (without keyword)
Charcoal, 39 bytes
≔E⁺θ× ¬﹪Lθ³⌕βιθ⭆⪪E⁺÷θ⁹⁺÷θ³θ﹪鳦³§⁺β ↨³ι
Try it online! Link is to verbose version of code. Explanation:
≔ Assign
θ Input string
⁺ Concatenated with
Literal space
× Repeated
θ Input string
L Length
﹪ Modulo
³ Literal 3
¬ Logical not
E Mapped over characters
ι Current character
⌕ Position found in
β Lowercase alphabet
θ To variable
θ List of positions
÷ Vectorised integer divide by
⁹ Literal 9
⁺ Concatenated with
θ List of positions
÷ Vectorised integer divide by
³ Literal 3
⁺ Concatenated with
θ List of positions
E Map over values
ι Current value
﹪ Modulo
³ Literal 3
⪪ Split into
³ Groups of 3
⭆ Map over groups and join
β Lowercase alphabet
⁺ Concatenated with
Literal space
§ Cyclically indexed by
ι Current group
↨ Converted from
³ Base 3
Implicitly print
Python 2, 180 176 174 165 163 bytes
lambda s:''.join(chr(32+(33+a*9+3*b+c)%59)for a,b,c in zip(*[iter(sum(zip(*[(c/9,c/3%3,c%3)for c in map(o,s+' '[len(s)%3:])]),()))]*3))
o=lambda c:(ord(c)%32-1)%27
Try it online!
Input can be upper or lower. Output is uppercase
Pyth, 34 33 bytes
m@+G;id3csCmtj+27x+G;d3+W!%lz3zd3
Full program. Input is expected as lowercase, output is a character array. Try it online here, or verify all test cases at once here.
m@+G;id3csCmtj+27x+G;d3+W!%lz3zd3 Implicit: z=input(), d=" ", G=lowercase alphabet
lz Length of z
% 3 The above, mod 3
W! If the above != 3...
+ zd ... append a space to z
m Map the elements of the above, as d, using:
+G; Append a space to the lowercase alphabet
x d Find the 0-based index of d in the above
+27 Add 27 to the above
j 3 Convert to base 3
t Discard first element (undoes the +27, ensures result is 3 digits long)
C Transpose the result of the map
s Flatten
c 3 Split into chunks of length 3
m Map the elements of the above, as d, using:
id3 Convert to decimal from base 3
@+G; Index the above number into the alphabet + space
Implicit print
Alternative 34 byte solution: sm@+G;id3csCm.[03jx+G;d3+W!%lz3zd3
- rather than +27 and tail, uses .[03
to pad with 0 to length 3. Can be 33 if the leading s
is dropped.
Edit: saved a byte by dropping leading s
as character arrays are valid output