To shuffle a string, I could use something like this
String.prototype.shuffle = function () {
var arr = this.split("");
var len = arr.length;
for (var n = len - 1; n > 0; n--) {
m = Math.floor(Math.random() * (n + 1));
tmp = arr[n];
arr[n] = arr[m];
arr[m] = tmp;
}
return arr.join("");
}
But how could I randomly space it with n characters, while preserving the string order?
For example:
"test" => "t-es--t"
"test" => "-t-e-st"
"test" => "te--st-"
I've thought about creating a list from the string, generating a random number to represent an index, and then shifting the list to the left, but is there a better way to do this?
This will insert n characters char randomly into the string. If char is missing, it defaults to a space:
String.prototype.shuffle = function(n, char) {
var arr = this.split(''),
char= char || ' ';
while(n--) {
arr.splice(Math.floor(Math.random() * (arr.length+1)), 0, char);
}
return arr.join('');
} //shuffle
This Fiddle shows the relative random distribution using the method.
If you want a truly unbiased solution that produces all possibilities equally likely, and have access to a perfect random number generator (which is a whole other topic), there's a fairly easy solution. Let's define some terms:
m = number of characters in the string
k = number of spaces you want to insert (you called this n)
Consider one solution to this problem with m=7 and k=3:
0123456789
cab ba g e
What the problem essentially amounts to is choosing k different numbers from among a set of m+k numbers. There are (m+k)!/(m!*k!) possibilities. This is the concept of combinations and is similar to the stars-and-bars problem in the Wikipedia page. (To get an unbiased generator you would need a random number generator with the number of state values much higher than this number of possibilities. But I said RNGs are a whole other topic.)
Here's an example in Python showing all possibilities:
import itertools
def show_all(s, k):
# show all combinations of k spaces inserted into string s
m = len(s)
for sample in itertools.combinations(range(m+k),k):
jprev = 0
out = ''
for ispace, i in enumerate(sample):
j = i-ispace # adjust index by number of spaces used
out += s[jprev:j] + ' '
jprev = j
out += s[jprev:]
yield sample, out
for sample, out in show_all('shoe',2):
print sample,':'+out+':'
output:
(0, 1) : shoe:
(0, 2) : s hoe:
(0, 3) : sh oe:
(0, 4) : sho e:
(0, 5) : shoe :
(1, 2) :s hoe:
(1, 3) :s h oe:
(1, 4) :s ho e:
(1, 5) :s hoe :
(2, 3) :sh oe:
(2, 4) :sh o e:
(2, 5) :sh oe :
(3, 4) :sho e:
(3, 5) :sho e :
(4, 5) :shoe :
Now the problem becomes one of generating a random combination. In Python this is part of the itertools recipes:
def random_combination_with_replacement(iterable, r):
"Random selection from itertools.combinations_with_replacement(iterable, r)"
pool = tuple(iterable)
n = len(pool)
indices = sorted(random.randrange(n) for i in xrange(r))
return tuple(pool[i] for i in indices))
In Javascript we have to implement this ourselves, which we can do using Robert Floyd's algorithm for sampling without replacement:
pseudocode:
initialize set S to empty
for J := N-M + 1 to N do
T := RandInt(1, J)
if T is not in S then
insert T in S
else
insert J in S
Javascript:
function random_comb(r, n, m)
{
/* Generate a combination of m distinct random integers between 0 and n-1
using Floyd's algorithm
r: random generation function
such that r(k) generates an integer in the range [0, k-1]
*/
var S = {};
var out = [];
for (var i = 0; i < m; ++i)
{
var j = i+(n-m);
var t = r(j+1);
var item = (t in S) ? j : t;
S[item] = 1;
out.push(item);
}
return out.sort();
}
Now let's put it all together, ignoring the fact that Math.random() is inadequate:
var r = function(n) { return Math.floor(Math.random()*n); }
function random_comb(r, n, m)
{
/* Generate a combination of m distinct random integers between 0 and n-1
using Floyd's algorithm
r: random generation function
such that r(k) generates an integer in the range [0, k-1]
*/
var S = {};
var out = [];
for (var i = 0; i < m; ++i)
{
var j = i+(n-m);
var t = r(j+1);
var item = (t in S) ? j : t;
S[item] = 1;
out.push(item);
}
return out.sort();
}
function random_insert(r, s, k, c)
{
/* randomly insert k instances of character c into string s */
var m = s.length;
var S = random_comb(r, m+k, k);
var jprev = 0;
var out = '';
for (var ispace = 0; ispace < k; ++ispace)
{
var i = S[ispace];
var j = i - ispace; // adjust index by # of spaces
out += s.slice(jprev,j) + c;
jprev = j;
}
out += s.slice(jprev);
return out;
}
var word = 'shoe';
var results = [];
for (var i = 0; i < 10; ++i)
{
results.push(random_insert(r,word, 2, '-'));
}
var tally = {};
for (var i = 0; i < 100000; ++i)
{
var s = random_insert(r,word,2,'-');
tally[s] = (s in tally) ? (tally[s] + 1) : 1;
}
for (var s in tally)
{
results.push(s+": "+tally[s]);
}
for (var i = 0; i < results.length; ++i)
{
$("#results").append(results[i]+'<br>');
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="results"></div>
Working jsFiddle
Even though I loved #Barmar 's idea..
You can do it by simply looping and randomizing positions to insert the spaces..
String.prototype.insertSpaces = function (n, char) {
var str = this;
for(var i = 0; i < n; i++){
var randPos = Math.floor(Math.random() * (str.length + 1)); // get random index to insert
str = str.substring(0, randPos) + char + str.substring(randPos, str.legnth); // insert the repeated sting
}
return str;
}
function addRandomSpaces(str,n,char){
for (var newstr="", i=0; i<str.length;){
if (n && Math.random()<0.5) {
newstr += char;
n--;
} else {
newstr += str[i++];
}
}
while(n--){
newstr += char;
}
return newstr;
}
Here's a function that will loop through a given string str, adding n instances of char at random places. If when it finishes, n items haven't been added, it adds finishes them at the end.
You can use the slice function insert the new character:
var x = "this is phrase";
var y = " a";
[x.slice(0,7), y, x.slice(7)].join('');
Result: this is a phrase
Something like this:
String.prototype.shuffle2 = function() {
'use strict';
var numberOfSpaces = Math.floor(Math.random() * (this.length - 1));
var word = this;
for (var i = 0; i < numberOfSpaces; i++) {
var index = Math.floor(Math.random() * (this.length - 1));
word = [word.slice(0,index), '-', word.slice(index)].join('');
}
return word;
};
Greetings!
String.prototype.addspace = function () {
var arr = this.split("");
var len = arr.length;
maxSp = 4;
for(var i = 0; i <= len; i++){
m = Math.floor(Math.random() * (maxSp + 1));
for(var j = 0; j < m ; j++){
arr.splice(i,0," ");
}
len += m;
i +=m;
}
return arr.join("");
}
alert("Juanito".addspace().shuffle());
Related
I am trying to do one problem of hackerrank but I am not able to solve that problem
Can someone please help me with wrong logic implementation done by me?
problem
Print the length of the longest string, such that is a child of both s1 and s2.
Sample Input
HARRY
SALLY
Sample Output
2
Explanation
The longest string that can be formed by deleting zero or more characters from HARRY and SALLY is AY, whose length is 2.
Sample Input 1
AA
BB
Sample Output 1
0
Explanation 1
AA and BB have no characters in common and hence the output is 0
Sample Input 2
SHINCHAN
NOHARAAA
Sample Output 2
3
Explanation 2
The longest string that can be formed between SHINCHAN and NOHARAAA while maintaining the order is NHA.
I have written some logic which is as follows:
function commonChild(s1, s2) {
var arr = s2.split(),
currenString = '',
maxLength = 0,
index = -1;
console.log(arr);
for (var i = 0; i < s1.length; i++) {
var char = s1.charAt(i),
charIndex = arr.indexOf(char);
console.log(char)
if (index < charIndex) {
index = charIndex;
currenString +=char;
}
maxLength= Math.max(maxLength,currenString.length)
}
return maxLength;
}
commonChild('ABCDEF', 'FBDAMN');
console.log(commonChild('ABCDEF', 'FBDAMN'));
pardon me. this is an unoptimized solution.
function maxCommon(a, b, offset) {
offset = offset || 0;
if (a === b) {
return [[a, b]];
}
var possibleSolns = [];
for (var i = 0 + offset; i < a.length; i++) {
for (var j = 0 + offset; j < b.length; j++) {
if (a.charAt(i) === b.charAt(j)) {
possibleSolns.push([
a.substring(0, offset) + a.substring(i),
b.substring(0, offset) +b.substring(j)
]);
break;
}
}
}
var results = [];
possibleSolns.forEach(function(soln) {
var s = maxCommon(soln[0], soln[1], offset+1);
if (s.length === 0) {
s = [[soln[0].substring(0, offset +1), soln[1].substring(0, offset +1)]];
}
results = results.concat(s);
});
return results;
}
var maxLen = -1;
var soln = null;
maxCommon("ABCDEF", "FBDAMN").map(function(_) {
return _[0];
}).forEach(function(_) {
if (_.length > maxLen) {
soln = _;
maxLen = _.length;
}
});
console.log(soln);
I kept most of your logic in the answer:
function commonChild(s1, s2) {
var // Sets strings to arrays
arrayString1 = s1.split(""),
arrayString2 = s2.split(""),
collectedChars = "",
maxLength = 0,
max = arrayString1.length;
for (var i = 0; i < max; i++) {
var
char = arrayString1[i],
count = arrayString2.indexOf(char);
// check if char is in second string and not in collected
if (count != -1 && collectedChars.indexOf(char) == -1) {
collectedChars += char;
maxLength++;
}
}
return maxLength;
}
// expected output 4
console.log(commonChild(
'ABCDEF',
'FBDAMN'
));
// expected output 1
console.log(commonChild(
'AA',
'FBDAMN'
));
Using lodash and spread operation you can do it in this way.
const test = (first, second) => {
const stringArray1 = [...first];
const stringArray2 = [...second];
return _.intersection(stringArray1, stringArray2).length;
}
console.log(test('ABCDEF', 'FBDAMN'));
You can solve it using lcs least common subsequence
function LCS(s1,s2,x,y){
var result = 0;
if(x==0 || y==0){
result = 0
}else if(s1[x-1] == s2[y-1]){
result = 1+ LCS(s1,s2,x-1,y-1)
} else if(s1[x-1] != s2[y-1]){
result = Math.max(LCS(s1,s2,x-1,y), LCS(s1,s2,x,y-1))
}
return result;
}
// Complete the commonChild function below.
function commonChild(s1, s2) {
return LCS(s1,s2,s1.length,s2.length);
}
Based on your code before the edit.
One little change is to change var arr = s2.split() to split('').
The main change in the logic is that I added a loop to run over the string each time from another character (first loop from the first, second from the second etc).
function commonChild(s1, s2) {
var arr = s2.split(''),
currenString = '',
maxLength = 0,
index = -1,
j = -1;
for (var ii = 0; ii < s1.length; ii++) {
index = -1;
currenString = '';
for (var i = ii; i < s1.length; i++) {
var char = s1.charAt(i),
j = arr.indexOf(char);
if (index < j) {
index = j;
currenString += char;
}
maxLength = Math.max(maxLength, currenString.length)
}
}
return maxLength;
}
console.log(commonChild('ABCDEF', 'FBDAMN'));
i solving a challenge of Hacker rank . it about how anagrams. i give two string input and i have to find ...
Print a single integer denoting the number of characters you must delete to make the two strings anagrams of each other.
i have detected if it's anagrams or not and difference. but now can do the rest of it dont have any ideas.please help.
function main() {
var a = readLine();
var b = readLine();
var sum1 = 0 ;
var sum2 = 0 ;
for (var i= 0; i<= a.length-1; i++ )
{
sum1 = sum1 + a.charCodeAt(i);
}
console.log(sum1);
for (var i= 0; i<= b.length-1; i++ )
{
sum2 = sum2 + b.charCodeAt(i);
}
console.log(sum2);
if(sum1== sum2)
{
console.log("anagrams");
}
else
{
console.log("not anagram");
var diff = sum1 - sum2;
console.log(diff);
/// what to do now ?
}
}
I have solved this on hackerRank by using the object approach to count the frequency of letters if you are still looking for a reasonable solution.
function makeAnagrams(a,b){
let charA=buildcharMap(a)
let charB=buildcharMap(b)
let characters=[]
let counter=0
for(let char in charA){
if(charA[char] && charB[char]){
if(charA[char]===charB[char]){ //same frequency
continue;
}
else{
if(charA[char]>charB[char]){
counter=counter+ charA[char]-charB[char]
}
else{
counter=counter+ charB[char]-charA[char]
}
}
}
else{
counter=counter+charA[char]
}
}
for(let char in charB){
if(charB[char] && charA[char]===undefined){
counter=counter+charB[char]
}
}
return counter;
}
function buildcharMap(str){
var charMap={}
for(let char of str){
if (charMap[char]===undefined){
charMap[char]=1
}
else{
charMap[char]+=1
}
}
return charMap
}
console.log(makeAnagrams('cde','abc'))
I have solve this question on hackerearth, i took slightly different approach.
What i have done in this code is that i have check for all the characters and replace the character with "#" sign if both characters in string are same, then i count all the "#" signs in one of the strings that is modified, and then subtracted value of that count multiplied by two(because... they are similar in both strings) from total length of both strings.
Here is my code, hope you can convert it into javascript. ->
import java.util.Scanner;
public class Anagrams {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int Testcases = scanner.nextInt();
String[] str1 = new String[1000];
String[] str2 = new String[1000];
// Taking input
for (int i = 0; i < Testcases; i++) {
str1[i] = scanner.next().toLowerCase();
str2[i] = scanner.next().toLowerCase();
}
// For Total Length of both strings
int TotalLength[] = new int[Testcases];
// For counting "#" signs
int count[] = new int[Testcases];
// Loop through TestCases
for (int i = 0; i < Testcases; i++) {
TotalLength[i] = str1[i].length() + str2[i].length();
for (int j = 0; j < str1[i].length(); j++) {
for (int k = 0; k < str2[i].length(); k++) {
// If both characters are similar, then replace those characters with "#" signs
if (str1[i].charAt(j) == str2[i].charAt(k)) {
str1[i] = str1[i].replaceFirst(Character.toString(str1[i].charAt(j)),"#");
str2[i] = str2[i].replaceFirst(Character.toString(str2[i].charAt(k)),"#");
}
}
}
}
// Counting "#" signs from one string
for (int i = 0; i < Testcases; i++) {
count[i] = 0;
char[] c1 = str1[i].toCharArray();
for (char c: c1) {
if(c == '#'){
count[i]++;
}
}
}
// Output
for (int i = 0; i < Testcases; i++) {
System.out.println(TotalLength[i] - 2*count[i]);
}
scanner.close();
}
}
You are really just looking for the sum of the differences in later frequency. You can just count the frequencies into an 26 item array (the rules tell you there will only be lower case numbers). Then subtract each array from the other item by item but item and add the whole thing up. Seems like it only need about four lines of code:
function makeAnagram(a, b) {
const makeCountArray = (str) => [...str].reduce((a, c) => (a[c.charCodeAt(0) - 97]++, a), Array(26).fill(0))
let a1 = makeCountArray(a)
let a2 = makeCountArray(b)
return a1.reduce((a, c, i) => a + Math.abs(c - a2[i]), 0)
}
// test case expected: 30
let count = makeAnagram('fcrxzwscanmligyxyvym', 'jxwtrhvujlmrpdoqbisbwhmgpmeoke')
console.log(count)
Here's another approach using Map() of all the 26 alphabets in each string
function makeAnagram(a, b) {
let result = 0;
const alphabets = 'abcdefghijklmnopqrstuvwxyz'.split('');
const getCharCountMap = str => {
const strArray = str.split('');
let charMap = new Map();
alphabets.forEach(alphabet => charMap.set(alphabet, 0));
strArray.forEach(letter => charMap.set(letter, charMap.get(letter) + 1));
return charMap;
};
const aMap = getCharCountMap(a);
const bMap = getCharCountMap(b);
alphabets.forEach(alphabet => {
result = result + Math.abs(aMap.get(alphabet) - bMap.get(alphabet));
});
return result;
}
I'm working on a script that creates random mathematical problems (simple questions). The problem is that there seems to be an infinite loop, and I can't figure out where or how my script can run without this part of the code.
https://codepen.io/abooo/pen/GyJKwP?editors=1010
var arr = [];
var lastArr = [];
while(lastArr.length<122){
arr.push('<br>'+Math.round(Math.random() * 10)+'+'+Math.round(Math.random() * 10)+'=');
lastArr=removeDuplicates(arr);
}
document.write(lastArr.join(' '));
alert(arr.length);
function removeDuplicates(arr){
let unique_array = []
for(let i = 0;i < arr.length; i++){
if(unique_array.indexOf(arr[i]) == -1){
unique_array.push(arr[i])
}
}
return unique_array
}
This is the working snippet without any infinity loop.
var arr = [];
while(arr.length < 121){
var randValue = '<br>'+Math.round(Math.random() * 10)+'+'+Math.round(Math.random() * 10)+'='
arr.push();
// Check duplicate elements before push
if ( arr.indexOf(randValue) == -1 ) arr.push(randValue);
}
document.write(arr.join(' '));
alert(arr.length);
It looks like you are trying to shuffle every possible outcome of adding two numbers from 0 to 10. Why not do that, rather than your attempt of "throw missiles into pidgeonholes and hope for the best"?
function generateArray(maxA, maxB) {
var arr = [],
a, b;
for (a = 0; a <= maxA; a++) {
for (b = 0; b <= maxB; b++) {
arr.push([a, b]);
}
}
return arr;
}
function shuffleArray(arr) {
// simple Fisher-Yates shuffle, modifies original array
var l = arr.length,
i, j, t;
for (i = l - 1; i > 0; i--) {
j = Math.floor(Math.random() * (i + 1));
t = arr[i];
arr[i] = arr[j];
arr[j] = t;
}
}
function outputArray(arr) {
var i, l = arr.length;
for (i = 0; i < l; i++) {
document.write("<br />" + arr[i][0] + " + " + arr[i][1] + " = ");
}
}
var arr = generateArray(10, 10);
shuffleArray(arr);
outputArray(arr);
The line Math.round(Math.random() * 10) will give you 11 possible outcomes (from 0 to 10). That means there are 11*11 non-duplicates lastArr can hold.
As mentioned in the comments, it does not only take a long time for every possibility to occur, it is also impossible for lastArr to be longer than 121 (11*11), which means your loop cannot end, due to the condition while(lastArr.length<122).
Besides that there are better ways to achieve the desired result, changing your code to this will make it work:
var arr = [];
var lastArr = [];
while(lastArr.length<121){ // Here I change 122 to 121
arr.push('<br>'+Math.round(Math.random() * 10)+'+'+Math.round(Math.random() * 10)+'=');
lastArr=removeDuplicates(arr);
}
document.write(lastArr.join(' '));
alert(arr.length);
function removeDuplicates(arr){
let unique_array = []
for(let i = 0;i < arr.length; i++){
if(unique_array.indexOf(arr[i]) == -1){
unique_array.push(arr[i])
}
}
return unique_array
}
I am trying to count the number of permutations that do not contain consecutive letters. My code passes tests like 'aabb' (answer:8) and 'aab' (answer:2), but does not pass cases like 'abcdefa'(my answer: 2520; correct answer: 3600). Here's my code:
function permAlone(str) {
var totalPerm = 1;
var result = [];
//assign the first letter
for (var i = 0; i < str.length; i++) {
var firstNum = str[i];
var perm = firstNum;
//create an array from the remaining letters in the string
for (var k = 0; k < str.length; k++) {
if (k !== i) {
perm += str[k];
}
}
//Permutations: get the last letter and change its position by -1;
//Keep changing that letters's position by -1 until its index is 1;
//Then, take the last letter again and do the same thing;
//Keep doing the same thing until the total num of permutations of the number of items in the string -1 is reached (factorial of the number of items in the string -1 because we already established what the very first letter must be).
var permArr = perm.split("");
var j = permArr.length - 1;
var patternsLeft = totalNumPatterns(perm.length - 1);
while (patternsLeft > 0) {
var to = j - 1;
var subRes = permArr.move(j, to);
console.log(subRes);
if (noDoubleLettersPresent(subRes)) {
result.push([subRes]);
}
j -= 1;
if (j == 1) {
j = perm.length - 1;
}
patternsLeft--;
}
}
return result.length;
}
Array.prototype.move = function(from, to) {
this.splice(to, 0, (this.splice(from, 1))[0]);
return this.join("");
};
function totalNumPatterns(numOfRotatingItems) {
var iter = 1;
for (var q = numOfRotatingItems; q > 1; q--) {
iter *= q;
}
return iter;
}
function noDoubleLettersPresent(str) {
if (str.match(/(.)\1/g)) {
return false;
} else {
return true;
}
}
permAlone('abcdefa');
I think the problem was your permutation algorithm; where did you get that from? I tried it with a different one (after Filip Nguyen, adapted from his answer to this question) and it returns 3600 as expected.
function permAlone(str) {
var result = 0;
var fact = [1];
for (var i = 1; i <= str.length; i++) {
fact[i] = i * fact[i - 1];
}
for (var i = 0; i < fact[str.length]; i++) {
var perm = "";
var temp = str;
var code = i;
for (var pos = str.length; pos > 0; pos--) {
var sel = code / fact[pos - 1];
perm += temp.charAt(sel);
code = code % fact[pos - 1];
temp = temp.substring(0, sel) + temp.substring(sel + 1);
}
console.log(perm);
if (! perm.match(/(.)\1/g)) result++;
}
return result;
}
alert(permAlone('abcdefa'));
UPDATE: In response to a related question, I wrote an algorithm which doesn't just brute force all the permutations and then skips the ones with adjacent doubles, but uses a logical way to only generate the correct permutations. It's explained here: Permutations excluding repeated characters and expanded to include any number of repeats per character here: Generate all permutations of a list without adjacent equal elements
I agree with m69, the bug seems to be in how you are generating permutations. I got 3600 for 'abcdefa' by implementing a different algorithm for generating permutations. My solution is below. Since it uses recursion to generate the permutations the solution is not fast, however you may find the code easier to follow, if speed is not important.
The reason for having a separate function to generate the array index values in the permutations was to verify that the permutation code was working properly. Since there are duplicate values in the input strings it's harder to debug issues in the permutation algorithm.
// Simple helper function to compute all permutations of string indices
function permute_indices_helper(input) {
var result = [];
if (input.length == 0) {
return [[]];
}
for(var i = 0; i < input.length; i++) {
var head = input.splice(i, 1)[0];
var tails = permute_indices_helper(input);
for (var j = 0; j < tails.length; j++) {
tails[j].splice(0, 0, head);
result.push(tails[j]);
}
input.splice(i, 0, head); // check
}
return result;
};
// Given an array length, generate all permutations of possible indices
// for array of that length.
// Example: permute_indices(2) generates:
// [[0,1,2], [0,2,1], [1,0,2], ... , [2, 0, 1]]
function permute_indices(array_length) {
var result = [];
for (var i = 0; i < array_length; i++) {
result.push(i);
}
return permute_indices_helper(result);
}
// Rearrange letters of input string according to indices.
// Example: "car", [2, 1, 0]
// returns: "rac"
function rearrange_string(str, indices) {
var result = "";
for (var i = 0; i < indices.length; i++) {
var string_index = indices[i];
result += str[string_index];
}
return result;
}
function permAlone(str) {
var result = 0;
var permutation_indices = permute_indices(str.length);
for (var i = 0; i < permutation_indices.length; i++) {
var permuted_string = rearrange_string(str, permutation_indices[i]);
if (! permuted_string.match(/(.)\1/g)) result++;
}
return result;
}
You can see a working example on JSFiddle.
I am trying to shuffle words. I Want to shuffle First with its respective alphabets. Currently it is shuffling First with Second alphabets..
I Want to split words & shuffle "sFtir Seocdn".
String.prototype.shuffle = function () {
var a = this.split(""),
n = a.length;
for (var i = n - 1; i > 0; i--) {
var j = Math.floor(Math.random() * (i + 1));
var tmp = a[i];
a[i] = a[j];
a[j] = tmp;
}
return a.join("");
}
alert("First Second".shuffle());
I tried splitting by below code, but then it only splits & shuffles words not letters.
var a = this.split(" "),
return a.join(" ");
Jsfiddle link : http://jsfiddle.net/9L8rs/1/
Pls suggest what should I do.
Just split the string into words and shuffle the letters in words separately:
"First Second".split(' ').map(function(w) { return w.shuffle(); }).join(' ');
Here .split and .map (polyfill may be applied for old browsers) methods can help.
DEMO: http://jsfiddle.net/9L8rs/2/
Try splitting the incoming String first:
String.prototype.shuffle = function() {
return this.split(" ").map(function(word, i) {
var a = word.split(""),
n = a.length;
for (var i = n - 1; i > 0; i--) {
var j = Math.floor(Math.random() * (i + 1));
var tmp = a[i];
a[i] = a[j];
a[j] = tmp;
}
return a.join("");
}).join(" ");
}
alert("First Second".shuffle());
Updated JSFiddle
I just added a function shuffleWords that split on words and call your shuffle function on each of them. ex. a[i] = a[i].shuffle();
String.prototype.shuffleWords = function () {
var a = this.split(" "),
n = a.length;
for (var i = 0; i < n; i++) {
a[i] = a[i].shuffle();
}
return a.join(" ");
}
See your updated jsfiddle