Caesar Cipher
The Challenge
Write a function CaesarCipher(str, num) that takes a string and shifts each letter by num places in the alphabet. Punctuation, spaces, and capitalization should stay exactly the same.
For example, if the string is "Caesar Cipher" and num is 2, the output should be "Ecguct Ekrjgt".
Examples
CaesarCipher("Caesar Cipher", 2) → "Ecguct Ekrjgt"
CaesarCipher("Hello, World!", 5) → "Mjqqt, Btwqi!"Solution
function CaesarCipher(str, num) {
return str.split('').map(char => {
const code = char.charCodeAt(0);
if (code >= 65 && code <= 90) {
// Uppercase letters
return String.fromCharCode(((code - 65 + num) % 26 + 26) % 26 + 65);
} else if (code >= 97 && code <= 122) {
// Lowercase letters
return String.fromCharCode(((code - 97 + num) % 26 + 26) % 26 + 97);
} else {
// Anything else stays the same
return char;
}
}).join('');
}Explanation
- 65 to 90 are the ASCII codes for uppercase letters (A to Z).
- 97 to 122 are the ASCII codes for lowercase letters (a to z).
const shifted = ((char.charCodeAt(0) - 65 + shift) % 26 + 26) % 26;- Subtracting 65 moves the range from 65~90 down to 0~25, so
Abecomes0,Bbecomes1, and so on up toZas25. - Taking the remainder with
% 26wraps the shift around the alphabet, so a letter near the end loops back to the start instead of going out of range. - Adding
26before the second% 26handles negative shift values, making sure the result always stays positive even ifnumis negative. - Once you have the final value between
0and25, adding65back converts it to the correct ASCII code for an uppercase letter.
- Subtracting 65 moves the range from 65~90 down to 0~25, so
- Any character that is not a letter, like a space, comma, or exclamation mark, falls into the
elsebranch and is returned unchanged. This is why punctuation and spacing stay intact in the output.
Basic Roman Numerals
The Challenge
Convert a Roman numeral string into its numeric value.
Examples
BasicRomanNumerals("IV") → 4
BasicRomanNumerals("XLVI") → 46
BasicRomanNumerals("XXIV") → 24Solution
function BasicRomanNumerals(str) {
const romanValues = {
I: 1,
V: 5,
X: 10,
L: 50,
C: 100,
D: 500,
M: 1000
};
let total = 0;
for (let i = 0; i < str.length; i++) {
const current = romanValues[str[i]];
const next = romanValues[str[i + 1]];
if (next && current < next) {
total -= current;
} else {
total += current;
}
}
return total;
}Explanation
- Each Roman letter has a fixed value:
I is 1, V is 5, X is 10, L is 50, C is 100, D is 500, M is 1000.
- The loop checks each letter one at a time.
- It compares the current letter's value with the next letter's value.
- If the current value is smaller than the next value, this is a subtraction case, like IV or XL. So the code subtracts it instead of adding it.
- If not, the code just adds the current value to the total.
- This single loop handles both normal numerals and subtractive ones.
Star Rating
The Challenge
Convert a numeric rating string into a star rating made of full, half, and empty stars out of 5.
Examples
StarRating("2.36") → "full full half empty empty"
StarRating("4.9") → "full full full full full"
StarRating("0.2") → "empty empty empty empty empty"
StarRating("3.24") → "full full full empty empty"
StarRating("3.25") → "full full full half empty"Solution
function StarRating(str) {
const rating = parseFloat(str);
const rounded = Math.round(rating * 2) / 2;
const fullStars = Math.floor(rounded);
const hasHalf = rounded - fullStars === 0.5;
const emptyStars = 5 - fullStars - (hasHalf ? 1 : 0);
const stars = [];
for (let i = 0; i < fullStars; i++) {
stars.push('full');
}
if (hasHalf) {
stars.push('half');
}
for (let i = 0; i < emptyStars; i++) {
stars.push('empty');
}
return stars.join(' ');
}Explanation
- parseFloat turns the input string into a real number, so "2.36" becomes 2.36.
- Multiplying by 2, rounding, then dividing by 2 rounds the number to the nearest 0.5. This is a common trick for half step rounding.
- Math.floor gives the number of full stars.
- If the rounded value has a leftover of exactly 0.5, that means there is one half star.
- Empty stars are whatever is left after full stars and the half star are subtracted from 5.
- A for loop adds "full" that many times, then one "half" is added if needed, then another for loop adds "empty" for the rest.
- join(' ') turns the list into one readable string.
Run Length
The Challenge
Compress a string by counting how many times each character repeats in a row.
Examples
RunLength("aabbcde") → "2a2b1c1d1e"
RunLength("wwwbbbw") → "3w3b1w"
RunLength("wwwggopp") → "3w2g1o2p"Solution
function RunLength(str) {
let result = '';
let count = 1;
for (let i = 0; i < str.length; i++) {
if (str[i] === str[i + 1]) {
count++;
} else {
result += count + str[i];
count = 1;
}
}
return result;
}Explanation
- The loop walks through the string one character at a time and keeps a running count.
- If the current character matches the next one, the count simply goes up.
- If it does not match, the streak has ended. The code adds the count and the character to the result, then resets the count back to 1.
- This turns every group of repeated characters into a number followed by that character.
Number Encoding
The Challenge
Replace every letter in a string with its position in the alphabet. Everything else stays the same.
Examples
NumberEncoding("af5c a#!") → "1653 1#!"
NumberEncoding("hello 45") → "85121215 45"
NumberEncoding("jaj-a") → "10110-1"Solution
function NumberEncoding(str) {
let result = '';
for (let i = 0; i < str.length; i++) {
const char = str[i];
if (char >= 'a' && char <= 'z') {
const position = char.charCodeAt(0) - 96;
result += position;
} else if (char >= 'A' && char <= 'Z') {
const position = char.charCodeAt(0) - 64;
result += position;
} else {
result += char;
}
}
return result;
}Explanation
- The loop checks each character in the string one by one.
- If the character is a lowercase letter, subtracting 96 from its ASCII code gives its position in the alphabet. This makes 'a' equal to 1, 'b' equal to 2, and so on up to 'z' as 26.
- If the character is an uppercase letter, the same idea applies, but with 64 instead of 96, since uppercase letters start at a different ASCII value.
- Anything that is not a letter, like a space or a symbol, gets added to the result exactly as it is.
- Counting starts from 1, not 0, so 'a' becomes 1 instead of 0.

