2
\$\begingroup\$

I tried this contest: https://www.hackerrank.com/challenges/secret-language Well, the score in this contest said I made 30 out of 30 points. As the score is calculated with the formula 30*(1000-#chars)/1000 this is impossible. Here is my code:

import sys,string as s
b='anbycoduepfxgqhvirjzkslwmt'
a=s.letters
b+=b.upper()
t=s.translate
m=s.maketrans
for l in sys.stdin:
 print{'N':t(l[7:],m(a,b)),'E':t(l[7:],m(b,a)),'O':''}[l[1]],

The contest is over, so asking is no cheating but I would like to get some realistic score. I have 187 chars with newline and 195 with cr-lf. For pythoncode 24.39 (assuming newline) isn't so bad, but I think it can be done better.

For completeness here is the challenge:

Bob and Fred pass notes to each other in class all the time. However their teacher started intercepting their messages and reading the messages out loud to the class. Undeterred, Bob and Fred decided to encode their messages before they pass them so that when the message is intercepted the teacher and class will not understand it.

They got together and decided on using a simple substitution cipher. The substition cipher they agreed upon is listed below:

Old Letter: ABCDEFGHIJKLMNOPQRSTUVWXYZ New Letter: ANBYCODUEPFXGQHVIRJZKSLWMT

Using this key (Case matters!), A is changed to A, a is changed to a, B is changed to N, b is changed to n, C is changed to B, c is changed to b, … . All other characters remain the same.

However after Bob and Fred started using this method of note transfer they quickly realized that they are very slow at encoding and decoding messages. They have hired you to help them transfer messages faster by writing a program that will encode or decode messages using their substitution cipher. They want the code to be very portable so the smaller the source file is the better.

Input

Input will consist of several lines. Each line will begin with either the string “ENCODE”, “DECODE”, or “DONE”. If the string is “ENCODE” or “DECODE” then a message will follow. This is the message that you will have to either encode (if the first string is “ENCODE”) or decode (if the first string is “DECODE”). Messages will contain spaces and punctuation but will always be on the same line. If the string is “DONE” then this signifies that Bob and Fred are done exchanging messages.

Output

For each line that begins with “ENCODE” print the encoding of the message that follows.

For each line that begins with “DECODE” print the decoding of the message that follows.

Be sure to keep all capitolization and punctuation that is used in the message.

Sample Input

ENCODE This is a message. DECODE Zuej ej a gcjjadc. DONE

Sample Output

Zuej ej a gcjjadc. This is a message.

Scoring

Your score will be 30 * (1000 - #characters) / 1000. The minimum score a correct solution will receive is 0.03.

\$\endgroup\$
1
  • \$\begingroup\$ A real test case would include a DONE followed by another message, which shouldn't be translated. \$\endgroup\$ Commented Mar 28, 2013 at 9:48

4 Answers 4

3
\$\begingroup\$

bash and friends (168 167 chars)

T=ANBYCODUEPFXGQHVIRJZKSLWMT
while read x&&[ "$x" != "DONE" ]
do
[ "$x" \> "E" ]
for((z=1+$?*58;z;z--))do
x=$(tr a-zA-Z `tr A-Z a-z<<<$T`$T<<<$x)
done
echo ${x:6}
done

The magic number isn't so magic: it's obtained by solving a set of simultaneous modular identities obtained from the cycle structure of the permutation.

\$\endgroup\$
1
  • \$\begingroup\$ :O Impressive math... albeit simple, awesome too. \$\endgroup\$
    – kaoD
    Commented Mar 29, 2013 at 5:32
1
\$\begingroup\$

GolfScript, 93 characters

n/{(.1=3%{;0}{(2*343+\6>1/{{..'ANBYCODUEPFXGQHVIRJZKSLWMT'.{32+}%+.@+1/\$@+@?=}%}@*n@1}if}do;

Example:

>ENCODE This is a message.
>DECODE Zuej ej a gcjjadc.
>DONE
>ENCODE This line is not processed

Zuej ej a gcjjadc.
This is a message.

Note: Due to the nature of i/o the input is read completely before processing and output starts.

\$\endgroup\$
1
\$\begingroup\$

K, 95

d:(,/.Q`A`a)!t,_t:"ANBYCODUEPFXGQHVIRJZKSLWMT" 
while[~"DONE"~f:0:0;-1@7_f^$[f like"E*";d@;d?]f]

Example

k)d:(,/.Q`A`a)!t,_t:"ANBYCODUEPFXGQHVIRJZKSLWMT"
k)while[~"DONE"~f:0:0;-1@7_f^$[f like"E*";d@;d?]f]
ENCODE This is a message.
Zuej ej a gcjjadc.
DECODE Zuej ej a gcjjadc.
This is a message.
DONE
\$\endgroup\$
0
\$\begingroup\$

Python, 159

from string import*
n='anbycoduepfxgqhvirjzkslwmt'
r=raw_input
s=r()
while'N'>s[2]:print translate(s[7:],maketrans(*(letters,n+upper(n))[::1-2*('E'>s)]));s=r()
\$\endgroup\$
1
  • \$\begingroup\$ Thank you, I didn't expect raw_input to work as I always thought it must be commited by a CR(newline). Especially I like the trick with reversing the arguments for the maketrans method. \$\endgroup\$ Commented Mar 28, 2013 at 14:25

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.