Where is my implementation of rot13 in JavaScript going wrong?
Solution 1:
You could use the super-short:
s.replace(/[a-zA-Z]/g,function(c){return String.fromCharCode((c<="Z"?90:122)>=(c=c.charCodeAt(0)+13)?c:c-26);});
Solution 2:
Here's a solution using replace
and indexOf
functions:
function rot13(s) {
return s.replace(/[A-Z]/gi, c =>
"NOPQRSTUVWXYZABCDEFGHIJKLMnopqrstuvwxyzabcdefghijklm"[
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz".indexOf(c) ] )
}
This is made up of:
-
/[A-Z]/gi
regular expression for matching only characters -
replace
is used to substitute those characters - an a replacer function written as an arrow function
-
indexOf
is to convert the character into a numeric lookup index - we lookup the index in the substitution array and we're done
Solution 3:
This gives correct results.
function rot13(s)
{
return (s ? s : this).split('').map(function(_)
{
if (!_.match(/[A-Za-z]/)) return _;
c = Math.floor(_.charCodeAt(0) / 97);
k = (_.toLowerCase().charCodeAt(0) - 83) % 26 || 26;
return String.fromCharCode(k + ((c == 0) ? 64 : 96));
}).join('');
}
alert(rot13(rot13("Mark this as accepted answer :)")));
Solution 4:
Just because it's even shorter and also more understandable/logical:
function rot13(s) {
return s.replace( /[A-Za-z]/g , function(c) {
return String.fromCharCode( c.charCodeAt(0) + ( c.toUpperCase() <= "M" ? 13 : -13 ) );
} );
}