Different Implementation of the same JS program in C++ - javascript

I recently raised a question about implementing sieve of eratosthenes in Javascript on SO and here's the working answer I got:
function sieve(low, high) {
var primeArray = [], ll = Math.sqrt(high), output = [];
for (var i = 2; i <= high; i++) {
primeArray[i] = true;
}
for (var i = 2; i <= ll; i++) {
if (primeArray[i]) {
for (var j = i * i; j <= high; j += i) {
primeArray[j] = false;
}
}
}
for (var i = 2; i <= ll; i++) {
if(primeArray[i]) {
var segmentStart = Math.ceil(low/i) * i;
// need this test to ensure we are not deleting primes
if (primeArray[segmentStart]) segmentStart += i;
for(var j = segmentStart; j <= high; j+=i) {
primeArray[j] = false;
}
}
}
for(var i = low; i <= high; i++) {
if(primeArray[i]) {
output.push(i);
}
}
return output;
}
console.log(sieve(1, 20));
I tried implementing the same in C++
However the end result is quite different.
My C++ program is somehow ignoring the first 2 prime numbers while maintaining 1 as a prime.
Here's the same program in C++
#include <iostream>
#include <math.h>
using namespace std;
int main()
{
int low, high;
cout << "Enter lower bound: ";
cin >> low;
cout << "Enter upper bound: ";
cin >> high;
int root = floor(sqrt(high));
int primes[high];
for(int i = 2; i <= high; i++)
{
primes[i] = true;
}
for (int i = 2; i <= root; i++) {
if (primes[i]) {
for (int j = i * i; j <= high; j += i) {
primes[j] = false;
}
}
}
for (int i = 2; i <= root; i++) {
if(primes[i]) {
int segmentStart = ceil(low/i) * i;
if (primes[segmentStart]) segmentStart += i;
for(int j = segmentStart; j <= high; j+=i) {
primes[j] = false;
}
}
}
for(int i = low; i <= high; i++) {
if(primes[i]) {
cout << i;
}
}
return 0;
}

Found the solution.
low/i division operation in int segmentStart = ceil(low/i) * i; was returning an integer and hence it was ignoring results < 1;
I typecasted i as a double to solve this problem like this:
int segmentStart = ceil(low/(double)i) * i;

Related

How to compile this C code to WebAssembly correctly?

