Counting the occurence of a string after a for loop - javascript

I am working on a personal project, with Javascript. I am at an intermediary level.
I have created a for loop that gives me a list of random numbers. For each "i", there is one pair of integers. The integers are always positive, different and within a certain range (ex. between 1 and 10).
Let's say after I run the loop, I get this:
1 vs 3
4 vs 7
5 vs 8
2 vs 3
7 vs 5
3 vs 4
1 vs 2
3 vs 5
3 vs 1
5 vs 7
... and so on...
Now, how do I count the occurence of each pair of occurence. For example, I would like to be able to have:
3 vs 1: occurred 2 times
7 vs 5: occurred 2 times
3 vs 5: occurred 1 time
And so on...
The order does not matter, so I consider that 3 vs 1 and 1 vs 3 is the same thing. I realize that may complicate things.

// Generate Pairs
var randomPairs = []
for (var i = 0; i < 10; ++i) {
var randomPair = [Math.floor(Math.random() * 4) + 1, Math.floor(Math.random() * 4) + 1]
randomPairs.push(randomPair)
}
// Count Pairs
var randomPairsCounted = []
for (var i = 0; i < randomPairs.length; ++i) {
var a = randomPairs[i][0]
var b = randomPairs[i][1]
if (a > b) {
var t = a
a = b
b = t
}
var doublicate = false
for (var j = 0; j < randomPairsCounted.length; ++j) {
if (randomPairsCounted[j][0] == a && randomPairsCounted[j][1] == b) {
randomPairsCounted[j][2]++
doublicate = true
break
}
}
if (doublicate == false) {
randomPairsCounted.push([a, b, 1])
}
}
// Demo Output
document.write("Pairs: " + JSON.stringify(randomPairs) + "<br><br>")
for (var i = 0; i < randomPairsCounted.length; ++i) {
document.write(randomPairsCounted[i][0] + " vs " + randomPairsCounted[i][1] +
": occured " + randomPairsCounted[i][2] + " time" +
(randomPairsCounted[i][2] == 1 ? "" : "s") + "<br>")
}

Related

Compute the distance between elements in a bi-dimensional array in Javascript

Having the following input string: 923857614
This is represented into a matrix like this:
9 2 3
8 5 7
6 1 4
Having a moving sequence like this: 423692, this means that we start in point 4, we move to 2, then to 3, then to 6, then to 9 and finally to 2.
It must be computed the length of the road. At beginning it starts from 0, if the next step is adjacent to the current one, add 1, if it isn't adjacent, add 2.
How I tried to do it:
function computeRoadLength(keypad, movingSequence) {
// build the matrix
const arr = [[keypad[0], keypad[1], keypad[2]],
[keypad[3], keypad[4], keypad[5]],
[keypad[6], keypad[7], keypad[8]]];
let roadLength = 0;
for (i = 0; i < movingSequence.length; i++) {
// some way to compute the distance here
if (arr[i] > arr[i+1]) roadLength = roadLength + 1;
if (arr[i] < arr[i+1]) roadLength = roadLength + 2;
}
return roadLength;
}
computeRoadLength(923857614, 423692); // 2 + 1 + 2 + 2 + 1 = 8, should return 8
You could take a different approach by using an object of positions of all keypad values and take the absolute delta of the positions.
For adding to movingSequence add one or max two.
function computeRoadLength(keypad, movingSequence) {
const positions = {};
for (let i = 0; i < keypad.length; i++) {
positions[keypad[i]] = [Math.floor(i / 3), i % 3];
}
let roadLength = 0,
last = positions[movingSequence[0]];
for (let i = 1; i < movingSequence.length; i++) {
const
item = positions[movingSequence[i]],
sum = Math.abs(last[0] - item[0]) + Math.abs(last[1] - item[1]);
roadLength += Math.min(sum, 2);
last = item;
}
return roadLength;
}
console.log(computeRoadLength('923857614', '423692')); // 2 + 1 + 2 + 2 + 1 = 8

Print a list of number using While loop and Do While loop

I am trying to implement the while and do while loop without using an actual array to print an list of number. Here is my code and the output I want.
My code
console.log("While Loop")
let j = 0;
while(j < 5){
j += 1;
console.log (j);
}
console.log("Do While Loop")
var i = 0; //set varible i = 0
do {
i += 1; //return i + 1 to i
console.log (i);
}
while (i < 5); //where i suppose to less than 5
Actual Output I want:
1
1 2
1 2 3
1 2 3 4
1 2 3 4 5
5 4 3 2 1
4 3 2 1
3 2 1
2 1
1
There is two things here:
You need an inner loop to create the countdown of numbers.
If you are only using JavaScript, you need to form a string with your output and then use console.log() to print. This is because console.log() will append a newline.
The example below will print the first half of the triangle.
console.log("While Loop")
let j = 1;
while (j <= 5) {
let k = 1;
let str = "";
while (k <= j) {
str += k + " ";
k++;
}
j += 1;
console.log(str);
}
If you are using Node.js you can use process.stdout.write to print to the same line and then explicitly write the newline character when needed.
console.log("While Loop")
let j = 1;
while (j <= 5) {
let k = 1;
while (k <= j) {
process.stdout.write(k + " ");
k++;
}
j += 1;
process.stdout.write("\n");
}

