Solving random numbers and random variables from array Javascript - javascript

window.onload = start;
var nr1 = Math.floor(Math.random()*50);
var nr2 = Math.floor(Math.random()*50);
var eq1 = nr1 +"+"+nr2;
var eq2 = nr1 + "-"+ nr2;
var eq3 = nr1 +"*"+ nr2;
var eq4 = nr1 +"/"+ nr2;
var arr = [eq1,eq2,eq3,eq4];
var eq = arr[Math.floor(Math.random()*arr.length),Math.floor(Math.random()*arr.length)];
I want to practice something, making a basic Math game. Up there is the code I'm trying to use to generate random numbers and random equations which I want to come out of my html. The reason why I have "" for the operators is because I want the whole equation to come out as a text, I've tried it without the "" marks and I just get the answer straight away.
function start() {
document.getElementById("submit").onclick = submitans;
document.getElementById("question").innerHTML = eq;
}
this is my startup function which generates the equation. Now this works very well in the html if you look at this photo --
HTML. My problem is, I don't know how I'm going to connect the equation to the "if(statement)" from the input box. Because the script reads the commands as text, so it doesn't work even if I write
function submitans() {
var correct = "Correct!";
var wrong = "Wrong";
var inn = parseInt(document.getElementById("answer").value);
for (var i = 0; i < eq.length; i++) {
if(inn === eq[i])
document.getElementById("input").innerHTML = "correct";
}
}
Is there in anyway I can reach the goal I want from this script? I'm sticking with pure javascript, as I am just a beginner, and I really want to learn it. So I'd rather not use jquery.
Aside from this, I'm planning to make my script show the score for every right answer, I thought of having a maximum of 10 right answers for the goal, and the user is allowed to have 5 mistakes.

in the first snippet of code you can add the answer for each equation
var eq1 = nr1 +"+"+nr2;
var eq2 = nr1 + "-"+ nr2;
var eq3 = nr1 +"*"+ nr2;
var eq4 = nr1 +"/"+ nr2;
//answers
var ans1 = nr1 +"+"+nr2;
var ans2 = nr1 + "-"+ nr2;
var ans3 = nr1 +"*"+ nr2;
var ans4 = nr1 +"/"+ nr2;
and then when you get the random equation you get the answer for it too
var arr = [eq1,eq2,eq3,eq4];
var ansArr = [ans1, ans2, ans3, ans4];
var eqNumber = Math.floor(Math.random()*arr.length);
var eq = arr[eqNumber];
var ans = ansArr[eqNumber];
and edit the last snippet like this
function submitans() {
var correct = "Correct!";
var wrong = "Wrong";
var inn = parseInt(document.getElementById("answer").value);
//for (var i = 0; i < eq.length; i++) {//delete
if(inn == ans)
document.getElementById("input").innerHTML = correct;
else
document.getElementById("input").innerHTML = wrong;
//}//delete
}
--------------------------------------------------------------------------------
or instead of all of that you can also only change the last snippet of code like this
function submitans() {
var correct = "Correct!";
var wrong = "Wrong";
var inn = parseInt(document.getElementById("answer").value);
//for (var i = 0; i < eq.length; i++) {//delete
if(inn == eval(eq))
document.getElementById("input").innerHTML = correct;
else
document.getElementById("input").innerHTML = wrong;
//}//delete
}
eval will run the text as javascript and it will return the answer of the equation.

you can also use eval function to get the answer.
var answer = eval(document.getElementById("question").innerHTML) to get the correct answer

I would change the way you manage the equations... Maybe something like that could be useful :
function eq(x, y, op){
// Find the result depending on the operation
var res;
switch (op){
case: '+':
res = x + y;
break;
case: '-':
res = x - y;
break;
case: '*':
res = x * y;
break;
case: '/':
res = x / y;
break;
default:
throw "Error";
}
// Or something like is more compact
var res2 = op == '+' ? x+y : op == '-' ? x-y : op == '*' ? x*y : op == '/' ? x/y : null;
return {
text: x + op + y,
res: res
}
}
// ...
var eq1 = eq(nr1, nr2, '+');
var eq2 = eq(nr1, nr2, '-');
var eq3 = eq(nr1, nr2, '*');
var eq4 = eq(nr1, nr2, '/');
Then you just have to display eq.text in the HTML and check eq.res to compare with the answer... Maybe you can do something nicer but it should work

