Trifid Cipher (without keyword)











up vote
15
down vote

favorite
1












Introduction:



I have loads of different ciphers stored in a document I once compiled as a kid, I picked a few of the ones I thought were best suitable for challenges (not too trivial, and not too hard) and transformed them into challenges. Most of them are still in the sandbox, and I'm not sure yet whether I'll post all of them, or only a few. Here is the second one (the Computer Cipher was the first one I posted).





For the Trifid Cipher (without using a keyword) the alphabet (and an additional wildcard) is divided into three 3 by 3 tables:



table 1:     table 2:     table 3:
|1 2 3 |1 2 3 |1 2 3
-+----- -+----- -+-----
1|a b c 1|j k l 1|s t u
2|d e f 2|m n o 2|v w x
3|g h i 3|p q r 3|y z


A text we want to encipher is first character by character encoded into table-row-column numbers. For example, the text this is a trifid cipher becomes:



        t h i s   i s   a   t r i f i d   c i p h e r
table: 3 1 1 3 3 1 3 3 1 3 3 2 1 1 1 1 3 1 1 2 1 1 2
row: 1 3 3 1 3 3 1 3 1 3 1 3 3 2 3 2 3 1 3 3 3 2 3
column: 2 2 3 1 3 3 1 3 1 3 2 3 3 3 3 1 3 3 3 1 2 2 3


We then put everything after one another row by row in the table above in groups of three:



311 331 331 332 111 131 121 121 331 331 313 133 232 313 332 322 313 313 132 333 313 331 223


And those are transformed back to characters using the same tables:



s   y   y   z   a   g   d   d   y   y   u   i   q   u   z   w   u   u   h       u   y   o


One thing to note, the input-length should be coprime to 3. So if the length is a multiple of 3, we append one or two trailing spaces to make the input-length not a multiple 3 anymore.



Challenge:



Given a string sentence_to_encipher, encipher it as described above.



