This question already has answers here:
How does '&' work in relation to odd and even? In JS
(3 answers)
Closed last month.
I'm working through a problem on CodeSignal and trying to understand some of the solutions that other people have submitted. One of the solutions was as follows, and I don't understand what the ampersand is doing.
(a) => a.reduce((p,v,i) => (p[i&1]+=v,p), [0,0])
The problem is:
Several people are standing in a row and need to be divided into two teams. The first person goes into team 1, the second goes into team 2, the third goes into team 1 again, the fourth into team 2, and so on.
You are given an array of positive integers - the weights of the people. Return an array of two integers, where the first element is the total weight of team 1, and the second element is the total weight of team 2 after the division is complete.
Example
For a = [50, 60, 60, 45, 70], the output should be
solution(a) = [180, 105].
In this solution, the & operator is used to perform a bitwise AND operation. In JavaScript, the & operator compares each bit of the first operand to the corresponding bit of the second operand. If both bits are 1, the corresponding result bit is set to 1. Otherwise, the corresponding result bit is set to 0.
In the given solution, the & operator is used to determine whether the index i of the current element in the array is even or odd. If i is even, the result of i & 1 will be 0. If i is odd, the result of i & 1 will be 1.
Related
I want to pick a random item from an array at random.
Math.floor(Math.random() * array.length);
Is the way to go, but as far as I know this will cause a Uniform distribution to occur which means that the average is (lowbound+upperbound)/2 translated to an array with 10 elements the lower bound is the first element and the upper bound is the last element causes an average of 5, which is not random
Therefore, I looked at the frequency distribution of this way of random picking an item by having 10 elements and picking one with the code above. The element represents the index and is pushed into an array. After 10000 numbers, the frequency is counted and given.
This has the following results:
Index: Frequency
0: 1083
1: 996
2: 1022
3: 966
4: 958
5: 962
6: 1044
7: 1045
8: 972
9: 952
Ofc, this is only 1 run of 10k numbers. But it shows that index 0 has a 10.8% chance and index 9 has a 9.5% chance. This difference is 1.3% which I find quite a lot.
Are there methods that can do this better? For example, get to 0.05% difference in numbers? The ideal situation would be that they are all 10% (equally distributed).
If you can precompute the result (i.e. you need a finite number of results, not an infinite stream) and the number of results is divisible by the number of items, you can get a perfect distribution:
Generate an array that repeats the items until you've got enough, i.e. [1, 2, 3, 1, 2, 3, 1, 2, 3, ...]. The array is thus guaranteed to have exactly as many instances of each item.
Shuffle the array with a fair shuffle algorithm, e.g. Fisher-Yates. The array still has exactly as many instances of each item.
If you do need an infinite stream, you could use something like an "item bag" model (which, btw, is how the blocks in Tetris are chosen):
Fill a "bag" with your items ([1, 2, 3]). Shuffle it (as above).
When you need an item, pop the first one from the shuffled bag.
If the bag is empty, re-fill it according to step 1.
The only case where this doesn't have a perfect distribution is if you stop "mid-bag".
Here another method - count number of samples already happen, select values from Categorical distribution but with probability INVERSE to the count, thus more frequent item will be less probable to be sampled next time.
Some code (in C#)
import MathNet.Numerics.Distributions;
static void Main() {
const int N = 4;
var counts = new int [N] {1, 1, 1, 1};
var weights = new double [N] {1.0, 1.0, 1.0, 1.0};
while (true) {
int v = Categorical.Sample(weights[k]); // sample one value in [0...N)
// update counts and weights
counts[v] += 1;
weights[v] = 1.0/(double)counts[v];
// use v here for something
...
}
}
Actually, any monotonically growing function of count will do, f.e.
weights[v] = 1.0/(1.0 + .5*(double)counts[v]);
might work, or
var squared => (x) => x*x;
weights[v] = 1.0/(7.0 + .25*squared((double)counts[v]));
or
weights[v] = 1.0/(3.0 + Math.Sqrt((double)counts[v]));
What you have shown in your question is simply the fact that the JavaScript random number generator is simulating not just uniformly distributed, but also independent random numbers; each chosen number behaves as though it were independent of any other choice. Because of this independence, each number "doesn't care" how often each other number was chosen, as long as with each choice, each possible outcome is as likely as any other (according to the JavaScript generator).
If you want a distribution that "feels" more uniform, you will have to adjust the chances of each outcome, so that the chances depend on previous outcomes. A previous answer showed some ways how this can be done. Here is another, which I gave as an answer to a similar question.
Give each item the same weight, specified as a positive integer. For example, give a weight of 20 to each item.
Use a weighted-choice-with-replacement algorithm. Perhaps the simplest is rejection sampling, described as follows. Assume that the highest weight is max and each weight is 0 or greater. To choose an integer in the interval [1, weights.length] using rejection sampling:
Choose a uniform random integer i in [1, weights.length].
With probability weights[i]/max, return i. Otherwise, go to step 1. (For example, if all the weights are integers greater than 0, choose a uniform random integer in [1, max] and if that number is weights[i] or less, return i, or go to step 1 otherwise.)
There are many other ways to make a weighted choice besides rejection sampling; see my note on weighted choice algorithms.
As each item is chosen, reduce its weight by 1 to make it less likely to be chosen.
If all the weights are 0, assign each item the same weight chosen in step 1 (in this example, 20).
You didn't specify the kind of application you had in mind, but I see this desire for a "more uniform" distribution come up most often in games that wish to control which random numbers appear, to make the random outcomes appear "fairer" to players. In that case, however, you should also consider whether it may be better to make an (ordinary) independent uniform random choice instead, especially if you care whether players could gain an unfair advantage by predicting the random outcomes.
This is a simpler version of knapsack, which I am having trouble wrapping my head around.
In my version I don't care how valuable the items are. I just want to get as close to the weight capacity as possible, and order doesn't matter because I'm doing it multiple times and shuffling in between.
So to be clear:
I have an array of values like: weights = [{44, 52, 100, 33, 33, 22, 25, 4, 6, 77, 88, 45}] and a capacity of, for example:capacity: 204
I want the closest combination of array values to that capacity number without repeating any, I'm not super great at math, and the wikipedia article has completely lost me.
Can someone explain how to get this?
Naive approach: cycle through all subsets of N numbers, and check the sum of weights. Running time is O(2^N*N)
You can try dynamic programming.
The problem can be divided into 2 subproblems, to check whether the sum of set is equal to or less than the capacity.
1) Include the current element in subset, and recur for the remaining items with remaining sum.
2) Exclude the current element from the subset, recur remaining items.
The base case of the recursion would be when no items are left. Finally, we output the items included in the subset.
Running time is O(n*capacity) in O(n)
I am creating a algorithm to match any combination of cells of first array to second array value with priority in second array. for example in javascript :
var arr=[10,20,30,40,50,60,70,80,90];
var arr2=[100,120,140];
what I want is to define into following logic(priority for value of second array's cell serially) automatically and please help me finding pseudo for algorithm
100 = 10+20+30+40 //arr2[0] = arr1[0] + arr1[1] + arr1[2] + arr1[3]
120 = 50+70 //arr2[1] = arr1[4] + arr1[6]
140 = 60+80 //arr2[2] = arr1[5] + arr1[7]
90 = 90 //remaining arr1[8]
values are demo and can be changed dynamically.
Solution is possible if you take both array as sorted array and then start adding elements from last ends of first array (array1) which are the greatest as array is sorted , now check if sum matches then proceed else if sum is lesser than element in array2 you were checking then you need to add third element from array1. Another case if sum is greater than element in array2 then you have to neglect one of the element from array1 you have used in addition and replace the addition with the previous element you HV used from array one. Repeat the steps. You need to think how to do this correctly or else you need to share some of your work or logic u r thinking , so that we can help
As the matter is quite complex, over and above sufficing on a pseudo code style explanation, I have also coded a practical implementation that you may find at this link.
I advise you to refrain from looking at the solution and first try to implement the algorithm yourself as there is a lot of scope for further improvement.
Here is in broad lines an explanation to the way I have decided to tackle the algorithm:
The problem presented by the OP is related to a classic example of distributing n unique elements over k unique boxes.
In this case here, arr has 9 unique elements that need to be distributed over three distinct spots, represented by the container: arr2.
So the first step in tackling this problem is to figure out how you can implement a function that given n and k, is able to calculate all the possible distributions that apply.
The closest that I could come up with was the Stirling Numbers of the Second Kind, which is defined as:
The number of ways of partitioning a set of n elements into m nonempty sets (i.e., m set blocks), also called a Stirling set number. For example, the set {1,2,3} can be partitioned into three subsets in one way: {{1},{2},{3}}; into two subsets in three ways: {{1,2},{3}}, {{1,3},{2}}, and {{1},{2,3}}; and into one subset in one way: {{1,2,3}}.
If you pay close attention to the example provided, you will realize that it pertains to the enumeration of all the distribution combinations possible over INDISTINGUISHABLE partitions as order doesn't matter.
Since in our case, each spot in the container arr2 represents a UNIQUE spot and order therefore does matter, we will thus be required to enumerate all the Stirling Combinations over every possible combination of arr2.
Practically speaking, this means that for our example where arr2.length === 3, we will be required to apply all of the Stirling Combinations obtained to [100,120,140], [120,140,100], [140,100,120] etc.(in total 6 permutations)
The main challenging part here is to implement the Stirling Function, but luckily somebody has already done so:
http://blogs.msdn.com/b/oldnewthing/archive/2014/03/24/10510315.aspx
After copy and pasting the Stirling Function and using it to distribute arr over 3 unique spots, you now need to filter out the distributions that don't sum up to the designated spots encompassed by arr2.
This will then leave you with all the possible solutions that apply. In your case, for
var arr=[10,20,30,40,50,60,70,80,90];
var arr2=[100,120,140];
no solutions apply at all.
A quick workaround to that is by expanding the distribution target arr2 from [100,120,140] to [100,120,140,90]. A better workaround is that in the case zero solutions are found, then take away one element from list arr until you obtain a solution. Then you can later on expand your solution sets by including this element where it represents a mapping of it unto itself.
I'm struggling with increasing the speed of my pseudo branch & bound algo & thought a trie structure might be a good fit, but I'm stuck.
The problem (simplified & isolated best I can):
I've got 9 nodes & 3 vehicles. Each vehicle must visit 3 unique nodes. So, I created every possible trip (9 choose 3 = 84) & stuck it in an array. Now, I want to find every combination.
For example, trip 1 could be 111000000. trip 2 would be 000110001 and trip 3 would be 000001110. (84^3 = 592704 combinations).
To find out if they match, I just do a bitwise & and accept the trip combination if the value is 0.
I can't use nested loops since the # of vehicles may change, so I keep track of combinations with a counter that ticks up depth-wise like an odometer (e.g. 0,0,82, 0,0,83, 0,1,0).
I reduce combinations by keeping the following digit greater than the one that just increased (e.g. 11,83,83 goes to 12,13,14 because anything less than a 12 in the 2nd column would be a repeat like 12,1,1 is a duplicate of 1,1,12).
I also perform the bitwise AND check at each change (e.g. if (val[12] & val[13]) > 0 don't bother checking the 71 possibilities in the 3rd column, because the 12 and 13 invalidate the route. This reduces the combinations to 24720.
Since I'm doing depth-first, it's really space efficient (no queue to save), but computationally expensive. What I'd like to do is use a width-first approach to create subsets and minimize the search space. For example, assume the counter was at 11,19,20. Currently, it would check 20 - 83 in the 3rd column before incrementing the 19 to a 20. I would like to compute the AND for 19 - 83 in the 2nd column before moving on. In doing so, I would know all the values that don't work with the 11 in the first column and could use that subarray for the 3rd column (e.g. if (val[11] & val[45]) > 0, don't bother checking 11 & 19 & 45, rather use an array that excludes 45 from the 3rd column.
My idea is to create a trie, where each key is the result of the AND operation with an end key that would be the subarray.
For example:
doc = {
1: {
5: {
end: [8,9,10]
},
7: {
end: [11,14,42]
},
end: [81, 13, 42]
}
}
My problem is I can't for the life of me figure out how to iterate over my data to grow the trie. Or maybe there's a better approach? Any advice or code snippets would be great, and thanks for reading through the wall of text.
I'm reading "Professional JavaScript for Web Developers" (third edition) by Nicholas Zakas in an attempt to teach myself JS. However, I am having difficulty following the Location Methods section of chapter 5 on page 118 (in case you have the book). He explains that "the indexOf() method starts searching from the front of the array (item 0) and continues to the back, whereas lastIndexOf() starts from the last item in the array and continues to the front". Also he explains that "Each of these methods accepts two arguments: the item to look for and an optional index from which to start looking". He then attempts to illustrate this with examples.
As you can see below, to the right of the alert statements, he has listed what the correct output will be for each statement given the supplied argument(s). I do not understand how these outputs are determined. For example, how does alert(numbers.indexOf(4)); produce 3? I was reading this last night and thought I was just too tired to understand, however, I still cannot seem to figure out how this is achieved. I searched the Errata section from the book's companion website for a possible typo, but nothing was listed. I also searched elsewhere but found examples that mostly dealt with strings instead of numbers. Thanks for any help. This is my first post to stack overflow so my apologies if I have done something incorrect in my post.
His examples:
var numbers = [1,2,3,4,5,4,3,2,1];
alert(numbers.indexOf(4)); //3
alert(numbers.lastIndexOf(4)); //5
alert(numbers.indexOf(4, 4)); //5
alert(numbers.lastIndexOf(4, 4)); //3
The way I thought the outcome would be:
alert(numbers.indexOf(4));
//the item in the array with the fourth index, or 5
alert(numbers.lastIndexOf(4));
//5 (this was only one that seemed to make sense to me) by counting back from the last value
alert(numbers.indexOf(4, 4));
//start looking at index 4, or 5, and then count right four places to end up at 1 (last item in array).
alert(numbers.lastIndexOf(4, 4));
//1, counting back to the left from the value with index 4, or 5, to reach the first value in the array.
Any help in determining the outputs based on the required argument and then how to also count from a specified value given the additional optional argument would be much appreciated. Thanks again.
In most of the Programming languages, default indexing start from 0. Therefore, you have an understanding problem. Double consider your example with index starting from 0.
var numbers = [1,2,3,4,5,4,3,2,1];
alert(numbers.indexOf(4)); //3, because 4 is at 3rd index
alert(numbers.lastIndexOf(4)); //5, because last 4 is at 5th index
alert(numbers.indexOf(4, 4)); //5, because searching will start from 4th index
alert(numbers.lastIndexOf(4, 4)); //3, because searching will start from last 3rd element.
JavasScript arrays are zero indexed, in other words, the first item has an index of zero. This is true for almost all programming languages (apart fro XPath for some odd reason!).
The indexOf function returns the index of the first item it finds that equals the supplied argument.
var numbers = [1,2,3,4,5,4,3,2,1];
var index = numbers.indexOf(4); // index is 3
alert(numbers[index]); // outputs 4
In JS or many other languages the index count of array starts with 0 so for,
var numbers = [1,2,3,4,5,4,3,2,1];
numbers[0] = 1
numbers[1] = 2
numbers[2] = 3
numbers[3] = 4
numbers[4] = 5
numbers[5] = 4
numbers[6] = 3
numbers[7] = 2
numbers[8] = 1
It's
indexOf("SearchString");
not
indexOf(indexNumber);
That would be awfully redundant.