Function that randomizes a string (permutation) in javascript - javascript

Is there a way to code a function that gets a string for example "Overflow!" and returns a random Permutation with the first, last and penultimate char staying the same?
Examples of the randomized string could be "Orfevolw!" or "Oervolfw!".
Thank you.

You need to pass the string and the constants number array that you don't want to change.
const generateString = (str, constants = []) => {
const strArray = str.split("");
const result = Array(str.length)
.fill("")
.map((s, i) => {
if (constants.includes(i))
return strArray.splice(i - (str.length - strArray.length), 1);
return "";
});
for (let i = 0; i < result.length; ++i) {
if (!result[i]) {
const random = Math.floor(Math.random() * strArray.length);
result[i] = strArray.splice(random, 1);
}
}
return result.join("");
};
console.log(generateString("Overflow!", [0, 7, 8]));
console.log(generateString("Overflow!"));

Use string.randomize function ( I created this function returns randomly arranged string) on string variable
String.prototype.randomize = function() {
let str = "";
let array = [];
for (var i = 0; i < this.length; i++) {
array.push(this[i])
}
array.sort(() => 0.5 - Math.random());
array.forEach(word => {
str += word
})
return str;
}
let str = "Overflow";
// Calling .randomzie function
str = str.randomize()
// Logging it
console.log(str)

Related

JavaScript How to Create a Function that returns a string with number of times a characters shows up in a string