eval() should work good, try this:
function submitans() {
var correct = "Correct!";
var wrong = "Wrong";
var inn = parseInt(document.getElementById("answer").value);
if(inn === eval(document.getElementById("question").innerHTML))
document.getElementById("input").innerHTML = correct;
else
document.getElementById("input").innerHTML = wrong;
}

there is difference between parseInt and Number
var inn = parseInt(document.getElementById("answer").value);
var inn = Number(document.getElementById("input").value);
========================
eval() you need to be careful with. more so in how javascript will interpret a given string of
var ans1 = eval( 4-3/2*39+3)
adding brackets will make sure you get correct result in how you want evel() to return an answer.
var ans2 = eval( (4-((3/2)*39))+3 );
var ans3 = eval(document.getElementById("equation").value);
will most likely return like ans1, be careful!
to get around issue of above...
var eq1a = nr1 +"+"+nr2;
var eq1b = nr1 + nr2
var eq2a = nr1 + "-"+ nr2;
var eq2b = nr1 - nr2
var eq3a = nr1 +"*"+ nr2;
var eq3b = nr1 * nr2
var eq4a = nr1 +"/"+ nr2;
var eq4b = nr1 / nr2
easy enough above.....
taking next step
var eq1 = "nr1 + nr2"
var eq2 = "nr1 - nr2"
var eq3 = "nr1 * nr2"
var eq4 = "nr1 / nr2"
above is a string that you can do...
var nr1 = Math.floor(Math.random()*50);
var nr2 = Math.floor(Math.random()*50);
var eq1 = "nr1 + nr2"
document.getElementById("equation").innerHTML = eq1;
//and it will show correctly.
var ans = eval(eq1);
// and it will give you the answer
and taking it one more step further....
var eq1 = "((nr1 + nr2) * 4 / 4)"
document.getElementById("equation").innerHTML = eq1.regex();
var ans = eval(eq1);
i forgot what needs to be placed in regex() brackets to remove the ( and ) brackets. so it does not print them out to equation html element.
====================
just be careful with eval() if application is critical application. your application could get hacked quickly.

Related

Maintaining string length by adding zeros

I need to pass a string with at least has a length of 10. How do I add 0's to fill the remaining blank spaces so it will always have a length of 10?
This is what I tried but does not work as expected.
var passString = "Abcdefg";
if (passString.length<10){
var len = passString.length;
var missing = 10-len;
passString = passString + Array(missing).join("0")
}
Concat zeros to the end of the string and use slice or substring or substr.
var passString = "ABC";
var fixed = (passString + "0000000000").slice(0,10);
console.log(fixed);
Based on comment, I skipped the if, but you can just do a basic if
var passString = "ABC";
var fixed = passString;
if (passString.length<10) {
fixed = (passString + "0000000000").slice(0,10);
}
console.log(fixed);
or ternary operator
var passString = "ABC";
var fixed = passString >=10? passString : (passString + "0000000000").slice(0,10);
console.log(fixed);
or just override the original with an if
var passString = "ABC";
if (passString.length<10) {
passString = (passString + "0000000000").slice(0,10);
}
console.log(passString);
please try below code
var passString = "Abcdefg";
if (passString.length<10){
var len = passString.length;
var missing = 10-len;
passString =passString+ new Array(missing + 1).join("0");
}
thanks
You can do it in one line (I love giving one liners)
passString = (passString + Array(11).join('0')).substr(0,Math.max(10,passString.length))

Javascript: array.push is undefined

I have my code:
var name = [];
var mark1 = [];
var mark2 = [];
var mark3 = [];
var total = [];
count = 0
count2 = 0
var i = 0;
while (count != 2) {
var nam = prompt("Enter name:")
name.push(nam);
var mk1 = prompt("Enter mark 1:");
var mk1 = parseInt(mk1);
mark1.push(mk1);
var mk2 = prompt("Enter mark 2:");
var mk2 = parseInt(mk2);
mark2.push(mk2);
var mk3 = prompt("Enter mark 2:");
var mk3 = parseInt(mk3);
mark3.push(mk3);
var tot = mk1 + mk2 + mk3;
total.push(tot)
count = count + 1
console.log(mk1 + mk2 + mk3);
console.log(nam);
console.log("the count is " + count)
};
When I run it I get an error:
Uncaught TypeError: undefined is not a function
on Line 12 which is name.push(nam);
I have looked around but I am not sure what I am doing wrong. Help appreciated.
This is an interesting one. It all boils down to an unfortunate choice of variable name. Unfortunately name is a property of the window object. When you refer to name you are actually referring to window.name, not the array called name. If you rename name to something else, it should work just fine.

