Calculate Number from a loop increment number - javascript

+---+---+---+
| 1 | 0 | 0 |
+---+---+---+
| 2 | 1 | 0 |
+---+---+---+
| 3 | 2 | 0 |
+---+---+---+
| 4 | 0 | 1 |
+---+---+---+
| 5 | 1 | 1 |
+---+---+---+
| 6 | 2 | 1 |
+---+---+---+
| 7 | 0 | 2 |
+---+---+---+
| 8 | 1 | 2 |
+---+---+---+
| 9 | 2 | 2 |
+---+---+---+
The code I am trying
var loop = 1;
while(loop < 10) {
console.log(loop, loop%3, "I can't calculate this")
loop++;
}
I have a loop increment variable loop and it counting 1,2,3,4,5....
I need to calculate 2 number from incremental variable: one is rounding 0,1,2 (loop % 3) I can do this but other 0,0,0 or 1,1,1
I mean I need to hold a number according to my round number.

Fixed your code ((loop-1)%3) and you just need a division with rounding down:
var loop = 1;
while(loop < 10) {
console.log(loop, (loop-1)%3, Math.floor((loop-1)/3))
loop++;
}
Some other languages support "integer division", where the Math.floor thing would not be necessary.

Use bellow code snippet:
var loop = 1;
var round = 3;
while (loop < 10) {
console.log(loop, (loop - 1) % round, Math.floor((loop - 1) / round));
loop++;
}
So easy

Actually you have an need for getting a number in a different decimal system, here, you want to get a number to base of three with the slight complication of a one based starting value, where the number usually starts at zero and a reversed result by taking the lower indicators at left and the higer indicator at right.
Now you get first the straight conversion.
var i;
for (i = 0; i < 9; i++) {
console.log(i, i.toString(3).padStart(2, '0'));
}
And now the shifted result by adding one to the output and by reversing the result.
var i;
for (i = 0; i < 9; i++) {
console.log(i + 1, Array.from(i.toString(3).padStart(2, '0')).reverse().join(''));
}

Related

how to concatenate bits in javascript?

I want to concatenate the bits of two number values like this:
+---------+---------+---------+-----------------+
| | val1 | val2 | concatenate val |
+---------+---------+---------+-----------------+
| decimal | 18 | 16 | 592 |
| hexa | 0x12 | 0x10 | 0x250 |
| binary | 0b10010 | 0b10000 | 0b1001010000 |
+---------+---------+---------+-----------------+
I have try to just concatenate with + like that :
const test = 0b10010, test1 = 0b10000
console.log(test+test1)//return 34
It does not concatenate the values but adds them together.
You could shift the first value by the bitwise length of the second value before adding.
const
add = (a, b) => (a << Math.ceil(Math.log2(b)) + 1) + b;
test = 0b10010,
test1 = 0b10000,
console.log(add(test, test1)); //

How Do I Solve This Complex Javascript Algorithm Without Overcomplicating it?

