/** * Calculates the frequency of each letter in a given string. * * @param {string} str - The input string. * @returns {string} - A formatted string representing the letter frequency. */ function getLetterFrequency(str) { const frequencyMap = new Map(); const totalLetters = str.length; for (let i = 0; i < str.length; i++) { const letter = str[i]; if (frequencyMap.has(letter)) { frequencyMap.set(letter, frequencyMap.get(letter) + 1); } else { frequencyMap.set(letter, 1); } } const sortedMap = new Map([...frequencyMap.entries()].sort((a, b) => b[1] - a[1])); let mapString = Array.from(sortedMap) .map(([key, value]) => `${key}: ${value} (${(value / totalLetters * 100).toFixed(2)}%)`) .join("\n"); console.log(mapString); return mapString; } function removeWhitespaces(str) { return str.replace(/\s/g, ''); } /** * Counts the frequency of each character in a given string. * * @param {string} str - The input string. * @returns {string} - A formatted string displaying the count and percentage of each character. */ function countSingle(str){ let singCount = {}; const totalLetters = str.length; for (let i = 0; i < str.length; i++) { let letter = str[i]; if (singCount[letter]) { singCount[letter]++; } else { singCount[letter] = 1; } } const sortedCount = Object.entries(singCount) .sort((a, b) => b[1] - a[1]); let countString = sortedCount .map(([key, value]) => `${key}: ${value} (${(value / totalLetters * 100).toFixed(2)}%)`) .join("\n"); console.log(countString); return countString; } /** * Counts the frequency of digrams in a given string. * * @param {string} str - The input string. * @returns {string} - A string representation of the digram counts. */ function countDigrams(str) { let digramCounts = {}; const totalDigrams = str.length - 1; for (let i = 0; i < totalDigrams; i++) { let digram = str.substring(i, i + 2); if (digramCounts[digram]) { digramCounts[digram]++; } else { digramCounts[digram] = 1; } } const sortedCounts = Object.entries(digramCounts) .sort((a, b) => b[1] - a[1]); let digramString = sortedCounts .map(([key, value]) => `${key}: ${value} (${(value / totalDigrams * 100).toFixed(2)}%)`) .join("\n"); return digramString; } /** * Counts the occurrences of trigrams in a given string. * * @param {string} str - The input string. * @returns {string} - A formatted string displaying the trigram counts and percentages. */ function countTrigrams(str) { let trigramCounts = {}; const totalTrigrams = str.length - 2; for (let i = 0; i < totalTrigrams; i++) { let trigram = str.substring(i, i + 3); if (trigramCounts[trigram]) { trigramCounts[trigram]++; } else { trigramCounts[trigram] = 1; } } let sortedCounts = Object.entries(trigramCounts) .sort((a, b) => b[1] - a[1]); let trigramString = sortedCounts .map(([key, value]) => `${key}: ${value} (${(value / totalTrigrams * 100).toFixed(2)}%)`) .join("\n"); return trigramString; } /** * Substitutes characters in the given cipher text based on the provided substitution map. * * @param {string} cipherText - The cipher text to be substituted. * @param {Map} substitutionMap - The substitution map containing the character mappings. * @returns {string} - The substituted text. */ function substituteCipherText(cipherText, substitutionMap) { substitutionMap = constructMapFromInput(substitutionMap); let substitutedText = cipherText; for (let [key, value] of substitutionMap) { let regex = new RegExp(key, "g"); //global regex meaning it will replace all matching string, not just the first one substitutedText = substitutedText.replace(regex, value); } console.log(substitutedText); return substitutedText; } /** * Constructs a map from the given input string. * The input string should be in the format "key1:value1, key2:value2, ...". * @param {string} input - The input string to construct the map from. * @returns {Map} - The constructed map. */ function constructMapFromInput(input) { let map = new Map(); let pairs = input.split(', '); for (let pair of pairs) { let [key, value] = pair.split(':'); map.set(key, value); } return map; }