Finding Prime Numbers with Javascript - primes

I am trying to write a script which displays the prime numbers from 0 to 100, but when I execute it, the browser crashes. JSHint didn't detect any error.
I'd like to learn why this code doesn't work: I am not interested in finding a totally different code( like this one) that completes the same task.
This is the first code I've ever written, so I apologise in advance for all the silly mistakes I overlooked.
var i;
var m;
var primeArr = [2, 3, 5, 7, 11, 13, 17, 19];
var theMaxNumber = 100;
var theMinNumber = 21;
var theCounter = -1;
function myFunction() {
for (i = theMinNumber; i < theMaxNumber; i += 2) {
for (m = 0; m < primeArr.length; m++) {
if (i % primeArr[m] !== 0) {
theCounter++;
if (theCounter === primeArr.length) {
primeArr.push(i);
}
if (m === primeArr.length) {
theCounter = -1;
}
}
}
}
console.log( primeArr.toString());
}
This is how it should work in theory:
1) the function finds out whether or not the number i is divisible for a prime number smaller then itself.
2) In case it is, theCounter is resetted and i is incremented by two.
3) In case it isn't, theCounter is incremented by one. If, at the end of the cycle, i is not divisibile for all the prime numbers smaller than itself, it means that it's a prime number: i is pushed in the array (because theCounter = == primeArr.length), then i is incremented by two.
edit: I fixed all the errors in the code, it works perfectly now:
var i;
var m;
var primeArr = [3, 5, 7, 11, 13, 17, 19];
var theMaxNumber = 100;
var theMinNumber = 21;
var theCounter = 0;
function myFunction() {
for (i = theMinNumber; i < theMaxNumber; i += 2) {
theCounter = 0;
for (m = 0; m < primeArr.length; m++) {
if (i % primeArr[m] !== 0) {
theCounter++;
}
if (theCounter === primeArr.length) {
primeArr.push(i);
}
}
}
primeArr.unshift(2);
console.log( primeArr.toString());
}