How many ways can you make the sum of a number?
From wikipedia: https://en.wikipedia.org/wiki/Partition_(number_theory)#
In number theory and combinatorics, a partition of a positive integer n, also called an integer partition, is a way of writing n as a sum of positive integers. Two sums that differ only in the order of their summands are considered the same partition. If order matters, the sum becomes a composition. For example, 4 can be partitioned in five distinct ways:
4
3 + 1
2 + 2
2 + 1 + 1
1 + 1 + 1 + 1
Examples
Basic
sum(1) // 1
sum(2) // 2 -> 1+1 , 2
sum(3) // 3 -> 1+1+1, 1+2, 3
sum(4) // 5 -> 1+1+1+1, 1+1+2, 1+3, 2+2, 4
sum(5) // 7 -> 1+1+1+1+1, 1+1+1+2, 1+1+3, 1+2+2, 1+4, 5, 2+3
sum(10) // 42
Explosive
sum(50) // 204226
sum(80) // 15796476
sum(100) // 190569292
My Attempt
I tried to loop through two arrays simultaneously and test them against eachother. This doesn't work (at least in the way I did it) for a few reasons.
My Code:
function sum(num, arr = []) {
if(num == 0){
return testNumbers(arr, num);
}
arr.push(num);
return sum(num - 1, arr);
function testNumbers(arrr, n){
let arr2 = [...arrr];
let count = 0;
let calculations = arrr.filter((item)=>{
return item + arr2.map((a)=>{
return a;
}) == n;
})
console.log(calculations);
}
}
console.log(sum(10));
You don't need to fix my code, as I don't think its salvageable, but how do you solve the problem?
This is in fact a fairly simple recursion, if we think of the problem as counting the partitions with a given lower bound. We have two simple bases cases of 0 and 1 if the lower bound is greater than our target number or equal to it. Otherwise we recur in two ways, one for when we use that lower bound, and one for when we don't. Here's one version, where lb is the lower bound of the numbers to use:
const count = (n, lb = 1) =>
lb > n
? 0
: lb == n
? 1
: count (n - lb, lb) + count (n, lb + 1)
This counts the number of partitions with the given lower bound. So count(10, 3) would yield 5, one for each array in [[3, 3, 4], [3, 7], [4, 6], [5, 5], [10]]. Although the default value for the lower bound means that we can call it with just our target number, there are potential issues with this if we tried, say, to map over it. So it might be best to wrap this in a separate function, const countPartitions = (n) => count (n, 1)
const count = (n, lb) =>
lb > n
? 0
: lb == n
? 1
: count (n - lb, lb) + count (n, lb + 1)
const countPartitions = (n) => count (n, 1)
console .log ([1, 2, 3, 4, 5, 6, 7, 8, 9, 10] .map (countPartitions))
But this will be quite slow for larger input. My test for 100 took 56.3 seconds.) If we memoize the intermediate results, we should speed things up a great deal. We can do this manually or, as I'd prefer, with a memoization helper:
const memoize = (makeKey, fn) => {
const memo = {}
return (...args) => {
const key = makeKey (...args)
return memo [key] || (memo [key] = fn (...args))
}
}
const count = memoize (
(n, lb) => `${n}~${lb}`,
(n, lb) =>
lb > n
? 0
: lb == n
? 1
: count (n - lb, lb) + count (n, lb + 1)
)
const countPartitions = (n) => count (n, 1)
console .log (countPartitions (100))
And this now takes 20 milliseconds in my test.
Update: answering comment
A comment asked
Hey Scott, sorry to bring up an old post, but I've been going over your solution here and I'm afraid I'm having trouble understanding exactly how it works. If you don't mind, could you go a little more in-depth on why counting instances of n===lb leads to the answer? Maybe my math is just weak, but I'm not following the partitions logic.
Let's imagine we're trying to partition 10, and we've already counted those whose lowest value is 1 and those whose lowest value is 2, and now we're trying to count the partitions where the lowest value is at least 3.
We call count (10, 3). Since 3 > 10 is false, we don't return 0. And since 3 == 10 is false, we don't return 1. Instead we make two recursive calls and add their results together. The first one is where we choose to use 3 in our output, choose (7, 3), since we will have seven remaining when we've selected the first 3. The second one is where we choose not to use 3 in our output, choose (10, 4), since the lowest bound will be 4 if we are to skip 3, but we still have ten to partition.
The call structure would look like this:
(10, 3)
___________________________________/\____________________
/ \
(7, 3) + (10, 4)
___________/\___________ __________/\_________
/ \ / \
(4, 3) + (7, 4) (6, 4) + (10, 5)
____/\___ ________/\_______ ____/\____ _____/\_______
/ \ / \ / \ / \
(1, 3) + (4, 4) (3, 4) + (7, 5) (2, 4) + (6, 5) (5, 5) + (10, 6)
| | | ___/\___ | ___/\___ | _____/\_____
| | | / \ | / \ | / \
| | | (2, 5) + (7, 6) | (1, 5) + (6, 6) | (4, 6) + (10, 7)
| | | | __/\__ | | | | | ____/\____
| | | | / \ | | | | | / \
| | | | (1, 6) + (7, 7) | | | | | (3, 7) + (10, 8)
| | | | | | | | | | | | ___/\____
| | | | | | | | | | | | / \
| | | | | | | | | | | | (2, 8) + (10, 9)
| | | | | | | | | | | | | ___/\___
| | | | | | | | | | | | | / \
| | | | | | | | | | | | | (1, 9) + (10, 10)
| | | | | | | | | | | | | | |
| | | | | | | | | | | | | | |
(3>1) (4=4) (4>3) (5>2) (6>1) (7=7) (4>2) (5>1) (6=6)(5=5) (6>4) (7>3) (8>2) (9>1) (10=10)
| | | | | | | | | | | | | | |
| | | | | | | | | | | | | | |
0 + 1 + 0 + 0 + 0 + 1 + 0 + 0 + 1 + 1 + 0 + 0 + 0 + 0 + 1
| | | | |
| | | | |
[[3, 3, 4], [3, 7], [4, 6],[5, 5], [10]]
We can get a speed up over Scott's solution by using the recurrence relation for the partition function that uses pentagonal numbers:
function _p(k, memo){
if (k == 0)
return 1;
if (memo[k])
return memo[k];
let result = 0;
let i = 1;
const ms = [1, 1, -1, -1];
while (true){
const n = i & 1 ? (i + 1) / 2 : -i / 2;
const pentagonal = (3*n*n - n) / 2;
if (pentagonal > k)
break;
result = result + ms[(i-1) % 4] * _p(k - pentagonal, memo);
i = i + 1;
}
return memo[k] = result;
}
function p(k){
return _p(k, {});
}
var ks = [1, 2, 3, 4, 5, 6, 10, 50, 80, 100];
for (let k of ks){
const start = new Date;
console.log(`${ k }: ${ p(k) }`);
console.log(`${ new Date - start } ms`);
console.log('');
}