I am trying to figure out how to make a function that takes a string. Then it needs to return a string with each letter that appears in the function along with the number of times it appears in the string. For instance "eggs" should return e1g2s1.
function charRepString(word) {
var array = [];
var strCount = '';
var countArr = [];
// Need an Array with all the characters that appear in the String
for (var i = 0; i < word.length; i++) {
if (array.indexOf(word[i]) === false) {
array.push(word[i]);
}
}
// Need to iterate through the word and compare it with each char in the Array with characters and save the count of each char.
for (var j = 0; j < word.length; i++) {
for (var k = 0; k < array.length; k++){
var count = 0;
if (word[i] === array[k]){
count++;
}
countArr.push(count);
}
// Then I need to put the arrays into a string with each character before the number of times its repeated.
return strCount;
}
console.log(charRepString("taco")); //t1a1co1
console.log(charRepString("egg")); //e1g2
let str = prompt('type a string ') || 'taco'
function getcount(str) {
str = str.split('')
let obj = {}
for (i in str) {
let char = str[i]
let keys = Object.getOwnPropertyNames(obj)
if (keys.includes(char)) {
obj[char] += 1
} else {
obj[char] = 1
}
}
let result = ''
Object.getOwnPropertyNames(obj).forEach((prop) => {
result += prop + obj[prop]
})
return result
}
console.log(getcount(str))
If the order of the alphanumeric symbols matters
const str = "10zza";
const counted = [...[...str].reduce((m, s) => (
m.set(s, (m.get(s) || 0) + 1), m
), new Map())].flat().join("");
console.log(counted); // "1101z2a1"
Or also like (as suggested by Bravo):
const str = "10zza";
const counted = [...new Set([...str])].map((s) =>
`${s}${str.split(s).length-1}`
).join("");
console.log(counted); // "1101z2a1"
A more clear and verbose solution-
Let m be max number of symbols in charset
Time complexity- O(n log(m))
Space complexity- O(m)
function countFrequencies(str) {
const freqs = new Map()
for (const char of str) {
const prevFreq = freqs.get(char) || 0
freqs.set(char, prevFreq + 1)
}
return freqs
}
function getCountStr(str) {
const freqs = countFrequencies(str)
const isListed = new Set()
const resultArray = []
for (const char of str) {
if (isListed.has(char)) continue
resultArray.push(char)
resultArray.push(freqs.get(char))
isListed.add(char)
}
return resultArray.join("")
}
console.log(getCountStr("egg"))
console.log(getCountStr("taco"))
console.log(getCountStr("10za"))
Using Set constructor, first we will get the unique data.
function myfun(str){
let createSet = new Set(str);
let newArr = [...createSet].map(function(elem){
return `${elem}${str.split(elem).length-1}`
});
let newStr = newArr.join('');
console.log(newStr);
}
myfun('array');

Write function strLetterCount and return new string with the characters followed by the count

I need to write a function strLetterCount(word) that takes the string input, and returns a string followed by the count of occurrences.
Ex:
strLetterCount("coconut"); // "c2o2n1u1t1"
Here is what I have so far:
function strLetterCount (word){
let results = ""
for(let i = 0; i < word.length; i++) {
let charAt = word.charAt(i)
let count = 0
results += charAt
for (let j = 0; j < word.length ; j++)
{
if(word.charAt(j) === charAt)
{
count++
}
}
results += count
}
return results;
}
But the issue is that it returns c2o2c2o2n1u1t1 instead of c2o2n1u1t1. I'm not sure how to get rid of the duplicates
function strLetterCount (word){
let results = ""
for(let i = 0; i < word.length; i++) {
let charAt = word.charAt(i)
if (!results.includes(charAt)) // <----------------------
{
let count = 0
results += charAt
for (let j = 0; j < word.length ; j++)
{
if(word.charAt(j) === charAt)
{
count++
}
}
results += count
}
}
return results;
}
console.log(strLetterCount("coconut"));
Using String.prototype.split function, you can convert string into char array.
Based on that char array, using Array.prototype.reduce, you can get the duplicated char info.
With that duplicated info, can get the string linked using Array.prototype.map.
console.log(strLetterCount("coconut")); // "c2o2n1u1t1"
function strLetterCount(word) {
const wordArr = word.split('');
const duplicates = wordArr.reduce((acc, cur) => {
acc[cur] ? acc[cur] ++ : acc[cur] = 1;
return acc;
}, {});
return Object.entries(duplicates).map(([key, value]) => key + value).join('');
}
function strLetterCount(word) {
let results = {};
for (let i = 0; i < word.length; i++) {
let c = word.charAt(i)
results[c] = (results[c] || 0) + 1;
}
let r = '';
for (let c in results)
r += c + results[c];
return r;
}
console.log(strLetterCount("coconut")); // "c2o2n1u1t1"
Using the String split method, a Set, the Array map method and the Array join method you can do it in a single line of code
const strLetterCount = word => [...new Set(word.split(''))].map(l => `${l}${word.split(l).length - 1}`).join('');
console.log(strLetterCount('coconut'));

Array elements not mutating inside for of loop

function rot13(str) {
let alphArr = "ABCDEFGHIJKLMNOPQRSTUVWXYZ".split("");
let n = 13;
let arr = str.split("");
let len = alphArr.length;
for (let i of arr) {
if (alphArr.includes(i)) {
if (alphArr.indexOf(i) + n <= len - 1) {
i = (alphArr[alphArr.indexOf(i) + n])
console.log(i) // This is as expected
}
}
}
console.log(arr) // Array itself did not mutate and is showing the initial array.
return str;
}
rot13("SERR PBQR PNZC");
The value of i inside the second if statement is proper as can be seen in the console.log statement but the array in itself did not mutate. Why was that?
P.S. I've solved it by using map function and it works properly because map function does not mutate the original array.
It's worth mentioning that your code can be simplified:
let rot = (str, n, asciiStart='A'.charCodeAt(0), asciiEnd='Z'.charCodeAt(0), asciiRange=asciiEnd-asciiStart+1) =>
str.split('')
.map(c => {
let code = c.charCodeAt(0) - asciiStart;
if (code >= 0 && code <= asciiRange) code = (code + n) % asciiRange;
return String.fromCharCode(asciiStart + code);
})
.join('');
let inp = document.getElementsByTagName('input')[0];
let p = document.getElementsByTagName('p')[0];
inp.addEventListener('input', () => p.innerHTML = rot(inp.value, 13));
<input type="text" placeholder="test here (use capital letters)"/>
<p></p>
Your code wasn't working because replacing the value of i does not effect the array index that i was initially based off of. Once you define i, it doesn't remember how it was defined (e.g. it doesn't think to itself, "I originated from a value within an array')
You can't directly set value to element in for of loop try the following...
function rot13(str) {
let alphArr = "ABCDEFGHIJKLMNOPQRSTUVWXYZ".split("");
let n = 13;
let arr = str.split("");
let len = alphArr.length;
let j=0
for (let i of arr) {
if (alphArr.includes(i)) {
if (alphArr.indexOf(i) + n <= len - 1) {
arr[j]= (alphArr[alphArr.indexOf(i) + n])
console.log(i) // This is as expected
}
}
j++
}
console.log(arr) // Array itself did not mutate and is showing the initial array.
return str;
}
rot13("SERR PBQR PNZC");
Instead of using a for of loop you should use map to create a new array and used the newly mapped array. Fixed fulling working example:
function rot13(str) {
let alphArr = "ABCDEFGHIJKLMNOPQRSTUVWXYZ".split("");
let n = 13;
let arr = str.split("");
let len = alphArr.length;
arr = arr.map((i) => {
if (alphArr.includes(i)) {
let index = (alphArr.indexOf(i) + n) % len;
return alphArr[index];
}
return i;
});
return arr.join("");
}
console.log(rot13("SERR PBQR PNZC")); // logs "FREE CODE CAMP"

how to fix the function to check the same random array value

I am learning javascript, I have been able to create a function that has a parameter, the function has the task of forming an array containing a 2 character (0/1) random string of 1 parameter and the return value must be an array.
example:
console.log (generateString(2));
sample results:
['01', '11']
The problem I face is even though it's a random string, but it still has the possibility to have the same value. Suppose I run the program code
console.log (generateString(4));
and one of the results is like this:
['00', '00', '01', '10']
my question is how can I ensure that the return value of the array has no duplicate value? This is my code so far..
function generateString(num){
let newArray = [];
for(let i = 0; i < num; i++){
let randomChar = generateCharacters();
if(i >= 1 && (newArray[i - 1] === randomChar)){
randomChar = generateCharacters();
newArray.push(randomChar);
} else {
newArray.push(randomChar);
}
}
return newArray;
}
function generateCharacters(){
const chars = '01';
let result = '';
for (let j = 2; j > 0; --j){
result += chars[Math.floor(Math.random() * chars.length)];
}
return result;
}
console.log(generateString(4));
Just check for the duplicate before adding the new string.
function generateString(num){
let newArray = [];
let i =0;
while(i<num){
console.log(newArray)
let randomChar = generateCharacters();
if(newArray.indexOf(randomChar)<=-1){
newArray.push(randomChar);
i+=1;
}
}
return newArray;
}
You can use a do-while inside the for-loop and keep making new random strings until the new strings generated is not included in the previous array.
function generateString(num){
let newArray = [];
let randomChar;
for(let i = 0; i < num; i++){
do{
randomChar = generateCharacters();
}
while(newArray.includes(randomChar));
newArray.push(randomChar)
}
return newArray;
}
function generateCharacters(){
const chars = '01';
let result = '';
for (let j = 2; j > 0; --j){
result += chars[Math.floor(Math.random() * chars.length)];
}
return result;
}
console.log(generateString(4));
You can shuffle the array of all 4 possible pairs of digits:
function shuffle(a) {
for (let i = a.length - 1; i > 0; i--) {
let j = Math.floor(Math.random() * (i + 1));
let temp = a[i];
a[i] = a[j];
a[j] = temp;
}
return a;
}
function generateString(num){
let all = ["00", "01", "10", "11"];
shuffle(all);
return all.slice(0, num); // Only take the number of elements requested
}
console.log(generateString(4));
Made changes in your generateString function. You can use set for not updating duplicates in the result. I think you need to update generateCharacters function to generate all possible strings properly.
function generateString(num){
let newArraySet = new Set();
for(let i = 0; i < num; i++){
let randomChar = generateCharacters();
while(newArraySet.has(randomChar)) {
randomChar = generateCharacters();
}
newArraySet.add(randomChar);
}
return Array.from(newArraySet);
}
function generateCharacters(){
const chars = '01';
let result = '';
for (let j = 2; j > 0; --j){
result += chars[Math.floor(Math.random() * chars.length)];
}
return result;
}
console.log(generateString(4));
When building the array you need to check to see if the random number is not already in the array before adding it to the array. This function will return true if you feed it the array in question and your "random" item you need to check.
function isInArray(myArray, arrayItemToCheck)
{
var found = myArray.find(function(arrayItem) {
return arrayItem == arrayItemToCheck;
});
return !!found
}
in your function, you change the line let randomChar = generateCharacters(); to:
let randomChar;
// loops forever until condition is met
while (true) {
randomChar = generateCharacters();
if (!isInArray(newArray, randomChar)) {
break;
}
}

Convert this hex string into array of integer in javascript

I am using node.js v6.
I have this hex string;
let hex_string = "0102030402";
I would like to convert hex_string into an array of integer array_hex_integer that looks like this;
let array_hex_integer;
array_hex_integer = [1, 2, 3, 4, 2];
The first element in array_hex_integer corresponds to '01' (1st and 2nd chars) in hex_string, 2nd element corresponds to '02' (3rd and 4th chars) in hex_string and so on.
Here is one possible way to do what you need.
var hex_string = "0102030402";
var tokens = hex_string.match(/[0-9a-z]{2}/gi); // splits the string into segments of two including a remainder => {1,2}
var result = tokens.map(t => parseInt(t, 16));
See: https://stackblitz.com/edit/js-hozzsn?file=index.js
In javascript I use this function to convert hexstring to unsigned int array
function hexToUnsignedInt(inputStr) {
var hex = inputStr.toString();
var Uint8Array = new Array();
for (var n = 0; n < hex.length; n += 2) {
Uint8Array.push(parseInt(hex.substr(n, 2), 16));
}
return Uint8Array;
}
Hope this helps someone
First, split hex_string into an array of string. See my function split_str(). Then, convert this array of string into the array of integer that you want.
function split_str(str, n)
{
var arr = new Array;
for (var i = 0; i < str.length; i += n)
{
arr.push(str.substr(i, n));
}
return arr;
}
function convert_str_into_int_arr(array_str)
{
let int_arr = [];
for (let i =0; i < array_str.length; i++)
{
int_arr [i]=parseFloat(array_str[i]);
}
return int_arr;
}
let answer_str = split_str(hex_string,10);
let answer_int = convert_str_into_int_arr(answer_str);

Categories