Encoding Input Data: ABC - Output: ZBYX
The encoding happens such that the odd numbered letters of the English alphabet are replaced by their alphabetic opposite, even numbered letters are replaced by a combination of that same letter and it's alphabetic opposite (ie. as shown above 'B' is even numbered alphabet so it got replaced as 'BY', A is replaced by Z, C is replaced by X)
I need to decode the encoded output data to get the input (the reverse logic). I wrote the below function but it doesn't quite give me the expected output for all test cases. (eg: When the input is ZBYX, output comes up correctly as ABC, but in other cases such as:
- JQPLO (input) - output comes as QJKL (supposed to come as JKL)
- NMLPK (input) - output comes as MNOP (supposed to come as NOP)
)
How should I refactor the below code so that I get the expected output for all test cases?
let alpha="ABCDEFGHIJKLMNOPQRSTUVWXYZ"
function decode(str){
let answer=""
for(let i=0;i<str.length;i ){
if(alpha.indexOf(answer[answer.length-1])%2==0){
if((alpha.indexOf(str[i]) 1)%2==0){
continue
}
answer =alpha[alpha.length-(alpha.indexOf(str[i]) 1)]
}else{
answer =alpha[alpha.length-(alpha.indexOf(str[i]) 1)]
}
}
return answer
}
CodePudding user response:
The trick for decoding is, if you get to an even letter l
AND the next letter is the opposite of l
, then you add l
to the decoded output and skip the next letter. Otherwise, you need to just add the opposite of l
to the output.
I would recommend trying it yourself before reading the code below, but the below code passed all the test cases you provided.
let alpha = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
function isEven(c) {
return (alpha.indexOf(c) 1) % 2 === 0;
}
function opposite(c) {
return alpha[alpha.length - alpha.indexOf(c) - 1];
}
function encode(str) {
let answer = "";
for (let i = 0; i < str.length; i ) {
if (!isEven(str[i])) {
answer = opposite(str[i]);
} else {
answer = str[i];
answer = opposite(str[i]);
}
}
return answer;
}
function decode(str) {
let answer = "";
for (let i = 0; i < str.length; i ) {
if (isEven(str[i]) && str[i 1] === opposite(str[i])) {
answer = str[i];
i ;
} else {
answer = opposite(str[i]);
}
}
return answer;
}
console.log(encode('ABC'));
console.log(decode('ZBYX'));
console.log(decode('NMLPK'));
console.log(decode('JQPLO'));
CodePudding user response:
const alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
const decode = str => {
str = str.split("").reduce((p, c, i, arr) => {
if (alphabet.indexOf(arr[i 1]) % 2 !== 0)
p = alphabet[25 - alphabet.indexOf(c)];
return p
}, "");
return str;
}
console.log(decode("ZBYX"));
console.log(decode("JQPLO"));
console.log(decode("NMLPK"));
const encode = str => {
str = str.split("").reduce((p, c) => {
if (alphabet.indexOf(c) % 2 !== 0)
p = c alphabet[25 - alphabet.indexOf(c)];
else
p = alphabet[25 - alphabet.indexOf(c)];
return p
}, "");
return str
}
console.log(encode("ABC"));
CodePudding user response:
I eventually figured out a solution based off my initial program in the question, I just don't know how it works but it passed all test cases; Thanks for all the other answers here, appreciate the effort guys!
here's my updated code:
function decode(str){
try{
let answer=""
if(!(/^[A-Z] $/).test(str)){
throw Error("Input must only contain upper case letters")
}
for(let i=0;i<str.length;i ){
if(alpha.indexOf(answer[answer.length-1])%2==0){
if((alpha.indexOf(str[i]) 1)%2==0){
continue
}
}else{
if(str.length>4)answer=answer.slice(-1)
}
answer =alpha[alpha.length-(alpha.indexOf(str[i]) 1)]
}
return answer
} catch (err){
console.log(err)
}
}
I just added a condition to check for the string length given at the input under the else block, but I guess the other answers here were more logical than mine