How could I possibly shorten this script than how I am doing it?

Trying to loop through every possible combination of characters. I've tried mixing various arrays, takes about three lines but then I can't concatenate. Or maybe there's a better way to concatenate as well? Where I have the +''+letters in between the quotes should be a line break but stackoverflow doesn't allow :P Sorry If I'm too vague I just shortened this script and altered it in a way it works the same but stackoverflow allows?
function go() {
var letters = ('abcdefghijklmnopqrstuvwxyz').split('');
var p1 = '';
var p2 = '';
for (var i = 0;i < 27; i++) {
var p1 = p1+''+letters[i];
var p2 = p2+''+letters[0]+letters[i];
var p3 = p3+''+letters[1]+letters[i];
var p4 = p4+''+letters[2]+letters[i];
var p5 = p5+''+letters[3]+letters[i];
var p6 = p6+''+letters[4]+letters[i];
var p7 = p7+''+letters[5]+letters[i];
var p8 = p8+''+letters[6]+letters[i];
var p9 = p9+''+letters[7]+letters[i];
var p10 = p10+''+letters[8]+letters[i];
var p11 = p11+''+letters[9]+letters[i];
var p12 = p12+''+letters[10]+letters[i];
var p13 = p13+''+letters[11]+letters[i];
var p14 = p14+''+letters[12]+letters[i];
var p15 = p15+''+letters[13]+letters[i];
var p16 = p16+''+letters[14]+letters[i];
var p17 = p17+''+letters[15]+letters[i];
var p18 = p18+''+letters[16]+letters[i];
var p19 = p19+''+letters[17]+letters[i];
var p20 = p20+''+letters[18]+letters[i];
var p21 = p21+''+letters[19]+letters[i];
}
}
Generally, for creating combinations of characters, You may use recursion (or just a stack) like this:
function handleString(str) {
if (str is valid combination of characters by Your rules) {
doSomething(str);
}
for each character c that may be added to incomplete str by Your rules {
handleString(str + c);
}
}
You must be careful not to create endless recursion, all this depends on Your rules. For example, to create all possible 3-character strings out of alphabet "abcdefgh", it may look like this:
function handleString(str, alphabet, length) {
// just in case...
if (str.length > length)
return;
// if the string has desired length (my rule), use it as a valid combination
if (str.length === length) {
console.log(str);
return;
}
// string doesn't have desired length yet, try adding
// each one of possible characters from the alphabet (my rule)
for (var i = 0; i < alphabet.length; i++)
handleString(str + alphabet.charAt(i), alphabet, length);
}
handleString("", "abcdefgh", 3);

For Loops inside For Loops inside For Loops... = Problems

