Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 2 years ago.
Improve this question
n = 1;
while (n < 1024) {
alert(Math.pow(n, 2));
n = n + 2;
}
How can I make this display the powers of 2 from 2^0 to 2^10 inclusive i.e. (1-1024) and end once it reaches 1024 in Javascript
I would do something like this:
for(let n = 0; n <= 10; n++) {
console.log(2 ** n)
}
This logs the answer of each loop iteration. As Pointy suggested in the comment, we have to make the n value iterate from 1 to 10, since that is the variable that generates the output, whereas the 1024 is simply the output that comes from the power values. You could also use Math.pow as follows:
for(let n = 0; n <= 10; n++) {
console.log(Math.pow(2, n))
}
Implementing Secan's suggestion, here is a function which will take any number as a parameter:
function foo(x, exp) {
for(let i = 0; i <= exp; i++) {
console.log(x ** i)
}
}
So to apply this to the original answer, we would call it like this:
foo(2, 10)
Sorry for the ambuiguity with my original question. I've figured it out-
n=0;
while (n <= 10) {
alert(Math.pow(2, n));
n = n + 1;
}
Setting n=0, n<=10 in while and changing n + 1 instead of 2 resolved my issue. Thanks for your responses!
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 2 years ago.
Improve this question
OneR, short for "One Rule", is a simple yet accurate classification algorithm that generates one rule for each predictor in the data, then selects the rule with the smallest total error as its "one rule".
I tried to find code samples on GitHub, but found only one, developed with R language. How could I implement this algorithm in Javascript?
What I have tried?
I am trying to implement following this sample article:
https://www.saedsayad.com/oner.htm
class OneR {
/**
* Pass dataset which will be an array of values.
* Last value is classifcator's value.
* All other values are predictors.
*
* Example
*
* The meaning of sequence values:
* |Outlook|Temp|Humidity|Windy|Play Golf|
*
* Representation of a sequence:
* ['rainy', 'hot', 'high', 0, 0]
*
* True and False are represented as zeros or ones
*/
constructor(data = []) {
this.data = data;
this.frequences = {};
}
predict() {
if (this.data && this.data.length > 0) {
const firstRow = this.data[0];
const predictorCount = firstRow.length - 1;
let classifcator;
// For each predictor,
for (let i = 0; i < predictorCount; i++) {
// For each value of that predictor, make a rule as follos;
for (let y = 0; y < this.data.length; y++) {
// Count how often each value of target (class) appears
classifcator = this.data[y][predictorCount];
console.log(classifcator);
// Find the most frequent class
// Make the rule assign that class to this value of the predictor
}
// Calculate the total error of the rules of each predictor
}
// Choose the predictor with the smallest total error
} else {
console.log("Cannot predict!");
}
}
}
module.exports = {
OneR
};
I have loaded data from csv
rainy,hot,high,0,0
rainy,hot,high,1,0
overcast,hot,high,0,1
sunny,mild,high,0,1
sunny,cool,normal,0,1
sunny,cool,normal,1,0
overcast,cool,normal,1,1
rainy,mild,high,0,0
rainy,cool,normal,0,1
sunny,mild,normal,0,1
rainy,mild,normal,1,1
overcast,mild,high,1,1
overcast,hot,normal,0,1
sunny,mild,high,1,0
If I understand correctly how the frequency tables must be compared (lowest error rate, highest accuracy), you could use Maps so to cope with non-string types if ever necessary.
Although your example has target values that are booleans (0 or 1), in general they could be from a larger domain, like for example "call", "fold", "raise", "check".
Your template code creates a class, but I honestly do not see the benefit of that, since you can practically only do one action on it. Of course, if you have other actions in mind, other than one-rule prediction, then a class could make sense. Here I will just provide a function that takes the data, and returns the number of the selected predictor and the rule table that goes with it:
function oneR(data) {
if (!data && !data.length) return console.log("Cannot predict!");
const predictorCount = data[0].length - 1;
// get unique list of classes (target values):
let classes = [...new Set(data.map(row => row[predictorCount]))];
let bestAccuracy = -1;
let bestFreq, bestPredictor;
// For each predictor,
for (let i = 0; i < predictorCount; i++) {
// create frequency table for this predictor: Map of Map of counts
let freq = new Map(data.map(row => [row[i], new Map(classes.map(targetValue => [targetValue, 0]))]));
// For each value of that predictor, collect the frequencies
for (let row of data) {
// Count how often each value of target (class) appears
let targetValue = row[predictorCount];
let predictorValueFreq = freq.get(row[i]);
let count = predictorValueFreq.get(targetValue);
predictorValueFreq.set(targetValue, count+1);
}
// Find the most frequent class for each predictor value
let accuracy = 0;
for (let [predictorValue, predictorValueFreq] of freq) {
let maxCount = 0;
let chosenTargetValue;
for (let [targetValue, count] of predictorValueFreq) {
if (count > maxCount) {
// Make the rule assign that class to this value of the predictor
maxCount = count;
chosenTargetValue = targetValue;
}
}
freq.set(predictorValue, chosenTargetValue);
accuracy += maxCount;
}
// If this accuracy is best, then retain this frequency table
if (accuracy > bestAccuracy) {
bestAccuracy = accuracy;
bestPredictor = i;
bestFreq = freq;
}
}
// Return the best frequency table and the predictor for which it applies
return {
predictor: bestPredictor, // zero-based column number
rule: [...bestFreq.entries()]
}
}
let data = [
["rainy","hot","high",0,0],
["rainy","hot","high",1,0],
["overcast","hot","high",0,1],
["sunny","mild","high",0,1],
["sunny","cool","normal",0,1],
["sunny","cool","normal",1,0],
["overcast","cool","normal",1,1],
["rainy","mild","high",0,0],
["rainy","cool","normal",0,1],
["sunny","mild","normal",0,1],
["rainy","mild","normal",1,1],
["overcast","mild","high",1,1],
["overcast","hot","normal",0,1],
["sunny","mild","high",1,0]
];
let result = oneR(data);
console.log(result);
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 3 years ago.
Improve this question
I would like to sum up all the elements inside the array covertedValue. Why I am getting a Nan result? whats wrong with the recursive function I have written?
function findOutlier(integers){
var covertedValue = integers.map(x => x % 2);
var total = 0;
for (i=0 ; i<covertedValue.length ; i++){
total = total + covertedValue[0] + findOutlier(integers.splice(1));
}
console.log(total);
}
findOutlier([0, 1, 2]);
because this line create a function and a private alias to itself
var factorial =
// create a variable named factorial in global scope
// it contains the function fac
function fac(n) {
// fac is a function available only in the factorial var context
return n < 2 ? // if n < 2
1 : // return 1
n * fac(n - 1); // else return n * fac(n - 1)
};
console.log(factorial(5));
// calls factorial(5) which is 5*fac(4) which is 5*(4*fac(3)) ...
note that the fac function is not available outside of itself
var factorial = function fac(n) { return n < 2 ? 1 : n * fac(n - 1); };
console.log(fac(5));
This way of coding where a function call itself is called recursive programming it can be hard to grasp at first but can be VERY powerful in some situations
recurcive programming can easily be used when the result of func(n) depend directly on the result of func(n+x)
the cond ? then : else structure is called ternary operator, it's a way to make if in one line, can become messy very quick
as you noted in a comment : recursion can be replaced by a loop (it can be hard to do it sometime)
here's a more beginner way to write it
function factorial(n) {
if(n < 2) {
return 1
} else {
let fac = 1;
for(var i = n; i > 0; i--) {
fac = fac * i
// here fac takes the value of the precedent iteration
}
// this whole loop is the same as i*fac(i-1) in the recurcive way
return fac
}
};
console.log(factorial(5));
I have an array of number
[350000, 350000, 350000]
I have the following code:
function getNPV(rate, periods, Cashflow) {
var npv = 0;
for (var i = 0; i < Cashflow.length; i++) {
npv += Cashflow[i] / Math.pow(1 + rate, periods);
}
return npv;
}
Here, cashflow is our array, rate = 6% and period = 91days.
When I take :
npv = Cashflow[i] / Math.pow(1 + rate, periods);
The output is [348328,346664,344952] when 6% discount rate is applied to 350000 each time.
I am trying to take the sum of [348328,346664,344952] which is $1,039,944
But, it is giving me $1034856 as the result.
Trying the console, it's actually taking the sum of the 3rd value 3 times instead. [344952+344952+344952] for some reason.
Can someone please tell me how to fix this error. Any help is appreciated. Thank you.
As I refer to your spreadsheet, you need an array for period not cashflow.
Pass periods and cashflow like:
var periods = [30, 60, 91];
var cashflow = 350000;
getNPV(rate, periods, cashflow);
Your cash flow is same, so no need an array (You may still have an array if you want to vary cashflow)
And use it in the loop:
function getNPV(rate, periods, Cashflow) {
var npv = rate;
for (var i = 0; i < periods.length; i++) {
npv += Cashflow / Math.pow(1 + rate, periods[i]);
}
return npv;
}
You can use returnSum to get the sum of the array
function returnSum(arr) {
function sum(a, b) {
return a + b;
}
return arr.reduce(sum, 0);
}
let array = [348328,346664,344952]
returnSum(array); //result 1039944
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 7 years ago.
Improve this question
I'm trying to make JavaScript Minesweeper and I've got some problems in pushBombs function, I guess. I'm trying to put bombs in array, sometimes it puts exact number that is said but sometimes it puts less number.
My questions:
When condition is true it puts bomb in array but when it's false it passes this itaration or looks for another index in array that is true?
Math.random() returns different values in condition and in code block.
It puts bomb where it already was but then why?
var grid = {
_grid: [],
createGrid: function (c) {
for (var i = 0; i < c; i++) {
this._grid.push([]);
for (var a = 0; a < c; a++) {
this._grid[i][a] = 'Empty';
}
}
},
pushBombs: function (b) {
for (var i = 0; i < b; i++) {
if (this._grid[Math.round(Math.random() * (this._grid.length - 1))][Math.round(Math.random() * (this._grid.length - 1))] == 'Empty') {
this._grid[Math.round(Math.random() * (this._grid.length - 1))][Math.round(Math.random() * (this._grid.length - 1))] = 'Bomb';
}
}
},
Everytime you call Math.random() you are going to get a different value. Assuming that during your code, you want to be looking at the same slot in both the check and in the assignment, you would want to only call that once for each axis of your grid. Below, I'm calling them xx and yy.
pushBombs: function (b) {
for (var i = 0; i < b; i++) {
var xx = Math.round(Math.random() * (this._grid.length - 1));
var yy = Math.round(Math.random() * (this._grid.length - 1));
if (this._grid[xx][yy] == 'Empty') {
this._grid[xx][yy] = 'Bomb';
}
}
}
EDIT
Something you might want to think about is that, this code assumes that both dimensions of your grid are equal in length. Based on the createGrid() method it looks like that is the case. Thinking ahead you may choose to have a rectangular grid, in which case, this pushBombs() method would break. One option is to store the X and Y lengths in so that the xx and yy can correctly randomize their values. Alternatively, I might suggest changing the code above slightly to use:
//randmomize the length of the first dimension
var xx = Math.round(Math.random() * (this._grid.length - 1));
//randomize the second dimension. Notice, this is looking at the length
//of the first item in the grid (which is your second dimension).
var yy = Math.round(Math.random() * (this._grid[0].length - 1));
EDIT 2
If you want to ensure that you always get the exact number of bombs, you should use a while loop as #PierreDuc suggested:
while(b > 0) {
var xx = Math.round(Math.random() * (this._grid.length - 1));
var yy = Math.round(Math.random() * (this._grid[0].length - 1));
if (this._grid[xx][yy] == 'Empty') {
this._grid[xx][yy] = 'Bomb';
b--;
}
}
Note though that if the value of b is greater than the number of Empty slots, this will turn into an infinite loop.