Your stop condition is wrong in the inner for loop it has an infinite loop increasing primeArr for ever until it crashes the JS engine.
Add an "alert" or "debugger" command to see the issue
for (m = 0; m < primeArr.length; m++) {
if (i % primeArr[m] !== 0) {
theCounter++;
if (theCounter === primeArr.length) {
primeArr.push(i);
}

Related

Initializing Lists to Avoid Potential Errors

This function
List<int> _calculateTrips() {
List<int> trips = [];
trips = List.generate(
30,
(index) {
var counter = 0;
var aDay = DateTime.now().subtract(Duration(days: index));
for (var aWalk in walks) {
if ((aDay.month == aWalk.month) && (aDay.day == aWalk.day)) {
counter++;
}
}
trips.add(counter);
},
);
return trips;
}
creates the error The body might complete normally, causing null to be returned, but the return type is a potentially non-nullable type.Try adding either a return or a throw statement at the end. I'm struggling a bit to understand the message because (a) I thought I initialized the list at the beginning of the function and (b) I thought I had a return statement at the end.
The issue is with the function you pass to List.generate(). It expects a E Function(int), where E is the type of the element, for example:
final evenNumbers = List.generate(10, (index) {
return index * 2;
});
Your issue comes from trips.add(counter):
List<int> trips = [];
trips = List.generate(30, (index) {
final trip = calculateTrip(index);
trips.add(trip);
})
The inner function needs to be an int Function(int) (i.e. a function that takes an int, and returns an int), because your list is a List<int>.
However, your inner function never returns anything.
Simply replace trips.add(counter); with return counter; and it should solve this error. You may also want to refactor your function a little:
List<int> _calculateTrips() => List.generate(30, (index {
var counter = 0;
var aDay = DateTime.now().subtract(Duration(days: index));
for (var aWalk in walks) {
if ((aDay.month == aWalk.month) && (aDay.day == aWalk.day)) {
counter++;
}
}
return counter;
});

How to update a variable maintaining the length of a list in a cascade-like structure?

class CoinData {
var _controller = StreamController<Map<String,dynamic>>();
.....
Stream<Map<String,dynamic>> getAllCurrentRates() {
int numAssets = 0;
int counter = 0;
this.listAllAssets()
.then((list) {
if (list != null) {
numAssets = list.length;
List<Map<String, dynamic>>.from(list)
.where((map) => map["type_is_crypto"] == 1)
.take(3)
.map((e) => e["asset_id"].toString())
.forEach((bitCoin) {
this.getCurrentRate(bitCoin)
.then((rate) => _controller.sink.add(Map<String,dynamic>.from(rate)))
.whenComplete(() {
if (++counter >= numAssets) _controller.close();
});
});
}
});
return _controller.stream;
}
.....
}
The length of returned list is around 2500 and this value is assumed by numAssets, however as you see that list is modified later and therefore its length is less, then the evaluation (++counter >= numAssets) is incorrect. So, is it possible to fix that code maintaining its current structure?
.take(3) is temporal, it shall be removed later.

How to alter this script to add another condition

I have this piece of code which has been working great for me, however, I need a minor alteration to it and don't know how to proceed.
I would like for 'Multiple Use' to be added as another condition, alongside 'Yes' for the onEdit() to work.
function numberToLetter(number){
// converts the column number to a letter
var temp = "";
var letter = "";
while (number > 0){
temp = (number - 1) % 26;
letter = String.fromCharCode(temp + 65) + letter;
number = (number - temp - 1) / 26;
}
return letter;
}
function obtainFirstBlankRow() {
var sheet = SpreadsheetApp.getActive().getSheetByName('Aug2019');
// search for first blank row
var col = sheet.getRange('A:A');
var vals = col.getValues();
var count = 0;
while (vals[count][0] != "") {
count++;
}
return count + 1;
}
function onEdit(e) {
var ss = SpreadsheetApp.getActiveSheet();
if (ss.getName() == 'ProspectiveSites' && e.range.getColumn() == 26) {
if (e.range.getValue() != 'Yes'){
Logger.log('test');
return;
}
var sourceSheet = SpreadsheetApp.getActive().getSheetByName('ProspectiveSites');
var targetSheet = SpreadsheetApp.getActive().getSheetByName('Aug2019');
//Logger.log('O' + e.getRow() + ':O' + e.getRow());
Logger.log(e);
Logger.log(e.range.getValue());
var cell15 = sourceSheet.getRange('O' + e.range.getRow() + ':O' + e.range.getRow()).getValue();
var cell24 = sourceSheet.getRange('X' + e.range.getRow() + ':X' + e.range.getRow()).getValue();
Logger.log(cell15);
Logger.log(cell24);
var row = obtainFirstBlankRow();
targetSheet.getRange(row, 1).setValue(cell15);
targetSheet.getRange(row, 2).setValue(cell24);
}
}
Solution
What stops you from adding another condition for the if statement? Please, take some time to research JS documentation, it will greatly help you in the long run (see useful links after the sample).
Modifications
This modification assumes that you need to exit if value is not equal to "Multiple use" and not equal to "Yes". Also, note that there are a few additional changes made for optimization purposes (I changed all comparison operators to strict as well).
Sample
/**
* onEdit simple trigger;
* #param {Object} event object;
*/
function onEdit(e) {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var actS = ss.getActiveSheet(); //active sheet === source sheet;
//access event object params;
var range = e.range;
var row = range.getRow();
var column = range.getColumn();
var value = range.getValue();
if (actS.getName()==='ProspectiveSites' && column===26) {
if (value!=='Yes'&&value!=='Multiple Use') {
Logger.log('test');
return;
}
var augS = ss.getSheetByName('Aug2019'); //target sheet;
var cell15val = actS.getRange('O'+row+':O'+row).getValue();
var cell24val = actS.getRange('X'+row+':X'+row).getValue();
var rowBlank = obtainFirstBlankRow();
var target = augS.getRange(rowBlank,1,1,2); //idx, first col, 1 row, 2 cols;
target.setValues([[ cell15val , cell24val ]]);
}
}
Useful links
if..else statement reference on MDN;
Comparison operators reference on MDN;
getRange() method reference;
setValues() method reference;

Why doesn't this Javascript succesfully change the background on the second mouseover?

The function is supposed to increment x by 1 every time it launches, thus forcing the code to choose a different option on the next launch.
function changeBackground() {
var x = 0;
if (x % 2 === 0) {
document.getElementById("sample").style.backgroundColor = "purple";
}
else {
document.getElementById("sample").style.backgroundColor = "white";
}
x++;
}
var x = document.getElementById("sample");
x.onmouseover = changeBackground;
This is just grabbing a heading and launching changeBackground every time the cursor is placed on it. The background color stays on purple.
because you set it to 0 every time in the beginning of the function.. you need to set the variable outside of the function
var x = 0;
function changeBackground() {
if (x % 2 === 0) {
document.getElementById("sample").style.backgroundColor = "purple";
}
else {
document.getElementById("sample").style.backgroundColor = "white";
}
x++;
}
var x = document.getElementById("sample");
x.onmouseover = changeBackground;

CouchDB list view error when no key requested

Having trouble with a list function I wrote using CouchApp to take items from a view that are name, followed by a hash list of id and a value to create a CSV file for the user.
function(head, req) {
// set headers
start({ "headers": { "Content-Type": "text/csv" }});
// set arrays
var snps = {};
var test = {};
var inds = [];
// get data to associative array
while(row = getRow()) {
for (var i in row.value) {
// add individual to list
if (!test[i]) {
test[i] = 1;
inds.push(i);
}
// add to snps hash
if (snps[row.key]) {
if (snps[row.key][i]) {
// multiple call
} else {
snps[row.key][i] = row.value[i];
}
} else {
snps[row.key] = {};
snps[row.key][i] = row.value[i];
}
//send(row.key+" => "+i+" => "+snps[row.key][i]+'\n');
}
}
// if there are individuals to write
if (inds.length > 0) {
// sort keys in array
inds.sort();
// print header if first
var header = "variant,"+inds.join(",")+"\n";
send(header);
// for each SNP requested
for (var j in snps) {
// build row
var row = j;
for (var k in inds) {
// if snp[rs_num][individual] is set, add to row string
// else add ?
if (snps[j][inds[k]]) {
row = row+","+snps[j][inds[k]];
} else {
row = row+",?";
}
}
// send row
send(row+'\n');
}
} else {
send('No results found.');
}
}
If I request _list/mylist/myview (where mylist is the list function above and the view returns as described above) with ?key="something" or ?keys=["something", "another] then it works, but remove the query string and I get the error below:
{"code":500,"error":"render_error","reason":"function raised error: (new SyntaxError(\"JSON.parse\", \"/usr/local/share/couchdb/server/main.js\", 865)) \nstacktrace: getRow()#/usr/local/share/couchdb/server/main.js:865\n([object Object],[object Object])#:14\nrunList(function (head, req) {var snps = {};var test = {};var inds = [];while ((row = getRow())) {for (var i in row.value) {if (!test[i]) {test[i] = 1;inds.push(i);}if (snps[row.key]) {if (snps[row.key][i]) {} else {snps[row.key][i] = row.value[i];}} else {snps[row.key] = {};snps[row.key][i] = row.value[i];}}}if (inds.length > 0) {inds.sort();var header = \"variant,\" + inds.join(\",\") + \"\\n\";send(header);for (var j in snps) {var row = j;for (var k in inds) {if (snps[j][inds[k]]) {row = row + \",\" + snps[j][inds[k]];} else {row = row + \",?\";}}send(row + \"\\n\");}} else {send(\"No results found.\");}},[object Object],[object Array])#/usr/local/share/couchdb/server/main.js:979\n(function (head, req) {var snps = {};var test = {};var inds = [];while ((row = getRow())) {for (var i in row.value) {if (!test[i]) {test[i] = 1;inds.push(i);}if (snps[row.key]) {if (snps[row.key][i]) {} else {snps[row.key][i] = row.value[i];}} else {snps[row.key] = {};snps[row.key][i] = row.value[i];}}}if (inds.length > 0) {inds.sort();var header = \"variant,\" + inds.join(\",\") + \"\\n\";send(header);for (var j in snps) {var row = j;for (var k in inds) {if (snps[j][inds[k]]) {row = row + \",\" + snps[j][inds[k]];} else {row = row + \",?\";}}send(row + \"\\n\");}} else {send(\"No results found.\");}},[object Object],[object Array])#/usr/local/share/couchdb/server/main.js:1024\n(\"_design/kbio\",[object Array],[object Array])#/usr/local/share/couchdb/server/main.js:1492\n()#/usr/local/share/couchdb/server/main.js:1535\n#/usr/local/share/couchdb/server/main.js:1546\n"}
Can't say for sure since you gave little detail, however, a probable source of problems, is the use of arrays to collect data from every row: it consumes an unpredictable amount of memory. This may explain why it works when you query for a few records, and fails when you query for all records.
You should try to arrange data in a way that eliminates the need to collect all values before sending output to the client. And keep in mind that while map and reduce results are saved on disk, list functions are executed on every single query. If you don't keep list function fast and lean, you'll have problems.