So. I have 4 for loops inside other for loops in JS, and my code appears (FireBug agrees with me) that my code is syntactically sound, and yet it refuses to work. I'm attempting to calculate the key length in a vigenere cipher through the use of the Index of Coincidence, and Kappa tests <- if that helps any.
My main problem is that the task seems to be too computationally intensive for Javascript to run, as Firefox shoots up past 1GB of memory usage, and 99% CPU when I attempt to run the keylengthfinder() function. Any ideas of how to solve this problem, even if it takes much longer to calculate, would be greatly appreciated. Here's a link to the same code - http://pastebin.com/uYPBuZZz - Sorry about any indenting issues in this code. I'm having issues putting it on the page correctly.
function indexofcoincidence(text){
text = text.split(" ").join("").toUpperCase();
var textL = text.length;
var hashtable = [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0];
var alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
for (d=0; d<=25; d++) {
for (i=0; i < textL; i++){
if (text.charAt(i) === alphabet.charAt(d)){
hashtable[d] = hashtable[d] + 1;
}
}
}
var aa = hashtable[0]/textL;
var A = aa*aa;
var bb = hashtable[1]/textL;
var B = bb*bb;
var cc = hashtable[2]/textL;
var C = cc*cc;
var dd = hashtable[3]/textL;
var D = dd*dd;
var ee = hashtable[4]/textL;
var E = ee*ee;
var ff = hashtable[5]/textL;
var F = ff*ff;
var gg = hashtable[6]/textL;
var G = gg*gg;
var hh = hashtable[7]/textL;
var H = hh*hh;
var ii = hashtable[8]/textL;
var I = ii*ii;
var jj = hashtable[9]/textL;
var J = jj*jj;
var kk = hashtable[10]/textL;
var K = kk*kk;
var ll = hashtable[11]/textL;
var L = ll*ll;
var mm = hashtable[12]/textL;
var M = mm*mm;
var nn = hashtable[13]/textL;
var N = nn*nn;
var oo = hashtable[14]/textL;
var O = oo*oo;
var pp = hashtable[15]/textL;
var P = pp*pp;
var qq = hashtable[16]/textL;
var Q = qq*qq;
var rr = hashtable[17]/textL;
var R = rr*rr;
var ss = hashtable[18]/textL;
var S = ss*ss;
var tt = hashtable[19]/textL;
var T = tt*tt;
var uu = hashtable[20]/textL;
var U = uu*uu;
var vv = hashtable[21]/textL;
var V = vv*vv;
var ww = hashtable[22]/textL;
var W = ww*ww;
var xx = hashtable[23]/textL;
var X = xx*xx;
var yy = hashtable[24]/textL;
var Y = yy*yy;
var zz = hashtable[25]/textL;
var Z = zz*zz;
var Kappa = 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 Top = 0.027*textL;
var Bottom1 = 0.038*textL + 0.065;
var Bottom2 = (textL - 1)*Kappa;
var KeyLength = Top/(Bottom2 - Bottom1) ;
return Kappa/0.0385;
}
function keylengthfinder(text){
// Average Function Definition
Array.prototype.avg = function() {
var av = 0;
var cnt = 0;
var len = this.length;
for (var i = 0; i < len; i++) {
var e = +this[i];
if(!e && this[i] !== 0 && this[i] !== '0') e--;
if (this[i] == e) {av += e; cnt++;}
}
return av/cnt;
}
// Begin the Key Length Finding
var textL = text.length;
var hashtable = new Array(0,0,0,0,0,0,0,0,0,0,0,0);
for (a = 0; a <= 12; a++){ // This is the main loop, testing each key length
var stringtable = [];
for (z = 0; z <= a; z++){ // This allows each setting, ie. 1st, 4th, 7th AND 2nd, 5th, 8th to be tested
for (i = z; i < textL; i + a){
var string = '';
string = string.concat(text.charAt(i)); // Join each letter of the correct place in the string
stringtable[z] = indexofcoincidence(string);
}
}
hashtable[a] = stringtable.avg();
}
return hashtable;
}
Your problem is definitely right here
for (i = z; i < textL; i + a){
var string = '';
string = string.concat(text.charAt(i)); // Join each letter of the correct place in the string
stringtable[z] = indexofcoincidence(string);
}
Notice that if a=0 i never changes and therefore you are in an infinite loop.
Array.prototype.avg = function() {...}
should be only done once, and not every time keylengthfinder is called.
var Top = 0.027*textL;
var Bottom1 = 0.038*textL + 0.065;
var Bottom2 = (textL - 1)*Kappa;
var KeyLength = Top/(Bottom2 - Bottom1) ;
return Kappa/0.0385;
Why do you computer those variables if you don't use them at all?
var string = '';
string = string.concat(text.charAt(i)); // Join each letter of the correct place in the string
stringtable[z] = indexofcoincidence(string);
I don't know what you are trying to do in here. The string will always be only one character?
for (i = z; i < textL; i + a) {
...
stringtable[z] = ...
}
In this loop, you are computing values for i from z to textL - but you overwrite the same array item each time. So it would be enough to compute the stringtable[z] for i=textL-1 - or your algorithm is flawed.
A much shorter and more concise variant of the indexofcoincidence function:
function indexofcoincidence(text){
var l = text.replace(/ /g, "").length;
text = text.toUpperCase().replace(/[^A-Z]/g, "");
var hashtable = {};
for (var i=0; i<l; i++) {
var c = text.charAt(i);
hashtable[c] = (hashtable[c] || 0) + 1;
}
var kappa = 0;
for (var c in hashtable)
kappa += hashtable[c] * hashtable[c];
return kappa/(l*l)/0.0385;
}
All right. Now that we found your problem (including the infinite loop in case a=0, as detected by qw3n), let's rewrite the loop:
function keylengthfinder(text) {
var length = text.length,
probabilities = []; // probability by key length
maxkeylen = 13; // it might make more sense to determine this in relation to length
for (var a = 1; a <= maxkeylen; a++) { // testing each key length
var stringtable = Array(a); // strings to check with this gap
// read "a" as stringtable.length
for (var z = 0; z < a; z++) {
var string = '';
for (var i = z; i < textL; i += a) {
string += text.charAt(i);
}
// a string consisting of z, z+a, z+2a, z+3a, ... -th letters
stringtable[z] = string;
}
var sum = 0;
// summing up the coincidence indizes for current stringtable
for (var i=0; i<a; i++) {
sum += indexofcoincidence(stringtable[i]);
}
probabilities[a] = sum / a; // average
}
return probabilities;
}
Every of the loop statements has changed against your original script!
Never forget to declare the running variable to be local (var keyword)
a needs to start at zero - a key must have a minimum length of 1
to run from 1 to n, use i=1; i<=n; i++
to run from 0 to n-1, use i=0; i<n; i++ (nearly all loops, especially on zero-based array indizes).
Other loops than those two never occur in normal programs. You should get suspicious if you have loops from 0 to n or from 1 to n-1...
The update expression needs to update the running variable. i++ is a shortcut for i+=1 is a shortcut for i=i+1. Your expression, i + a, did not assign the new value (apart from the a=0 problem)!

