Factorials/Combinations Yields NaN When Not Supposed To - javascript

I am solving for y Choose p combinations. I am a beginner with Javascript.
I have produced this definition of the factorial function:
It was inteded to do x * (x-1) * (x-2) ... * 1.
function factorial(z)
{
var product = z;
if (z == 0)
{
return 1;
}
else
{
for (var m = 1; m < z; m++)
{
product = m * product;
return product;
}
}
}
I then have this function, which uses the factorial function.
function placeBoxes()
{
var ids = 0;
for (var y = 0; y < (numOfRows-1); y++)
{
for (var p = 0; p < (y+1); p++, ids++)
{
x = document.createElement('div');
x.className = "box";
x.id = ids;
x.innerHTML = (factorial(y))/((factorial(y-p))*(factorial(p)));
document.getElementById('holdsBoxes').appendChild(x);
}
}
}
It is supposed to choose the combinations. For experimental purposes, numOfRows is realistically between 5 and 30. 0C0 1C0 1C1 2C0 2C1 2C2 and so on...
This is equivalent to 1, 1, 1, 1, 2, 1 and so on...
Does anyone know what I have done wrong? I am getting NaN instead of a value for the second, third, fifth, eighth, ninth, and many other values.
Edit: Thank you everyone! The problem is solved. The factorial function was messed up.

Change
for (var m = 1; m < z; m++)
{
product = m * product;
return product;
}
To
for (var m = 1; m < z; m++)
{
product = m * product;
}
return product;
You're never completing the loop

for (var m = 1; m < z; m++)
{
product = m * product;
return product;
}
Your returning product inside your loop. Are you sure about this? Don't you want to return product outside your loop?
This is also the cause of your NaN. What if z is 1 ? then m < z is m < 1 and thats always false. So that loop body is never being called. and the return statement is never called.
So the function returns undefined. And undefined * 1 === NaN

I believe that the factorial function is incorrect. Try changing it to this:
function factorial(z)
{
var product = z;
if (z == 0)
{
return 1;
}
else
{
for (var m = 1; m < z; m++)
{
product = product*(product - m);
}
return product;
}
}

Related

Fibronacci sequence spitting wrong number

I have created a function that sumbs up all odd fibronacci numbers up to a given number, and for the most part it works all for except one number. For example sumFibs(10) should return 10 becuz all Fib #s <= 10 are 1,1,3 and 5.
If I do sumFibs(75024); I get 135721 instead of the expected value is 60696. For every other number it works perfectly and am scratching my head to solve it
function sumFibs(num) {
let thunderAss = [];
let currDmp = 0;
let nxtRmp = 1;
var pushNxt = 0;
// push into array
for (let x = 0; x < num; x++) {
if (x <= 1) {
console.log("lets go");
thunderAss.push(1); // 2l almond milk
} else {
thunderAss.push(thunderAss[x - 1] + thunderAss[x - 2]);
console.log(x, " x is factor");
}
}
console.log(thunderAss);
let cuntNuts = 0;
for (let x = 0; x < num; x++) {
if (cuntNuts < num) {
if (thunderAss[x] % 2 == 0) {} else {
cuntNuts += thunderAss[x];
}
} else {
break;
}
}
console.log("CN: ", cuntNuts);
return cuntNuts;
}
sumFibs(75024); // 60696 but 135721
sumFibs(4);
The condition if (cuntNuts < num) is wrong. cuntNuts is the sum of fibonacci numbers, not the fibonacci number itself. So you're stopping when the sum reaches n, not summing all the odd numbers up to n.
You should be comparing thunderAss[x] with num. And it should be <= if that number should be included in the total.
You can also put this condition into the for loop header rather than adding it as a separate check in the body.
function sumFibs(num) {
let thunderAss = [];
let currDmp = 0;
let nxtRmp = 1;
var pushNxt = 0;
// push into array
for (let x = 0; x < num; x++) {
if (x <= 1) {
console.log("lets go");
thunderAss.push(1); // 2l almond milk
} else {
thunderAss.push(thunderAss[x - 1] + thunderAss[x - 2]);
console.log(x, " x is factor");
}
}
console.log(thunderAss);
let cuntNuts = 0;
for (let x = 0; thunderAss[x] <= num; x++) {
if (thunderAss[x] % 2 == 0) {} else {
cuntNuts += thunderAss[x];
}
}
console.log("CN: ", cuntNuts);
return cuntNuts;
}
sumFibs(75024); // 60696 but 135721
sumFibs(4);
You are adding the num first Fibonacci numbers instead of the Fibonacci numbers less than or equal to num.
In my solution here, I do the correct thing and get the correct answer:
function* fibonacci()
{
let x = 0;
let y = 1;
while (true) {
yield x;
[x, y] = [y, x+y];
}
}
function sum_odd_fibonacci(max)
{
const fib_seq = fibonacci();
let s = 0;
let n;
while ( (n=fib_seq.next().value) <= max) {
if (n % 2 == 1) {
s += n;
}
}
return s;
}
console.log(sum_odd_fibonacci(75024));