Double Cola Challenge, JavaScript code wrong?

Five friends are drinking magic cola in an line. When the first friend drinks the cola he disappears, and multiplies into two copies! After that, those new copies go to the end of the line and the next friend drinks the magic cola, repeating the proccess.
For example, imagine we have the following friends:
[Sheldon, Leonard, Penny, Rajesh, Howard]
After Sheldon drinking the first cola, the line will look like this:
[Leonard, Penny, Rajesh, Howard, Sheldon, Sheldon]
After Leonard drinking the cola, the line gets like this:
[Penny, Rajesh, Howard, Sheldon, Sheldon, Leonard, Leonard]
And so on...
My objective is to write a function in JavaScript, that given an array with the names of the people in the line, and a number N, it will return the the name of the N-ith person drinking the magic cola.
So, for example, doing console.log(whoIsNext([Sheldon, Leonard, Penny, Rajesh, Howard], 1)) should return Sheldon.
To achieve this, I made this code:
function whoIsNext(names, r){
var fistInLine;
if(r <= names.length){
return names[r-1];
}else{
while(r > names.length){
fistInLine = names.shift();
names.push(fistInLine, fistInLine);
}
return names[r-1];
}
}
This function works well for the following case:
names = ["Sheldon", "Leonard", "Penny", "Rajesh", "Howard"];
Test.assertEquals(whoIsNext(names, 1), "Sheldon");
But it fails for the test:
names = ["Sheldon", "Leonard", "Penny", "Rajesh", "Howard"];
Test.assertEquals(whoIsNext(names, 52), "Penny");
And if I try with a really big number, like:
names = ["Sheldon", "Leonard", "Penny", "Rajesh", "Howard"];
Test.assertEquals(whoIsNext(names, 7230702951), "Leonard");
It doesn't even stop running (takes forever).
So obviously, my solution is not only incorrect, it seems to be inneficient as well. How can I fix it?
A zero based recursive proposal which returns the index of the array, here with length base = 5.
1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 3 3 3 3 3 3 3 3 3 3
number 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9
index 0 1 2 3 4 0 0 1 1 2 2 3 3 4 4 0 0 0 0 1 1 1 1 2 2 2 2 3 3 3 3 4 4 4 4 0 0 0 0 0
It become visible, the pattern is based on 5 and goes up for every round by factor 2.
5 -> 10- > 20 -> 40
Example of calculation
Array after step
0 1 2 3 4 5 6 7 8 9
0: 0 Sheldon |
1: 1 Leonard | |
2: 2 Penny | | |
3: 3 Rajesh | | | |
4: 4 Howard | | | | |
5: 0 Sheldon | | | | |
6: 0 Sheldon | | | | | |
7: 1 Leonard | | | | | |
8: 1 Leonard | | | | | | |
9: 2 Penny | | | | | |
10: 2 Penny | | | | | |
11: 3 Rajesh | | | | |
12: 3 Rajesh | | | | |
13: 4 Howard | | | |
14: 4 Howard | | | |
15: 0 Sheldon | | |
16: 0 Sheldon | | |
17: 0 Sheldon | |
18: 0 Sheldon | |
19: 1 Leonard |
20: 1 Leonard |
21: 1 Leonard
22: 1 Leonard
var friends = ['Sheldon', 'Leonard', 'Penny', 'Rajesh', 'Howard'],
base = friends.length;
function getIndex(n, i) {
i = i || base;
if (n < i) {
return Math.floor(n * base / i);
}
return getIndex(n - i, 2 * i);
}
var i = 0, index;
document.write(friends[getIndex(1 - 1)] + '<br>'); // "Sheldon"
document.write(friends[getIndex(52 - 1)] + '<br>'); // "Penny"
document.write(friends[getIndex(7230702951 - 1)] + '<hr>'); // "Leonard"
for (i = 0; i < 200; i++) {
index = getIndex(i);
document.write(i + ': ' + index + ' ' + friends[index] + '<br>');
}
Okay, here we go, this is a really simplistic approach and I'll come up with a better one (it's half way through my mind, I'll just have to fit it together)
function whoIsNext(names, index, multiplyFactor)
{
var count = names.length;
var fullLoops = 0;
var currIndex = 0;
while(currIndex <= index)
{
for(var i = 0; i < count; i++)
{
currIndex += Math.pow(multiplyFactor, fullLoops);
if(currIndex > index)
{
return names[i];
}
}
fullLoops++;
}
}
The idea is that the amount the same person comes is doubled each time the people do a full loop (countPerson = Math.pow(2, countFullLoops)). If you then accumulate the amount of people before the set index until you reach the index, you then get the right person (I feel like I just explained a really easy thing really hard).
Also you can substitute any input (change the amount of people on start, change the multiplication factor (did someone say quadruple coke?)) as you want.