I have the C code:
int edges_start[3000];
int edges_end[3000];
float edges_len[3000];
int g_links_id[1000][100];
float g_links_weight[1000][100];
int cache_id[1000];
float cache_distance[1000];
int cache_prev[1000];
int cache_links_id[1000][100];
float cache_links_weight[1000][100];
int queue_id[1000];
float queue_distance[1000];
int queue_prev[1000];
int queue_links_id[1000][100];
float queue_links_weight[1000][100];
void* memcpy(char* dst, char* src, int count) {
while(count--) *dst++ = *src++;
}
void init_cpp() {
for (int i=0; i < 1000; i++) {
cache_id[i] = -2;
queue_id[i] = -2;
cache_distance[i] = 100000;
queue_distance[i] = 100000;
cache_prev[i] = -2;
queue_prev[i] = -2;
for (int j=0; j < 100; j++) {
queue_links_id[i][j] = -2;
queue_links_weight[i][j] = 100000;
cache_links_id[i][j] = -2;
cache_links_weight[i][j] = 100000;
}
}
}
void init_edges_cpp() {
for (int i=0; i < 3000; i++) {
edges_start[i] = -2;
edges_end[i] = -2;
edges_len[i] = -2.0;
}
for (int i=0; i < 1000; i++) {
for (int j=0; j < 100; j++) {
g_links_id[i][j] = -2;
g_links_weight[i][j] = -2.0;
}
}
}
void add_edge_cpp(int index, int start, int end, float len) {
edges_start[index] = start;
edges_end[index] = end;
edges_len[index] = len;
}
void fill_graph_cpp() {
for (int i=0; i < 3000; i++) {
int s = edges_start[i];
int e = edges_end[i];
float len = edges_len[i];
if (s == -2) {
break;
}
int links_len = 0;
for (int j=0; j < 100; j++) {
if (g_links_id[s][j] == -2) {
links_len = j;
break;
}
}
g_links_id[s][links_len] = e;
g_links_weight[s][links_len] = len;
for (int j=0; j < 100; j++) {
if (g_links_id[e][j] == -2) {
links_len = j;
break;
}
}
g_links_id[e][links_len] = s;
g_links_weight[e][links_len] = len;
}
}
void get_dists_cpp(int a, int L) {
int i = L;
while (--i >= 0) {
for (int j = 0; j < 100; j++) {
//console.log()
if (g_links_id[i][j] == -2) {
break;
}
cache_links_id[i][j] = g_links_id[i][j];
cache_links_weight[i][j] = g_links_weight[i][j];
}
cache_id[i] = i;
}
queue_id[0] = cache_id[a];
cache_distance[a] = 0;
queue_distance[0] = cache_distance[a];
queue_prev[0] = queue_prev[a];
for (int j=0; j < 100; j++) {
queue_links_id[0][j] = cache_links_id[a][j];
queue_links_weight[0][j] = cache_links_weight[a][j];
}
i=0;
int queue_len = 1;
while (i < queue_len) {
int node_id = queue_id[i];
float node_distance = queue_distance[i];
int node_prev = queue_prev[i];
int j=0;
for (int k=0; k < 100; k++) {
if (queue_links_id[i][k] == -2) {
j=k;
break;
}
}
while (--j >= 0) {
int link_id = queue_links_id[i][j];
float link_weight = queue_links_weight[i][j];
int c_id = cache_id[link_id];
float c_distance = cache_distance[link_id];
int c_prev = cache_prev[link_id];
float d = node_distance + link_weight;
if (d < c_distance) {
cache_prev[link_id] = node_id;
cache_distance[link_id] = d;
int last_ind = queue_len;
queue_id[last_ind] = cache_id[link_id];
queue_distance[last_ind] = cache_distance[link_id];
for (int k=0; k < 100; k++) {
if (cache_links_id[link_id][k] == -2) {
break;
}
queue_links_id[last_ind][k] = cache_links_id[link_id][k];
queue_links_weight[last_ind][k] = cache_links_weight[link_id][k];
}
queue_prev[last_ind] = cache_prev[link_id];
queue_len++;
}
}
i++;
}
}
int get_edges_start(int index) {
return edges_start[index];
}
float get_cache_distance(int index) {
return cache_distance[index];
}
int get_cache_prev(int index) {
return cache_prev[index];
}
int main() {
init_edges_cpp();
init_cpp();
add_edge_cpp(0, 0, 2, 1);
add_edge_cpp(1, 0, 1, 1);
add_edge_cpp(2, 1, 2, 1);
add_edge_cpp(3, 2, 3, 1);
add_edge_cpp(4, 2, 4, 1);
add_edge_cpp(5, 3, 4, 1);
fill_graph_cpp();
get_dists_cpp(0, 5);
/*
for (int i=0; i < 10; i++) {
cout << i << " " << get_cache_distance(i) << " " << get_cache_prev(i) << endl;
}
*/
return 0;
}
It works correct, you can check it here
But, when I tried to compile it to wasm with this website
I put in the left field this code: https://pastebin.com/NG10Z0jX
And in the right field that js code:
var wasmModule = new WebAssembly.Module(wasmCode);
var wasmInstance = new WebAssembly.Instance(wasmModule, wasmImports);
var wasm_module = wasmInstance.exports
wasm_module.main();
for (var i=0; i < 5; i++) {
var c1 = wasm_module.get_cache_distance(i);
var c2 = wasm_module.get_cache_prev(i);
log(i+" " +c1 + " " + c2)
}
It returned wrong output:
vert: 0 dist: 0 prev -2
vert: 1 dist: 100000 prev -2
vert: 2 dist: 100000 prev -2
vert: 3 dist: 100000 prev -2
vert: 4 dist: 100000 prev -2
It should return this:
vert: 0 dist: 0.000000 prev: -2
vert: 1 dist: 1.000000 prev: 0
vert: 2 dist: 1.000000 prev: 0
vert: 3 dist: 2.000000 prev: 2
vert: 4 dist: 2.000000 prev: 2
How to compile this C code to WebAssembly correctly?
The answer is to put this in C code:
void* memcpy(char* dst, char* src, int count) {
void* p=dst;
while(count--) *dst++ = *src++;
return p;
}

