Javascript Random Name Guesser: Unresponsive Script Issues - javascript

This is my first post here and I am having trouble wording a question, so please bear with me as I have been on this issue for hours.
My friend and I have thought of a fun little function that is supposed to guess the user's name (through an <input> tag) in a certain amount of trials using the random number function to access string letters from an alphabet array numbered 0-25. The function is also supposed to give the user the number of trials it took to guess their name.
I keep getting a non-responsive script, (line 33 - The line containing the second "for loop").
var goal = document.getElementById("your_Name").value;
var alphabet = ["a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z"];
var goalArray = goal.split("");
var trials = 0;
var guessArray = new Array();
var i;
var n;
for (i = 0; i < goalArray.length; i++){
guessArray.push(alphabet[Math.floor(Math.random()*26)]);
}
while (goalArray != guessArray){
trials++;
guessArray = [];
for (n = 0; n < goalArray.length; n++){
guessArray.push(alphabet[Math.floor(Math.random()*26)]);
}
}
document.getElementById("appendomatic").innerHTML = "It took " + guessArray + " trials to guess correctly";
Any help or attempt to help would be immensely appreciated!
In case anyone was wondering: This little idea of ours was to test the randomness of Javascript's random function through trials (he made the same program in MatLab, so we are going to compare results of the random functions from both languages).

goalArray != guessArray is always true since they are two separate arrays; even if they contain the same elements.
Since they appear to just be arrays of individual letters in a-z you could compare them with something like goalArray + '' != guessArray, because the toString() of the arrays will compare correctly.

This is how I eventually got it to work (by nesting the while loop and second for loop in another for loop):
var goal = document.getElementById("your_Name").value;
var goalArray = goal.split("");
var alphabet = ["a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z"];
var trials = 0;
var guessArray = [];
for (i = 0; i < goalArray.length; i++){
guessArray.push(alphabet[Math.floor(Math.random()*26)]);
}
for (x = 0; x < goalArray.length; x++){
while (goalArray[x] != guessArray[x]){
trials++;
guessArray = [];
for (n = 0; n < goalArray.length; n++){
guessArray.push(alphabet[Math.floor(Math.random()*26)]);
}
}
document.getElementById("appendomatic").innerHTML = "It took " + trials + " trials to guess correctly";
}
}

Related

trying to make an lfsr in js

