Sum of Primes using Sieve of Eratosthenes can't find bug - javascript

I'm working in JavaScript and this is a bit confusing because the code is returning the correct sum of primes. It is working with larger numbers. There is a bug where for 977 it returns the sum of primes for 976, which is 72179, instead of the sum for 977 which is 73156. Everything I've test so far has come back correctly.
function sumPrimes(num) {
var sum = 0;
var count = 0;
var array = [];
var upperLimit = Math.sqrt(num);
var output = [];
for (var i = 0; i < num; i++) {
array.push(true);
}
for (var j = 2; j <= upperLimit; j++) {
if (array[j]) {
for (var h = j * j; h < num; h += j) {
array[h] = false;
}
}
}
for (var k = 2; k < num; k++) {
if (array[k]) {
output.push(k);
}
}
for (var a = 0; a < output.length; a++) {
sum += output[a];
count++;
}
return sum;
}
sumPrimes(977);

The problem stems from the fact that your "seive" Array is indexed from 0, but your algorithm assumes that array[n] represents the number n.
Since you want array[n]===true to mean that n is prime, you need an Array of length 978 if you want the last item to be indexed as array[977] and mean the number 977.
The issue seems to be fixed when I change all instances of < num to < num+1.

Related

Why does a => 0 also return after my console.log? Javascript

I am trying to find the phone number whose digits sum to the largest number. I was able to get get the correct phone number but it returned with a => 0. I'm curious to know why that follow.
var allNum = ['123-456-7777', '963-481-7945', '111-222-3333'];
console.log(allNum[highest_number_index]);
var sum;
var highest_Num;
var highest_number_index;
for (var i = 0; i < allNum.length; i++){
allNum[i] = allNum[i].replace(/-/g, "");
for(var j= 0; j < (allNum[i].length); j++){
sum += parseInt(newNum[j], 10);
}
if (sum > highest_Num) {
highest_Num = sum;
highest_number_index = i;
}
sum = 0;
}

Find the multiple of n numbers within given range

