Javascript code runs fine... almost all the time - javascript

I have come across a problem that I cannot seem to resolve. Please take a look at the code below:
<script>
function createFunctions() {
var first = ["", "", ""];
var second = ["", "", ""];
var func = ["", ""];
var sign = ["", ""];
for (i = 0; i < 3; i++) {
first[i] = (Math.round(Math.random() * 9) + 1);
second[i] = (Math.round(Math.random() * 9) + 1);
sign[i] = (Math.round(Math.random()));
if (sign[i] == "1") {
sign[i] = '+';
} else {
sign[i] = '-';
}
if (first < 2) {
func[i] = 'f(x) = x ' + sign[i] + ' ' + second[i] + '<p>';
} else {
func[i] = 'f(x) = ' + first[i] + 'x ' + sign[i] + ' ' + second[i] + '<br>';
}
}
for (i = 0; i < 3; i++) {
document.getElementById("createFunctions").innerHTML += 'Function ' + [i + 1] + ': ' + func[i];
}
//whichFunction=
findAnswers(first, second, sign);
}
function findAnswers(first, second, sign, rand) {
var num = ["", "", ""];
rand = (Math.round(Math.random() * 1));
document.getElementById("findAnswers").innerHTML = 'Which <b>one (or more)</b> of these functions holds true, when plugged in with the following <b>values of x</b>? (' + [rand + 1] + ')<br>';
for (i = 0; i < 3; i++) {
num[i] = (Math.round(Math.random() * 9));
}
for (i = 0; i < 3; i++) {
ans = 0;
if (sign[rand] == "+") {
ans = [first[rand] * num[i]] + second[rand];
} else {
ans = [first[rand] * num[i]] - second[rand];
}
document.getElementById("findAnswers").innerHTML += [i + 1] + '. You put in a ' + num[i] + ': ' + ans + '<br>';
}
}
</script>
<BODY onload=createFunctions()>
<b>A Machine Called Effex</b>
<p><input type="button" value="New Examples" onclick="history.go(0)" VALUE="Refresh"></p>
<p id="createFunctions"></p>
<p id="findAnswers"></p>
Everything works great. Except occasionally, when calculating the function, the code multiplies by x, and then simply concatenates the second value onto the first, instead of adding (or subtracting).

You should change [first[rand]*num[i]] to (first[rand]*num[i]).
The [] bracket is instantiating an array with only one value (the product of your multiplication) and then you're 'adding' the array to a number, which forces the engine to cast the array to a string and concatenate the string with the number you're 'adding'.
To illustrate, consider the code below. It also instantiates an array but casts it to a number using the unary + operator. This will result in a numerical value and not an array, so your code will work as expected.
+[first[rand]*num[i]]
To further illustrate what's happening, consider the code below. It too instantiates a single-element array, but by appending it with [0], we specify the (numerical) value of that element and so the engine is not forced to cast the array to a string when you use the + operator.
[first[rand]*num[i]][0]

Related

JavaScript Permutations using Recursion

I know that there are many solutions on the internet for my specific question, but I have been trying to solve it in a specific way and it doesn't work and I really can't understand what is wrong.
In my case I simply want to print the permutations.
Here is my code:
a = "abc";
function f7(a, b) {
//document.write("str: "+a+" b:"+b+"<br>");
if (b.length == 2) {
perm = b + a;
return perm;
}
var c = [];
var str = [];
for (i = 0; i < a.length; i++) {
c[i] = b + a.charAt(i);
str[i] = a.substring(0, i) + a.substring(i + 1);
document.write("i: " + i + " c[i]: " + c[i] + " str[i]: " + str[i] + "<br>");
return f7(str[i], c[i]);
}
//return {str,c}
}
document.write(f7(a, ""));
//g=f7(a,"");
//document.write(g.str+"<br>");
//document.write(g.c+"<br>");
The above code doesn't go beyond the first permutation, and I can't understand why.
Thanks in advance for any advice
Returning value in the loop causes escaping the loop. You are returning the value in for statement that stops immediately before loop complete.
You can use temporary variable to save value in for loop, and then return it.
a = "abc";
function f7(a, b) {
//document.write("str: "+a+" b:"+b+"<br>");
if (b.length == 2) {
perm = b + a;
return perm;
}
var c = [];
var str = [];
var temp = '';
for (i = 0; i < a.length; i++) {
c[i] = b + a.charAt(i);
str[i] = a.substring(0, i) + a.substring(i + 1);
document.write("i: " + i + " c[i]: " + c[i] + " str[i]: " + str[i] + "<br>");
temp += f7(str[i], c[i]);
}
return temp
}
document.write(f7(a, ""));
//g=f7(a,"");
//document.write(g.str+"<br>");
//document.write(g.c+"<br>");

Can J2V8 execute anonymous function?

