How can i Add two For statement value - javascript

I want In the for statement add two values
resultSum.value = number_format(parseInt(productAmount.value));
resultSum.value = number_format(parseInt(localAmount.value));
But, sum separately
How can i sum productAmount.value + localAmount.value?
for (let i = 0; i < productChcbx.length; i++) {
productChcbx[i].addEventListener("click", () => {
let sum = 0;
let cnt = 0;
for (let j = 0; j < productChcbx.length; j++) {
if (productChcbx[j].checked) {
cnt++;
if (cnt == 1) {
addProduct.style.display = "flex";
productAmount.innerHTML = "70,000원";
productAmount.value = 70000;
} else if (cnt > 1) {
sum = 70000 + 60000 * (cnt - 1);
productAmount.innerHTML = number_format(sum) + "원";
productAmount.value = sum;
}
} else if (!productChcbx[j].checked) {
if (cnt == 0) {
addProduct.style.display = "none";
productAmount.value = 0;
}
}
}
resultSum.value = number_format(parseInt(productAmount.value));
})
}
for (let k = 0; k < localCheckboxs.length; k++) {
localCheckboxs[k].addEventListener("click", () => {
let sum = 0;
let cnt = 0;
for (let h = 0; h < localCheckboxs.length; h++) {
if (localCheckboxs[h].checked) {
cnt++;
if (cnt == 1) {
addLocal.style.display = "flex";
localAmount.innerHTML = "150,000원";
localAmount.value = 150000;
} else if (cnt > 1) {
sum = 150000 + 100000 * (cnt - 1);
localAmount.innerHTML = number_format(sum) + "원";
localAmount.value = sum;
}
} else if (!localCheckboxs[h].checked) {
if (cnt == 0) {
addLocal.style.display = "none";
localAmount.value = 0;
}
}
}
resultSum.value = number_format(parseInt(localAmount.value));
})
}
resultSum.value = parseInt(productAmount.value) + parseInt(localAmount.value);
if do this code it is possible to add
but can't productAmount.value + productAmount.value / localAmount.value + localAmount.value
Could you give me a best resolving?
Thank you!

