Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 3 years ago.
Improve this question
I find that algorithm/functionality in two games already, but I always wanted to know what was the logic behind it.
Basically, there is a list of items and each of them has an id.
For example:
item_1 has id: 1
item_2 has id: 2
item_3 has id: 4
item_4 has id: 8
item_5 has id: 16
etc.
The id is multiplied by two every new item.
There is then a number, let's say 4, that indicate what the current item is. Is this case that would be item_3, but the tricky part is that number could also select multiple items at once like 7 which is 4 + 2 + 1 (item_3, item_2, item_1) or 17 which is 16 + 1 (item_5, item_1). It can go really high like 16384 if you have a long list and still be perfectly accurate for the multiple selections.
How do I solve this problem?
The algorithm you described is basically outputting where the 1's are in the binary representation of the number.
For 7, its binary representation is 111. There are three 1's: in the first, second, and third position from the left respectively, so it's item 1, 2 and 3. Note that we are counting from the left.
Another example:
For 10, its binary representation is 1010. There are two 1's: in the second and fourth position from the left, so the output would be items 2 and 4.
Here is an implementation in C#.
public static List<int> FindOnes(int number) {
var list = new List<int>();
var binaryString = Convert.ToString(number, 2);
for (int i = 0 ; i < binaryString.Length ; i++) {
if (binaryString[binaryString.Length - i - 1] == '1') {
list.Add(i + 1);
}
}
return list;
}
// usage:
FindOnes(7) // [1,2,3]
No idea how the games you're talking about implement it, but if this was me I would do it using bits in the binary expression of the number (example code in java).
public boolean isItemSelected(final int number, final int itemId) {
return (number & (1 << (itemId - 1))) != 0;
}
The trick here being that the binary representation of a number (from right to left) already denotes whether 1, 2, 4, 8, 16, etc. is required additively to make the number using only powers of two. The left shift simply makes a number which (in binary) is all 0's except a 1 in the 'itemId - 1'th slot. The & will match if that bit is 1 in the given number. And then checking that the result is not 0 simply turns it into a boolean.
Obviously you can combine this with some looping or anything else if you want to build the array/List of all the 'itemIds' which match.
In Javascript, you could take the number, convert it to a binary value, take the bits, reverse it and take the values (index plus one) or zero for a filtering of truthy values.
var value = 13,
items = [...value.toString(2)].reverse().map((v, i) => +v && (i + 1)).filter(Boolean);
console.log(items);
Related
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.
I'm making this acres and karats calculator for my uncle to help him in his work.
I'll explain the whole idea of this thing with this example. So if you add 3.22 + 2.2 it should be = 5.42 but in this calculator 3.22 + 2.2 should = 6, because 3 acres + 2 acres = 5 acres and 22 karats + 2 karats = 1 acre, so the total would be 6 acres.
The way I'm doing it in the code is that I'm splitting a number like 3.22 to two, 3 and 22 and the other number to 2 and 2 and I add the whole numbers together and the fractions together and if the fractions are >= 24 I add one to the whole numbers and if there're fractions left from the whole calculation I leave it. For example 3.15 + 2.15 = 6.6, but I'm stuck on how I can add the numbers, there's also an error in there that I don't know how to resolve.
Anyway here's the code
function getValue(v) {
return +v.toString().match(/\.(\d*)/)[1] || 0;
}
function getTotal() {
d += Math.floor(num);
p += getValue(num);
if (p >= 24) {
p -= 24;
++d;
}
total = d + p / 100;
ptag.textContent = total;
}
I added the part of the code where I'm stuck.
Note: I'm trying to make the thing able to add multiple numbers not only two. Also I'm trying to add subtraction but I have no idea how to start working on the subtraction because I haven't even finished the addition.
If the error you are talking about is something like this:
Uncaught TypeError: Cannot read property '1' of null
It is because of your getValue function.
My suggestion is, instead of using something as complicated as
function getValue(v) {
return +v.toString().match(/\.(\d*)/)[1] || 0;
}
use
function getValue(v) {
return floor((v % 1) * 100);
}
This has the same effect as the code you wrote. Which for example, from input 3.13, returns 13.
But there are few other problems.
First, you should update your num variable every now and often, otherwise, it is always going to stay as an empty string (you only defined it on line 20, and you didn't update it after that).
Second, you should clear the d and p variable after you use. As of right now, both of these variables just keeps on increasing every time you run the getTotal function
For your question of how you can add two numbers, I suggest you to create a variable where you can store the first number that the user typed.
For example, when the user typed in 4.19 and pressed the plus button, save that 4.19 into a variable (let's say firstNum).
Then when the user pressed equal button, add the number from the current input field with the firstNum variable.
On how exactly you are going to add two different numbers, break two numbers you want to add into Acres part and Karats parts. Then add them separately, then use your getTotal.
So if the number is 3.21 and 5.18, add 3 and 5, add 21 and 18, then add both of them.
you'll get 8.39. Finally, convert 8.39 into 9.15.
Sorry if my calculation is not correct. It is my first time with this concept!
But I believe this is the way to go.
This question already has answers here:
Testing whether a value is odd or even
(23 answers)
Closed 6 years ago.
I have a function that I want to run every time my counter is 1, 3, 5 or 7. I am confused about what the right syntax is for jQuery in this situation.
My try so far:
if (i == (0, 2, 4, 6)) {
This is one of the many versions that I have tried, and failed with.
What is the right syntax, both for every odd number, as well as a specific collection of numbers, for example '3, 12, 512, 2231'?
use the modulus operator in which the value %2 will either give a 0 or a 1 depending on the value:
if (i % 2 == 1) { // code for odd event
or do it for evens:
if (i % 2 == 0) { // code for even event
What this does is divide the value by the number given (in this case 2) and returns the remainder. So if i is 5, dividing it by two will leave a remainder of 1, so its n odd number. If i = 44, dividing by two will leave a remainder of 0, so its even.
if(i % 2 == 1) //odd number
It's a modulo operator. See this documentation for more information on JavaScript arithmetic operators.
Explained in this thread.
if(i % 2) {
// If Odd then do this
}
Is this not what you're after?
i % 2 will return 1 when an odd number and 0 when an even number.
I had this code written by a user here yesterday and I'm having trouble understanding it. I understand all by line 9 of the deal function, it creates a random card out of 52 numbers but on the next line I don't understand what this does. Could somebody please explain what this code does so I could modify it and expand on it?
//Creates the deck
var Ace = 1;
var Face = 10;
var deck = [Ace, 2, 3, 4, 5, 6, 7, 8, 9, 10, Face, Face, Face];
/*Creates a deal function that can deal cards to each player.
Use object_name.property_name = deal() to call this function.*/
var deal = function () {
var randomcard = Math.ceil(Math.random() * 52) + 1;
return deck[Math.floor(randomcard % 13)];
};
Well, first let's correct the code. The original code does give you a working result, but it does it in a confusing way. It doesn't pick a value between 0 and 51 which would be the natural thing to do, it picks a value between 2 and 53. (The result is still useful for getting a value between 0 and 12 to use for a value, but getting the suit for the card is not very straight forward.)
var randomcard = Math.floor(Math.random() * 52);
return deck[randomcard % 13];
The modulo operator gets the reminder from a division, so the result from the expression would get the value for the card. Up to 12 it returns the number itself, then at 13 it starts over at 0 again.
To get the index for the suit for the card, you would use Math.floor(randomcard / 13). With the original random value (2 to 53) you would have needed to use (Math.floor(randomcard / 13) % 4) instead.
There are 52 cards in the deck. 13 different values with 4 different suit( clubs/diamonds...). Note 4 * 13 = 52. The modulus 13 is just there to assure that one of the values from in the deck variables gets picked, and the suit is ignored.
You have an array of only 13 items -- the cards. 0 through 12.
If you take any number and % 13 it, you will always get a value between 0 and 12 -- the remainder of a division of that number by 13. The deck of 52 then % 13 basically reduces the deck from suit + card to just card.
This could have equally been written as Math.ceil(Math.random() * 13) + 1 instead of 52. However if the code needs to be expanded to also have a suit, then you might likely
The code is only half-valid. The modulo is poorly selecting the type of card to draw out of the deck, but not the suit the card is. In addition, the code doesn't account for having already dealt out a specific card (it's never removed from the deck), so multiple players could have identical cards.
See this page for information on how deck structure looks in JavaScript:
http://www.brainjar.com/js/cards/default2.asp
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 3 years ago.
Improve this question
I want return the difference between 2 values how to do that?
0.0.0.1.0 and 0.0.0.1.12
so the difference between these two values is 12
so how to calculate that I tried with Math.abs() but it is fine with single digits.
Assuming that they are strings (since you can't have more than 1 full stop in a valid JS number), you could split it by . character and calculate the difference of individual components:
function numStringDiff(a, b) {
// split them on dot characters
const aParts = a.split('.');
const bParts = b.split('.');
// loop using longest array length as a container for mapped results
return Array(Math.max(aParts.length, bParts.length)).fill(undefined).map((_, i) => {
const i1 = parseInt(aParts[i] || 0); // fetch aParts[i] or default to 0
const i2 = parseInt(bParts[i] || 0); // fetch bParts[i] or default to 0
// return compared value after defaulting the values.
return i2 - i1;
});
}
console.log(numStringDiff('0.0.0.1.0', '0.0.0.1.12'));
The problem here is that, as you stated in the comments, they can be of different length. To make it work in this scenario, we must iterate an amount of times equal to the length of the longest array and ensure that any missing items in the shorter one are defaulted to some non-breaking value like 0 so that we can safely subtract every digit present in the longest list with something or 0.
Note that 0 is a value I only used to ensure you can calculate a difference between different-length arrays, choose any (numeric or float) value that fits your needs.
If in this case the second argument has less dots than the first, negative difference will be returned, otherwise if first is longer than last, positive difference will be returned.
Some examples:
numStringDiff('1.1.1', '1.1') // => [0, 0, -1]
numStringDiff('1.1', '1.1.1') // => [0, 0, 1]
numStringDiff('1.1.1', '1.1.1') // => [0, 0, 0]
For the absolute distance between two values, one can simply .map over this array:
numStringDiff('1.1.1', '1.1').map(num => Math.abs(num));
// OR, using short form:
numStringDiff('1.1.1', '1.1').map(Math.abs);
And finally, should you need the result as a string, simply .join it back together with '.':
numStringDiff('1.1.1', '1.1').map(Math.abs).join('.');
Do know what you are trying to achieve though. If you're trying to manually bisect version numbers (like semver versions) I'd recommend against it since there will always be scenario's uncovered by this function such as pre-releases that wouldn't include only digits but rather 0.0.0-pre-foo-version or something. Since I don't know what it is you're trying to do exactly I'll leave that a responsibility for you to figure out :)