What is the difference in calculation between a code in C# and Javascript

I was looking for an answer for a question from Project Euler and I found one here
http://www.mathblog.dk/triangle-number-with-more-than-500-divisors/
int number = 0;
int i = 1;
while(NumberOfDivisors(number) < 500){
number += i;
i++;
}
private int NumberOfDivisors(int number) {
int nod = 0;
int sqrt = (int) Math.Sqrt(number);
for(int i = 1; i<= sqrt; i++){
if(number % i == 0){
nod += 2;
}
}
//Correction if the number is a perfect square
if (sqrt * sqrt == number) {
nod--;
}
return nod;
}
So I tried to implement the same solution in Javascript but it doesn't give me the same result.
var number = 0;
var i = 1;
while (numberOfDivisors(number) < 500) {
number += i;
i++;
}
console.log(number);
function numberOfDivisors(num) {
var nod = 0;
var sqr = Math.sqrt(num);
for (i = 1; i <= sqr; i++) {
if (num % i === 0) {
nod += 2;
}
}
if (sqr * sqr == num) {
nod--;
}
return nod;
}
I tested the other code in C# and it gives the right solution. I was wondering if I made a mistake or whether they work differently in some aspect I'm unaware of.
The problem is that you are testing non-triangle numbers because you forgot one important thing ... scope ...
for (i = 1; i <= sqr; i++) {
screws your (global) value of i ...
see in c# you have
for(int i = 1; i<= sqrt; i++){
^^^
give javascript the same courtesy and try
for (var i = 1; i <= sqr; i++) {
^^^
you should also get the square root as an integer, otherwise you'll be one off in most counts
var sqr = Math.floor(Math.sqrt(num));
i.e.
var number = 0;
var i = 1;
console.time('took');
while (numberOfDivisors(number) < 500) {
number += i;
i++;
}
console.timeEnd('took');
console.log(number);
function numberOfDivisors(num) {
var nod = 0;
var sqr = Math.floor(Math.sqrt(num));
for (var i = 1; i <= sqr; i++) {
if (num % i === 0) {
nod += 2;
}
}
if (sqr * sqr == num) {
nod--;
}
return nod;
}
(added some timing info for fun)

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);

javascript - missing ) after for-loop control

Im trying to solve problem #4 on project Euler,im using a simple for-loop to sift through each element of the array and "missing ) after for-loop control"
Code below
var palidrome = function (num) {
var numstr = (num).toString().split("");
var count = 0;
for (var i = 0, i2 = numstr.length - 1; i < numstr.length / 2 && i2 >= numstr.length / 2; i++, i2--) {
if (numstr[i] !== numstr[i2]) {
return 0;
} else {
if (count == 3) {
return numstr.join("");
}
}
count++;
}
};
for (var i = 999; i >= 100; i--) {
for (var j = 100; j = < i; j++) {
if (palidrome(i * j) !== 0) {
alert(palidrome(i * j));
break;
}
}
}
Thank you for the assistance,much appreciated.
In for loop you have error: j = < i must be j <= i
for (var i = 999; i >= 100; i--) {
for (var j = 100; j <= i; j++) {
if (palidrome(i * j) !== 0) {
alert(palidrome(i * j));
break;
}
}
}

Got 90% of the JavaScript code - can't figure out the rest

So I am trying to model Gram-Schmidt for any size N×N matrix, and I have officially hit a roadblock I can't get past. I know it's a matter of looping this correctly, but I can't figure out what the problem is. Remember I do not want to just pass in a 3×3 matrix, but any size N×N.
The course notes QR Decomposition with Gram-Schmidt explains exactly what I want to do. Very simple calculation by the way. In the course notes ||u|| means that it is the sum of the square of the elements, so sqrt(x12 + x22 + x32 + .... + xn2).
The multiplication symbol is actually the dot product.
The code I wrote so far is listed below. What is wrong with it?
function qrProjection(arr) {
var qProjected = [];
var tempArray = [];
var aTemp = arr;
var uTemp = new Array(arr.length);
var uSquareSqrt = new Array(arr.length);
var eTemp = [];
var sum = 0;
var sumOfSquares = 0;
var breakCondition = 0;
var secondBreakCondition = 0;
var iterationCounter = 0;
//Build uTemp Array
for (i = 0; i < arr.length; i++) {
uTemp[i] = new Array(arr[i].length);
}
for (i = 0; i < arr.length; i++) {
eTemp[i] = new Array(arr[i].length);
}
uTemp[0] = aTemp[0];
for (j = 0; j <= arr.length; j++) {
for (l = 0; l < arr[j].length; l++) {
if (breakCondition == 1) break;
sumOfSquares = Math.pow(uTemp[j][l], 2) + sumOfSquares;
}
if (breakCondition == 0) {
uSquareSqrt[j] = Math.sqrt(sumOfSquares);
sumOfSquares = 0;
}
for (i = 0; i < arr[j].length; i++) {
if (breakCondition == 1) break;
eTemp[j][i] = (1 / (uSquareSqrt[j])) * (uTemp[j][i]);
}
breakCondition = 1;
if (iterationCounter == 0) {
for (m = 0; m < arr[j].length; m++) {
matrixDotProduct = aTemp[j + 1][m] * eTemp[j][m] + matrixDotProduct;
}
}
else {
for (m = 0; m < arr[j].length; m++) {
for (s = 0; s <= iterationCounter; s++) {
matrixDotProduct = aTemp[j + 1][s] * eTemp[m][s] + matrixDotProduct;
}
for (t = 0; t < arr[j].length; t++) {
uTemp[j + 1][t] = aTemp[j + 1][t] - eTemp[j][t] * matrixDotProduct;
}
}
}
if (iterationCounter == 0) {
for (m = 0; m < arr[j].length; m++) {
uTemp[j + 1][m] = aTemp[j + 1][m] - eTemp[j][m] * matrixDotProduct;
}
}
matrixDotProduct = 0;
for (l = 0; l < arr[j].length; l++) {
sumOfSquares = Math.pow(uTemp[j + 1][l], 2) + sumOfSquares;
}
uSquareSqrt[j + 1] = Math.sqrt(sumOfSquares);
sumOfSquares = 0;
for (i = 0; i < arr[j].length; i++) {
eTemp[j + 1][i] = (1 / (uSquareSqrt[j + 1])) * (uTemp[j + 1][i]);
}
iterationCounter++;
}
qProjected = eTemp;
return qProjected;
}
I must apologize that instead of tweaking your code, I wrote my own from scratch:
/* Main function of interest */
// Each entry of a matrix object represents a column
function gramSchmidt(matrixA, n) {
var totalVectors = matrixA.length;
for (var i = 0; i < totalVectors; i++) {
var tempVector = matrixA[i];
for (var j = 0; j < i; j++) {
var dotProd = dot(matrixA[i], matrixA[j], n);
var toSubtract = multiply(dotProd, matrixA[j], n);
tempVector = subtract(tempVector, toSubtract, n);
}
var nrm = norm(tempVector, n);
matrixA[i] = multiply(1 / nrm, tempVector, n);
}
}
/*
* Example usage:
* var myMatrix = [[1,0,0],[2,3,0],[5,4,7]];
* gramSchmidt(myMatrix, 3);
* ==> myMatrix now equals [[1,0,0],[0,1,0],[0,0,1]]
* 3 here equals the number of dimensions per vector
*/
/* Simple vector arithmetic */
function subtract(vectorX, vectorY, n) {
var result = new Array(n);
for (var i = 0; i < n; i++)
result[i] = vectorX[i] - vectorY[i];
return result;
}
function multiply(scalarC, vectorX, n) {
var result = new Array(n);
for (var i = 0; i < n; i++)
result[i] = scalarC * vectorX[i];
return result;
}
function dot(vectorX, vectorY, n) {
var sum = 0;
for (var i = 0; i < n; i++)
sum += vectorX[i] * vectorY[i];
return sum;
}
function norm(vectorX, n) {
return Math.sqrt(dot(vectorX, vectorX, n));
}
Note that the algorithm above computes the Gram-Schmidt orthogonalization, which is the matrix [e1 | e2 | ... | en], not the QR factorization!

Categories