Alphabet Between Encryption

4

You must write a program that encrypts an input into a string of characters.

For every character i in the input up to the second to last character, take the i and i+1 characters and encode them by writing the letters of the alphabet, in order, that range in the same direction between those chosen characters.

For example: if the original string were bo then it would be encoded as cdefghijklmn, but if the string were boa then bo is encoded as cdefghijklmn and oa is encoded as nmlkjihgfedcb with the final encrypted string being cdefghijklmnnmlkjihgfedcb.

If the original string contain zero letters between two chosen characters, such as the string ab then you should encrypt it as aRb with R standing for what direction in the alphabet to go in determining the original characters. The encrypted string aRb represents ab but the encrypted string aLb represents ba (R = right, L = left).

If two chosen characters in the original string are the same, such as the string tt, then you should encrypt it as tZt with Z standing for zero letters in between.

Examples:

Input: att Output: bcdefghijklmnopqrstZt

Input: brep Output: cdefghijklmnopqqponmlkjihgffghijklmno

Input: Optimizer Output: oRpqrssrqponmlkjjkllkjjklmnopqrstuvwxyyxwvutsrqponmlkjihgffghijklmnopq

Rules:

  • You can write a program or a function.
  • Your input may contain uppercase letters, so you need to put them all to lowercase before encrypting.
  • You can ignore non-alphabet characters.
  • One character length strings are undefined.
  • Shortest code in bytes wins!

phase

Posted 2015-07-22T01:10:27.937

Reputation: 2 540

1I'm not sure I quite get all the rules - what's the expected output for aabbcfcBBAa? – Sp3000 – 2015-07-22T01:22:09.513

Is "ab" encrypted as "aZb"? Is "aa" encrypted as "aZa"? – MtnViewMark – 2015-07-22T01:25:51.363

@Sp3000 aZa aRb bZb bRc de ed cRb bZb bLa aZa without any spaces. – phase – 2015-07-22T01:27:01.977

@MtnViewMark ab = aRb, aa = aZa – phase – 2015-07-22T01:27:37.367

What should the output be for the input a? – Doorknob – 2015-07-22T02:36:14.937

@Doorknob That is undefined, meaning it doesn't matter. – phase – 2015-07-22T02:41:10.850

Does "You can ignore non-alphabet characters." mean that we can expect the input to be letters only or can the input have non-letters and we have to filter them out? – Sp3000 – 2015-07-22T11:49:13.260

shouldn't cB in @Sp3000's test be encoded cLb not cRb? – MtnViewMark – 2015-07-22T22:31:25.183

@MtnViewMark Yes, I messed up. – phase – 2015-07-22T22:35:24.767

@phase In your question, you wrote that the encrypted string aLb represents ba. This mean that the letters are always ordered alphabetically and cLb or bLa is invaild. – TheCrypt – 2015-07-26T08:24:08.563

Answers

3

Pyth, 38 bytes

M|strFGjHGsm?>Fd_g_d\Lgd?qFd\Z\R.:rzZ2

Demonstration.

M|strFGjHGsm?>Fd_g_d\Lgd?qFd\Z\R.:rzZ2
                                          Implicit: z = input(), Z = 0
                                          g is a function of a 2 letter string
                                          and an insert letter.
M                                         def g(G, H): return
    rFG                                   Take the string range between the
                                          letters in G.
   t                                      Remove the first letter to get just
                                          the letters in between.
  s                                       Concatenate.
 |                                        Logical or (if nothing in between)
       jHG                                H.join(G)
                                  rzZ     Convert input to lowercase.
                                .:   2    Take 2 letter substrings.
           m                              Map d over the substrings
            ?>Fd                          If the first character of `d`
                                          is greater than the second,
                 _g_\L                    g(d[::-1], 'L')[::-1]
                      gd                  else, g(d,
                        ?qFd              if the letters of d are the same,
                            \Z            'Z'
                              \R          else 'R')
          s                               Concatenate and print.

isaacg

Posted 2015-07-22T01:10:27.937

Reputation: 39 268

3

C - 161 Bytes - GCC

#define y(x) putchar(x)
main(_,z){for(_=getchar();-~(z=getchar());_=z)for(_==z?y(_),y(90),y(z):-~_==z?y(_++),y(82),y(z):_==-~z?y(_),y(76),y(z):_;_<z;y(_),_++);}

Will update when I get it shorter

jake

Posted 2015-07-22T01:10:27.937

Reputation: 31

2

JavaScript ES6, 253 bytes

(d,y=`abcdefghijklmnopqrstuvwxyz`)=>[...`${d}`.toLowerCase()].map((l,i,a,m=a[i-1],c=s=>y.search(s),d=(s,e)=>y.slice(c(s),c(e)).slice(1),j=c(m),k=c(l))=>m?l==m?l+'Z'+l:j+1==k?m+'R'+l:k+1==j?l+'L'+m:j>k?[...d(l,m)].reverse().join``:k>j?d(m,l):0:'').join``

Just by glancing you can see all the places where this can be golfed. I can probably chop off 100 bytes.

Ungolfed:

(d,y=`abcdefghijklmnopqrstuvwxyz`)=>
[...`${d}`.toLowerCase()].map((l,i,a, m=a[i-1],
 c=s=>y.search(s),
 d=(s,e)=>y.slice(c(s),c(e)).slice(1))
   =>m?
     l==m?         l+'Z'+l:
     c(m)+1==c(l)? m+'R'+l:
     c(l)+1==c(m)? l+'L'+m:
     c(m)>c(l)?    [...d(l,m)].reverse().join``:
     c(l)>c(m)?    d(m,l):  0:
'').join``