How can I find the number of multiple for N numbers(as an array input) for a range 1 to K, where 1 < K < 10⁸ and 3 ≤ N < 25.
function findNumberOfMultiples(inputArray, maxSize) {
var count = 0;
var tempArray = [];
for (var i=0; i<maxSize; i++){
tempArray[i] = 0;
}
for (var j=0; j<inputArray.length; j++) {
for (var i=1; i<=maxSize; i++) {
if (i % inputArray[j]) {
tempArray[i-1] = 1;
}
}
}
for (var i=0; i<maxSize; i++) {
if (tempArray[i]==1) {
count++;
}
}
return count;
}
The above program fails for large number K. For example, if inputArray = [2,3,4] and maxSize(k) is 5,
Multiple of 2 is 2,4
Multiple of 3 is 3
multiple of 4 is 4
so total number of mutiple of 2 or 3 or 4 is 3 in range 1 to 5
You can solve this in O(N^2) where N is the number of elements in your array.
let us say you have two element in your array [a1,a2] and the range is K
your answer will be = >
K/a1 + K/a2 - K/lcm(a1,a2) // because you added them in both a1 and a2
So If you have a1,.....ax elements, your answer would be
K/a1+.....K/ax - K/lcm(ai,aj) (you have to replace i,j by (n*n-1)/2 combinations.
You will have to do K/lcm(ai,aj) O(N^2) times ((n*n-1)/2 time to be precise). So the algorithm complexity will be O(N^2) (There will be a Log(min(ai,aj)) factor but that would not make much difference to the overall complexity).
This will work any K as it only depends on your innput array size.
public int combinations(int K, int[] input){
int total = 0;
for(int i=0;i<input.length;i++){
total = total + Math.floor(K/input[i]);
}
for(int i=0;i<input.length;i++){
for(int j=i+1;j<input.length;j++){
if(i!=j){
int lcm =lcmFind(input[i], input[j]);
total = total - Math.floor(K/lcm);
}
}
}
return total;
}
The test case you have provided:
This function seems to do the trick :
var findMultiplesLength = function(arrayInput, max) {
var globalMultiples = [];
for (var j = 0; j < arrayInput.length; j++) {
var x = arrayInput[j];
var n = max / x;
for (var i=1; i < n; i++) {
mult = i * x;
if (globalMultiples.indexOf(mult) === -1) {
globalMultiples.push(mult);
}
}
}
return globalMultiples.length;
};
EDIT : You won't have any stack error but choosing big values for the range may hang your browser.

Counting Sort array values aren't changing

I am trying to implement the counting sort algorithm. Based on the pseudocode from Introduction to Algorithms (and if you don't know it it's just a book), I came up with this code:
var countingSort = function(array, array2, k){
var a = [];
a.length = k;
for(var i in a){
a[i] = 0;
}
for(var j in array){
a[array[j]] += 1;
}
for(var i in a){
a[i] += a[i - 1];
}
for(var j = array.length; j >= 0; j--){
array2[a[array[j]]] = array[j];
a[array[j]] -= 1;
}
};
When I use the function, however, my array stays the same (I put in all the arguments!) How to fix this? Can someone please explain what is going on?
First of all, you shouldn't use a for in loop in short because it doesn't only iterate over the elements in the array but also over all the properties on the of Array object. Here's more info
In you case, a simple for loop would suffice.
Further, you should use descriptive names so that you (now or when you are looking at the code later on) or somebody else can understand the code more clearly.
I assume the variables in your program mean the following:
array stores the initial data to be sorted.
array2 stores the final, sorted list.
k is the max value in the array (all values are in the range 0..k)
a is the array used to count unique occurrences of values in array
These can be renamed into something like:
This one is fine as array
array2 can be renamed to sorted
k can be renamed to max
a can be renamed to count
Another thing you are doing wrong is in the last for loop. You are starting the loop at array.length but arrays are 0-indexed in javascript so your first value is out-of-bounds. You should start from array.length - 1.
And as far as setting a.length = k, this is not necessary in javascript because arrays are objects and objects have no direct concept of length. You can view arrays in javascript as dynamic lists.
Adding all the stated changes, here is how your code could look like:
function countingSort(array, sorted, max){
var i, j;
var count = [];
// initialize counting array
for(i = 0; i <= max; i++){
count[i] = 0;
}
// count unique occurrences
for(i = 0; i <= max; i++){
count[array[i]] += 1;
}
// compute proper indices
for(i = 1; i <= max; i++){
count[i] += count[i - 1];
}
// sort
for(i = array.length - 1; i >= 0; i--){
sorted[count[array[i]] - 1] = array[i];
count[array[i]] -= 1;
}
}
Running example:
var countingSort = function(array, sorted, max) {
var i, j;
var count = [];
// initialize counting array
for (i = 0; i <= max; i++) {
count[i] = 0;
}
// count unique occurrences
for (i = 0; i <= max; i++) {
count[array[i]] += 1;
}
// compute proper indices
for (i = 1; i <= max; i++) {
count[i] += count[i - 1];
}
// sort
for (i = array.length - 1; i >= 0; i--) {
sorted[count[array[i]] - 1] = array[i];
count[array[i]] -= 1;
}
}
document.getElementById("button").onclick = function() {
var i, array, max, sorted = [];
array = document.getElementById("input").value.split(',');
// convert strings to numbers
for (i = 0; i < array.length; i++) {
array[i] = +array[i];
}
// find max
var max = Number.MIN_VALUE;
for (i = 0; i < array.length; i++) {
if (max < array[i]) {
max = array[i];
}
}
countingSort(array, sorted, max);
document.getElementById("result").value = sorted;
}
input {
width: 100%;
margin: 10px 0;
padding: 10px;
border: 1px solid #018bbc;
border-radius: 5px;
}
<input type="text" id="input" placeholder="Enter comma separated list of integers">
<button type="button" id="button">Sort</button>
<input type="text" id="result" disabled placeholder="Sorted array is displayed here...">
Additionally, here is a version of counting sort which IMHO seems more intuitive and less complicated than the general approach above:
var countingSort = function(array, sorted, max) {
var i, j, count = [];
// initialize counting array
for (i = 0; i <= max; i++) {
count[i] = 0;
}
// count unique occurences
for (i = 0; i < array.length; i++) {
count[array[i]] ++;
}
// sort
for (i = 0, j = 0; i <= max; i++) {
while (count[i] > 0) {
sorted[j++] = i;
count[i] --;
}
}
};

JavaScript iterate loop every x number of times in same loop?

I am not sure how to phrase this, so please re-title this question if it doesn't make sense. Anyways, this is what I am trying to do.
I have a variable with the length of 9.
And then I have another variable with the length of 3.
How do I write a loop that iterates through all 9 but starts over every third time?
For example: I have this,
x = 3;
l = 9;
for ( var i = 0; i < l; i++)
{
console.log(i + 1);
}
output = 1,2,3,4,5,6,7,8,9
The output I want to create
output = 1,2,3,1,2,3,1,2,3
I was thinking there might be away to do this with an if statement or possibly modulus, but wasn't quite sure how to implement it. What would be a good way to do this? Thanks in advance.
Embrace the modulus:
function expand(length, loop_length) {
for (var i = 0; i < length; i++) {
console.log(i % loop_length + 1);
}
}
expand(9, 3) // => 1, 2, 3, 1, 2, 3, 1, 2, 3
x = 3;
l = 9;
for ( var i = 0; i < l; i++)
{
console.log(i % x + 1);
}
output = 1,2,3,1,2,3,1,2,3
See it in action here: http://jsfiddle.net/BgBGL/
If you want to loop from a min value to a max value a specific number of times, the easiest way is just to have 2 loops, like this:
var min = 1, max = 3, times = 3;
for (var i = 0; i < times; i++) {
for (var j = min; j <= max; j++) {
console.log(j);
}
}
Or if you want to fix total length of the sequence, then yes, you can do it with a single loop and a little bit of math:
var min = 1, max = 3, totalLength = 9;
for (var i = 0; i < totalLength; i++) {
console.log((i % (max - min + 1)) + min);
}
For that case, this works:
x = 3;
l = 9;
for ( var i = 0; i < l; i++)
{
var num=(i %(x+1)) || 1;
console.log(num);
}
You could go mad with following syntax:
var i = 0;
do {
console.log(i++ % 3 + 1);
} while (i < 9);
Alternative, you could define 3 and 9 as a variable also.
I took an advantage of the fact that calling i++ will display old variable and increases it by 1 after, so I saved some bits!
See: fiddle example
x = 3;
l = 9;
for ( var i = 0; i <= l; i++)
{
for ( var j = 1; j <= x; j++)
{
console.log(j);
}
}

Specific combination algorithm

If I have n balls and k containers then this -> ( (n+k-1)! / n!(k-1)! ) will work out how many combinations there are.
I am having difficulty changing this to produce a list of all combinations in javascript.
In a function taking an array of balls and some amount of containers.
combinations([1,2,3,4,5,6], 3)
Each container can have any number of balls and containers can be empty.
Here is something i attempted but im only getting one ball in each container.
function generateCombinations(array, r, callback) {
function equal(a, b) {
for (var i = 0; i < a.length; i++) {
if (a[i] != b[i]) return false;
}
return true;
}
function values(i, a) {
var ret = [];
for (var j = 0; j < i.length; j++) ret.push(a[i[j]]);
return ret;
}
var n = array.length;
var indices = [];
for (var i = 0; i < r; i++) indices.push(i);
var final = [];
for (var i = n - r; i < n; i++) final.push(i);
while (!equal(indices, final)) {
callback(values(indices, array));
var i = r - 1;
while (indices[i] == n - r + i) i -= 1;
indices[i] += 1;
for (var j = i + 1; j < r; j++) indices[j] = indices[i] + j - i;
}
callback(values(indices, array));
}
count = 0
generateCombinations([1,2,3,4,5,6,7,8,9,1],3,function(first){
$("#hello").append(first+"<br />")
count = count +1
})
$("#hello").append(count)
You can do it in this way:
var containers = [];
// n - number of balls, k - number of containers
function dfs(n, k) {
// Ending point of recursion, all balls are placed
if(n == 0) {
var output = [];
for(var i = 0; i < k; i++) {
output.push('{' + containers[i].join(', ') + '}');
}
output = '[' + output.join(', ') + ']';
console.log(output);
return;
}
// Try to put ball #n
for(var i = 0; i < k; i++) {
containers[i].push(n);
// Now we have placed ball #n, so we have 1 .. n - 1 balls only
dfs(n - 1, k);
// Remove ball when back to use again
containers[i].pop();
}
}
var n = 4;
var k = 3;
for(var i = 0; i < k; i++) {
containers[i] = [];
}
dfs(n, k);
I initially thought you wanted all the combinations of k elements out of n, but your problem is different, it's partitioning n elements in k parts.
When going through the elements, at each steps, you may choose to put the current element in any container, that's k possibilities. In total, you will have kn possible solutions.
Therefore, it would be faster to iterate through all the solutions, rather than storing them in an array.
You can represent a solution as a unique number in base k, with n digits, and iterate through the solutions by incrementing that number.
In your example, the base is 3, and the number of digits is 6. The first solution is to put all the balls in container 0, ie.
000000
The next solution is to put all the balls in container 0, excepted the last which goes in container 1.
000001
...
000002
000010
000011
000020
Hopefully you should get the idea.

Categories