I think I understand the question to ask how the click handler for one set of checkboxes can include the result of a click handler from the other set. The answer is to factor the calculation code from the handlers into functions that both may share.
(1) Factor the math into functions that do only math. Something like the following (many more improvements can be made to these functions, but I've left mostly intact so the OP can recognize the existing logic...)
// these two functions do only math on numerical values
const computeProductSum = () => {
let cnt = 0,
result = 0
for (let j = 0; j < productChcbx.length; j++) {
if (productChcbx[j].checked) {
cnt++;
if (cnt == 1) {
result = 70000;
} else if (cnt > 1) {
result = 70000 + 60000 * (cnt - 1);
}
} else {
if (cnt == 0) {
result = 0;
}
}
}
return result
}
const computeLocalSum = () => {
let cnt = 0,
result = 0
for (let j = 0; j < localCheckboxs.length; j++) {
if (localCheckboxs[j].checked) {
cnt++;
if (cnt == 1) {
result = 150000;
} else if (cnt > 1) {
result = 150000 + 100000 * (cnt - 1);
}
} else {
if (cnt == 0) {
result = 0;
}
}
}
return result
}
(2) Factor the ability to take a numeric value and convert it to formatted html...
const formatHtml = number => {
return number_format(number) + "원";
}
(3) With these tools factored out (if I understand the logic goal of the OP correctly) we can perform the math calculations for both types in the same click handler for both types of checkbox...
// both checkbox types can share this code
const checkboxClick = () => {
const sum = computeProductSum() + computeLocalSum()
resultSum.value = formatHtml(sum)
}
(4) Attach the same function to all checkboxes...
for (let i = 0; i < productChcbx.length; i++) {
productChcbx[i].addEventListener("click", checkboxClick);
}
for (let k = 0; k < localCheckboxs.length; k++) {
localCheckboxs[k].addEventListener("click", checkboxClick)
}
EDIT
Once this is working, the improvement to the math is as follows: we want a function that assigns a numerical value to the first checkbox checked, and another value for all of the others.
// for the list of checkboxes, compute a weighted sum for the checked ones
const computeCheckboxSum = (list, firstWeight, weight) => {
const count = list.reduce((sum, el) => sum + (el.checked ? 1 : 0), 0);
return count ? firstWeight + (count-1)*weight : 0
}
Use that to substantially reduce the code in the two compute functions we wrote earlier...
const computeProductSum = () => {
return computeCheckboxSum = (productChcbx, 70000, 60000);
}
const computeLocalSum = () => {
return computeCheckboxSum = (localCheckboxs, 150000, 100000);
}

Related

How to add to a variable when addition is in an for-loop

This is a problem from codewars. Heres my code.
function narcissistic(value) {
var total = 0
var valLength = value.length
const digit = [...`${value}`];
for(var i = 0; i < value.length; i++){
total += Math.pow(value.length , digit)
}
if(total == value){ return true
} else {
return false
}
}
The problem I'm having is I don't why when I do total += value.length * digit[i] it isn't adding to total. Any ideas?
You can try something like this:
You need to convert the function parameters into an array with different values and then calculate the power of each number and then add to the total.
Also, try to use let instead of var as it is better for block-level scope.
function narcissistic(value) {
let total = 0;
const digit = [...`${value}`];
for (let i = 0; i < digit.length; i++) {
total += Math.pow(digit[i], digit.length);
}
if(total === value) {
return true;
} else {
return false;
}
}
console.log(narcissistic(153));
console.log(narcissistic(432));
This function can return you the required value
function narcissistic(value) {
const stringValue = [...`${value}`];
const len = stringValue.length;
const sum = stringValue.reduce((prev, current) => {
return prev + Math.pow(parseInt(current, 10), len);
}, 0)
return `${value}` === sum.toString();
}

unary operator prefix execution in recursion is not working as expected

I am trying to count number of combinations in given range and length of combinations. Here is following code.
function generateCombination() {
const perm = [];
const permLength = 2;
const numberRange = 8;
let total = 0;
const getCombinations = (result, permLength, numberRange) => {
if (result.length === permLength) {
//console.log('result: ', result);
return 1;
}
for (var i = 0; i < numberRange; i++) {
if (result.indexOf(i) === -1) {
result.push(i);
total = total + getCombinations(result, permLength, numberRange);
result.pop();
}
}
return 0;
}
getCombinations(perm, permLength, numberRange);
console.log("total: ", total); // expected value "total: 56"
}
generateCombination();
the console log for total variable always print 0. but following code works as expected with little change in for loop code. I couldn't understand how the prefix is works here (somex = somex + fn()). Can someone please help here?
// working solution
function generateCombination() {
const perm = [];
const permLength = 2;
const numberRange = 8;
let total = 0;
const getCombinations = (result, permLength, numberRange) => {
if (result.length === permLength) {
//console.log('result: ', result);
return 1;
}
for (var i = 0; i < numberRange; i++) {
if (result.indexOf(i) === -1) {
result.push(i);
if (getCombinations(result, permLength, numberRange)) {
total += 1;
}
result.pop();
}
}
return 0;
}
getCombinations(perm, permLength, numberRange);
console.log("total: ", total); // expected value is "total: 56" and working here
}
generateCombination();
My question is, I don't understand, why solution 1 (top one) is not working as expected (printing total as 0 rather than 56 )?
Thanks
You could move total into getCombinations and return this value on exit.
function generateCombination() {
const perm = [];
const permLength = 2;
const numberRange = 8;
const getCombinations = (result, permLength, numberRange) => {
if (result.length === permLength) return 1;
let total = 0;
for (let i = 0; i < numberRange; i++) {
if (result.indexOf(i) === -1) {
result.push(i);
total += getCombinations(result, permLength, numberRange);
result.pop();
}
}
return total;
}
console.log("total: ", getCombinations(perm, permLength, numberRange)); // expected value "total: 56"
}
generateCombination();

Tic-Tac-Toe in JavaScript with minimax algorithm

I'm trying to implement a Tic-Tac-Toe game using a minimax algorithm for n number of grid size in Javascript.
I have copied the algorithm from geeksforgeeks exactly, but in Javascript the result is not expected and something weird is happening beyond my understanding.
I'm calling the function computerTurn(moves) to make the computer move, and inside it calling the function getBestMove(gridArr, depth, isMax, moves) to get the best move via the minimax algorithm.
In both functions, I'm first checking the empty cell in the grid then assigning it with a specific turn, and then calling the getBestMove function with the new grid. However sometimes the assignment of the grid does not take place and the getBestMove method is called.
Secondly, when I'm printing the grid array in the getBestMove method, it's always printing the same array with only two elements like...
gridArr:- 0:-[1,2,0], 1:-[0,0,0], 2:-[0,0,0]
... and every time the next empty cell is returned as bestMove.
At first, I thought that the same array has been passed to every getBestMove function but when I log the score I'm getting results from the evaluateScore(grid) method (which returns 10 for win, -10 to lose and 0 for draw) returning 10 and -10 as well.
See code below.
In any case, what needs to happen is in each iteration of both functions, when an empty cell is detected the function makes a move i.e assignment of turn into the grid and then pass that grid into the function call.
I'm using 1 for 'X', 2 for '0' and 0 for empty cells in the grid. GRID_LENGTH is the size of row of Tic-Tac-Toe which is 3 for now, and grid is the 2d array for storing X and 0. In the evaluateScore function, WIN_LENGTH is the length to decide winning state, which 3 in this case
This is git repository, which creates the error(s) in question
Thank You all!!
function computerTurn(moves) {
let bestValue = -1000,
bestMove = [];
for (let row = 0; row < GRID_LENGTH; row++) {
for (let col = 0; col < GRID_LENGTH; col++) {
if (grid[row][col] == 0) {
// searching for empty cell
grid[row][col] = 2; // making move
moves++; // increment moves count
let moveValue = getBestMove(grid, 0, false, moves); // checking is this is the best move
moves--;
grid[row][col] = 0;
if (moveValue > bestValue) {
// updating values
bestMove[0] = row;
bestMove[1] = col;
bestValue = moveValue;
}
}
}
}
grid[bestMove[0]][bestMove[1]] = 2;
turn = 'X';
return bestMove;
}
function getBestMove(gridArr, depth, isMax, moves) {
let score = evaluateScore(gridArr);
let arr = gridArr;
if (score == 10 || score == -10) {
return score;
}
if (moves == totalMoves) {
return 0;
}
if (isMax) {
let best = -1000;
for (let i = 0; i < GRID_LENGTH; i++) {
for (let j = 0; j < GRID_LENGTH; j++) {
if (arr[i][j] == 0) {
arr[i][j] = 2;
moves++;
best = Math.max(best, getBestMove(arr, depth + 1, !isMax, moves));
arr[i][j] = 0;
moves--;
}
}
}
return best;
} else {
let best = 1000;
for (let i = 0; i < GRID_LENGTH; i++) {
for (let j = 0; j < GRID_LENGTH; j++) {
if (arr[i][j] == 0) {
arr[i][j] = 1;
moves++;
best = Math.min(best, getBestMove(arr, depth + 1, !isMax, moves));
arr[i][j] = 0;
moves--;
}
}
}
return best;
}
}
function evaluateScore(gridArr) {
let diff = GRID_LENGTH - WIN_LENGTH;
let len = WIN_LENGTH - 1;
for (let i = 0; i < GRID_LENGTH; i++) { // check win for different rows
if (diff == 0) {
let win = true;
for (let j = 0; j < len; j++) {
if (gridArr[i][j] != gridArr[i][j + 1]) {
win = false;
break;
}
}
if (win) {
if (gridArr[i][0] == 1) {
return -10;
} else if (gridArr[i][0] == 2) {
return 10;
}
}
} else {
for (let j = 0; j <= diff; j++) {
let count = 0;
for (let k = j; k < len; k++) {
if ((gridArr[i][k] != gridArr[i][k + 1])) {
count++;
}
if (count == len) {
if (gridArr[i][k] == 1) {
return -10;
} else if (gridArr[i][k] == 2) {
return 10;
}
}
}
}
}
}
for (let i = 0; i < GRID_LENGTH; i++) { // check win for different cols
if (diff == 0) {
let win = true;
for (let j = 0; j < len; j++) {
if (gridArr[j][i] != gridArr[j][i + 1]) {
win = false;
break;
}
}
if (win) {
if (gridArr[0][i] == 1) {
return -10;
} else if (gridArr[0][i] == 2) {
return 10;
}
}
} else {
for (let j = 0; j <= diff; j++) {
let count = 0;
for (let k = j; k < len; k++) {
if ((gridArr[k][i] != gridArr[k][i + 1])) {
count++;
}
if (count == len) {
if (gridArr[k][i] == 1) {
return -10;
} else if (gridArr[k][i] == 2) {
return 10;
}
}
}
}
}
}
let diagonalLength = GRID_LENGTH - WIN_LENGTH;
for (let i = 0; i <= diagonalLength; i++) { // diagonals from left to right
for (let j = 0; j <= diagonalLength; j++) {
let row = i,
col = j;
let win = true;
for (let k = 0; k < len; k++) {
if (gridArr[row][col] != gridArr[row + 1][col + 1]) {
win = false;
break;
}
row++;
col++;
}
if (win) {
if (gridArr[i][j] == 1) {
return -10;
} else if (gridArr[i][j] == 2) {
return 10;
}
}
}
}
let compLen = GRID_LENGTH - diagonalLength - 1;
for (let i = 0; i >= diagonalLength; i--) { // diagonals from right to left
for (let j = GRID_LENGTH - 1; j >= compLen; j--) {
let row = i,
col = j;
let win = true;
for (let k = 0; k < len; k++) {
if (gridArr[row][col] != gridArr[row + 1][col - 1]) {
win = false;
break;
}
row++;
col--;
}
if (win) {
if (gridArr[i][j] == 1) {
return -10;
} else if (gridArr[i][j] == 2) {
return 10;
}
}
}
}
return 0;
}

Project Euler #23 in JS

My results for numbers between 1 and 28321 (limit)
sum of all numbers: 395465626
sum of all abundant numbers: 392188885
sum of all non abundant numbers: 3276741 (correct answer is 4179871)
var divisors = function(number){
sqrtNumber = Math.sqrt(number);
var sum = 1;
for(var i = 2; i<= sqrtNumber; i++)
{
if (number == sqrtNumber * sqrtNumber)
{
sum += sqrtNumber;
sqrtNumber--;
}
if( number % i == 0 )
{
sum += i + (number/i);
}
}
if (sum > number) {return true;}
else {return false;}
};
var abundent = [], k = 0;
var upperLimit = 28123;
for (var i = 1; i <= upperLimit; i++)
{
if (divisors(i))
{abundent[k] = i; k++};
}
var abundentCount = abundent.length;
var canBeWrittenAsAbundant = [];
for (var i = 0; i < abundentCount; i++){
for (var j = i; j < abundentCount; j++){
if (abundent[i] + abundent[j] <= upperLimit){canBeWrittenAsAbundant[abundent[i]+abundent[j]] = true;}
else {
break;
}
}
}
for (i=1; i <= upperLimit; i++){
if (canBeWrittenAsAbundant[i] == true){continue;}
else {canBeWrittenAsAbundant[i] = false;}
}
var sum = 0;
for (i=1; i <= upperLimit; i++)
{
if (!canBeWrittenAsAbundant[i]){
sum += i;
}
}
console.log(sum);
I'm using http://www.mathblog.dk/project-euler-23-find-positive-integers-not-sum-of-abundant-numbers/ as guidance, but my results are different. I'm a pretty big newb in the programming community so please keep that in mind.
You do not need to calculate the sum of all numbers using a cycle, since there is a formula, like this:
1 + 2 + ... + number = (number * (number + 1)) / 2
Next, let's take a look at divisors:
var divisors = function(number){
sqrtNumber = Math.sqrt(number);
var sum = 1;
for(var i = 2; i<= sqrtNumber; i++)
{
if (number == sqrtNumber * sqrtNumber)
{
sum += sqrtNumber;
sqrtNumber--;
}
if( number % i == 0 )
{
sum += i + (number/i);
}
}
if (sum > number) {return true;}
else {return false;}
};
You initialize sum with 1, since it is a divisor. However, I do not quite understand why do you iterate until the square root instead of the half of the number. For example, if you call the function for 100, then you are iterating until i reaches 10. However, 100 is divisible with 20 for example. Aside of that, your function is not optimal. You should return true as soon as you found out that the number is abundant. Also, the name of divisors is misleading, you should name your function with a more significant name, like isAbundant. Finally, I do not understand why do you decrease square root if number happens to be its exact square and if you do so, why do you have this check in the cycle. Implementation:
var isAbundant = function(number) {
var sum = 1;
var half = number / 2;
for (var i = 2; i <= half; i++) {
if (number % i === 0) {
sum += i;
if (sum > number) {
return true;
}
}
}
return false;
}
Note, that perfect numbers are not considered to be abundant by the function.
You do not need to store all numbers, since you are calculating aggregate data. Instead, do it like this:
//we assume that number has been initialized
console.log("Sum of all numbers: " + ((number * (number + 1)) / 2));
var abundantSum = 0;
var nonAbundantSum = 0;
for (var i = 0; i <= number) {
if (isAbundant(i)) {
abundantSum += i;
} else {
nonAbundantSum += i;
}
}
console.log("Sum of non abundant numbers: " + nonAbundantSum);
console.log("Sum of abundant numbers: " + abundantSum);
Code is not tested. Also, beware overflow problems and structure your code.
Below is the Corrected Code for NodeJS..
var divisors = function (number) {
sqrtNumber = Math.sqrt(number);
var sum = 1;
var half = number / 2;
for (var i = 2; i <= half; i++) {
if (number % i === 0) { sum += i; }
}
if (sum > number) { return true; }
else { return false; }
};
var abundent = [], k = 0;
var upperLimit = 28123;
for (var i = 1; i <= upperLimit; i++) {
if (divisors(i)) { abundent[k] = i; k++ };
}
var abundentCount = abundent.length;
var canBeWrittenAsAbundant = [];
for (var i = 0; i < abundentCount; i++) {
for (var j = i; j < abundentCount; j++) {
if (abundent[i] + abundent[j] <= upperLimit) { canBeWrittenAsAbundant[abundent[i] + abundent[j]] = true; }
else {
break;
}
}
}
for (i = 1; i <= upperLimit; i++) {
if (canBeWrittenAsAbundant[i] == true) { continue; }
else { canBeWrittenAsAbundant[i] = false; }
}
var sum = 0;
for (i = 1; i <= upperLimit; i++) {
if (!canBeWrittenAsAbundant[i]) {
sum += i;
}
}
console.log(sum);

finding the nth prime javascript

the functions below are supposed to spit out the nth prime number. However, it keeps on spitting out 3. Can somebody please help? Cheers, Anthony
function Prime(num) {
output = true
for (i=2 ; i<num ; i++) {
if (num%i === 0) {
output = false ; break
}
}
return output
}
function PrimeMover(num) {
var count = 0
for (i=2 ; i<10000 ; i++) {
if (Prime(i) === true) {
count = count + 1
}
if (count === num) {
return i
break
}
}
}
You have created loop counter i in global scope.so both PrimeMover and Prime mutates same global i.In every iteration ,PrimeMover assigns i=2.After that Prime assigns i=2.your i variable's value will be changed between 2 and 3.use local loop counter variable var i=0;
function Prime(num) {
output = true
for (var i=2 ; i<num ; i++) { //var i=2
if (num%i === 0) {
output = false ; break
}
}
return output
}
function PrimeMover(num) {
var count = 0
for (var i=2 ; i<10000 ; i++) { //var i=2
if (Prime(i) === true) {
count = count + 1
}
if (count === num) {
return i
break
}
}
}
For minimal code lovers,
function nthprime(n)
{
var prime=[], i=1
while (i++ && prime.length<n) prime.reduce((a,c)=>(i%c)*a,2) && prime.push(i)
return prime.length?prime.pop():-1
}
[-1,0,1,2,3,5,10,100].forEach(n=>console.log(`nthprime(${n})=${nthprime(n)}`))
function main(inp) {
var count = 0;
for (var i = 2; i <= 100000; i++) {
if (isPrime(i)) count = count + 1;
if (count == inp) return i;
}
}
function isPrime(i) {
for (var j = 2; j < i; j++) {
//instead of `j < i` it can be reduced using other conditions
if (i % j == 0) {
return false
}
}
return true
}
main(5) // any number
This might be a bit more optimal
function nthPrime(n) {
var P = 0;
function isPrime(x) {
var isPrime= true;
for (var d = 2; d <= Math.sqrt(x); d++) {
if((x/d) % 1 == 0) {
isPrime = false;
break;
}
}
return isPrime;
}
for (var i = 1; 0 < n; i++) {
if(isPrime(i)) {
P = i; n--;
}
// we can skip the even numbers
if(3 <= i){
i++;
}
}
return P;
}
Try this
var pos=10001;
console.log(primeNumforPos(pos));
function primeNumforPos(pos){
var num=2,curPos=0;
while(curPos<=pos){
if(isPrime(num)){
curPos++;
}
if(curPos==pos){
return num;
}else{
num++;
}
}
}
function isPrime(num){
for(var i=2;i<=Math.sqrt(num);i++){
if(num%i==0){
return false;
}
}
return true;
}
So, I decided to optimise the hell out of the code (cuz why not). It is almost 6 times as fast as that of ppseprus (297ms vs 1773ms in nth_prime(100000)).
let primes = [2, 3];
const nth_prime = (n) => {
if (n <= primes.length) return primes[n - 1]; // handle values which have been cached
let i = 1;
while (1){
const a = 6 * i - 1, b = 6 * i + 1, a_limit = Math.sqrt(a), b_limit = Math.sqrt(b); // the 6n - 1 and 6n + 1 rule for primes
let a_prime = true, b_prime = true;
i++;
// prime check
for (const prime of primes){
if (prime > a_limit) break;
if (a % prime == 0){
a_prime = false;
break;
}
}
if (a_prime){
if (primes.length + 1 == n) return a;
primes.push(a); // cache
}
for (const prime of primes){
if (prime > b_limit) break;
if (b % prime == 0){
b_prime = false;
break;
}
}
if (b_prime){
if (primes.length + 1 == n) return b;
primes.push(b); // cache
}
}
}
const findPrime = num => {
let i, primes = [2, 3], n = 5
const isPrime = n => {
let i = 1, p = primes[i],
limit = Math.ceil(Math.sqrt(n))
while (p <= limit) {
if (n % p === 0) {
return false
}
i += 1
p = primes[i]
}
return true
}
for (i = 2; i <= num; i += 1) {
while (!isPrime(n)) {
n += 2
}
primes.push(n)
n += 2
};
return primes[num - 1]
}
console.time('Time')
let x = findPrime(9999)
console.timeEnd('Time')
console.log(x)

Categories