You can clearly see where this can be golfed in the ?: sequence.


ES5 Snippet:

function t(d) {
    var y = 'abcdefghijklmnopqrstuvwxyz';
    return (d+'').toLowerCase().split('').map(function (l,i,a) {
        var m = a[i - 1],
            c = function (s) {
                return y.search(s)
            },
            d = function (s,e) {
                return y.slice( c(s), c(e) ).slice(1);
            };
       return m ? 
              l == m           ? l + 'Z' + l :
              c(m) + 1 == c(l) ? m + 'R' + l :
              c(l) + 1 == c(m) ? l + 'L' + m :
              c(m) > c(l)      ? d(l,m).split('').reverse().join('') :
              c(l) > c(m)      ? d(m,l)                              :
              0 : ''
    }).join('');
}

// Demo
document.getElementById('go').onclick=function(){
  document.getElementById('output').innerHTML = t(document.getElementById('input').value)
};
<div style="padding-left:5px;padding-right:5px;"><h2 style="font-family:sans-serif">Encoding Snippet</h2><div><div  style="background-color:#EFEFEF;border-radius:4px;padding:10px;"><input placeholder="Text here..." id="input"><button id='go'>Encode!</button></div><br><div style="background-color:#EFEFEF;border-radius:4px;padding:10px;"><span style="font-family:sans-serif;">Output:</span><br><pre id="output" style="background-color:#DEDEDE;padding:1em;border-radius:2px;overflow-x:auto;"></pre></div></div></div>

Downgoat

Posted 2015-07-22T01:10:27.937

Reputation: 27 116

By setting y, can you use a different alphabet/set of characters? – phase – 2015-07-22T02:23:31.480

@phase yeah, that contains all the characters the program uses. – Downgoat – 2015-07-22T02:26:17.167

1

Python 343 334 bytes

import sys,re,string
j=''.join
a=string.ascii_lowercase
for l in sys.stdin:
 s,L=re.sub('[^a-z]','',l.lower()).strip(),[]
 for i,c in enumerate(s[:-1]):o=s[i+1:i+2]or c;b,d=a.index(c),a.index(o);L.extend(j(e[1])for e in[(c==o,[c,'Z',c]),(c<o,(a[b+1:d],[c,'R',o])[b+1==d]),(c>o,(a[d+1:b][::-1],[c,'L',o])[b-1==d])]if e[0])
 print(j(L))

Code on ideone.

First golf ever. Any suggestions would be great.

Winny

Posted 2015-07-22T01:10:27.937

Reputation: 1 120

Welcome to the site! A couple of suggestions: Using semicolons to separate your lines instead of newlines is typically shorter, as it avoids indentation. Also, you can alias ''.join to something shorter, like j, which saves bytes because you use it twice. Take a look at this page if you want more tips.

– isaacg – 2015-07-22T11:12:41.720

Hi, thanks! How would I go about aliasing a built-in's method invocation to save space? For example this is illegal in all pythons str.j=str.join since 'str' is a built-in type. I could do something like j=lambda L:''.join(L) (21 bytes), but the definition alone is as twice as long as ''.join(L) (10 bytes). – Winny – 2015-07-22T11:23:05.540

It's very simple: j=''.join – isaacg – 2015-07-22T11:29:05.267

Super! I overthought that one! Thanks a bunch! – Winny – 2015-07-22T11:33:51.017

1

K5, 77 bytes

ouch

,/{$[(p:d>0)&3>d:1+x-y;"LZR"@d;`c$$[p;1_y+!x-y;|1_x+!y-x]]}':{(x;x+32)@x<97}'

Explanation coming after more golfing.

kirbyfan64sos

Posted 2015-07-22T01:10:27.937

Reputation: 8 730

1

Haskell, 168 bytes

import Data.Char
s=succ
b#a|a==b=[a,'Z',b]|s a==b=[a,'R',b]|a==s b=[a,'L',b]|a>b=reverse$a#b|a<b=[s a..pred b]
e=concat.(tail>>=zipWith(#)).map toLower.filter isLetter

running:

λ: e "att"
"bcdefghijklmnopqrstZt"
λ: e "brep"
"cdefghijklmnopqqponmlkjihgffghijklmno"
λ: e "Optimizer"
"oRpqrssrqponmlkjjkllkjjklmnopqrstuvwxyyxwvutsrqponmlkjihgffghijklmnopq"
λ: e "aabbcfcBBAa"
"aZaaRbbZbbRcdeedcLbbZbbLaaZa"

MtnViewMark

Posted 2015-07-22T01:10:27.937

Reputation: 4 779

Nice. 1 byte to save: use both id=<< instead of concat and a list comprehension instead of map and filter: e x=id=<<(tail>>=zipWith(#))[toLower i|i<-x,isLetter i] – nimi – 2015-07-24T12:55:44.727

0

Haskell, 185 bytes

import Data.Char
s=succ
p=pred
f(a:b:c)|b==s a=q 'R'|a==s b=q 'L'|a==b=q 'Z'|a<b=[s a..p b]++n|a>b=[p a,p$p a..s b]++n where q m=a:m:b:n;n=f(b:c)
f _=[]
g x=f[toLower e|e<-x,isLetter e]

Usage: g "brep" -> "cdefghijklmnopqqponmlkjihgffghijklmno".

How it works: g throws away all non-letters and converts the letters to lower case and calls f to do the encryption. Depending on the first two characters f inserts R, L or Z or builds the sequence in-between and and appends the result of a recursive call of itself with the tail of the input.

nimi

Posted 2015-07-22T01:10:27.937

Reputation: 34 639