Leetcode not accepting correct sudoku solver algorithim

I wrote a sudoku solver in Javascript for https://leetcode.com/problems/sudoku-solver/solution/. Whenever I use the same code in an IDE outside of leetcode, it solves the sudoku board fine. However, when I submit it as an answer in leetcode, it always returns a the default board parameter passed in to the function. Can anyone figure out why?
Note: The leetcode problem says to solve the board in place and not to return anything.
Error: imgur.com/a/63v7sOu
/**
* #param {character[][]} board
* #return {void} Do not return anything, modify board in-place instead.
*/
var solveSudoku = function(board) {
function check(y, x, n, board){
// Search column for n
for (let i = 0; i < 9; i++){
if (board[y][i] == n) return false;
}
// Search row for n
for (let i = 0; i < 9; i++){
if (board[i][x] == n) return false;
}
const row = Math.floor(x / 3) * 3;
const col = Math.floor(y / 3) * 3;
for (let i = 0; i < 3; i++){
for (let j = 0; j < 3; j++){
if (board[col+i][row+j] == n) return false;
}
}
return true;
}
function solve(board){
for (let y = 0; y < 9; y++){
for (let x = 0; x < 9; x++){
if (board[y][x] === "."){
for (let n = 1; n < 10; n++){
if(check(y, x, n, board)){
board[y][x] = n.toString();
solve(board);
board[y][x] = ".";
}
}
return;
}
}
}
}
solve(board)
}
solveSudoku doesn't do anything, it only defines two functions. Call solve(board) in the function body.

JS simple math task (raising an inputed number to a power)

I have a task in js. My program should take a number from a user and put it into power that is also inserted. I have coped with positive powers but the algorithm for negative ones always gives a positive answer and after putting an option for a zero power every variant somehow returns -1; Please help me find an error.
function powX(x, pow) {
x = +prompt('Insert a number: ');
pow = +prompt('Insert a power: ');
var result;
if (x > 0) {
var result = x;
for (i = 1; i < pow; i++) {
result *= x;
}
}
if (x < 0) {
var result = x;
for (i = 1; i < Math.abs(pow); i++) {
result /= x;
}
} else {
result = 1;
}
return result;
}
console.log(powX());
There are few mistakes in the code:
You should use else-if instead of if in your second block.
You should check pow instead of x
You are not using var or let with i so it will become global variable. Use let or var
You are using var again inside your if blocks but variables declared with var have function scope so it will not throw error. But with let it will break your code. Don't redeclare result again and again.
function powX(x, pow) {
x = +prompt('Insert a number: ');
pow = +prompt('Insert a power: ');
var result;
if (pow > 0) {
result = x;
for (let i = 1; i < pow; i++) {
result *= x;
}
}
else if (pow < 0) {
result = x;
for (let i = 0; i <= Math.abs(pow); i++) {
result /= x;
}
} else {
result = 1;
}
return result;
}
console.log(powX());
You don't need two loops one to divide and other using multiply. Just calculate the result just by multiplying and at the end multiply the result with x or divide it based on condition.
function powX(x, pow) {
x = +prompt('Insert a number: ');
pow = +prompt('Insert a power: ');
if(pow === 0) return 1;
var result = x;
for (let i = 1; i < Math.abs(pow); i++) {
result *= x;
}
return pow < 0 ? (x/result/x) : result;
}
console.log(powX());
Use an else if for your second condition, otherwise, its else block will always be executed for x > 0, setting your result to 1.
function powX(x, pow) {
x = +prompt('Insert a number: ');
pow = +prompt('Insert a power: ');
var result;
if (x > 0) {
result = x;
for (i = 1; i < pow; i++) {
result *= x;
}
}
else if (x < 0) {
result = x;
for (i = 1; i < Math.abs(pow); i++) {
result /= x;
}
} else {
result = 1;
}
return result;
}
console.log(powX());
Also, it'll look better if you remove the re-declaration of result in the if and else if blocks. It won't affect your output but still.
Note: As #ASDFGerte correctly pointed out in the comments, OP's code has other flaws, but I think this still answers his main concern and actual question.

count 9's from 1 to n - 5kyu Kata