Bitwise operator "&" [duplicate]

x <<= y (x = x << y)
x >>= y (x = x >> y)
x >>>= y (x = x >>> y)
x &= y (x = x & y)
x ^= y (x = x ^ y)
x |= y (x = x | y)
What do these different operators do?
<<, >>
Bit shift left and right, respectively. If you imagine the left operand as a binary sequence of bits, you are shifting those to the left or right by the number of bits indicated by the right operand.
&, ^, |
These are bitwise and, xor, and or, respectively. You can think of & and | as the counterparts to && and ||, except that they will treat their operands as bit vectors, and perform the logical operations on each of the bits. There is no ^^ operator, but this operation is "xor" or "exclusive or". You can think of "a xor b" as "a or b, but not both".
Here is an attempt to make things simple for the very beginner.
Prerequisites
You have to be familiar with the binary number system (numbers made of two digits). If you are not then check this link first: https://www.mathsisfun.com/binary-number-system.html. Just in case the previous link breaks, this answer may help a little: https://stackoverflow.com/a/32155850/1636522.
Indeed, in order to figure out how these operators work, you need to know which bit sequence is behind the numbers involved in the operation. After that you should be able to understand the following stuffs.
Reminder
Decimal digits and their binary notations:
0 0 | 5 101
1 1 | 6 110
2 10 | 7 111
3 11 | 8 1000
4 100 | 9 1001
What do >>>, >> and << do?
These operators shift a bit sequence to the left or to the right.
decimal | binary decimal | binary
---------|--------- ---------|---------
9 | 1001 2 | 10
>> 2 | >> 2 << 2 | << 2
= 2 | = 10 = 8 | = 1000
What do &, | and ^ do?
These operators combine the bits of two numbers to create a new number.
decimal | binary decimal | binary decimal | binary
---------|-------- ---------|-------- ---------|--------
5 | 101 5 | 101 5 | 101
& 6 | & 110 | 6 | | 110 ^ 6 | ^ 110
= 4 | = 100 = 7 | = 111 = 3 | = 011
How does & work?
For each pair of bits: If at least one of the two bits is 0, the resulting bit is 0. If none of the two bits is 0, the resulting bit is 1.
101 bit 3 | bit 2 | bit 1
& 110 -------|-------|-------
= 100 1 | 0 | 1
& | & | &
1 | 1 | 0
= | = | =
1 | 0 | 0
How does | work?
For each pair of bits: If at least one of the two bits is 1, the resulting bit is 1. If none of the two bits is 1, the resulting bit is 0.
101 bit 3 | bit 2 | bit 1
| 110 -------|-------|-------
= 111 1 | 0 | 1
| | | | |
1 | 1 | 0
= | = | =
1 | 1 | 1
How does ^ work?
For each pair of bits: If the two bits are different, the resulting bit is 1. If the two bits are the same, the resulting bit is 0.
101 bit 3 | bit 2 | bit 1
^ 110 -------|-------|-------
= 011 1 | 0 | 1
^ | ^ | ^
1 | 1 | 0
= | = | =
0 | 1 | 1
Bitwise Operators