JavaScript - Need help with string manipulation

say you have:
var foo = "donut [$25]"
What would you need to do in order to delete everything between and including the [ ].
so you get: foo = "donut" after the code is run.
So far I have tried most of the solutions below, but they all either do nothing or crash.
Maybe it's something with my code, please see below:
$('select').change(function () { OnSuccess(mydata); });
function OnSuccess(data) {
var total = 0;
$('select').each(function () {
var sov = parseInt($(this).find('option:selected').attr('value')) || 0; //Selected option value
var sop; //Selected Option Price
for (i = 0; i <= data.length; i++) {
if (data[i].partid == sov) {
sop = data[i].price;
total += sop;
$('#totalprice').html(total);
break;
}
};
//debugger;
$(this).find('option').each(function () {
// $(this).append('<span></span>');
var uov = parseInt($(this).attr('value')) || 0; //Unselected option value
var uop; //Unselected Option Price
for (d = 0; d <= data.length; d++) {
if (data[d].partid == uov) {
uop = data[d].price;
break;
}
}
//debugger;
var newtext = uop - sop;
//{ newtext = "" };
//if (newtext = 0) { newtext.toString; newtext = ""; };
//debugger;
var xtext = $(this).text().toString();
//if (xtext.match(/\[.*\]/) != null) {
xtext.replace(/\s*\[[\s\S]*?\]\s*/g, '').trim();
//}
// var temp = xtext.split('[')[0];
// var temp2 = xtext.split(']')[1];
// resultx = temp + temp2;
if (newtext != 0) {
//xtext.replace(/[.*?]/, "");
$(this).attr("text", xtext + " " + "[" + "$" + newtext + "]");
};
});
});
};
You can also use a regular expression, as Jon Martin pointed out:
var yum = "donut[$25]";
yum.replace(/[.*?]/, ""); // returns "donut"
Alternatively:
var temp = foo.split('[')[0];
var temp2 = foo.split(']')[1];
foo = temp + temp2;
You can use regular expressions (the RegExp() object) to match strings.
var foo = "donut[$25]";
foo.match(/\[.*\]/);
The above will return an array of every item in [square brackets], in this case ["[$25]"].
To just get one result as a string, specify the first index like so:
foo.match(/\[.*\]/)[0];
The above will return "[$25]"
Edit: You know what? I completely misread which bit of the string you're after. This is what you're after:
var foo = "donut[$25]";
foo.match(/\w*/)[0];
How about simply;
var yum = "donut[$25]";
print( yum.substr(0, yum.indexOf("[")) );
>>donut
var begin = foo.search("[");
var end = foo.search("]");
var result = foo.substr(0, begin) + foo.substr(end+1); //Combine anything before [ and after ]
Should be ok right?
Your question leaves unspecified the treatment of the spaces before the [ character, anything after the ], will your string ever contain a linefeed character, multiple occurrences of [..], leading or trailing spaces.
The following will replace all occurrences of 'spaces [ ... ] spaces' with a single space, then it trims the result to remove any leading/trailing spaces.
v.replace (/\s*\[[\s\S]*?\]\s*/g, ' ').trim ();

Categories

Resources