You only have to encipher given the sentence_to_encipher, so no need to create a deciphering program/function as well. I might make a part 2 challenge for the deciphering in the future however (although I have the feeling it's to trivial/similar to the enciphering process).



Challenge rules:




  • You can assume the sentence_to_encipher will only contain letters and spaces.

  • You can use either full lowercase or full uppercase (please state which one you've used in your answer).

  • You can choose to append either one or two trailing spaces when the input-length is 3 to make it not a multiple of 3 anymore.

  • I/O is flexible. Both input and output can be a string, list/array/stream of characters, etc.


General rules:




  • This is code-golf, so shortest answer in bytes wins.

    Don't let code-golf languages discourage you from posting answers with non-codegolfing languages. Try to come up with an as short as possible answer for 'any' programming language.


  • Standard rules apply for your answer with default I/O rules, so you are allowed to use STDIN/STDOUT, functions/method with the proper parameters and return-type, full programs. Your call.


  • Default Loopholes are forbidden.

  • If possible, please add a link with a test for your code (i.e. TIO).

  • Also, adding an explanation for your answer is highly recommended.


Test cases:



Input:            "this is a trifid cipher"
Output: "syyzagddyyuiquzwuuh uyo"

Input: "test"
Output: "utbk"

Input: "output"
Possible outputs: "rrvgivx" (one space) or "rrzcc lr" (two spaces)

Input: "trifidcipher"
Possible output: "vabbuxlzz utr" (one space) or "vabbyzv rx ie " (two spaces)









share|improve this question
























  • I read that as "without keyboard". That was going to be a delightful challenge!
    – Cort Ammon
    7 hours ago






  • 1




    Why should the input's length be coprime to 3? I don't see how that matters here.
    – Nic Hartley
    7 hours ago










  • The coprime requirement isn't necessary to make the cipher work, but it does make it very slightly more secure by ensuring the groups of three digits will not line up with the row divisions of the initial digit list.
    – Sparr
    4 hours ago















up vote
15
down vote

favorite
1












Introduction:



I have loads of different ciphers stored in a document I once compiled as a kid, I picked a few of the ones I thought were best suitable for challenges (not too trivial, and not too hard) and transformed them into challenges. Most of them are still in the sandbox, and I'm not sure yet whether I'll post all of them, or only a few. Here is the second one (the Computer Cipher was the first one I posted).





For the Trifid Cipher (without using a keyword) the alphabet (and an additional wildcard) is divided into three 3 by 3 tables:



table 1:     table 2:     table 3:
|1 2 3 |1 2 3 |1 2 3
-+----- -+----- -+-----
1|a b c 1|j k l 1|s t u
2|d e f 2|m n o 2|v w x
3|g h i 3|p q r 3|y z


A text we want to encipher is first character by character encoded into table-row-column numbers. For example, the text this is a trifid cipher becomes:



        t h i s   i s   a   t r i f i d   c i p h e r
table: 3 1 1 3 3 1 3 3 1 3 3 2 1 1 1 1 3 1 1 2 1 1 2
row: 1 3 3 1 3 3 1 3 1 3 1 3 3 2 3 2 3 1 3 3 3 2 3
column: 2 2 3 1 3 3 1 3 1 3 2 3 3 3 3 1 3 3 3 1 2 2 3


We then put everything after one another row by row in the table above in groups of three:



311 331 331 332 111 131 121 121 331 331 313 133 232 313 332 322 313 313 132 333 313 331 223


And those are transformed back to characters using the same tables:



s   y   y   z   a   g   d   d   y   y   u   i   q   u   z   w   u   u   h       u   y   o


One thing to note, the input-length should be coprime to 3. So if the length is a multiple of 3, we append one or two trailing spaces to make the input-length not a multiple 3 anymore.



Challenge:



Given a string sentence_to_encipher, encipher it as described above.



You only have to encipher given the sentence_to_encipher, so no need to create a deciphering program/function as well. I might make a part 2 challenge for the deciphering in the future however (although I have the feeling it's to trivial/similar to the enciphering process).



Challenge rules:




  • You can assume the sentence_to_encipher will only contain letters and spaces.

  • You can use either full lowercase or full uppercase (please state which one you've used in your answer).

  • You can choose to append either one or two trailing spaces when the input-length is 3 to make it not a multiple of 3 anymore.

  • I/O is flexible. Both input and output can be a string, list/array/stream of characters, etc.


General rules:




  • This is code-golf, so shortest answer in bytes wins.

    Don't let code-golf languages discourage you from posting answers with non-codegolfing languages. Try to come up with an as short as possible answer for 'any' programming language.


  • Standard rules apply for your answer with default I/O rules, so you are allowed to use STDIN/STDOUT, functions/method with the proper parameters and return-type, full programs. Your call.


  • Default Loopholes are forbidden.

  • If possible, please add a link with a test for your code (i.e. TIO).

  • Also, adding an explanation for your answer is highly recommended.


Test cases:



Input:            "this is a trifid cipher"
Output: "syyzagddyyuiquzwuuh uyo"

Input: "test"
Output: "utbk"

Input: "output"
Possible outputs: "rrvgivx" (one space) or "rrzcc lr" (two spaces)

Input: "trifidcipher"
Possible output: "vabbuxlzz utr" (one space) or "vabbyzv rx ie " (two spaces)









share|improve this question
























  • I read that as "without keyboard". That was going to be a delightful challenge!
    – Cort Ammon
    7 hours ago






  • 1




    Why should the input's length be coprime to 3? I don't see how that matters here.
    – Nic Hartley
    7 hours ago










  • The coprime requirement isn't necessary to make the cipher work, but it does make it very slightly more secure by ensuring the groups of three digits will not line up with the row divisions of the initial digit list.
    – Sparr
    4 hours ago













up vote
15
down vote

favorite
1









up vote
15
down vote

favorite
1






1





Introduction:



I have loads of different ciphers stored in a document I once compiled as a kid, I picked a few of the ones I thought were best suitable for challenges (not too trivial, and not too hard) and transformed them into challenges. Most of them are still in the sandbox, and I'm not sure yet whether I'll post all of them, or only a few. Here is the second one (the Computer Cipher was the first one I posted).





For the Trifid Cipher (without using a keyword) the alphabet (and an additional wildcard) is divided into three 3 by 3 tables:



table 1:     table 2:     table 3:
|1 2 3 |1 2 3 |1 2 3
-+----- -+----- -+-----
1|a b c 1|j k l 1|s t u
2|d e f 2|m n o 2|v w x
3|g h i 3|p q r 3|y z


A text we want to encipher is first character by character encoded into table-row-column numbers. For example, the text this is a trifid cipher becomes:



        t h i s   i s   a   t r i f i d   c i p h e r
table: 3 1 1 3 3 1 3 3 1 3 3 2 1 1 1 1 3 1 1 2 1 1 2
row: 1 3 3 1 3 3 1 3 1 3 1 3 3 2 3 2 3 1 3 3 3 2 3
column: 2 2 3 1 3 3 1 3 1 3 2 3 3 3 3 1 3 3 3 1 2 2 3


We then put everything after one another row by row in the table above in groups of three:



311 331 331 332 111 131 121 121 331 331 313 133 232 313 332 322 313 313 132 333 313 331 223


And those are transformed back to characters using the same tables:



s   y   y   z   a   g   d   d   y   y   u   i   q   u   z   w   u   u   h       u   y   o


One thing to note, the input-length should be coprime to 3. So if the length is a multiple of 3, we append one or two trailing spaces to make the input-length not a multiple 3 anymore.



Challenge:



Given a string sentence_to_encipher, encipher it as described above.



You only have to encipher given the sentence_to_encipher, so no need to create a deciphering program/function as well. I might make a part 2 challenge for the deciphering in the future however (although I have the feeling it's to trivial/similar to the enciphering process).



Challenge rules:




  • You can assume the sentence_to_encipher will only contain letters and spaces.

  • You can use either full lowercase or full uppercase (please state which one you've used in your answer).

  • You can choose to append either one or two trailing spaces when the input-length is 3 to make it not a multiple of 3 anymore.

  • I/O is flexible. Both input and output can be a string, list/array/stream of characters, etc.


General rules:




  • This is code-golf, so shortest answer in bytes wins.

    Don't let code-golf languages discourage you from posting answers with non-codegolfing languages. Try to come up with an as short as possible answer for 'any' programming language.


  • Standard rules apply for your answer with default I/O rules, so you are allowed to use STDIN/STDOUT, functions/method with the proper parameters and return-type, full programs. Your call.


  • Default Loopholes are forbidden.

  • If possible, please add a link with a test for your code (i.e. TIO).

  • Also, adding an explanation for your answer is highly recommended.


Test cases:



Input:            "this is a trifid cipher"
Output: "syyzagddyyuiquzwuuh uyo"

Input: "test"
Output: "utbk"

Input: "output"
Possible outputs: "rrvgivx" (one space) or "rrzcc lr" (two spaces)

Input: "trifidcipher"
Possible output: "vabbuxlzz utr" (one space) or "vabbyzv rx ie " (two spaces)









share|improve this question















Introduction:



I have loads of different ciphers stored in a document I once compiled as a kid, I picked a few of the ones I thought were best suitable for challenges (not too trivial, and not too hard) and transformed them into challenges. Most of them are still in the sandbox, and I'm not sure yet whether I'll post all of them, or only a few. Here is the second one (the Computer Cipher was the first one I posted).





For the Trifid Cipher (without using a keyword) the alphabet (and an additional wildcard) is divided into three 3 by 3 tables:



table 1:     table 2:     table 3:
|1 2 3 |1 2 3 |1 2 3
-+----- -+----- -+-----
1|a b c 1|j k l 1|s t u
2|d e f 2|m n o 2|v w x
3|g h i 3|p q r 3|y z


A text we want to encipher is first character by character encoded into table-row-column numbers. For example, the text this is a trifid cipher becomes:



        t h i s   i s   a   t r i f i d   c i p h e r
table: 3 1 1 3 3 1 3 3 1 3 3 2 1 1 1 1 3 1 1 2 1 1 2
row: 1 3 3 1 3 3 1 3 1 3 1 3 3 2 3 2 3 1 3 3 3 2 3
column: 2 2 3 1 3 3 1 3 1 3 2 3 3 3 3 1 3 3 3 1 2 2 3


We then put everything after one another row by row in the table above in groups of three:



311 331 331 332 111 131 121 121 331 331 313 133 232 313 332 322 313 313 132 333 313 331 223


And those are transformed back to characters using the same tables:



s   y   y   z   a   g   d   d   y   y   u   i   q   u   z   w   u   u   h       u   y   o


One thing to note, the input-length should be coprime to 3. So if the length is a multiple of 3, we append one or two trailing spaces to make the input-length not a multiple 3 anymore.



Challenge:



Given a string sentence_to_encipher, encipher it as described above.



You only have to encipher given the sentence_to_encipher, so no need to create a deciphering program/function as well. I might make a part 2 challenge for the deciphering in the future however (although I have the feeling it's to trivial/similar to the enciphering process).



Challenge rules:




  • You can assume the sentence_to_encipher will only contain letters and spaces.

  • You can use either full lowercase or full uppercase (please state which one you've used in your answer).

  • You can choose to append either one or two trailing spaces when the input-length is 3 to make it not a multiple of 3 anymore.

  • I/O is flexible. Both input and output can be a string, list/array/stream of characters, etc.


General rules:




  • This is code-golf, so shortest answer in bytes wins.

    Don't let code-golf languages discourage you from posting answers with non-codegolfing languages. Try to come up with an as short as possible answer for 'any' programming language.


  • Standard rules apply for your answer with default I/O rules, so you are allowed to use STDIN/STDOUT, functions/method with the proper parameters and return-type, full programs. Your call.


  • Default Loopholes are forbidden.

  • If possible, please add a link with a test for your code (i.e. TIO).

  • Also, adding an explanation for your answer is highly recommended.


Test cases:



Input:            "this is a trifid cipher"
Output: "syyzagddyyuiquzwuuh uyo"

Input: "test"
Output: "utbk"

Input: "output"
Possible outputs: "rrvgivx" (one space) or "rrzcc lr" (two spaces)

Input: "trifidcipher"
Possible output: "vabbuxlzz utr" (one space) or "vabbyzv rx ie " (two spaces)






code-golf string cipher encoding






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited 11 hours ago

























asked 17 hours ago









Kevin Cruijssen

35.2k554185




35.2k554185












  • I read that as "without keyboard". That was going to be a delightful challenge!
    – Cort Ammon
    7 hours ago






  • 1




    Why should the input's length be coprime to 3? I don't see how that matters here.
    – Nic Hartley
    7 hours ago










  • The coprime requirement isn't necessary to make the cipher work, but it does make it very slightly more secure by ensuring the groups of three digits will not line up with the row divisions of the initial digit list.
    – Sparr
    4 hours ago


















  • I read that as "without keyboard". That was going to be a delightful challenge!
    – Cort Ammon
    7 hours ago






  • 1




    Why should the input's length be coprime to 3? I don't see how that matters here.
    – Nic Hartley
    7 hours ago










  • The coprime requirement isn't necessary to make the cipher work, but it does make it very slightly more secure by ensuring the groups of three digits will not line up with the row divisions of the initial digit list.
    – Sparr
    4 hours ago
















I read that as "without keyboard". That was going to be a delightful challenge!
– Cort Ammon
7 hours ago




I read that as "without keyboard". That was going to be a delightful challenge!
– Cort Ammon
7 hours ago




1




1




Why should the input's length be coprime to 3? I don't see how that matters here.
– Nic Hartley
7 hours ago




Why should the input's length be coprime to 3? I don't see how that matters here.
– Nic Hartley
7 hours ago












The coprime requirement isn't necessary to make the cipher work, but it does make it very slightly more secure by ensuring the groups of three digits will not line up with the row divisions of the initial digit list.
– Sparr
4 hours ago




The coprime requirement isn't necessary to make the cipher work, but it does make it very slightly more secure by ensuring the groups of three digits will not line up with the row divisions of the initial digit list.
– Sparr
4 hours ago










10 Answers
10






active

oldest

votes

















up vote
5
down vote














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





share|improve this answer






























    up vote
    5
    down vote














    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






    share|improve this answer






























      up vote
      5
      down vote













      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






      share|improve this answer






























        up vote
        4
        down vote














        Jelly, 29 26 25 bytes



        ⁶Øa;3ṗ¤,©Ṛy;⁶$L3ḍƊ¡ZFs3®y


        Try it online!



        How it works



        ⁶Øa;3ṗ¤,©Ṛy;⁶$L3ḍƊ¡ZFs3®y  Main link. Argument: s (string)

        ⁶ Set the return value to space.
        Øa; Append it to "a...z".
        3ṗ¤ Yield the third Cartesian power of [1, 2, 3].
        ,© Pair the results and store the pair in the register.
        The register now holds
        [[[1, 1, 1], ..., [3, 3, 3]], ['a', ... ,'z', ' '].
        Ṛ Reverse the outer array.
        ;⁶$ Append a space to s...
        L3ḍƊ¡ if the length is divisible by 3.
        y Transliterate according to the mapping to the left.
        ZFs3 Zip/transpose, flatten, split into chunks of length 3.
        ®y Transliterate according to the mapping in the register.





        share|improve this answer























        • I never know the rules about side-effect outputs... but the arrangement ;L3ḍƊ¡⁶µ⁶Øa;3ṗ¤,ðṚyZFs3⁸y can do away with the µ if it's acceptable for 24.
          – Jonathan Allan
          6 hours ago










        • We have a weak consensus (+6/-1) that this is allowed, so thanks!
          – Dennis
          5 hours ago










        • The output appears to be incorrect. I don't think the appended space "sticks".
          – Dennis
          5 hours ago


















        up vote
        3
        down vote














        Ruby, 153 145 138 131 bytes





        ->a{a<<" "if a.size%3<1;a.map{|c|[(b=(c.ord%32-1)%27)/9,b%9/3,b%3]}.transpose.join.scan(/.{3}/).map{|x|((x.to_i(3)+65)%91+32).chr}}


        Try it online!



        A quick and naive approach, works with lowercase text. Inputs and outputs arrays of characters.






        share|improve this answer






























          up vote
          2
          down vote













          APL+WIN, 102 bytes



          ⎕av[n[c⍳(⊂[2]((⍴t),3)⍴,⍉⊃(c←⊂[2]c,(,⍉9 3⍴c←9/⍳3),[1.1]27⍴⍳3)[(⎕av[n←(97+⍳26),33])⍳t←t,(3|⍴t←⎕)↓' '])]]


          Explanation:



          t←t,(3|⍴t←⎕)↓' ' Prompts for input and applies coprime condition

          (⎕av[n←(97+⍳26),33]⍳ Indices of characters in APL atomic vector

          c←⊂[2]c,(,⍉9 3⍴c←9/⍳3),[1.1]27⍴⍳3) Create a matrix of table, row column for 27 characters

          ⊂[2]((⍴t),3)⍴,⍉⊃ Extract columns of c corresponding to input and re-order

          c⍳ Identify Column indices of re-ordered columns

          ⎕av[.....] Use indices back in atomic vector to give enciphered text


          Example of screen shot of test case:



          ⎕av[n[c⍳(⊂[2]((⍴t),3)⍴,⍉⊃(c←⊂[2]c,(,⍉9 3⍴c←9/⍳3),[1.1]27⍴⍳3)[(⎕av[n←(97+⍳26),33])⍳t←t,(3|⍴t←⎕)↓' '])]]
          ⎕:
          'output'
          rrvgivx





          share|improve this answer























          • Would you mind adding a screenshot of (one or multiple of) the test cases? I know the WIN APL version isn't available on TIO, but I'd still like to see some kind of verification, since I barely know how to interpret APL code by just reading it, let alone verifying it without running. :)
            – Kevin Cruijssen
            12 hours ago










          • Not quite sure how to do that but this is what it would look like. I will add something to entry above
            – Graham
            11 hours ago












          • Normally I can use Dyalog Classic in TIO but in this case its atomic vector is in a different order so the indexing will not work.
            – Graham
            11 hours ago


















          up vote
          2
          down vote














          Java (JDK), 192 bytes





          s->{String T="",R=T,C=T,r=T;for(int c:s){c-=c<33?6:97;T+=c/9;R+=c%9/3;C+=c%3;}for(var S:(s.length%3<1?T+2+R+2+C+2:T+R+C).split("(?<=\G...)"))r+=(char)((Byte.valueOf(S,3)+65)%91+32);return r;}


          Try it online!



          Very naive approach. Takes a lowercase char as input but outputs a String.



          Explanations



          s->{                                       // char-accepting lambda
          String T="", // declare variables Table as an empty string,
          R=T, // Row as an empty string,
          C=T, // Column as an empty string,
          r=T; // result as an empty string.
          for(int c:s){ // for each character
          c-=c<33?6:97; // map each letter to a number from 0 to 25, space to 26.
          T+=c/9; // append the table-value to Table
          R+=c%9/3; // append the row-value to Row
          C+=c%3; // append the column-value to Column
          } //
          for(var S: // For each token of...
          (s.length%3<1?T+2+R+2+C+2:T+R+C) // a single string out of table, row and column and take the space into account if the length is not coprime to 3...
          .split("(?<=\G...)")) // split every 3 characters
          r+=(char)((Byte.valueOf(S,3)+65)%91+32); // Parses each 3-characters token into a number, using base 3,
          // and make it a letter or a space
          return r; // return the result
          }


          Credits




          • -14 bytes thanks to Kevin Cruijssen






          share|improve this answer



















          • 1




            Two small golfs: Integer.valueOf to Byte.valueOf and R+=c<26?(char)(c+97):' '; to R+=(char)(c<26?c+97:32);
            – Kevin Cruijssen
            14 hours ago






          • 1




            202 bytes
            – Kevin Cruijssen
            13 hours ago


















          up vote
          2
          down vote














          R, 145 bytes





          function(s,K=array(c(97:122,32),rep(3,3)))intToUtf8(K[matrix(arrayInd(match(c(utf8ToInt(s),32[!nchar(s)%%3]),K),dim(K))[,3:1],,3,byrow=T)[,3:1]])


          Try it online!



          I/O as strings; adds one space. The strange repetition of [,3:1] is because R's natural array indexing is somewhat different.






          share|improve this answer





















          • Dang, you beat me by over 200 bytes. I'm always impressed by your coding, @Giuseppe. I shouldn't even bother trying sometimes
            – Sumner18
            5 hours ago








          • 1




            @Sumner18 well thanks! I usually try to let a day or two pass before answering challenges since I know there are plenty of other R golfers here now, but I couldn't resist this one since I saw it in the Sandbox. You're always welcome to bounce ideas for golfing off us in the R golfing chatroom. :-)
            – Giuseppe
            5 hours ago








          • 1




            @Sumner18 also there's no shame in trying and coming up short, my first submission here was horrible and I've only gotten better! Please continue to post, I think it's always good to get feedback so you can improve :-)
            – Giuseppe
            4 hours ago


















          up vote
          2
          down vote














          JavaScript (Node.js),  146 141 139  136 bytes



          I/O is in lowercase.





          s=>'931'.replace(/./g,d=>Buffer(s.length%3?s:s+0).map(c=>(o=(c>48?c-16:26)/d%3+o*3%27|0,++i)%3?0:(o+97)%123||32),i=o=0).split``.join``


          Try it online!



          Commented



          s =>                       // s = input string
          '931'.replace(/./g, d => // for each digit d = 9, 3 and 1:
          Buffer( // create a buffer from:
          s.length % 3 ? // if the length of s is coprime with 3:
          s // the original input string
          : // else:
          s + 0 // the input string + an extra '0'
          ) //
          .map(c => // for each ASCII code c from this Buffer:
          ( o = // update o:
          ( c > 48 ? // if c is neither a space nor the extra '0':
          c - 16 // yield c - 16 (which gives 81 .. 106)
          : // else:
          26 // this is the 26th character (space)
          ) / d % 3 + // divide by d and apply modulo 3
          o * 3 % 27 | 0, // add o * 3, apply modulo 27, coerce to integer
          ++i // increment i
          ) % 3 ? // if i mod 3 is not equal to 0:
          0 // yield 0 (NUL character)
          : // else:
          (o + 97) % 123 // convert o to the ASCII code of the output letter
          || 32 // or force 32 (space) for the 26th character
          ), // end of map()
          i = o = 0 // start with i = o = 0
          ).split``.join`` // end of replace(); remove the NUL characters





          share|improve this answer























          • I think you've explained it once before, but how does (o=...,++i)%3 work in JS again? Is (o,i) a tuple or something, and both inner integers are converted to their modulo-3? As a Java developer, it still confuses me a bit to see (a,b)%c. Nice answer though! I like how you convert every third digit, and then remove the first two null-bytes. +1 from me.
            – Kevin Cruijssen
            12 hours ago






          • 1




            @KevinCruijssen Quoting MDN: "The comma operator evaluates each of its operands (from left to right) and returns the value of the last operand." So, the modulo is only applied to ++i.
            – Arnauld
            12 hours ago


















          up vote
          1
          down vote













          SAS, 305 bytes



          A hearty 'oof' for this SAS monstrosity. There's a lot of random string formatting that I thought I could avoid going into this; I'm sure there are better ways of doing some of this.



          data;input n:&$99.;n=tranwrd(trim(n)," ","{");if mod(length(n),3)=0then n=cats(n,'{');f=n;l=length(n);array a(999);do i=1to l;v=rank(substr(n,i,1))-97;a{i}=int(v/9);a{i+l}=mod(int(v/3),3);a{i+l*2}=mod(v,3);end;f='';do i=1to l*3by 3;f=cats(f,byte(a{i}*9+a{i+1}*3+a{i+2}+97));end;f=tranwrd(f,"{"," ");cards;


          Input is entered on newlines after the cards statement, like so:



          data;input n:&$99.;n=tranwrd(trim(n)," ","{");if mod(length(n),3)=0then n=cats(n,'{');f=n;l=length(n);array a(999);do i=1to l;v=rank(substr(n,i,1))-97;a{i}=int(v/9);a{i+l}=mod(int(v/3),3);a{i+l*2}=mod(v,3);end;f='';do i=1to l*3by 3;f=cats(f,byte(a{i}*9+a{i+1}*3+a{i+2}+97));end;f=tranwrd(f,"{"," ");cards;
          this is a trifid cipher
          test
          output
          trifidcipher


          Outputs a dataset containing the output in the variable f, along with a bunch of helper variables/array values.



          enter image description here



          Ungolfed/explanation:



          data;
          input n : & $99.; /* Read a line of input, maximum 99 characters */

          n=tranwrd(trim(n)," ","{"); /* Replace spaces with '{' (this is the ASCII character following 'z', so it makes it easy to do byte conversions, and lets us not have to deal with spaces, which SAS does not like) */
          if mod(length(n),3)=0then n=cats(n,'{'); /* If length of n is not coprime with 3, add an extra "space" to the end */

          f=n; /* Set output = input, so that the string will have the same length */
          l=length(n); /* Get the length of the input */
          array a(999); /* Array of values to store intermediate results */

          do i = 1 to l; /* For each character in the input... */
          v = rank(substr(n,i,1))-97; /* Get the value of the current character, from 0-26 */

          a{i}=int(v/9); /* Get the table of the current character and store at appropriate index, from 0-2 */
          a{i+l}=mod(int(v/3),3); /* Get the row of the current character, from 0-2 */
          a{i+l*2}=mod(v,3); /* Get the column of the current character, from 0-2 */
          end;

          f='';

          do i = 1 to l*3 by 3; /* For each character in the output... */
          f=cats(f,byte(a{i}*9+a{i+1}*3+a{i+2}+97)); /* Convert values back from base 3 to base 10, and convert back into ASCII value */
          end;

          f = tranwrd(f,"{"," "); /* Replaces our "spaces" with actual spaces for final output */

          /* Test cases */
          cards;
          this is a trifid cipher
          test
          output
          trifidcipher





          share|improve this answer





















            Your Answer





            StackExchange.ifUsing("editor", function () {
            return StackExchange.using("mathjaxEditing", function () {
            StackExchange.MarkdownEditor.creationCallbacks.add(function (editor, postfix) {
            StackExchange.mathjaxEditing.prepareWmdForMathJax(editor, postfix, [["\$", "\$"]]);
            });
            });
            }, "mathjax-editing");

            StackExchange.ifUsing("editor", function () {
            StackExchange.using("externalEditor", function () {
            StackExchange.using("snippets", function () {
            StackExchange.snippets.init();
            });
            });
            }, "code-snippets");

            StackExchange.ready(function() {
            var channelOptions = {
            tags: "".split(" "),
            id: "200"
            };
            initTagRenderer("".split(" "), "".split(" "), channelOptions);

            StackExchange.using("externalEditor", function() {
            // Have to fire editor after snippets, if snippets enabled
            if (StackExchange.settings.snippets.snippetsEnabled) {
            StackExchange.using("snippets", function() {
            createEditor();
            });
            }
            else {
            createEditor();
            }
            });

            function createEditor() {
            StackExchange.prepareEditor({
            heartbeatType: 'answer',
            convertImagesToLinks: false,
            noModals: true,
            showLowRepImageUploadWarning: true,
            reputationToPostImages: null,
            bindNavPrevention: true,
            postfix: "",
            imageUploader: {
            brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
            contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
            allowUrls: true
            },
            onDemand: true,
            discardSelector: ".discard-answer"
            ,immediatelyShowMarkdownHelp:true
            });


            }
            });














            draft saved

            draft discarded


















            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodegolf.stackexchange.com%2fquestions%2f177353%2ftrifid-cipher-without-keyword%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown

























            10 Answers
            10






            active

            oldest

            votes








            10 Answers
            10






            active

            oldest

            votes









            active

            oldest

            votes






            active

            oldest

            votes








            up vote
            5
            down vote














            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





            share|improve this answer



























              up vote
              5
              down vote














              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





              share|improve this answer

























                up vote
                5
                down vote










                up vote
                5
                down vote










                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





                share|improve this answer















                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






                share|improve this answer














                share|improve this answer



                share|improve this answer








                edited 15 hours ago

























                answered 16 hours ago









                Neil

                78.7k744175




                78.7k744175






















                    up vote
                    5
                    down vote














                    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






                    share|improve this answer



























                      up vote
                      5
                      down vote














                      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






                      share|improve this answer

























                        up vote
                        5
                        down vote










                        up vote
                        5
                        down vote










                        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






                        share|improve this answer















                        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







                        share|improve this answer














                        share|improve this answer



                        share|improve this answer








                        edited 14 hours ago

























                        answered 15 hours ago









                        TFeld

                        13.9k21240




                        13.9k21240






















                            up vote
                            5
                            down vote













                            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






                            share|improve this answer



























                              up vote
                              5
                              down vote













                              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






                              share|improve this answer

























                                up vote
                                5
                                down vote










                                up vote
                                5
                                down vote









                                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






                                share|improve this answer














                                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







                                share|improve this answer














                                share|improve this answer



                                share|improve this answer








                                edited 7 hours ago

























                                answered 13 hours ago









                                Sok

                                3,429722




                                3,429722






















                                    up vote
                                    4
                                    down vote














                                    Jelly, 29 26 25 bytes



                                    ⁶Øa;3ṗ¤,©Ṛy;⁶$L3ḍƊ¡ZFs3®y


                                    Try it online!



                                    How it works



                                    ⁶Øa;3ṗ¤,©Ṛy;⁶$L3ḍƊ¡ZFs3®y  Main link. Argument: s (string)

                                    ⁶ Set the return value to space.
                                    Øa; Append it to "a...z".
                                    3ṗ¤ Yield the third Cartesian power of [1, 2, 3].
                                    ,© Pair the results and store the pair in the register.
                                    The register now holds
                                    [[[1, 1, 1], ..., [3, 3, 3]], ['a', ... ,'z', ' '].
                                    Ṛ Reverse the outer array.
                                    ;⁶$ Append a space to s...
                                    L3ḍƊ¡ if the length is divisible by 3.
                                    y Transliterate according to the mapping to the left.
                                    ZFs3 Zip/transpose, flatten, split into chunks of length 3.
                                    ®y Transliterate according to the mapping in the register.





                                    share|improve this answer























                                    • I never know the rules about side-effect outputs... but the arrangement ;L3ḍƊ¡⁶µ⁶Øa;3ṗ¤,ðṚyZFs3⁸y can do away with the µ if it's acceptable for 24.
                                      – Jonathan Allan
                                      6 hours ago










                                    • We have a weak consensus (+6/-1) that this is allowed, so thanks!
                                      – Dennis
                                      5 hours ago










                                    • The output appears to be incorrect. I don't think the appended space "sticks".
                                      – Dennis
                                      5 hours ago















                                    up vote
                                    4
                                    down vote














                                    Jelly, 29 26 25 bytes



                                    ⁶Øa;3ṗ¤,©Ṛy;⁶$L3ḍƊ¡ZFs3®y


                                    Try it online!



                                    How it works



                                    ⁶Øa;3ṗ¤,©Ṛy;⁶$L3ḍƊ¡ZFs3®y  Main link. Argument: s (string)

                                    ⁶ Set the return value to space.
                                    Øa; Append it to "a...z".
                                    3ṗ¤ Yield the third Cartesian power of [1, 2, 3].
                                    ,© Pair the results and store the pair in the register.
                                    The register now holds
                                    [[[1, 1, 1], ..., [3, 3, 3]], ['a', ... ,'z', ' '].
                                    Ṛ Reverse the outer array.
                                    ;⁶$ Append a space to s...
                                    L3ḍƊ¡ if the length is divisible by 3.
                                    y Transliterate according to the mapping to the left.
                                    ZFs3 Zip/transpose, flatten, split into chunks of length 3.
                                    ®y Transliterate according to the mapping in the register.





                                    share|improve this answer























                                    • I never know the rules about side-effect outputs... but the arrangement ;L3ḍƊ¡⁶µ⁶Øa;3ṗ¤,ðṚyZFs3⁸y can do away with the µ if it's acceptable for 24.
                                      – Jonathan Allan
                                      6 hours ago










                                    • We have a weak consensus (+6/-1) that this is allowed, so thanks!
                                      – Dennis
                                      5 hours ago










                                    • The output appears to be incorrect. I don't think the appended space "sticks".
                                      – Dennis
                                      5 hours ago













                                    up vote
                                    4
                                    down vote










                                    up vote
                                    4
                                    down vote










                                    Jelly, 29 26 25 bytes



                                    ⁶Øa;3ṗ¤,©Ṛy;⁶$L3ḍƊ¡ZFs3®y


                                    Try it online!



                                    How it works



                                    ⁶Øa;3ṗ¤,©Ṛy;⁶$L3ḍƊ¡ZFs3®y  Main link. Argument: s (string)

                                    ⁶ Set the return value to space.
                                    Øa; Append it to "a...z".
                                    3ṗ¤ Yield the third Cartesian power of [1, 2, 3].
                                    ,© Pair the results and store the pair in the register.
                                    The register now holds
                                    [[[1, 1, 1], ..., [3, 3, 3]], ['a', ... ,'z', ' '].
                                    Ṛ Reverse the outer array.
                                    ;⁶$ Append a space to s...
                                    L3ḍƊ¡ if the length is divisible by 3.
                                    y Transliterate according to the mapping to the left.
                                    ZFs3 Zip/transpose, flatten, split into chunks of length 3.
                                    ®y Transliterate according to the mapping in the register.





                                    share|improve this answer















                                    Jelly, 29 26 25 bytes



                                    ⁶Øa;3ṗ¤,©Ṛy;⁶$L3ḍƊ¡ZFs3®y


                                    Try it online!



                                    How it works



                                    ⁶Øa;3ṗ¤,©Ṛy;⁶$L3ḍƊ¡ZFs3®y  Main link. Argument: s (string)

                                    ⁶ Set the return value to space.
                                    Øa; Append it to "a...z".
                                    3ṗ¤ Yield the third Cartesian power of [1, 2, 3].
                                    ,© Pair the results and store the pair in the register.
                                    The register now holds
                                    [[[1, 1, 1], ..., [3, 3, 3]], ['a', ... ,'z', ' '].
                                    Ṛ Reverse the outer array.
                                    ;⁶$ Append a space to s...
                                    L3ḍƊ¡ if the length is divisible by 3.
                                    y Transliterate according to the mapping to the left.
                                    ZFs3 Zip/transpose, flatten, split into chunks of length 3.
                                    ®y Transliterate according to the mapping in the register.






                                    share|improve this answer














                                    share|improve this answer



                                    share|improve this answer








                                    edited 9 hours ago

























                                    answered 12 hours ago









                                    Dennis

                                    185k32295734




                                    185k32295734












                                    • I never know the rules about side-effect outputs... but the arrangement ;L3ḍƊ¡⁶µ⁶Øa;3ṗ¤,ðṚyZFs3⁸y can do away with the µ if it's acceptable for 24.
                                      – Jonathan Allan
                                      6 hours ago










                                    • We have a weak consensus (+6/-1) that this is allowed, so thanks!
                                      – Dennis
                                      5 hours ago










                                    • The output appears to be incorrect. I don't think the appended space "sticks".
                                      – Dennis
                                      5 hours ago


















                                    • I never know the rules about side-effect outputs... but the arrangement ;L3ḍƊ¡⁶µ⁶Øa;3ṗ¤,ðṚyZFs3⁸y can do away with the µ if it's acceptable for 24.
                                      – Jonathan Allan
                                      6 hours ago










                                    • We have a weak consensus (+6/-1) that this is allowed, so thanks!
                                      – Dennis
                                      5 hours ago










                                    • The output appears to be incorrect. I don't think the appended space "sticks".
                                      – Dennis
                                      5 hours ago
















                                    I never know the rules about side-effect outputs... but the arrangement ;L3ḍƊ¡⁶µ⁶Øa;3ṗ¤,ðṚyZFs3⁸y can do away with the µ if it's acceptable for 24.
                                    – Jonathan Allan
                                    6 hours ago




                                    I never know the rules about side-effect outputs... but the arrangement ;L3ḍƊ¡⁶µ⁶Øa;3ṗ¤,ðṚyZFs3⁸y can do away with the µ if it's acceptable for 24.
                                    – Jonathan Allan
                                    6 hours ago












                                    We have a weak consensus (+6/-1) that this is allowed, so thanks!
                                    – Dennis
                                    5 hours ago




                                    We have a weak consensus (+6/-1) that this is allowed, so thanks!
                                    – Dennis
                                    5 hours ago












                                    The output appears to be incorrect. I don't think the appended space "sticks".
                                    – Dennis
                                    5 hours ago




                                    The output appears to be incorrect. I don't think the appended space "sticks".
                                    – Dennis
                                    5 hours ago










                                    up vote
                                    3
                                    down vote














                                    Ruby, 153 145 138 131 bytes





                                    ->a{a<<" "if a.size%3<1;a.map{|c|[(b=(c.ord%32-1)%27)/9,b%9/3,b%3]}.transpose.join.scan(/.{3}/).map{|x|((x.to_i(3)+65)%91+32).chr}}


                                    Try it online!



                                    A quick and naive approach, works with lowercase text. Inputs and outputs arrays of characters.






                                    share|improve this answer



























                                      up vote
                                      3
                                      down vote














                                      Ruby, 153 145 138 131 bytes





                                      ->a{a<<" "if a.size%3<1;a.map{|c|[(b=(c.ord%32-1)%27)/9,b%9/3,b%3]}.transpose.join.scan(/.{3}/).map{|x|((x.to_i(3)+65)%91+32).chr}}


                                      Try it online!



                                      A quick and naive approach, works with lowercase text. Inputs and outputs arrays of characters.






                                      share|improve this answer

























                                        up vote
                                        3
                                        down vote










                                        up vote
                                        3
                                        down vote










                                        Ruby, 153 145 138 131 bytes





                                        ->a{a<<" "if a.size%3<1;a.map{|c|[(b=(c.ord%32-1)%27)/9,b%9/3,b%3]}.transpose.join.scan(/.{3}/).map{|x|((x.to_i(3)+65)%91+32).chr}}


                                        Try it online!



                                        A quick and naive approach, works with lowercase text. Inputs and outputs arrays of characters.






                                        share|improve this answer















                                        Ruby, 153 145 138 131 bytes





                                        ->a{a<<" "if a.size%3<1;a.map{|c|[(b=(c.ord%32-1)%27)/9,b%9/3,b%3]}.transpose.join.scan(/.{3}/).map{|x|((x.to_i(3)+65)%91+32).chr}}


                                        Try it online!



                                        A quick and naive approach, works with lowercase text. Inputs and outputs arrays of characters.







                                        share|improve this answer














                                        share|improve this answer



                                        share|improve this answer








                                        edited 13 hours ago

























                                        answered 15 hours ago









                                        Kirill L.

                                        3,4351118




                                        3,4351118






















                                            up vote
                                            2
                                            down vote













                                            APL+WIN, 102 bytes



                                            ⎕av[n[c⍳(⊂[2]((⍴t),3)⍴,⍉⊃(c←⊂[2]c,(,⍉9 3⍴c←9/⍳3),[1.1]27⍴⍳3)[(⎕av[n←(97+⍳26),33])⍳t←t,(3|⍴t←⎕)↓' '])]]


                                            Explanation:



                                            t←t,(3|⍴t←⎕)↓' ' Prompts for input and applies coprime condition

                                            (⎕av[n←(97+⍳26),33]⍳ Indices of characters in APL atomic vector

                                            c←⊂[2]c,(,⍉9 3⍴c←9/⍳3),[1.1]27⍴⍳3) Create a matrix of table, row column for 27 characters

                                            ⊂[2]((⍴t),3)⍴,⍉⊃ Extract columns of c corresponding to input and re-order

                                            c⍳ Identify Column indices of re-ordered columns

                                            ⎕av[.....] Use indices back in atomic vector to give enciphered text


                                            Example of screen shot of test case:



                                            ⎕av[n[c⍳(⊂[2]((⍴t),3)⍴,⍉⊃(c←⊂[2]c,(,⍉9 3⍴c←9/⍳3),[1.1]27⍴⍳3)[(⎕av[n←(97+⍳26),33])⍳t←t,(3|⍴t←⎕)↓' '])]]
                                            ⎕:
                                            'output'
                                            rrvgivx





                                            share|improve this answer























                                            • Would you mind adding a screenshot of (one or multiple of) the test cases? I know the WIN APL version isn't available on TIO, but I'd still like to see some kind of verification, since I barely know how to interpret APL code by just reading it, let alone verifying it without running. :)
                                              – Kevin Cruijssen
                                              12 hours ago










                                            • Not quite sure how to do that but this is what it would look like. I will add something to entry above
                                              – Graham
                                              11 hours ago












                                            • Normally I can use Dyalog Classic in TIO but in this case its atomic vector is in a different order so the indexing will not work.
                                              – Graham
                                              11 hours ago















                                            up vote
                                            2
                                            down vote













                                            APL+WIN, 102 bytes



                                            ⎕av[n[c⍳(⊂[2]((⍴t),3)⍴,⍉⊃(c←⊂[2]c,(,⍉9 3⍴c←9/⍳3),[1.1]27⍴⍳3)[(⎕av[n←(97+⍳26),33])⍳t←t,(3|⍴t←⎕)↓' '])]]


                                            Explanation:



                                            t←t,(3|⍴t←⎕)↓' ' Prompts for input and applies coprime condition

                                            (⎕av[n←(97+⍳26),33]⍳ Indices of characters in APL atomic vector

                                            c←⊂[2]c,(,⍉9 3⍴c←9/⍳3),[1.1]27⍴⍳3) Create a matrix of table, row column for 27 characters

                                            ⊂[2]((⍴t),3)⍴,⍉⊃ Extract columns of c corresponding to input and re-order

                                            c⍳ Identify Column indices of re-ordered columns

                                            ⎕av[.....] Use indices back in atomic vector to give enciphered text


                                            Example of screen shot of test case:



                                            ⎕av[n[c⍳(⊂[2]((⍴t),3)⍴,⍉⊃(c←⊂[2]c,(,⍉9 3⍴c←9/⍳3),[1.1]27⍴⍳3)[(⎕av[n←(97+⍳26),33])⍳t←t,(3|⍴t←⎕)↓' '])]]
                                            ⎕:
                                            'output'
                                            rrvgivx





                                            share|improve this answer























                                            • Would you mind adding a screenshot of (one or multiple of) the test cases? I know the WIN APL version isn't available on TIO, but I'd still like to see some kind of verification, since I barely know how to interpret APL code by just reading it, let alone verifying it without running. :)
                                              – Kevin Cruijssen
                                              12 hours ago










                                            • Not quite sure how to do that but this is what it would look like. I will add something to entry above
                                              – Graham
                                              11 hours ago












                                            • Normally I can use Dyalog Classic in TIO but in this case its atomic vector is in a different order so the indexing will not work.
                                              – Graham
                                              11 hours ago













                                            up vote
                                            2
                                            down vote










                                            up vote
                                            2
                                            down vote









                                            APL+WIN, 102 bytes



                                            ⎕av[n[c⍳(⊂[2]((⍴t),3)⍴,⍉⊃(c←⊂[2]c,(,⍉9 3⍴c←9/⍳3),[1.1]27⍴⍳3)[(⎕av[n←(97+⍳26),33])⍳t←t,(3|⍴t←⎕)↓' '])]]


                                            Explanation:



                                            t←t,(3|⍴t←⎕)↓' ' Prompts for input and applies coprime condition

                                            (⎕av[n←(97+⍳26),33]⍳ Indices of characters in APL atomic vector

                                            c←⊂[2]c,(,⍉9 3⍴c←9/⍳3),[1.1]27⍴⍳3) Create a matrix of table, row column for 27 characters

                                            ⊂[2]((⍴t),3)⍴,⍉⊃ Extract columns of c corresponding to input and re-order

                                            c⍳ Identify Column indices of re-ordered columns

                                            ⎕av[.....] Use indices back in atomic vector to give enciphered text


                                            Example of screen shot of test case:



                                            ⎕av[n[c⍳(⊂[2]((⍴t),3)⍴,⍉⊃(c←⊂[2]c,(,⍉9 3⍴c←9/⍳3),[1.1]27⍴⍳3)[(⎕av[n←(97+⍳26),33])⍳t←t,(3|⍴t←⎕)↓' '])]]
                                            ⎕:
                                            'output'
                                            rrvgivx





                                            share|improve this answer














                                            APL+WIN, 102 bytes



                                            ⎕av[n[c⍳(⊂[2]((⍴t),3)⍴,⍉⊃(c←⊂[2]c,(,⍉9 3⍴c←9/⍳3),[1.1]27⍴⍳3)[(⎕av[n←(97+⍳26),33])⍳t←t,(3|⍴t←⎕)↓' '])]]


                                            Explanation:



                                            t←t,(3|⍴t←⎕)↓' ' Prompts for input and applies coprime condition

                                            (⎕av[n←(97+⍳26),33]⍳ Indices of characters in APL atomic vector

                                            c←⊂[2]c,(,⍉9 3⍴c←9/⍳3),[1.1]27⍴⍳3) Create a matrix of table, row column for 27 characters

                                            ⊂[2]((⍴t),3)⍴,⍉⊃ Extract columns of c corresponding to input and re-order

                                            c⍳ Identify Column indices of re-ordered columns

                                            ⎕av[.....] Use indices back in atomic vector to give enciphered text


                                            Example of screen shot of test case:



                                            ⎕av[n[c⍳(⊂[2]((⍴t),3)⍴,⍉⊃(c←⊂[2]c,(,⍉9 3⍴c←9/⍳3),[1.1]27⍴⍳3)[(⎕av[n←(97+⍳26),33])⍳t←t,(3|⍴t←⎕)↓' '])]]
                                            ⎕:
                                            'output'
                                            rrvgivx






                                            share|improve this answer














                                            share|improve this answer



                                            share|improve this answer








                                            edited 11 hours ago

























                                            answered 13 hours ago









                                            Graham

                                            2,18678




                                            2,18678












                                            • Would you mind adding a screenshot of (one or multiple of) the test cases? I know the WIN APL version isn't available on TIO, but I'd still like to see some kind of verification, since I barely know how to interpret APL code by just reading it, let alone verifying it without running. :)
                                              – Kevin Cruijssen
                                              12 hours ago










                                            • Not quite sure how to do that but this is what it would look like. I will add something to entry above
                                              – Graham
                                              11 hours ago












                                            • Normally I can use Dyalog Classic in TIO but in this case its atomic vector is in a different order so the indexing will not work.
                                              – Graham
                                              11 hours ago


















                                            • Would you mind adding a screenshot of (one or multiple of) the test cases? I know the WIN APL version isn't available on TIO, but I'd still like to see some kind of verification, since I barely know how to interpret APL code by just reading it, let alone verifying it without running. :)
                                              – Kevin Cruijssen
                                              12 hours ago










                                            • Not quite sure how to do that but this is what it would look like. I will add something to entry above
                                              – Graham
                                              11 hours ago












                                            • Normally I can use Dyalog Classic in TIO but in this case its atomic vector is in a different order so the indexing will not work.
                                              – Graham
                                              11 hours ago
















                                            Would you mind adding a screenshot of (one or multiple of) the test cases? I know the WIN APL version isn't available on TIO, but I'd still like to see some kind of verification, since I barely know how to interpret APL code by just reading it, let alone verifying it without running. :)
                                            – Kevin Cruijssen
                                            12 hours ago




                                            Would you mind adding a screenshot of (one or multiple of) the test cases? I know the WIN APL version isn't available on TIO, but I'd still like to see some kind of verification, since I barely know how to interpret APL code by just reading it, let alone verifying it without running. :)
                                            – Kevin Cruijssen
                                            12 hours ago












                                            Not quite sure how to do that but this is what it would look like. I will add something to entry above
                                            – Graham
                                            11 hours ago






                                            Not quite sure how to do that but this is what it would look like. I will add something to entry above
                                            – Graham
                                            11 hours ago














                                            Normally I can use Dyalog Classic in TIO but in this case its atomic vector is in a different order so the indexing will not work.
                                            – Graham
                                            11 hours ago




                                            Normally I can use Dyalog Classic in TIO but in this case its atomic vector is in a different order so the indexing will not work.
                                            – Graham
                                            11 hours ago










                                            up vote
                                            2
                                            down vote














                                            Java (JDK), 192 bytes





                                            s->{String T="",R=T,C=T,r=T;for(int c:s){c-=c<33?6:97;T+=c/9;R+=c%9/3;C+=c%3;}for(var S:(s.length%3<1?T+2+R+2+C+2:T+R+C).split("(?<=\G...)"))r+=(char)((Byte.valueOf(S,3)+65)%91+32);return r;}


                                            Try it online!



                                            Very naive approach. Takes a lowercase char as input but outputs a String.



                                            Explanations



                                            s->{                                       // char-accepting lambda
                                            String T="", // declare variables Table as an empty string,
                                            R=T, // Row as an empty string,
                                            C=T, // Column as an empty string,
                                            r=T; // result as an empty string.
                                            for(int c:s){ // for each character
                                            c-=c<33?6:97; // map each letter to a number from 0 to 25, space to 26.
                                            T+=c/9; // append the table-value to Table
                                            R+=c%9/3; // append the row-value to Row
                                            C+=c%3; // append the column-value to Column
                                            } //
                                            for(var S: // For each token of...
                                            (s.length%3<1?T+2+R+2+C+2:T+R+C) // a single string out of table, row and column and take the space into account if the length is not coprime to 3...
                                            .split("(?<=\G...)")) // split every 3 characters
                                            r+=(char)((Byte.valueOf(S,3)+65)%91+32); // Parses each 3-characters token into a number, using base 3,
                                            // and make it a letter or a space
                                            return r; // return the result
                                            }


                                            Credits




                                            • -14 bytes thanks to Kevin Cruijssen






                                            share|improve this answer



















                                            • 1




                                              Two small golfs: Integer.valueOf to Byte.valueOf and R+=c<26?(char)(c+97):' '; to R+=(char)(c<26?c+97:32);
                                              – Kevin Cruijssen
                                              14 hours ago






                                            • 1




                                              202 bytes
                                              – Kevin Cruijssen
                                              13 hours ago















                                            up vote
                                            2
                                            down vote














                                            Java (JDK), 192 bytes





                                            s->{String T="",R=T,C=T,r=T;for(int c:s){c-=c<33?6:97;T+=c/9;R+=c%9/3;C+=c%3;}for(var S:(s.length%3<1?T+2+R+2+C+2:T+R+C).split("(?<=\G...)"))r+=(char)((Byte.valueOf(S,3)+65)%91+32);return r;}


                                            Try it online!



                                            Very naive approach. Takes a lowercase char as input but outputs a String.



                                            Explanations



                                            s->{                                       // char-accepting lambda
                                            String T="", // declare variables Table as an empty string,
                                            R=T, // Row as an empty string,
                                            C=T, // Column as an empty string,
                                            r=T; // result as an empty string.
                                            for(int c:s){ // for each character
                                            c-=c<33?6:97; // map each letter to a number from 0 to 25, space to 26.
                                            T+=c/9; // append the table-value to Table
                                            R+=c%9/3; // append the row-value to Row
                                            C+=c%3; // append the column-value to Column
                                            } //
                                            for(var S: // For each token of...
                                            (s.length%3<1?T+2+R+2+C+2:T+R+C) // a single string out of table, row and column and take the space into account if the length is not coprime to 3...
                                            .split("(?<=\G...)")) // split every 3 characters
                                            r+=(char)((Byte.valueOf(S,3)+65)%91+32); // Parses each 3-characters token into a number, using base 3,
                                            // and make it a letter or a space
                                            return r; // return the result
                                            }


                                            Credits




                                            • -14 bytes thanks to Kevin Cruijssen






                                            share|improve this answer



















                                            • 1




                                              Two small golfs: Integer.valueOf to Byte.valueOf and R+=c<26?(char)(c+97):' '; to R+=(char)(c<26?c+97:32);
                                              – Kevin Cruijssen
                                              14 hours ago






                                            • 1




                                              202 bytes
                                              – Kevin Cruijssen
                                              13 hours ago













                                            up vote
                                            2
                                            down vote










                                            up vote
                                            2
                                            down vote










                                            Java (JDK), 192 bytes





                                            s->{String T="",R=T,C=T,r=T;for(int c:s){c-=c<33?6:97;T+=c/9;R+=c%9/3;C+=c%3;}for(var S:(s.length%3<1?T+2+R+2+C+2:T+R+C).split("(?<=\G...)"))r+=(char)((Byte.valueOf(S,3)+65)%91+32);return r;}


                                            Try it online!



                                            Very naive approach. Takes a lowercase char as input but outputs a String.



                                            Explanations



                                            s->{                                       // char-accepting lambda
                                            String T="", // declare variables Table as an empty string,
                                            R=T, // Row as an empty string,
                                            C=T, // Column as an empty string,
                                            r=T; // result as an empty string.
                                            for(int c:s){ // for each character
                                            c-=c<33?6:97; // map each letter to a number from 0 to 25, space to 26.
                                            T+=c/9; // append the table-value to Table
                                            R+=c%9/3; // append the row-value to Row
                                            C+=c%3; // append the column-value to Column
                                            } //
                                            for(var S: // For each token of...
                                            (s.length%3<1?T+2+R+2+C+2:T+R+C) // a single string out of table, row and column and take the space into account if the length is not coprime to 3...
                                            .split("(?<=\G...)")) // split every 3 characters
                                            r+=(char)((Byte.valueOf(S,3)+65)%91+32); // Parses each 3-characters token into a number, using base 3,
                                            // and make it a letter or a space
                                            return r; // return the result
                                            }


                                            Credits




                                            • -14 bytes thanks to Kevin Cruijssen






                                            share|improve this answer















                                            Java (JDK), 192 bytes





                                            s->{String T="",R=T,C=T,r=T;for(int c:s){c-=c<33?6:97;T+=c/9;R+=c%9/3;C+=c%3;}for(var S:(s.length%3<1?T+2+R+2+C+2:T+R+C).split("(?<=\G...)"))r+=(char)((Byte.valueOf(S,3)+65)%91+32);return r;}


                                            Try it online!



                                            Very naive approach. Takes a lowercase char as input but outputs a String.



                                            Explanations



                                            s->{                                       // char-accepting lambda
                                            String T="", // declare variables Table as an empty string,
                                            R=T, // Row as an empty string,
                                            C=T, // Column as an empty string,
                                            r=T; // result as an empty string.
                                            for(int c:s){ // for each character
                                            c-=c<33?6:97; // map each letter to a number from 0 to 25, space to 26.
                                            T+=c/9; // append the table-value to Table
                                            R+=c%9/3; // append the row-value to Row
                                            C+=c%3; // append the column-value to Column
                                            } //
                                            for(var S: // For each token of...
                                            (s.length%3<1?T+2+R+2+C+2:T+R+C) // a single string out of table, row and column and take the space into account if the length is not coprime to 3...
                                            .split("(?<=\G...)")) // split every 3 characters
                                            r+=(char)((Byte.valueOf(S,3)+65)%91+32); // Parses each 3-characters token into a number, using base 3,
                                            // and make it a letter or a space
                                            return r; // return the result
                                            }


                                            Credits




                                            • -14 bytes thanks to Kevin Cruijssen







                                            share|improve this answer














                                            share|improve this answer



                                            share|improve this answer








                                            edited 11 hours ago

























                                            answered 14 hours ago









                                            Olivier Grégoire

                                            8,58711843




                                            8,58711843








                                            • 1




                                              Two small golfs: Integer.valueOf to Byte.valueOf and R+=c<26?(char)(c+97):' '; to R+=(char)(c<26?c+97:32);
                                              – Kevin Cruijssen
                                              14 hours ago






                                            • 1




                                              202 bytes
                                              – Kevin Cruijssen
                                              13 hours ago














                                            • 1




                                              Two small golfs: Integer.valueOf to Byte.valueOf and R+=c<26?(char)(c+97):' '; to R+=(char)(c<26?c+97:32);
                                              – Kevin Cruijssen
                                              14 hours ago






                                            • 1




                                              202 bytes
                                              – Kevin Cruijssen
                                              13 hours ago








                                            1




                                            1




                                            Two small golfs: Integer.valueOf to Byte.valueOf and R+=c<26?(char)(c+97):' '; to R+=(char)(c<26?c+97:32);
                                            – Kevin Cruijssen
                                            14 hours ago




                                            Two small golfs: Integer.valueOf to Byte.valueOf and R+=c<26?(char)(c+97):' '; to R+=(char)(c<26?c+97:32);
                                            – Kevin Cruijssen
                                            14 hours ago




                                            1




                                            1




                                            202 bytes
                                            – Kevin Cruijssen
                                            13 hours ago




                                            202 bytes
                                            – Kevin Cruijssen
                                            13 hours ago










                                            up vote
                                            2
                                            down vote














                                            R, 145 bytes





                                            function(s,K=array(c(97:122,32),rep(3,3)))intToUtf8(K[matrix(arrayInd(match(c(utf8ToInt(s),32[!nchar(s)%%3]),K),dim(K))[,3:1],,3,byrow=T)[,3:1]])


                                            Try it online!



                                            I/O as strings; adds one space. The strange repetition of [,3:1] is because R's natural array indexing is somewhat different.






                                            share|improve this answer





















                                            • Dang, you beat me by over 200 bytes. I'm always impressed by your coding, @Giuseppe. I shouldn't even bother trying sometimes
                                              – Sumner18
                                              5 hours ago








                                            • 1




                                              @Sumner18 well thanks! I usually try to let a day or two pass before answering challenges since I know there are plenty of other R golfers here now, but I couldn't resist this one since I saw it in the Sandbox. You're always welcome to bounce ideas for golfing off us in the R golfing chatroom. :-)
                                              – Giuseppe
                                              5 hours ago








                                            • 1




                                              @Sumner18 also there's no shame in trying and coming up short, my first submission here was horrible and I've only gotten better! Please continue to post, I think it's always good to get feedback so you can improve :-)
                                              – Giuseppe
                                              4 hours ago















                                            up vote
                                            2
                                            down vote














                                            R, 145 bytes





                                            function(s,K=array(c(97:122,32),rep(3,3)))intToUtf8(K[matrix(arrayInd(match(c(utf8ToInt(s),32[!nchar(s)%%3]),K),dim(K))[,3:1],,3,byrow=T)[,3:1]])


                                            Try it online!



                                            I/O as strings; adds one space. The strange repetition of [,3:1] is because R's natural array indexing is somewhat different.






                                            share|improve this answer





















                                            • Dang, you beat me by over 200 bytes. I'm always impressed by your coding, @Giuseppe. I shouldn't even bother trying sometimes
                                              – Sumner18
                                              5 hours ago








                                            • 1




                                              @Sumner18 well thanks! I usually try to let a day or two pass before answering challenges since I know there are plenty of other R golfers here now, but I couldn't resist this one since I saw it in the Sandbox. You're always welcome to bounce ideas for golfing off us in the R golfing chatroom. :-)
                                              – Giuseppe
                                              5 hours ago








                                            • 1




                                              @Sumner18 also there's no shame in trying and coming up short, my first submission here was horrible and I've only gotten better! Please continue to post, I think it's always good to get feedback so you can improve :-)
                                              – Giuseppe
                                              4 hours ago













                                            up vote
                                            2
                                            down vote










                                            up vote
                                            2
                                            down vote










                                            R, 145 bytes





                                            function(s,K=array(c(97:122,32),rep(3,3)))intToUtf8(K[matrix(arrayInd(match(c(utf8ToInt(s),32[!nchar(s)%%3]),K),dim(K))[,3:1],,3,byrow=T)[,3:1]])


                                            Try it online!



                                            I/O as strings; adds one space. The strange repetition of [,3:1] is because R's natural array indexing is somewhat different.






                                            share|improve this answer













                                            R, 145 bytes





                                            function(s,K=array(c(97:122,32),rep(3,3)))intToUtf8(K[matrix(arrayInd(match(c(utf8ToInt(s),32[!nchar(s)%%3]),K),dim(K))[,3:1],,3,byrow=T)[,3:1]])


                                            Try it online!



                                            I/O as strings; adds one space. The strange repetition of [,3:1] is because R's natural array indexing is somewhat different.







                                            share|improve this answer












                                            share|improve this answer



                                            share|improve this answer










                                            answered 5 hours ago









                                            Giuseppe

                                            16.3k31052




                                            16.3k31052












                                            • Dang, you beat me by over 200 bytes. I'm always impressed by your coding, @Giuseppe. I shouldn't even bother trying sometimes
                                              – Sumner18
                                              5 hours ago








                                            • 1




                                              @Sumner18 well thanks! I usually try to let a day or two pass before answering challenges since I know there are plenty of other R golfers here now, but I couldn't resist this one since I saw it in the Sandbox. You're always welcome to bounce ideas for golfing off us in the R golfing chatroom. :-)
                                              – Giuseppe
                                              5 hours ago








                                            • 1




                                              @Sumner18 also there's no shame in trying and coming up short, my first submission here was horrible and I've only gotten better! Please continue to post, I think it's always good to get feedback so you can improve :-)
                                              – Giuseppe
                                              4 hours ago


















                                            • Dang, you beat me by over 200 bytes. I'm always impressed by your coding, @Giuseppe. I shouldn't even bother trying sometimes
                                              – Sumner18
                                              5 hours ago








                                            • 1




                                              @Sumner18 well thanks! I usually try to let a day or two pass before answering challenges since I know there are plenty of other R golfers here now, but I couldn't resist this one since I saw it in the Sandbox. You're always welcome to bounce ideas for golfing off us in the R golfing chatroom. :-)
                                              – Giuseppe
                                              5 hours ago








                                            • 1




                                              @Sumner18 also there's no shame in trying and coming up short, my first submission here was horrible and I've only gotten better! Please continue to post, I think it's always good to get feedback so you can improve :-)
                                              – Giuseppe
                                              4 hours ago
















                                            Dang, you beat me by over 200 bytes. I'm always impressed by your coding, @Giuseppe. I shouldn't even bother trying sometimes
                                            – Sumner18
                                            5 hours ago






                                            Dang, you beat me by over 200 bytes. I'm always impressed by your coding, @Giuseppe. I shouldn't even bother trying sometimes
                                            – Sumner18
                                            5 hours ago






                                            1




                                            1




                                            @Sumner18 well thanks! I usually try to let a day or two pass before answering challenges since I know there are plenty of other R golfers here now, but I couldn't resist this one since I saw it in the Sandbox. You're always welcome to bounce ideas for golfing off us in the R golfing chatroom. :-)
                                            – Giuseppe
                                            5 hours ago






                                            @Sumner18 well thanks! I usually try to let a day or two pass before answering challenges since I know there are plenty of other R golfers here now, but I couldn't resist this one since I saw it in the Sandbox. You're always welcome to bounce ideas for golfing off us in the R golfing chatroom. :-)
                                            – Giuseppe
                                            5 hours ago






                                            1




                                            1




                                            @Sumner18 also there's no shame in trying and coming up short, my first submission here was horrible and I've only gotten better! Please continue to post, I think it's always good to get feedback so you can improve :-)
                                            – Giuseppe
                                            4 hours ago




                                            @Sumner18 also there's no shame in trying and coming up short, my first submission here was horrible and I've only gotten better! Please continue to post, I think it's always good to get feedback so you can improve :-)
                                            – Giuseppe
                                            4 hours ago










                                            up vote
                                            2
                                            down vote














                                            JavaScript (Node.js),  146 141 139  136 bytes



                                            I/O is in lowercase.





                                            s=>'931'.replace(/./g,d=>Buffer(s.length%3?s:s+0).map(c=>(o=(c>48?c-16:26)/d%3+o*3%27|0,++i)%3?0:(o+97)%123||32),i=o=0).split``.join``


                                            Try it online!



                                            Commented



                                            s =>                       // s = input string
                                            '931'.replace(/./g, d => // for each digit d = 9, 3 and 1:
                                            Buffer( // create a buffer from:
                                            s.length % 3 ? // if the length of s is coprime with 3:
                                            s // the original input string
                                            : // else:
                                            s + 0 // the input string + an extra '0'
                                            ) //
                                            .map(c => // for each ASCII code c from this Buffer:
                                            ( o = // update o:
                                            ( c > 48 ? // if c is neither a space nor the extra '0':
                                            c - 16 // yield c - 16 (which gives 81 .. 106)
                                            : // else:
                                            26 // this is the 26th character (space)
                                            ) / d % 3 + // divide by d and apply modulo 3
                                            o * 3 % 27 | 0, // add o * 3, apply modulo 27, coerce to integer
                                            ++i // increment i
                                            ) % 3 ? // if i mod 3 is not equal to 0:
                                            0 // yield 0 (NUL character)
                                            : // else:
                                            (o + 97) % 123 // convert o to the ASCII code of the output letter
                                            || 32 // or force 32 (space) for the 26th character
                                            ), // end of map()
                                            i = o = 0 // start with i = o = 0
                                            ).split``.join`` // end of replace(); remove the NUL characters





                                            share|improve this answer























                                            • I think you've explained it once before, but how does (o=...,++i)%3 work in JS again? Is (o,i) a tuple or something, and both inner integers are converted to their modulo-3? As a Java developer, it still confuses me a bit to see (a,b)%c. Nice answer though! I like how you convert every third digit, and then remove the first two null-bytes. +1 from me.
                                              – Kevin Cruijssen
                                              12 hours ago






                                            • 1




                                              @KevinCruijssen Quoting MDN: "The comma operator evaluates each of its operands (from left to right) and returns the value of the last operand." So, the modulo is only applied to ++i.
                                              – Arnauld
                                              12 hours ago















                                            up vote
                                            2
                                            down vote














                                            JavaScript (Node.js),  146 141 139  136 bytes



                                            I/O is in lowercase.





                                            s=>'931'.replace(/./g,d=>Buffer(s.length%3?s:s+0).map(c=>(o=(c>48?c-16:26)/d%3+o*3%27|0,++i)%3?0:(o+97)%123||32),i=o=0).split``.join``


                                            Try it online!



                                            Commented



                                            s =>                       // s = input string
                                            '931'.replace(/./g, d => // for each digit d = 9, 3 and 1:
                                            Buffer( // create a buffer from:
                                            s.length % 3 ? // if the length of s is coprime with 3:
                                            s // the original input string
                                            : // else:
                                            s + 0 // the input string + an extra '0'
                                            ) //
                                            .map(c => // for each ASCII code c from this Buffer:
                                            ( o = // update o:
                                            ( c > 48 ? // if c is neither a space nor the extra '0':
                                            c - 16 // yield c - 16 (which gives 81 .. 106)
                                            : // else:
                                            26 // this is the 26th character (space)
                                            ) / d % 3 + // divide by d and apply modulo 3
                                            o * 3 % 27 | 0, // add o * 3, apply modulo 27, coerce to integer
                                            ++i // increment i
                                            ) % 3 ? // if i mod 3 is not equal to 0:
                                            0 // yield 0 (NUL character)
                                            : // else:
                                            (o + 97) % 123 // convert o to the ASCII code of the output letter
                                            || 32 // or force 32 (space) for the 26th character
                                            ), // end of map()
                                            i = o = 0 // start with i = o = 0
                                            ).split``.join`` // end of replace(); remove the NUL characters





                                            share|improve this answer























                                            • I think you've explained it once before, but how does (o=...,++i)%3 work in JS again? Is (o,i) a tuple or something, and both inner integers are converted to their modulo-3? As a Java developer, it still confuses me a bit to see (a,b)%c. Nice answer though! I like how you convert every third digit, and then remove the first two null-bytes. +1 from me.
                                              – Kevin Cruijssen
                                              12 hours ago






                                            • 1




                                              @KevinCruijssen Quoting MDN: "The comma operator evaluates each of its operands (from left to right) and returns the value of the last operand." So, the modulo is only applied to ++i.
                                              – Arnauld
                                              12 hours ago













                                            up vote
                                            2
                                            down vote










                                            up vote
                                            2
                                            down vote










                                            JavaScript (Node.js),  146 141 139  136 bytes



                                            I/O is in lowercase.





                                            s=>'931'.replace(/./g,d=>Buffer(s.length%3?s:s+0).map(c=>(o=(c>48?c-16:26)/d%3+o*3%27|0,++i)%3?0:(o+97)%123||32),i=o=0).split``.join``


                                            Try it online!



                                            Commented



                                            s =>                       // s = input string
                                            '931'.replace(/./g, d => // for each digit d = 9, 3 and 1:
                                            Buffer( // create a buffer from:
                                            s.length % 3 ? // if the length of s is coprime with 3:
                                            s // the original input string
                                            : // else:
                                            s + 0 // the input string + an extra '0'
                                            ) //
                                            .map(c => // for each ASCII code c from this Buffer:
                                            ( o = // update o:
                                            ( c > 48 ? // if c is neither a space nor the extra '0':
                                            c - 16 // yield c - 16 (which gives 81 .. 106)
                                            : // else:
                                            26 // this is the 26th character (space)
                                            ) / d % 3 + // divide by d and apply modulo 3
                                            o * 3 % 27 | 0, // add o * 3, apply modulo 27, coerce to integer
                                            ++i // increment i
                                            ) % 3 ? // if i mod 3 is not equal to 0:
                                            0 // yield 0 (NUL character)
                                            : // else:
                                            (o + 97) % 123 // convert o to the ASCII code of the output letter
                                            || 32 // or force 32 (space) for the 26th character
                                            ), // end of map()
                                            i = o = 0 // start with i = o = 0
                                            ).split``.join`` // end of replace(); remove the NUL characters





                                            share|improve this answer















                                            JavaScript (Node.js),  146 141 139  136 bytes



                                            I/O is in lowercase.





                                            s=>'931'.replace(/./g,d=>Buffer(s.length%3?s:s+0).map(c=>(o=(c>48?c-16:26)/d%3+o*3%27|0,++i)%3?0:(o+97)%123||32),i=o=0).split``.join``


                                            Try it online!



                                            Commented



                                            s =>                       // s = input string
                                            '931'.replace(/./g, d => // for each digit d = 9, 3 and 1:
                                            Buffer( // create a buffer from:
                                            s.length % 3 ? // if the length of s is coprime with 3:
                                            s // the original input string
                                            : // else:
                                            s + 0 // the input string + an extra '0'
                                            ) //
                                            .map(c => // for each ASCII code c from this Buffer:
                                            ( o = // update o:
                                            ( c > 48 ? // if c is neither a space nor the extra '0':
                                            c - 16 // yield c - 16 (which gives 81 .. 106)
                                            : // else:
                                            26 // this is the 26th character (space)
                                            ) / d % 3 + // divide by d and apply modulo 3
                                            o * 3 % 27 | 0, // add o * 3, apply modulo 27, coerce to integer
                                            ++i // increment i
                                            ) % 3 ? // if i mod 3 is not equal to 0:
                                            0 // yield 0 (NUL character)
                                            : // else:
                                            (o + 97) % 123 // convert o to the ASCII code of the output letter
                                            || 32 // or force 32 (space) for the 26th character
                                            ), // end of map()
                                            i = o = 0 // start with i = o = 0
                                            ).split``.join`` // end of replace(); remove the NUL characters






                                            share|improve this answer














                                            share|improve this answer



                                            share|improve this answer








                                            edited 4 hours ago

























                                            answered 12 hours ago









                                            Arnauld

                                            71.2k688298




                                            71.2k688298












                                            • I think you've explained it once before, but how does (o=...,++i)%3 work in JS again? Is (o,i) a tuple or something, and both inner integers are converted to their modulo-3? As a Java developer, it still confuses me a bit to see (a,b)%c. Nice answer though! I like how you convert every third digit, and then remove the first two null-bytes. +1 from me.
                                              – Kevin Cruijssen
                                              12 hours ago






                                            • 1




                                              @KevinCruijssen Quoting MDN: "The comma operator evaluates each of its operands (from left to right) and returns the value of the last operand." So, the modulo is only applied to ++i.
                                              – Arnauld
                                              12 hours ago


















                                            • I think you've explained it once before, but how does (o=...,++i)%3 work in JS again? Is (o,i) a tuple or something, and both inner integers are converted to their modulo-3? As a Java developer, it still confuses me a bit to see (a,b)%c. Nice answer though! I like how you convert every third digit, and then remove the first two null-bytes. +1 from me.
                                              – Kevin Cruijssen
                                              12 hours ago






                                            • 1




                                              @KevinCruijssen Quoting MDN: "The comma operator evaluates each of its operands (from left to right) and returns the value of the last operand." So, the modulo is only applied to ++i.
                                              – Arnauld
                                              12 hours ago
















                                            I think you've explained it once before, but how does (o=...,++i)%3 work in JS again? Is (o,i) a tuple or something, and both inner integers are converted to their modulo-3? As a Java developer, it still confuses me a bit to see (a,b)%c. Nice answer though! I like how you convert every third digit, and then remove the first two null-bytes. +1 from me.
                                            – Kevin Cruijssen
                                            12 hours ago




                                            I think you've explained it once before, but how does (o=...,++i)%3 work in JS again? Is (o,i) a tuple or something, and both inner integers are converted to their modulo-3? As a Java developer, it still confuses me a bit to see (a,b)%c. Nice answer though! I like how you convert every third digit, and then remove the first two null-bytes. +1 from me.
                                            – Kevin Cruijssen
                                            12 hours ago




                                            1




                                            1




                                            @KevinCruijssen Quoting MDN: "The comma operator evaluates each of its operands (from left to right) and returns the value of the last operand." So, the modulo is only applied to ++i.
                                            – Arnauld
                                            12 hours ago




                                            @KevinCruijssen Quoting MDN: "The comma operator evaluates each of its operands (from left to right) and returns the value of the last operand." So, the modulo is only applied to ++i.
                                            – Arnauld
                                            12 hours ago










                                            up vote
                                            1
                                            down vote













                                            SAS, 305 bytes



                                            A hearty 'oof' for this SAS monstrosity. There's a lot of random string formatting that I thought I could avoid going into this; I'm sure there are better ways of doing some of this.



                                            data;input n:&$99.;n=tranwrd(trim(n)," ","{");if mod(length(n),3)=0then n=cats(n,'{');f=n;l=length(n);array a(999);do i=1to l;v=rank(substr(n,i,1))-97;a{i}=int(v/9);a{i+l}=mod(int(v/3),3);a{i+l*2}=mod(v,3);end;f='';do i=1to l*3by 3;f=cats(f,byte(a{i}*9+a{i+1}*3+a{i+2}+97));end;f=tranwrd(f,"{"," ");cards;


                                            Input is entered on newlines after the cards statement, like so:



                                            data;input n:&$99.;n=tranwrd(trim(n)," ","{");if mod(length(n),3)=0then n=cats(n,'{');f=n;l=length(n);array a(999);do i=1to l;v=rank(substr(n,i,1))-97;a{i}=int(v/9);a{i+l}=mod(int(v/3),3);a{i+l*2}=mod(v,3);end;f='';do i=1to l*3by 3;f=cats(f,byte(a{i}*9+a{i+1}*3+a{i+2}+97));end;f=tranwrd(f,"{"," ");cards;
                                            this is a trifid cipher
                                            test
                                            output
                                            trifidcipher


                                            Outputs a dataset containing the output in the variable f, along with a bunch of helper variables/array values.



                                            enter image description here



                                            Ungolfed/explanation:



                                            data;
                                            input n : & $99.; /* Read a line of input, maximum 99 characters */

                                            n=tranwrd(trim(n)," ","{"); /* Replace spaces with '{' (this is the ASCII character following 'z', so it makes it easy to do byte conversions, and lets us not have to deal with spaces, which SAS does not like) */
                                            if mod(length(n),3)=0then n=cats(n,'{'); /* If length of n is not coprime with 3, add an extra "space" to the end */

                                            f=n; /* Set output = input, so that the string will have the same length */
                                            l=length(n); /* Get the length of the input */
                                            array a(999); /* Array of values to store intermediate results */

                                            do i = 1 to l; /* For each character in the input... */
                                            v = rank(substr(n,i,1))-97; /* Get the value of the current character, from 0-26 */

                                            a{i}=int(v/9); /* Get the table of the current character and store at appropriate index, from 0-2 */
                                            a{i+l}=mod(int(v/3),3); /* Get the row of the current character, from 0-2 */
                                            a{i+l*2}=mod(v,3); /* Get the column of the current character, from 0-2 */
                                            end;

                                            f='';

                                            do i = 1 to l*3 by 3; /* For each character in the output... */
                                            f=cats(f,byte(a{i}*9+a{i+1}*3+a{i+2}+97)); /* Convert values back from base 3 to base 10, and convert back into ASCII value */
                                            end;

                                            f = tranwrd(f,"{"," "); /* Replaces our "spaces" with actual spaces for final output */

                                            /* Test cases */
                                            cards;
                                            this is a trifid cipher
                                            test
                                            output
                                            trifidcipher





                                            share|improve this answer

























                                              up vote
                                              1
                                              down vote













                                              SAS, 305 bytes



                                              A hearty 'oof' for this SAS monstrosity. There's a lot of random string formatting that I thought I could avoid going into this; I'm sure there are better ways of doing some of this.



                                              data;input n:&$99.;n=tranwrd(trim(n)," ","{");if mod(length(n),3)=0then n=cats(n,'{');f=n;l=length(n);array a(999);do i=1to l;v=rank(substr(n,i,1))-97;a{i}=int(v/9);a{i+l}=mod(int(v/3),3);a{i+l*2}=mod(v,3);end;f='';do i=1to l*3by 3;f=cats(f,byte(a{i}*9+a{i+1}*3+a{i+2}+97));end;f=tranwrd(f,"{"," ");cards;


                                              Input is entered on newlines after the cards statement, like so:



                                              data;input n:&$99.;n=tranwrd(trim(n)," ","{");if mod(length(n),3)=0then n=cats(n,'{');f=n;l=length(n);array a(999);do i=1to l;v=rank(substr(n,i,1))-97;a{i}=int(v/9);a{i+l}=mod(int(v/3),3);a{i+l*2}=mod(v,3);end;f='';do i=1to l*3by 3;f=cats(f,byte(a{i}*9+a{i+1}*3+a{i+2}+97));end;f=tranwrd(f,"{"," ");cards;
                                              this is a trifid cipher
                                              test
                                              output
                                              trifidcipher


                                              Outputs a dataset containing the output in the variable f, along with a bunch of helper variables/array values.



                                              enter image description here



                                              Ungolfed/explanation:



                                              data;
                                              input n : & $99.; /* Read a line of input, maximum 99 characters */

                                              n=tranwrd(trim(n)," ","{"); /* Replace spaces with '{' (this is the ASCII character following 'z', so it makes it easy to do byte conversions, and lets us not have to deal with spaces, which SAS does not like) */
                                              if mod(length(n),3)=0then n=cats(n,'{'); /* If length of n is not coprime with 3, add an extra "space" to the end */

                                              f=n; /* Set output = input, so that the string will have the same length */
                                              l=length(n); /* Get the length of the input */
                                              array a(999); /* Array of values to store intermediate results */

                                              do i = 1 to l; /* For each character in the input... */
                                              v = rank(substr(n,i,1))-97; /* Get the value of the current character, from 0-26 */

                                              a{i}=int(v/9); /* Get the table of the current character and store at appropriate index, from 0-2 */
                                              a{i+l}=mod(int(v/3),3); /* Get the row of the current character, from 0-2 */
                                              a{i+l*2}=mod(v,3); /* Get the column of the current character, from 0-2 */
                                              end;

                                              f='';

                                              do i = 1 to l*3 by 3; /* For each character in the output... */
                                              f=cats(f,byte(a{i}*9+a{i+1}*3+a{i+2}+97)); /* Convert values back from base 3 to base 10, and convert back into ASCII value */
                                              end;

                                              f = tranwrd(f,"{"," "); /* Replaces our "spaces" with actual spaces for final output */

                                              /* Test cases */
                                              cards;
                                              this is a trifid cipher
                                              test
                                              output
                                              trifidcipher





                                              share|improve this answer























                                                up vote
                                                1
                                                down vote










                                                up vote
                                                1
                                                down vote









                                                SAS, 305 bytes



                                                A hearty 'oof' for this SAS monstrosity. There's a lot of random string formatting that I thought I could avoid going into this; I'm sure there are better ways of doing some of this.



                                                data;input n:&$99.;n=tranwrd(trim(n)," ","{");if mod(length(n),3)=0then n=cats(n,'{');f=n;l=length(n);array a(999);do i=1to l;v=rank(substr(n,i,1))-97;a{i}=int(v/9);a{i+l}=mod(int(v/3),3);a{i+l*2}=mod(v,3);end;f='';do i=1to l*3by 3;f=cats(f,byte(a{i}*9+a{i+1}*3+a{i+2}+97));end;f=tranwrd(f,"{"," ");cards;


                                                Input is entered on newlines after the cards statement, like so:



                                                data;input n:&$99.;n=tranwrd(trim(n)," ","{");if mod(length(n),3)=0then n=cats(n,'{');f=n;l=length(n);array a(999);do i=1to l;v=rank(substr(n,i,1))-97;a{i}=int(v/9);a{i+l}=mod(int(v/3),3);a{i+l*2}=mod(v,3);end;f='';do i=1to l*3by 3;f=cats(f,byte(a{i}*9+a{i+1}*3+a{i+2}+97));end;f=tranwrd(f,"{"," ");cards;
                                                this is a trifid cipher
                                                test
                                                output
                                                trifidcipher


                                                Outputs a dataset containing the output in the variable f, along with a bunch of helper variables/array values.



                                                enter image description here



                                                Ungolfed/explanation:



                                                data;
                                                input n : & $99.; /* Read a line of input, maximum 99 characters */

                                                n=tranwrd(trim(n)," ","{"); /* Replace spaces with '{' (this is the ASCII character following 'z', so it makes it easy to do byte conversions, and lets us not have to deal with spaces, which SAS does not like) */
                                                if mod(length(n),3)=0then n=cats(n,'{'); /* If length of n is not coprime with 3, add an extra "space" to the end */

                                                f=n; /* Set output = input, so that the string will have the same length */
                                                l=length(n); /* Get the length of the input */
                                                array a(999); /* Array of values to store intermediate results */

                                                do i = 1 to l; /* For each character in the input... */
                                                v = rank(substr(n,i,1))-97; /* Get the value of the current character, from 0-26 */

                                                a{i}=int(v/9); /* Get the table of the current character and store at appropriate index, from 0-2 */
                                                a{i+l}=mod(int(v/3),3); /* Get the row of the current character, from 0-2 */
                                                a{i+l*2}=mod(v,3); /* Get the column of the current character, from 0-2 */
                                                end;

                                                f='';

                                                do i = 1 to l*3 by 3; /* For each character in the output... */
                                                f=cats(f,byte(a{i}*9+a{i+1}*3+a{i+2}+97)); /* Convert values back from base 3 to base 10, and convert back into ASCII value */
                                                end;

                                                f = tranwrd(f,"{"," "); /* Replaces our "spaces" with actual spaces for final output */

                                                /* Test cases */
                                                cards;
                                                this is a trifid cipher
                                                test
                                                output
                                                trifidcipher





                                                share|improve this answer












                                                SAS, 305 bytes



                                                A hearty 'oof' for this SAS monstrosity. There's a lot of random string formatting that I thought I could avoid going into this; I'm sure there are better ways of doing some of this.



                                                data;input n:&$99.;n=tranwrd(trim(n)," ","{");if mod(length(n),3)=0then n=cats(n,'{');f=n;l=length(n);array a(999);do i=1to l;v=rank(substr(n,i,1))-97;a{i}=int(v/9);a{i+l}=mod(int(v/3),3);a{i+l*2}=mod(v,3);end;f='';do i=1to l*3by 3;f=cats(f,byte(a{i}*9+a{i+1}*3+a{i+2}+97));end;f=tranwrd(f,"{"," ");cards;


                                                Input is entered on newlines after the cards statement, like so:



                                                data;input n:&$99.;n=tranwrd(trim(n)," ","{");if mod(length(n),3)=0then n=cats(n,'{');f=n;l=length(n);array a(999);do i=1to l;v=rank(substr(n,i,1))-97;a{i}=int(v/9);a{i+l}=mod(int(v/3),3);a{i+l*2}=mod(v,3);end;f='';do i=1to l*3by 3;f=cats(f,byte(a{i}*9+a{i+1}*3+a{i+2}+97));end;f=tranwrd(f,"{"," ");cards;
                                                this is a trifid cipher
                                                test
                                                output
                                                trifidcipher


                                                Outputs a dataset containing the output in the variable f, along with a bunch of helper variables/array values.



                                                enter image description here



                                                Ungolfed/explanation:



                                                data;
                                                input n : & $99.; /* Read a line of input, maximum 99 characters */

                                                n=tranwrd(trim(n)," ","{"); /* Replace spaces with '{' (this is the ASCII character following 'z', so it makes it easy to do byte conversions, and lets us not have to deal with spaces, which SAS does not like) */
                                                if mod(length(n),3)=0then n=cats(n,'{'); /* If length of n is not coprime with 3, add an extra "space" to the end */

                                                f=n; /* Set output = input, so that the string will have the same length */
                                                l=length(n); /* Get the length of the input */
                                                array a(999); /* Array of values to store intermediate results */

                                                do i = 1 to l; /* For each character in the input... */
                                                v = rank(substr(n,i,1))-97; /* Get the value of the current character, from 0-26 */

                                                a{i}=int(v/9); /* Get the table of the current character and store at appropriate index, from 0-2 */
                                                a{i+l}=mod(int(v/3),3); /* Get the row of the current character, from 0-2 */
                                                a{i+l*2}=mod(v,3); /* Get the column of the current character, from 0-2 */
                                                end;

                                                f='';

                                                do i = 1 to l*3 by 3; /* For each character in the output... */
                                                f=cats(f,byte(a{i}*9+a{i+1}*3+a{i+2}+97)); /* Convert values back from base 3 to base 10, and convert back into ASCII value */
                                                end;

                                                f = tranwrd(f,"{"," "); /* Replaces our "spaces" with actual spaces for final output */

                                                /* Test cases */
                                                cards;
                                                this is a trifid cipher
                                                test
                                                output
                                                trifidcipher






                                                share|improve this answer












                                                share|improve this answer



                                                share|improve this answer










                                                answered 5 hours ago









                                                Josh Eller

                                                1913




                                                1913






























                                                    draft saved

                                                    draft discarded




















































                                                    If this is an answer to a challenge…




                                                    • …Be sure to follow the challenge specification. However, please refrain from exploiting obvious loopholes. Answers abusing any of the standard loopholes are considered invalid. If you think a specification is unclear or underspecified, comment on the question instead.


                                                    • …Try to optimize your score. For instance, answers to code-golf challenges should attempt to be as short as possible. You can always include a readable version of the code in addition to the competitive one.
                                                      Explanations of your answer make it more interesting to read and are very much encouraged.


                                                    • …Include a short header which indicates the language(s) of your code and its score, as defined by the challenge.



                                                    More generally…




                                                    • …Please make sure to answer the question and provide sufficient detail.


                                                    • …Avoid asking for help, clarification or responding to other answers (use comments instead).






                                                    Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


                                                    Please pay close attention to the following guidance:


                                                    • Please be sure to answer the question. Provide details and share your research!

                                                    But avoid



                                                    • Asking for help, clarification, or responding to other answers.

                                                    • Making statements based on opinion; back them up with references or personal experience.


                                                    To learn more, see our tips on writing great answers.




                                                    draft saved


                                                    draft discarded














                                                    StackExchange.ready(
                                                    function () {
                                                    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodegolf.stackexchange.com%2fquestions%2f177353%2ftrifid-cipher-without-keyword%23new-answer', 'question_page');
                                                    }
                                                    );

                                                    Post as a guest















                                                    Required, but never shown





















































                                                    Required, but never shown














                                                    Required, but never shown












                                                    Required, but never shown







                                                    Required, but never shown

































                                                    Required, but never shown














                                                    Required, but never shown












                                                    Required, but never shown







                                                    Required, but never shown







                                                    Popular posts from this blog

                                                    Quarter-circle Tiles

                                                    build a pushdown automaton that recognizes the reverse language of a given pushdown automaton?

                                                    Mont Emei