find sum of multiples 3 and 5, JS

I'm given a number and I need to find the sum of the multiples of 3 and 5 below the number.
For example:
20 => 78 = 3 + 5 + 6 + 9 + 10 + 12 + 15 + 18
My code works, but not for numbers greater than 1,000,000 (I tested it for 100,000 - it gives the result with 2sec delay). So, it should be optimized. Could someone help me? Why is my code slow? Thanks.
My logic is as follows:
add multiples to an array
filter duplicate values
sum all values
my code:
function sumOfMultiples(number) {
let numberBelow = number - 1;
let numberOfThrees = Math.floor(numberBelow / 3);
let numberOfFives = Math.floor(numberBelow / 5);
let multiples = [];
let multipleOfThree = 0;
let multipleOfFive = 0;
for (var i = 0; i < numberOfThrees; i++) {
multiples.push(multipleOfThree += 3);
}
for (var j = 0; j < numberOfFives; j++) {
multiples.push(multipleOfFive += 5);
}
return multiples
.filter((item, index) => multiples.indexOf(item) === index)
.reduce((a, b) => a + b);
}
You can also do this without using any loops.
For example if N is 1000, the sum of all multiples of 3 under 1000 is 3 + 6 + 9 ..... 999 => 3( 1 + 2 + 3 .... 333)
Similarly for 5, sum is 5(1 + 2 + 3 .... 200). But we have to subtract common multiples like 15, 30, 45 (multiples of 15)
And sum of first N natural numbers is N*(N+1)/2;
Putting all of this together
// Returns sum of first N natural numbers
const sumN = N => N*(N+1)/2;
// Returns number of multiples of a below N
const noOfMulitples = (N, a) => Math.floor((N-1)/a);
function sumOfMulitples(N) {
const n3 = noOfMulitples(N, 3); // Number of multiples of 3 under N
const n5 = noOfMulitples(N, 5); // Number of multiples of 5 under N
const n15 = noOfMulitples(N, 15); // Number of multiples of 3 & 5 under N
return 3*sumN(n3) + 5*sumN(n5) - 15*sumN(n15);
}
You can just run a loop from 1 to number, and use the modulo operator % to check if i divides 3 or 5:
function sumOfMultiples(number) {
var result = 0;
for (var i = 0; i < number; i++) {
if (i % 5 == 0 || i % 3 == 0) {
result += i;
}
}
return result;
}
console.log(sumOfMultiples(1000));
console.log(sumOfMultiples(100000));
console.log(sumOfMultiples(10000000));
You can do that just using a single loop.
function sumOfMultiples(number) {
let sum = 0;
for(let i = 1; i < number; i++){
if(i % 3 === 0 || i % 5 === 0){
sum += i;
}
}
return sum;
}
console.time('t');
console.log(sumOfMultiples(100000))
console.timeEnd('t')
You can do something like this
Set the difference equal to 5 - 3
Start loop with current as 0, keep looping until current is less than number,
Add 3 to current in every iteration,
Add difference to current and check if it is divisible by 5 only and less than number, than add it final result,
Add current to final result
function sumOfMultiples(number) {
let num = 0;
let difference = 5 - 3
let current = 0
while(current < number){
current += 3
let temp = current + difference
if((temp % 5 === 0) && (temp %3 !== 0) && temp < number ){
num += temp
}
difference += 2
if(current < number){
num += current
}
}
return num
}
console.log(sumOfMultiples(20))
console.log(sumOfMultiples(1000));
console.log(sumOfMultiples(100000));
console.log(sumOfMultiples(10000000));
you can do something like this
function multiplesOfFiveAndThree(){
let sum = 0;
for(let i = 1; i < 1000; i++) {
if (i % 3 === 0 || i % 5 === 0) sum += i;
}
return sum;
}
console.log(multiplesOfFiveAndThree());

Combination Algorithm without sort()