i'm trying to make an lfsr in js, on its head every thing is looking good, i'm using strings and im converting them back and forth to get the last bit, my problem is printing the number i'm trying to make a large hex number, my logic is give me a seed and a length and the function should generate a hex number in that length.
function lfsr(seed, length ){
var arr = Array.from(seed.toString(2));
result ="";
for (var i = 0; i < lenght; i++) {
let _last = parseInt(arr.pop());
let _blast = parseInt(arr[arr.length - 1])
let _newbit = _last ^ _blast;
arr.splice(0 , 0 ,_newbit.toString());
result += _newbit.toString();
}
return parseInt(result, 2).toString(16);
this is my code, i ran some tests and got a good output, but when i pring the answer i get this output:
be92231350d87800000000000
oh, and my input is this:
var ans = lfsr(6543123123798,100);
any idea how to get rid of the excess 0's and get what I need? thanks for your time.
i've changed the code to be :
function lfsr(seed, length,base){
var arr = Array.from(seed.toString(base));
var result ="";
for (var i = 0; i < length ; i++) {
let _newbit = parseInt(arr.pop(),16) ^ parseInt(arr[arr.length - 1],base);
arr.splice(0 , 0 ,_newbit.toString(base));
result += _newbit.toString(base);
}
return result;
}
and it solved my problem. any one is welcome to use it.

javascript generating random characters [duplicate]

This question already has answers here:
Generate random string/characters in JavaScript
(93 answers)
Closed 6 years ago.
I am trying to program a password generator. However, I find that my code is unreliable. I want each run of my function to return 20 random characters. This works most times, however if I spam the function enough times then I sometimes get a result that's below my criteria (eg: 2 strings, none, etc).
var longth = 20,
allc = "!##$%^&*()_+~`|}{[]\:;?><,./-=0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ",
passgen = '';
for (var i = 0; i < longth; i++) {
passgen += allc.charAt(Math.floor(Math.random() * allc.length));
}
Not sure if the problem is with logic in my code, or if there's a break in one of the characters in my allc variable that's causing problems. Maybe I'm not expressing the variable correctly.
I don't see any problem with your code. I have modified it slightly to take a direct index out of the array, rather than using charAt but that shouldn't matter.
This code is tested by creating 1,000,000 strings and logs how many failed the creation criteria. It doesn't seem to fail.
function makePassword(){
var longth = 20,
allc = "!##$%^&*()_+~`|}{[]\:;?><,./-=0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ",
passgen = '';
for (var i = 0; i < longth; i++) {
passgen += allc[Math.floor(Math.random() * allc.length)];
}
return passgen;
}
// Test
var failed = [];
var result = "";
for(var x = 0; x < 1000000; ++x){
result = makePassword();
if(result.length !== 20){
failed.push(result);
}
}
console.log("Incorrect strings generated: " + failed.length, failed);

Project Euler -- Largest palindrome product

There seems to be a problem with this code as in it doesn't check for the largest palindrome. I mixed it with the example they showed of largest palindrome from two digit numbers (The largest palindrome made from the product of two 2-digit numbers is 9009 = 91 × 99) and it worked. I've looked around, but I still don't understand exactly why my code doesn't show the final product. If someone is willing to explain instead of just giving the answer, that would be quite helpful
for(var i = 100; i < 1000; i++) {
for(var j = 100; j < 1000; j++) {
var total = String(i*j);
var regularI = total.substring(0, Math.floor(total.length/2));
var regularJ = total.substring(total.length/2,total.length);
var reversedJ = regularJ.split("").reverse().join("");
if(regularI === reversedJ) {
console.log("SUCCESS\nTotal: " + (i*j) + "\nI: " + i + "\nJ: " + j);
}
}
}
993 * 913 = 906609
995 * 583 = 580085
Suppose the first number in the multiplication corresponds to i, and the second to j. In your nested for-loop with i and j, the result of the former multiplication will be output before the latter. You can see this if you look at the end of your code's output. Therefore, the final success that is output is not guaranteed to be the largest palindrome. It's possible that the largest palindrome appears earlier in your output.
One straightforward method of fixing this problem is to keep a list of palindromes you've found in an array. After the nested for-loop completes, you can sort the array by number value and get the largest number by looking at the last position:
var palindromes = [];
for(var i = 100; i < 1000; i++) {
for(var j = 100; j < 1000; j++) {
var total = String(i*j);
var regularI = total.substring(0, Math.floor(total.length/2));
var regularJ = total.substring(total.length/2,total.length);
var reversedJ = regularJ.split("").reverse().join("");
if(regularI === reversedJ) {
palindromes.push(Number(total));
}
}
}
// sorts the array in-place
// "default sort order is according to string Unicode code points" - Mozilla docs
// so we'll need to pass in a comparison function.
palindromes.sort(function(a, b) {
return a - b;
});
console.log(palindromes[palindromes.length-1]);
If you do this, you'll see that the largest palindrome is indeed 906609, a number that appeared third-to-last (and once more, earlier) in your nested for-loop.
Another way of solving this would be to dedicate a variable, say maxSoFar, to keeping track of the highest palindrome value you've seen.
There are other ways of solving this problem, but I'll leave that up to you to discover.

show the location of each occurence of the character 'e' in a string

WORKED UP AN ANSWER. SCROLL TO BOTTTOM
I'm having trouble trying to display this character. For the most part, I have the code structure set but I'm having trouble storing the correct values in the arrays. Getting stuck and burned out!
wordString = 'i, always, have, fruit, for, breakfast, consisting, of, a, small, fruit, bowl, with, yogurt, on, top, of, the, fruit, but, if, it, is, doughnuts, I, always, have, two, sometimes, they, have, sprinkles, and, sometimes, not, i, never, have, cereal, or, eggs, this, breakfast, regimen, is, very, healthy, especially, the, doughnuts.';
var wordPosition = [];
var letterAppearance = wordString.match(/e/g);
var positionStart = 0;
for(i = 0; i <= letterAppearance.length; i++) {
positionStart = wordPosition[i];
if(positionStart === 0) {
positionString = wordString.substr(positionStart, wordString.length)
} else {
positionString = wordString.substr(wordPosition[i], wordString.length)
}
wordPosition[i] = positionString.indexOf('e');
}
Thanks for the help ahead of time
EDIT
Okay so I've worked on this a bit more and have something a bit simpler but have not yet gotten it to work. My values are not quite correct other than the 1st couple in the array
var wordPosition = [];
var letterAppearance = wordString.match(/e/g);
var positionStart = 0;
for( i = 0; i <= letterAppearance.length; i++){
wordPosition[i] = wordString.indexOf('e')+ positionStart;
positionStart = wordPosition[i];
}
Heres are the values that I get.
14,28,42,56,70,84,98,112,126,140,154,168,182,196,210,224,238,252,266,280,294,308,322,336,350,364
EDIT ANSWER FOUND
Okay, after working on it some more I've gotten the correct code for the answer. Here it is in the simplest form.
locations = " letter 'e' occurs at locations: ";
for (i = 0; i <= wordString.length; i++){
character = wordString.substr(i,1);
if(character === 'e'){
locations = locations + i.toString() + ",";
}
}
I think that's too complicated to search for just some 'e' positions. You can try this:
for (int i=0; i < /*string lenght*/ ; i++)
if (/*String char at i*/ == 'e')
/*Store position */
Okay, after working on it more, I've found the answer in it's simplest form.
locations = " letter 'e' occurs at locations: ";
for (i = 0; i <= wordString.length; i++){
character = wordString.substr(i,1);
if(character === 'e'){
locations = locations + i.toString() + ",";
}
}
Here is the output.
letter 'e' occurs at locations: 14,31,108,160,171,175,181,188,198,210,214,227,229,236,240,242,251,265,275,279,288,294,302,305,316,
You can try this:
var str = "scissors";
var indices = [];
for(var i=0; i<str.length;i++) {
if (str[i] === "s") indices.push(i+1);
}

Sorting function?

I need to organize an array of strings of random length into the least number of new strings with a max size. Is there a function or something in javascript, or something that can be translated to javascript, that will do this?
For example, the new strings might have max lengths of 1000 characters. The array might have strings of lengths 100, 48, 29, etc. I would want to combine those strings into as few new strings as possible.
edit: Sorry if this doesn't make sense, I tried my best.
No standard method in Javascript, but plenty of theoretical work has been done on this (i.e. the bin packing problem).
http://en.wikipedia.org/wiki/Bin_packing_problem
Some sample pseudo code in the link - should be trivial to translate to javascript.
The algorithm shown isn't going to be optimal in every case. To find the optimal solution to your example you'll just need to iterate over every possibility which might not be that bad depending on how many strings you have.
For my own entertainment, I wrote a simple bin packing algorithm. I picked a simple algorithm which is to sort the input strings by length. Create a new bin. Put the first (longest remaining) string into the bin and then keep filling it up with the longest strings that will fit until no more strings will fit. Create a new bin, repeat. To test it, I allocate an array of strings of random lengths and use that as input. You can see the output visually here: http://jsfiddle.net/jfriend00/FqPKe/.
Running it a bunch of times, it gets a fill percentage of between 91-98%, usually around 96%. Obviously the fill percentage is higher if there are more short strings to fill with.
Here's the code:
function generateRandomLengthStringArrays(num, maxLen) {
var sourceChars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXY1234567890";
var sourceIndex = 0;
var result = [];
var len, temp, fill;
function getNextSourceChar() {
var ch = sourceChars.charAt(sourceIndex++);
if (sourceIndex >= sourceChars.length) {
sourceIndex = 0;
}
return(ch);
}
for (var i = 0; i < num; i++) {
len = Math.floor(Math.random() * maxLen);
temp = new String();
fill = getNextSourceChar();
// create string
for (var j = 0; j < len; j++) {
temp += fill;
}
result.push(temp);
}
return(result);
}
function packIntoFewestBins(input, maxLen) {
// we assume that none of the strings in input are longer than maxLen (they wouldn't fit in any bin)
var result = [];
// algorithm here is to put the longest string into a bin and
// then find the next longest one that will fit into that bin with it
// repeat until nothing more fits in the bin, put next longest into a new bin
// rinse, lather, repeat
var bin, i, tryAgain, binLen;
// sort the input strings by length (longest first)
input.sort(function(a, b) {return(b.length - a.length)});
while (input.length > 0) {
bin = new String(); // create new bin
bin += input.shift(); // put first one in (longest we have left) and remove it
tryAgain = true;
while (bin.length < maxLen && tryAgain) {
tryAgain = false; // if we don't find any more that fit, we'll stop after this iteration
binLen = bin.length; // save locally for speed/convenience
// find longest string left that will fit in the bin
for (i = 0; i < input.length; i++) {
if (input[i].length + binLen <= maxLen) {
bin += input[i];
input.splice(i, 1); // remove this item from the array
tryAgain = true; // try one more time
break; // break out of for loop
}
}
}
result.push(bin);
}
return(result);
}
var binLength = 60;
var numStrings = 100;
var list = generateRandomLengthStringArrays(numStrings, binLength);
var result = packIntoFewestBins(list, binLength);
var capacity = result.length * binLength;
var fillage = 0;
for (var i = 0; i < result.length; i++) {
fillage += result[i].length;
$("#result").append(result[i] + "<br>")
}
$("#summary").html(
"Fill percentage: " + ((fillage/capacity) * 100).toFixed(1) + "%<br>" +
"Number of Input Strings: " + numStrings + "<br>" +
"Number of Output Bins: " + result.length + "<br>" +
"Bin Legnth: " + binLength + "<br>"
);

Categories

Resources