I'm trying to execute this piece of javascript code
(function() {
var z = '';
var b = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx';
for (var i = 0; i < b.length; i += 2) {
z = z + parseInt(b.substring(i, i + 2), 16) + ',';
}
z = z.substring(0, z.length - 1);
eval(eval('String.fromCharCode(' + z + ')'));
})();
but I got this error:
undefined:1: ReferenceError: document is not defined
If I assign the function to a variable, I haven't neither error nor result.
var a = function() {
var z = '';
var b = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx';
for (var i = 0; i < b.length; i += 2) {
z = z + parseInt(b.substring(i, i + 2), 16) + ',';
}
z = z.substring(0, z.length - 1);
eval(eval('String.fromCharCode(' + z + ')'));
};
Have you got any idea on how run this script with J2V8?
Thank you in advance
I'll be honest, I don't know what the JS is supposed to do. You have an eval wrapped in an eval, and the function has no return statement. Plus, xxxxx doesn't appear to be a valid input.
Having said all that, if I remove the wrapped eval, use a number for the the variable b and return the result, it works fine for me.
#Test
public void testExample2() {
String jsCode = "(function() {\n"
+ "var z = '';\n"
+ "var b = '12345678';\n"
+ "for (var i = 0; i < b.length; i += 2) {\n"
+ " z = z + parseInt(b.substring(i, i + 2), 16) + ',';\n"
+ "}\n"
+ "z = z.substring(0, z.length - 1);\n"
+ "return eval('String.fromCharCode(' + z + ')');\n"
+ "})();";
Object result = v8.executeScript(jsCode);
System.out.println(result);
}

How to console.log multiplication table without repeating x*y=z, y*x=z

How to make multiplication table without repeating reverse calculations like this xy=z yx=z? I tried to use if else with !== operator but it shows nothing. My code:
for (var x = 1; x <= 10; x++) {
for (var i = 1; i <= 10; i++) {
var result = x * i;
if (result !== result){
console.log(x + ' * ' + i + ' = ' + result);
}
else {
}
}
}
Pretty simple :
for (var x = 1; x <= 10; x++) {
for (var i = x; i <= 10; i++) {
var result = x * i;
console.log(x + ' * ' + i + ' = ' + result);
}
}
Replace i = 1 by i = x on the second line so that it starts later and ignores all the previous calculations it already did.
E.G.: When you're calculating the table 3, you can start with 3*3 as you already already did 3*1 (1*3) with table 1 and 3*2 (2*3) with table 2
You could keep track of the calculations you've already done in an hash table. If it's already in the table - skip that calculation. Something like this:
var doneCalculations = {};
for (var x = 1; x <= 10; x++) {
for (var i = 1; i <= 10; i++) {;
if (doneCalculations[i+'x'+x]) continue;
doneCalculations[x+'x'+i] = true;
var result = x * i;
console.log(x + ' * ' + i + ' = ' + result);
}
}
start the second loop with first loop variable
for (var x = 1; x <= 10; x++) {
for (var i = x; i <= 10; i++) {
var result = x * i;
console.log(x + ' * ' + i + ' = ' + result);
}
}
You want to print full multiplication table for each values of x, 1 to 10. Use memoization to avoid recalculation
In computing, memoization or memoisation is an optimization technique used primarily to speed up computer programs by storing the results of expensive function calls and returning the cached result when the same inputs occur again.
var doneCalculations = {};
var calculations = {};
var doneCalculations = {};
for (var x = 1; x <= 10; x++) {
for (var i = 1; i <= 10; i++) {;
if (doneCalculations[i+'x'+x]) {
result = calculations[i+'x'+x]
}
else {
doneCalculations[x+'x'+i] = true;
var result = x * i;
calculations[x+'x'+i] = result;
}
console.log(x + ' * ' + i + ' = ' + result);
}
}
console.log(calculations)

counting words of each sentence in a long string, jquery