I need results starting from the beginning with 123 as shown below. I want to print from the beginning without sort().
1 2 3
1 2 4
1 2 5
.....
3 5 6
4 5 6
But, The results are shown below.
4 5 6
3 5 6
2 5 6
1 5 6
3 4 6
2 4 6
1 4 6
2 3 6
1 3 6
1 2 6
3 4 5
2 4 5
1 4 5
2 3 5
1 3 5
1 2 5
2 3 4
1 3 4
1 2 4
1 2 3
result = "";
var N = 6;
var M = 3;
var arr = new Array(M);
combi(N, M, arr, M);
alert(result);
function combi(n, r, arr, sz) {
var i = n + 1;
while (i-- > r) {
// choose the first element
arr[r - 1] = i;
if (r > 1) { // if still needs to choose
// recursive into smaller problem
combi(i - 1, r - 1, arr, sz);
} else {
// print out one solution
var j = -1;
while (++j < sz) {
result += arr[j] + " ";
}
result += "\n";
}
}
}
Beside the inverting of all, you could start with one and iterat until the wanted value.
function combination(n, r) {
function iter(i, temp) {
if (temp.length === r) { // set complete
result.push(temp.join(' ')); // join values
return;
}
if (i + r > n + 1 + temp.length) { // exit early
return;
}
iter(i + 1, temp.concat(i)); // take the value
iter(i + 1, temp); // go without the value
}
var result = []; // result set
iter(1, []); // start with 1 and
return result; // empty array for collecting sets
}
console.log(combination(6, 3));
.as-console-wrapper { max-height: 100% !important; top: 0; }
You can revert the order by changing your code this way:
function combi(n, r, arr, sz) {
var i = r - 1;
while (i++ < n) {
// choose the first element
arr[r - 1] = i;
if (r > 1) { // if still needs to choose
// recursive into smaller problem
combi(i - 1, r - 1, arr, sz);
} else {
// print out one solution
var j = -1;
while (++j < sz) {
result += arr[j] + " ";
}
result += "\n";
}
}
}

javascript: summing even members of Fibonacci series

Yet Another (Project Euler) Fibonacci Question: Using (vanilla) javascript, I'm trying to sum the even numbers <= a given limit:
First, something is wrong with my 'if' statement, as some of the results (below) are wrong:
function fibonacciSum(limit) {
var limit = limit;
var series = [1,2];
var sum = 0;
var counter = 0;
for (var i=1; i<=33; i++) { // 33 is arbitrary, because I know this is more than enough
var prev1 = series[series.length-1];
var prev2 = series[series.length-2];
var newVal = prev1+prev2;
series.push(newVal);
counter ++;
console.log("series "+ counter + " is: " + series);
if (series[i] % 2 === 0 && series[i] <= limit) { // intending to sum only even values less than/equal to arbitrary limit
// sum = sum + series[i];
sum += series[i];
}
/*
var sum = series.reduce(function(a,b) {
/*
possible to filter here for even numbers? something like:
if (a %2 === 0)
*/
return a+b;
});
*/
console.log("SUM " + counter + ": " + sum);
} // for loop
} // fibonacci
fibonacciSum(4000000);
Results:
series 1 is: 1,2,3
SUM 1: 2
series 2 is: 1,2,3,5
SUM 2: 2
series 3 is: 1,2,3,5,8
SUM 3: 2 // looking for a '10' here
series 4 is: 1,2,3,5,8,13
SUM 4: 10
series 5 is: 1,2,3,5,8,13,21
SUM 5: 10
series 6 is: 1,2,3,5,8,13,21,34
SUM 6: 10 // looking for '44' here
Can someone please explain why neither of these working as intended?
if (series[i] % 2 === 0) { ...
... or
if (series[i] % 2 === 0 && series[i] <= limit) { ...
And secondly, as you can see I had also tried to use series.reduce(... but I can't figure how to sum only the even values; is that doable/cleaner?
Thank you,
Whiskey T.
No need for arrays. Use three variables for let's say previous, current and next numbers in fibonacci sequence.
We can also begin the sequence with 2 an 3 because there are no other even numbers that will affect the result.
We initialize the sum of even numbers with 2 because it's the current number and it's even. In a do...while we advance with the numbers in sequence and if the new numbers are even we add them to the sum. Stop when limit is reached.
function fibEvenSum(limit) {
var prev = 1,
current = 2,
next;
var sum = 2;
do {
next = prev + current;
prev = current;
current = next;
if (current >= limit)
break;
if (current % 2 == 0)
sum += current;
} while (true)
return sum;
}
This algorithm can be improved using properties of odd and even numbers:
odd + odd = even
even + even = even
even + odd = odd
This should work for you...
var fibonacciSum = function(limit) {
var nMinus2 = 1, nMinus1 = 2, evensFound = [2], sum = nMinus1;
while (sum <= limit){
var n = nMinus1 + nMinus2;
if (n % 2 == 0){
sum += n;
if (sum > limit){
break;
}
evensFound.push(n);
}
nMinus2 = nMinus1;
nMinus1 = n;
}
console.log("Evens found - " + evensFound);
return evensFound;
};
var evensFound1 = fibonacciSum(4),
evensFound2 = fibonacciSum(10),
evensFound3 = fibonacciSum(60),
evensFound4 = fibonacciSum(1000);
$(evenResults).append(evensFound1
+ "<br/>" + evensFound2
+ "<br/>" + evensFound3
+ "<br/>" + evensFound4);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="evenResults"></div>
A solution in the spirit of the one your attempted — with arrays — though as pointed out, they are not necessary.
var i = 0, sequence = [1, 2], total = 0;
while (sequence.slice(-1)[0] < 4000000) {
sequence.push(sequence.slice(-1)[0] + sequence.slice(-2)[0]);
}
for ( i; i <= sequence.length; i++ ) {
if ( sequence[i] % 2 === 0 ) {
total += sequence[i];
}
}

Categories

Resources