I am working on this kata https://www.codewars.com/kata/count-9-s-from-1-to-n/train/javascript
and i have written this code for it, but its not working. This question is similar to this one Count the number of occurrences of 0's in integers from 1 to N
but it is different because searching for 9's is practically very different to searching for 0's.
think part of the problem with this code is that it takes too long to run...
any advice appreciated!
function has9(n) {
var nine = [];
var ninearr = n.toString().split('');
for (var j = 0; j < ninearr.length; j++) {
if (ninearr[j] == '9') {
nine.push(ninearr[j]);
}
}
return nine.length;
}
function number9(n) {
var arr = [];
var arrnew = [];
for (var i = 0; i <= n; i++) {
arr.push(i);
}
for (var l = 0; l < arr.length; l++) {
arrnew.push(has9(l));
}
var sum = arrnew.reduce((a, b) => a + b, 0);
return sum;
}
Why not a regex based solution? (Too slow as well?)
const count9s = num => num.toString().match(/9/g).length
console.log(count9s(19716541879)) // 2
console.log(count9s(919191919191919)) // 8
console.log(count9s(999)) // 3
console.log(count9s(999999)) // 6
I have taken the above hint and completely re written the code, which I now feel should work, and it does for most inputs, but codewars is saying it fails on some of them. any ideas why?
function nines(n){
if(n>=100){
var q= Math.floor(n/100);
var nq= q * 20;
var r = (n%100);
var s = Math.floor(r/9);
if (r<=90){
return s + nq;
}
if (r == 99){
return 20 + nq;
}
if (90 < r < 100 && r!= 99){
var t = (r-90);
return nq + s + t;
}
}
if (n<100){
if (n<=90){
var a = Math.floor(n/9);
return a ;
}
if (n == 99){
return 20
}
if (90 < n < 100 && n!= 99){
var c = (n-90);
return 10 + c;
}
}
}
=== UPDATE ===
I just solved your kata using
function number9Helper(num) {
var pow = Math.floor(Math.log10(num));
var round = Math.pow(10, pow);
var times = Math.floor(num / round);
var rest = Math.abs(num - (round * times));
var res = pow * (round==10 ? 1 : round / 10) * times;
if (num.toString()[0] == '9') res += rest;
if (rest < 9) return res;
else return res + number9Helper(rest);
}
function number9(num) {
var res = number9Helper(num);
res = res + (num.toString().split('9').length-1);
return res;
}
== Function below works but is slow ===
So, could something like this work for you:
for (var nines=0, i=1; i<=n; i++) nines += i.toString().split('9').length-1;
Basically, there are many way to achieve what you need, in the end it all depends how do you want to approach it.
You can test it with
function nines(n) {
for (var nines=0, i=1; i<=n; i++) nines += i.toString().split('9').length-1;
return nines;
}
function number9(n) {
if (n < 8) {
return 0
};
if (n === 9) {
return 1
};
if (n > 10) {
let str = ''
for (let i = 9; i <= n; i++) {
str += String(i)
}
return str.match(/[9]/g).length
}
}

I'm trying to raise numbers to their consecutive powers and my code isn't working

https://codepen.io/aholston/pen/ZJbrjd
The codepen link has commented code as well as actual instructions in HTML
Otherwise.... what I ultimately have to do is write a function that takes two params(a and b) and takes all the numbers between those two params (a-b) and put every number that can be added to the consecutive fowers and be equal to that number into a new array. Ex: 89 = 8^1 + 9^2 = 89 or 135 = 1^1 + 3^2 + 5^3 = 135
function sumDigPow(a, b) {
// Your code here
var numbers = [];
var checkNum = [];
var finalNum = [];
var total = 0;
for (var i = 1; i <= b; i++) {
if (i >= a && i <= b) {
numbers.push(i);
}
}
for (var x = 0; x < numbers.length; x++) {
var checkNum = numbers[x].toString().split('');
if (checkNum.length == 1) {
var together = parseInt(checkNum);
finalNum.push(together);
} else if (checkNum.length > 1) {
var together = checkNum.join('');
var togNumber = parseInt(together);
for (var y = checkNum.length; y > 0; y--) {
total += Math.pow(checkNum[y - 1], y);
}
if (total == togNumber) {
finalNum.push(togNumber);
}
}
}
return finalNum;
}
try this:
function listnum(a, b) {
var finalNum = [];
for (var i = a; i <= b; i++) {
var x = i;
var y = i;
var tot = 0;
j = i.toString().length;
while (y) {
tot += Math.pow((y%10), j--);
y = Math.floor(y/10);
}
if (tot == x)
finalNum.push(i);
}
return finalNum;
}
console.log(listnum(1, 200));
Okay, after debugging this is what I learned.
for (var y = checkNum.length; y > 0; y--) {
total += Math.pow(checkNum[y - 1], y);
}
if (total == togNumber) {
finalNum.push(togNumber);
}
}
}
return finalNum;
}
Everytime this loop happened, I neglected to reset the 'total' variable back to 0. So I was never getting the right answer for my Math.pow() because my answer was always adding to the previous value of total. In order to fix this, I added var total = 0; after i decided whether or not to push 'togNumber' into 'finalNum.' So my code looks like this..
for (var y = checkNum.length; y > 0; y--) {
total += Math.pow(checkNum[y - 1], y);
}
if (total == togNumber) {
finalNum.push(togNumber);}
}
var total = 0;
}
return finalNum;
}

Categories