Wasn’t crazy about the amount of hard coding I did in my solution - did anyone have a different approach? Using a regex maybe?
function rot13(str) { // LBH QVQ VG!
var myCipher = [];
var myArray = [];
for (i=0; i < str.length; i++) {
// convert character - or don't if it's a punctuation mark. Ignore spaces.
if (str.charCodeAt(i) > 64 && str.charCodeAt(i) < 78) {
myArray.push(String.fromCharCode(str.charCodeAt(i) + 13));
} else if (str.charCodeAt(i) > 77 && str.charCodeAt(i) < 91) {
myArray.push(String.fromCharCode(77 - (90 - str.charCodeAt(i))));
} else if (str.charCodeAt(i) > 32 && str.charCodeAt(i) < 65) {
myArray.push(str.charAt(i));
}
// push word onto array when encountering a space or reaching the end of the string
if (str.charCodeAt(i) == 32) {
myCipher.push(myArray.join(''));
myArray.length = 0;
}
if (i == (str.length - 1)) {
myCipher.push(myArray.join(''));
}
}
return myCipher.join(" ");
}
// Change the inputs below to test
rot13("SERR CVMMN!");
Check out this video. It’s actually about implementing caesar’s in C, and the conditions are a bit different iirc, but the most juicy part is a mathematical formula they give you somewhere towards the end
It’s unlikely that char codes are likely to change, so I would have been fine using them. I chose to just get the codes for A, Z, and N. In cases where you know absolutely that the value won’t change (for example, the freezing temperature of water will always be 0C/32F) then it’s fine to rely on that but the best practice is still to assign it to a variable. When we know a variable won’t actually vary in value we call it a “constant” and these are usually named using all capital letters (var FREEZING_C = 0;) and put them at the top of the file.
Anyway, if you want to look at a different approach, here is mine:
function rot13(str) { // LBH QVQ VG!
var strArr = str.split('');
var start = 'A'.charCodeAt(0);
var middle = start + 13;
var end = 'Z'.charCodeAt(0);
strArr = strArr.map(function(currLetter){
var code = currLetter.charCodeAt(0);
var shift = 13;
if (code >= start){
if (code < middle){ // A-M
}
else if (code <= end){ // N-Z
shift = code - middle;
code = start;
}
return String.fromCharCode(code + shift);
}
else { // non letters
return currLetter;
}
});
str = strArr.join('');
return str;
}
// Change the inputs below to test
rot13("SERR CVMMN!");
Just finished mine. About two hours of work. A bit messy, could be cleaned up.
My solution
function rot13(str) {
// Build arr1 - array of character codes of str
var arr1 = [];
for ( var i = 0; i < str.length; i++ ) {
arr1.push(str.charCodeAt(i));
}
// Build arr2 - array of new character codes of str (ROT13)
var arr2 = [];
for ( var j = 0; j < str.length; j++ ) {
if ( arr1[j] >= 65 && arr1[j] <= 77 ) {
arr2.push(arr1[j]+13);
}
else if ( arr1[j] >= 78 && arr1[j] <= 90 ) {
arr2.push(arr1[j]-13);
}
else arr2.push(arr1[j]);
}
// Build str2 - string made from the new character codes above
var str2 = "";
for ( var k = 0; k < str.length; k++ ) {
var x = String.fromCharCode(arr2[k]);
str2 = str2.concat(x);
}
return str2;
}
// Change the inputs below to test
rot13("SERR PBQR PNZC");
Hi! I’d like to share my code as well. I did this with very, very minimal help (only using the ref links in the question and searching for the formula wrap to wrap around A - Z), took around 2hrs(?) and I am really happy about it! It’s messy but it works
function rot13(str) { // LBH QVQ VG!
var splitStr = str.split('');
var ciphCode = [];
var cipher = '';
// loop through the str array and +13 to each charCode
for (var i = 0; i < splitStr.length; i++) {
// in the ASCII table, A - Z is 65 - 90
if (splitStr[i].charCodeAt(splitStr[i]) > 64 && splitStr[i].charCodeAt(splitStr[i]) < 91) {
ciphCode.push(splitStr[i].charCodeAt(splitStr[i]) + 13);
// formula to wrap around A - Z
if (ciphCode[i] > 90) {
ciphCode[i] = ((ciphCode[i] - 65) % 26) + 65;
}
} else {
// push the array element as usual if it is not A - Z
ciphCode.push(splitStr[i]);
}
}
// loop ciphCode back into a string using fromCharCode
for (var j = 0; j < ciphCode.length; j++) {
if (ciphCode[j] > 64 && ciphCode[j] < 91) {
cipher += String.fromCharCode(ciphCode[j]);
} else {
cipher += ciphCode[j];
}
}
return cipher;
}
Here is my code as well; definitely need to work on regex. It would have made this a whole lot simpler like the example way above ^^
function rot13(str) { // LBH QVQ VG!
var arr = [];
var newString = '';
for (var i = 0; i<str.length; i++){
var val = str.charCodeAt(i);
if (val >= 65 && val <= 90 ){
if (val < 78){
val += 13;
var hold = String.fromCharCode(val);
newString += hold;
}
else if (val >= 78) {
val -= 13;
var holdE = String.fromCharCode(val);
newString += holdE;
}
}
else{
newString += str[i];
}
}
return newString;
}
Here is mine. It’s not pretty but I think it may be fairly legible to people with basic knowledge.
function rot13(str) { // LBH QVQ VG!
var regEx = /[A-M]/;
var regEx2 = /[N-Z]/;
var holder = [];
for (var i = 0; i < str.length; i++) {
if (regEx.test(str[i])) { //test if str[i] is A-M
holder[i] = str.charCodeAt(i)+13; //if true, push ASCII+13 to holder
} else if (regEx2.test(str[i])) { //test if str[i] is N-Z
holder[i] = str.charCodeAt(i)-13; //if true, push ASCII-13 to holder
} else if (!regEx.test(str[i]) && !regEx2.test(str[i])) { //test if str[i] is neither A-M nor N-Z, i.e non-alphabetic
holder[i] = str.charCodeAt(i); //if true, push to holder as is
}
} return String.fromCharCode.apply(null, holder); //return holder array as string by using .apply method
}
// Change the inputs below to test
rot13("FREE PIZZA!");
I had to take a break from this one, disappointing being right at the end of those challenges. When I came back to it though, it was really fun to work through. I used a fairly simple solution without RegEx though:
function rot13(str) { // LBH QVQ VG!
var tst = []; var i = 0; // tst is array of inputs, i is iteration through strings
var arr = []; // arr is array to return(?), l is length of strings to find
////////////////////////////////////////////////////////////////////////////////////////////////
tst = str.split(''); // split string into array of strings no seperator counts each
// element
function change(num) { // function to get unicode of decoded letter
if ((num > 90) || (num < 65)) { return num; } // leave alone if not capital letter
else if ((num + 13) > 90) { // subtract if adding goes beyond Z
return num - 13;
}
else return num + 13;
}
while ( i < tst.length ) { // iterate through array of strings to find uni vals
var word = tst[i]; var uni = []; // word is current string, uni is temp array of unicode
var dec = []; // dec is array (yes another) to decypher unicode vals
for ( var n=0; n < word.length; n++) {
uni.push(word.charCodeAt(n)); // get array of unicode for decyphering
}
for (var p= 0; p< uni.length; p++) { // loop through cyphered unicode
dec.push(change(uni[p])); // using change function, find decyphered unicode values
arr.push(String.fromCharCode(dec[p])); // create array of letters from decyphered unicode
}
i++;
}
/*x = arr.toString(); var re = (/,/g);
x = x.replace(re, " ");*/
//return String.fromCharCode(91); //testing
return arr.join(''); // join to string (remove commas with (''))
}
// Change the inputs below to test A=65, Z=90
rot13("XYNGH ORENGN AVXGH!");
I also find it fun to comment the crap out of challenges I finished afterward (can ya tell?)
TL;DR - Basically I made a function to translate unicode into letters and told it to leave anything that wasn’t a capital letter alone, that way I didn’t have to worry about putting spaces and exclamations back in. I’m happy with how it turned out.
I thought it’d be nice to share my solution with ya’ll. I took a simpler approach in solving this. I’m open for suggestions. Thanks!
function rot13(str) { // LBH QVQ VG!
var alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
str = str.split('');
var res = '';
for (var i = 0; i < str.length; i++) {
if (alphabet.indexOf(str[i]) !== -1) { // if letter exists in alphabet do the following
if (alphabet.indexOf(str[i]) < 13) { // if letter is positioned before the first 13 characters
res += String.fromCharCode(str[i].charCodeAt(0) + 13); // decode letter by adding 13 more ie 'E'->'R'
} else {
res += String.fromCharCode(str[i].charCodeAt(0) - 13); // if not, decode letter by subtracting 13 letter ie 'S'->'F'
}
} else {
res += str[i]; // if character is not part of alphabet, simply append to solution string
}
}
return res;
}
// Change the inputs below to test
rot13("SERR PBQR PNZC");
// console.log(rot13("LBH QVQ VG!"));