CoDEVIANT #13 (4/14/19)

Adrian Rosales
6 min readApr 15, 2019

--

Hey there, faithful readers…who I could probably count on one hand, but that’s okay — I love you all. I’m back again with a super-chonk size answer that someone who knows what they’re doing could probably do in the fraction of the size.

Before we run, we must walk, yes?

The far right describes the size of my answers :(

Problem of the Day: Rot13

(https://www.codewars.com/kata/rot13-1/train/javascript)

ROT13 is a simple letter substitution cipher that replaces a letter with the letter 13 letters after it in the alphabet. ROT13 is an example of the Caesar cipher.

Create a function that takes a string and returns the string ciphered with Rot13. If there are numbers or special characters included in the string, they should be returned as they are. Only letters from the latin/english alphabet should be shifted, like in the original Rot13 “implementation”.

How Adrian Solved It…

Oy…this was messy…but I did get it.

Somehow, someway…we get through.
function rot13(message){let answer = [];let regExPattern = /[0–9,!,’ ‘, +,.]/g;//your code hereconsole.log(message);let messageArray = message.split(‘’);console.log(messageArray);//lets make an array of the alphabetlet alphabet = ‘abcdefghijklmnopqrstuvwxyz’.split(‘’);//so we’re going to cycle through each letter as a new array we will create//we will find the value by cycling through the alphabet array//if that value plus 13 equals a new letter, then we push that into our answer array//else we push the value minus 13   messageArray.forEach((currentVal)=>{     console.log(currentVal);     if(currentVal.match(regExPattern)){         answer.push(currentVal);     }      for( let i = 0; i <= alphabet.length — 1; i++ ){         if(currentVal == alphabet[i]){          let value = ( alphabet[i + 13] !== undefined ) ? alphabet[i + 13] : alphabet[i — 13];          console.log(‘value is : ‘ + value);          answer.push(value);        } else if (currentVal == alphabet[i].toUpperCase()){          let capitalValue = ( alphabet[i + 13] !== undefined ) ? alphabet[i + 13].toUpperCase() : alphabet[i — 13].toUpperCase();          answer.push(capitalValue);        } else {}    }})console.log(‘behold our answer ‘);console.log(answer);return answer.join(‘’)//after all is said and done we will join it}
  • We make a variable to hold our answer as an array: answer
let answer = [];
  • We create a RegEx pattern to match the numbers and non-letter characters including a space, a period, exclamation mark, etc.
let regExPattern = /[0–9, !, ‘ ‘, +,.]/g;
  • We create a variable called alphabet that contains each letter of the alphabet and it’s just a string, but instead of painstakingly making something like this:
let alphabet = [‘a’,’b’,’c’….etc…..
  • We instead let string methods do the work for us and simply write out the alphabet -string and then attach .split(‘’) to it which will make it an array for us 😉
let alphabet = ‘abcdefghijklmnopqrstuvwxyz’.split(‘’);
  • We also have made our incoming message argument into an array in a different variable called messageArray, using the same method.
let messageArray = message.split(‘’);
  • At this point we have our players all set up. So we then use the array-method .forEach( ) on messageArray. In .forEach( )’s call back function we pass in currentVal to represent the value currently being processed at a given point in the method’ runtime.
  • Inside our callback function we say the following:
  • If currentVal matches any of the characters we have specified in regExPattern, then push currentVal into answer.
if(currentVal.match(regExPattern)){answer.push(currentVal);}
  • We employ a for-loop inside of this method’s code block where we are iterating over each of the elements in the alphabet array we made and say:
  • If currentVal is equal to the value at the index represented by i in alphabet, then we create a variable called value which is equal to the result of seeing whether or not that index of alphabet plus 13 is undefined or not. If adding 13 makes it undefined, then we make value equal alphabet[i — 13] and pass THAT into answer.
let value = ( alphabet[i + 13] !== undefined ) ? alphabet[i + 13] : alphabet[i — 13];
  • We do the same thing a bit below but create a version where we are seeing if currentVal equals alphabet[i] but if alphabet[i] were capitalized.
…. } else if (currentVal == alphabet[i].toUpperCase()){let capitalValue = ( alphabet[i + 13] !== undefined ) ? alphabet[i + 13].toUpperCase() : alphabet[i — 13].toUpperCase();answer.push(capitalValue);} ….
  • By this point we are basically out of the scope of the .forEach( ) method’s callback block, and we can return answer as a string by appending it with .join(‘’).

return answer.join(‘’);

Et voila.

You’re welcome…sometimes I impress myself, even.

Finalized prett(ier) answer:

function rot13(message){let answer = [];let regExPattern = /[0–9,!,’ ‘, +,.]/g;let messageArray = message.split(‘’);let alphabet = ‘abcdefghijklmnopqrstuvwxyz’.split(‘’);   messageArray.forEach((currentVal)=>{      if(currentVal.match(regExPattern)){         answer.push(currentVal);      }    for( let i = 0; i <= alphabet.length — 1; i++ ){      if(currentVal == alphabet[i]){      let value = ( alphabet[i + 13] !== undefined ) ? alphabet[i + 13] : alphabet[i — 13];      answer.push(value);      } else if (currentVal == alphabet[i].toUpperCase()){

let capitalValue = ( alphabet[i + 13] !== undefined ) ? alphabet[i + 13].toUpperCase() : alphabet[i — 13].toUpperCase();
answer.push(capitalValue); } else { } }});return answer.join(‘’)}
You’ll say my answer is pretty chonky though when you see what smart people did instead.

Best Practices

function rot13(message) {var a = “abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ”var b = “nopqrstuvwxyzabcdefghijklmNOPQRSTUVWXYZABCDEFGHIJKLM”return message.replace(/[a-z]/gi, c => b[a.indexOf(c)])}
….yeah this answer is thin *sobs and eats Oreos*

Ok…well I kinda like mine better, because I didn’t need to make two large strings to hop around with…but w/e, err’body’s a critic.

My answer may be fat, but it’s readable and full of character!….and hate ;)

This thin answer does involve far less looping so if something like this needed to be put to scale, this is the kind of solution you’d want, I guess 😕

  • So we have two variables a and b, each of which represent the alphabet starting and different points, the start and the middle.
  • Then we return message with the .replace( ) method appended to it.
  • In this use of .replace( ) we have two unique arguments being passed in:
  • /[a-z]/gi a regex pattern we are matching all letters across the entire string regardless of case
  • c => b[a.indexOf(c)] a function that creates a new substring to be used to replace the matches to the given regex expression above.
  • For each character, if it is a letter, the result of c will be whatever value is at the index (defined by where a matches up with the value c is currently at…) IN THE B string.
  • So if c is ’t’, then a would be ’t’ at that moment and we would get the value of let’s say ’13’, so a[13] would be t, but since that’s all in a bracket to evaluate to a number-index we can use with b, then we’ll get ‘g’…the opposite in this context of ’t’.

Good job, nerds.

I could have done it that way too…if I wanted too and had intense training and mentorship *boo hoo hoo*

Have a great day!

--

--

Adrian Rosales
Adrian Rosales

Written by Adrian Rosales

is a web developer, opera singer, actor, and lover of cats. (adrian-rosales.tech)

No responses yet