I am trying to count the words in each sentence from a long string. What I get is just the number of the sentences. I found some solution in C# and Ruby but they are not for me:-))
I am really new to java-script. Any help much appreciated. The code below:
the output is according:
Words: 1 in sent: 1
Words: 0 in sent: 2
Words: 1 in sent: 3
Words: 1 in sent: 4
Words: 1 in sent: 5
Words: 1 in sent: 6
the word counter is not increasing! Most probably it's something simple.
Thank you in advance.
var text1 = $('#textarea1').val();
var gaps = [];
var wordsC = 0;
var wordsTot = 0;
var tempC = 0;
var sents = text1.split('.');
for (var elem in sents)
{
tempC += 1;
wordsC = elem.split(" ").length;
wordsTot += wordsC;
if (tempC == 2) {
wordsC -= 1;
wordsTot -= 1;
}
document.write("<br />Words: " + wordsC + " |in sent: " + tempC + " sent");
};
document.write("<br />words total : " + wordsTot + "<br />" );
You shouldn't enumerate an array with for...in. text1.split('.'); is producing an array, which you are trying to enumerate with for...in. The value of elem on each iteration of the for...in is one of the the array indexes as a string ('0' on the first iteration, '1' on the second and so on). You'll even end up with some of the Array prototype methods and other things up the prototype change.
For pre ES6 environments, try:
for (var i = 0; i < sents.length; i++)
{
tempC += 1;
wordsC = sents[i].split(" ").length;
wordsTot += wordsC;
if (tempC == 2) {
wordsC -= 1;
wordsTot -= 1;
}
document.write("<br />Words: " + wordsC + " |in sent: " + tempC + " sent");
}
ES6 introduced a for...of construct which does what you're trying to do:
for (let elem of sents)
{
tempC += 1;
wordsC = elem.split(" ").length;
wordsTot += wordsC;
if (tempC == 2) {
wordsC -= 1;
wordsTot -= 1;
}
document.write("<br />Words: " + wordsC + " |in sent: " + tempC + " sent");
};
var str = "There are five words here. I like turtles a lot. This is five words long. Yep.";
var split = str.split(".");
var amountOfSentences = str.charAt(str.length - 1) == "." ? split.length : split.length + 1;
var total = 0;
for (i = 0; i < amountOfSentences - 1; i++) {
$("body").append("Sentence " + (i + 1) + ": ");
for (j = 0; j < split[i].split(" ").length - 1; j++) {
total++;
}
if (i == 0) total++;
$("body").append(" " + total + "<br />");
total = 0;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
There are five words here. I like turtles a lot. This is five words long. Yep.
This will output:
Sentence 1: 5
Sentence 2: 5
Sentence 3: 5
Sentence 4: 1
The end of sentence can end with a dot or not, it doesn't matter (taken account for in the var amountOfSentences). Does that work out for you?

how to start the function again if the condition is false in javascript

Here's the code: this Display the table of any number given by user.
function table(num){
var num = prompt("please enter any number");
var x = num;
if (num <= 0){
alert("invalid number or Zero") ;
} else {
for(var i=1; i <= 10; i++){
var y = x * i;
document.write(x + ' X ' + i +' = ' + y + '<br/>') ;
}
}
}
table();
now if -1 entered it display alert("invalid number or Zero"); and code breaks nothing is displayed. What I am looking for is how will it go again to start of function and prompt again for the number.
Recursion is your friend: call the method again
function table(num){
var num = prompt("please enter any number");
var x = num;
if (num <= 0){
alert("invalid number or Zero") ;
table(); // <----------------
} else {
for(var i=1; i <= 10; i++){
var y = x * i;
document.write(x + ' X ' + i +' = ' + y + '<br/>') ;
}
}
}
Apart from that, you might want to consider a slight refactoring, since there are some useless variables/parameters
As has been mentioned before, you'll want to call the table function again (recursion), after the alert().
You can also clean up the function a bit, since there's no need to copy num to x, and a num parameter in the function isn't necessary, because you're initializing num in the function itself, and you have no need to pass it as a parameter:
function table(){
var num = prompt("please enter any number");
if (num <= 0){
alert("invalid number or Zero") ;
table();
} else {
for(var i = 1; i <= 10; i++){
var y = num * i;
document.write(num + ' X ' + i +' = ' + y + '<br/>');
}
}
}
table();
You could use a while loop as well.
Have a fiddle: https://jsfiddle.net/hmea6rLx/
JS code:
function table(num){
var num=0;
while (num <= 0){
num = prompt("please enter any number");
var x = num;
$('#error').html("invalid number or Zero") ;
}
for(var i=1; i <= 10; i++){
var y = x * i;
$('#error').html(x + ' X ' + i +' = ' + y + '<br/>') ;
}
}
table();
Why the parameter (num)?
Your function rewritten in two ways, reusing itself:
document.querySelector('#table').addEventListener('click', start);
document.querySelector('#table2').addEventListener('click', start);
function start() {
return window[this.id]();
}
function table(){
var num = prompt("please enter any number");
if (num <= 0){
log(num + ": invalid number or zero");
return table();
}
for(var i = 1; i <= 10; i += 1){
log(i + ' * ' + num + ' = ' + (i * num));
}
}
// just for fun: more functional
function table2(){
var num = prompt("please enter any number");
var reslt = num <= 0 ? [num + ": invalid number or zero\n"] :
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10].map(
function(v, i) {
return v + ' * ' + num + ' = ' + (v * num);
}
);
log(reslt.join('\n'));
return reslt.length < 10 ? table2() : true;
}
function log(str) {
log.el = log.el || document.querySelector("#result");
log.el.textContent += str+'\n';
}
<button id="table">exec table</button>
<button id="table2">exec table2</button>
<pre id="result"></pre>

Categories