Reverse a percentage

I have a percentage, it ranges from 50% to 0%.
I need the values to be mirrored, so:
0% now equals 50%
1% = 49%
25% = 25%
48% = 2%
50% = 0%
etc.
Thanks for any help!
You can use j = max_i - i + min_i where the two constants min_i and max_i are the lower and upper limit of the range.
If i is always between 0 and 50 then you can just write j = 50 - i.
It looks like you want to define a function like this:
(x) f(x)
0 50
1 49
2 48
: :
48 2
49 1
50 0
Then the function is simply:
f(x) = 50 - x
More generally, if x is between low and high inclusive, then:
f(x) = (high + low) - x
Other functions of interest
Here are some other common functions:
(x) f(x)___
0 0 |
1 0 3
2 0 ___|
3 1 |
4 1 3 f(x) = x / 3
5 1 ___| where / is integer division
6 2 |
7 2 3
: : ___|
(x) f(x)___
0 0 |
1 1 3
2 2 ___|
3 0 |
4 1 3 f(x) = x % 3
5 2 ___| where % is integer remainder
6 0 |
7 1 3
: : ___|
Both of the above are sometimes combined when indexing a 2-dimensional table:
______4 columns______
/ \
_______________________ (x) row(x) col(x)
| | | | | 0 0 0
| 0 | 1 | 2 | 3 | 1 0 1
|_____|_____|_____|_____| 2 0 2 row(x) = x / 4
| | | | | 3 0 3 col(x) = x % 4
| 4 | 5 | 6 | 7 | 4 1 0
|_____|_____|_____|_____| 5 1 1 x = row(x) * 4 + col(x)
| | | | 6 1 2
| 8 | 9 | ... | 7 1 3
|_____|_____|_____| : : :
If i'm reading that correctly, the only way for the pcntAnimationComplt to go down is if your currImgWidth is decreasing. If that is so, then just do this:
pcntAnimationComplt = 50 - Math.round((parseFloat(currImgWidth / pageWidth) * 100) / 2);
This should go from 0 to 50, as per your requirements.
var min=1;
var max=50;
for(var i=min;i<=max;i++){document.writeln(i + "<br>");}
for(var i=max;i>=min;i--){document.writeln(i + "<br>");}

Categories