I have a series of numbers ranging from 0-9. Each number represents a position with an x and y co-ordinate. So, position 0 could represent (5, 5) or something similar, always (x, y). Now what I need to do is recursively bash each possible route using 5 positions to get the position given by a user. So for example:
Input = (1, 2) //This is the co-ordinate the user gives.
Now given this input it should take every possible path and find the shortest one. Some paths could be:
start 0 1 2 3 4 input
start 0 1 2 3 5 input
start 0 1 2 3 6 input
start 0 1 2 3 7 input
start 0 1 2 4 3 input
start 1 0 2 3 5 input
and so on....
It could be any combination of 5 numbers from the 0-9. It must end at the input destination and begin at start destination. Numbers cannot be reused. So I need to recursively add all the distances for a given course (ex. start 0 1 2 3 4 input) and find the shortest possible course while going through those 5 points.
Question: What would the base and recursive case be?
Basically what you want to do is generate all combinations of size k (the length of the path) from the set {1,..,n}, and then calculate the value of the path for it.
Here's a C# code sample:
void OPTPathForKSteps(List<int> currentPath, List<int> remainingPositions, int remainingSteps)
{
if (remainingSteps == 0)
{
// currentPath now contains a combination of k positions
// do something with currentPath...
}
else
{
for (int i = 0; i < remainingPositions.Count; i++)
{
int TempPositionIndex = remainingPositions[i];
currentPath.Add(TempPositionIndex);
remainingPositions.RemoveAt(i);
OPTPathForKSteps(currentPath, remainingPositions, remainingSteps - 1);
remainingPositions.Insert(i, TempPositionIndex);
currentPath.RemoveAt(currentPath.Count - 1);
}
}
}
This is the initial call for the function (assume Positions is an integer list of 0...n positions, and k is the length of the path):
OPTPathForKSteps(new List<int>(), Positions, K);
You can change the function and add arguments so it will return the optimal path and minimal value.
There are other (maybe shorter) ways to create these combinations, the good thing about my implementation is that it is light on the memory, and doesn't require storing all the possible combinations.
Related
I already found this one
Brute force is possible of course, but are there any other ways? Is there a way to find all multisets? Is there a way to find out how many combinations exist under a certain limit?
Perhaps this question is too mathy for SO, if that is the case I'll move it.
I created my own version in javascript by generating all possible combinations of a list of numbers, then checking for integer RMS. These are sets though, not multisets.
Edit: I used N for sum value and K for the number of squares.
Number of multi-sets grows fast, so N should have reasonable value. So this problem is equivalent to changing sum N by K coins with nominals 1,4,9,25... (and the number of variants might be calculated using dynamic programming).
The simplest implementation is recursive - we just generate all possible addends. In my Delphi implementation I collect summands in string (instead of list) for simplicity.
Note that such implementation might generate the same sequences again and again - note {5,7} end-sequence in my example. To improve performance (important for rather large values of N and K), it is worth to store generated sequences in table or map (with {N;K;Min} key). In that case generation from large summands to smaller ones would be better, because small summands give a lot of repeating patterns.
procedure FSP(N, K, Minn: Integer; Reslt: string);
var
i: Integer;
begin
if (K = 0) then begin
if (N = 0) then
Memo1.Lines.Add(Reslt); //yield result
Exit;
end;
i := Minn;
while (i * i <= N) do begin
FSP(N - i * i, K - 1, i, Reslt + Format('%d ', [i]));
i := i + 1;
end;
end;
procedure FindSquarePartitions(N, K: integer);
begin
FSP(N, K, 1, '');
end;
FindSquarePartitions(101, 5);
1 1 1 7 7
1 1 3 3 9
1 1 5 5 7
1 2 4 4 8
1 5 5 5 5
2 2 2 5 8
2 3 4 6 6
2 4 4 4 7
3 3 3 5 7
I have the following data:
y-n-y-y-n-n-n
This repeats infinitely, such as:
y-n-y-y-n-n-n-y-n-y-y-n-n-n-y-n-y-y-n-n-n...
I have 5 "x".
"x" only sticks with "y".
Meaning, if I distribute x on the loop above, it will be:
y-n-y-y-n-n-n-y-n-y-y-n-n-n
x---x-x-----x-x
I want to count how many of the loop's element I needed to use to spread 5 x across, and the answer is 10.
How do I calculate it with a formula?
I presume what you're saying is that you need to process the first 10 elements of the infinite list to get 5 Y's, which match/stick with the 5 X's you have.
y-n-y-y-n-n-n-y-n-y-y-n-n-n-y-n-y-y-n-n-n...
x-_-x-x-_-_-_-x-_-x
^
L____ 10 elements read from the infinite list to place the 5 x's.
I also presume that your question is: given an input of 5 Xs, what is the number of elements you need to process in the infinite list to match those 5 Xs.
You could calculate it with a loop like the following pseudo-code:
iElementsMatchedCounter = 0
iXsMatchedCounter = 0
iXLimit = 5
strElement = ""
if (InfiniteList.IsEmpty() == false)
{
do
{
strElement = InfiniteList.ReadNextElement()
if (strElement == "y")
{
iXsMatchedCounter += 1
}
iElementsMatchedCounter += 1
} while ( (InfiniteList.IsEndReached() == false) AND (iXsMatchedCounter < iXLimit) )
}
if (iXsMatchedCounter = iXLimit)
then Print(iElementsMatchedCounter)
else Print("End of list reached before all X's were matched!")
The drawback of the above approach is that you are actually reading the infinite list, which might not be preferable.
Instead, given you know your list is an infinitely repeating sequence of the same elements y-n-y-y-n-n-n, you don't even need to loop through the entire list, but just operate on the sub-list y-n-y-y-n-n-n. The following algorithm describes how:
Given your starting input:
iNumberOfXs = 5 (you have 5 Xs to match)
iNumberOfYsInSubList = 3
(you have 3 Ys in the sub-list, the total list repeats infinitely)
iLengthOfSubList = 7 (you have 7 elements in the sub-list
y-n-y-y-n-n-n)
We then have intermediate results which are calculated:
iQuotient
iPartialLengthOfList
iPendingXs
iPendingLengthOfList
iResult
The following steps should give the result:
Divide the iNumberOfXs by iNumberOfYsInSubList. Here, this gives us 5/3 = 1.666....
Discard the remainder of the result (the 0.666...), so you're left with 1 as iQuotient. This is the number of complete sub-lists you have to iterate.
Multiply this quotient 1 with iLengthOfSubList, giving you 1*7=7 as iPartialLengthOfList. This is the partial sum of the result, and is the number of elements in the complete sub-lists you iterate.
Also multiply the quotient with iNumberOfYsInSubList, and subtract this product from iNumberOfXs, i.e. iNumberOfXs - (iQuotient * iNumberOfYsInSubList) = 5 - (1 * 3) = 2. Save this value 2 as iPendingXs, which is the number of as-yet unmatched X's.
Note that iPendingXs will always be less than iLengthOfSubList (i.e. it is a modulo, iPendingXs = iNumberOfXs MODULO iNumberOfYsInSubList).
Now you have the trivial problem of matching 2 X's (i.e. the value of iPendingXs calculated above) in the sub-list of y-n-y-y-n-n-n.
The pending items to match (counted as iPendingLengthOfList) is:
Equal to iPendingXs if iPendingXs is 0 or 1
Equal to iPendingXs + 1 otherwise (i.e. if iPendingXs is greater than 1)
In this case, iPendingLengthOfList = 3, because iPendingXs is greater than 1.
The sum of iPartialLengthOfList (7) and iPendingLengthOfList (3) is the answer, namely 10.
In general, if your sub-list y-n-y-y-n-n-n is not pre-defined, then you cannot hard-code the rule in step 6, but will instead have to loop through only the sub-list once to count the Ys and elements, similar to the pseudo-code given above.
When it comes to actual code, you can use integer division and modulo arithmetic to quickly to the operations in steps 2 and 4 respectively.
iQuotient = iNumberOfXs / iNumberOfYsInSubList // COMMENT: here integer division automatically drops the remainder
iPartialLengthOfList = iQuotient * iLengthOfSubList
iPendingXs = iNumberOfXs - (iQuotient * iNumberOfYsInSubList)
// COMMENT: can use modulo arithmetic like the following to calculate iPendingXs
// iPendingXs = iNumberOfXs % iNumberOfYsInSubList
// The following IF statement assumes the sub-list to be y-n-y-y-n-n-n
if (iPendingXs > 1)
then iPendingLengthOfList = iPendingXs + 1
else iPendingLengthOfList = iPendingXs
iResult = iPartialLengthOfList + iPendingLengthOfList
I was looking at the following code:
function _fibonacci(n) {
if (n < 2){
return 1;
}else{
return _fibonacci(n-2) + _fibonacci(n-1);
}
}
console.log(_fibonacci(5))
I understand HOW this works, but I do not understand WHY this works. Can someone explain to me why this works?
It's quite simple, the fibonacci answer for both location 0 and 1 are both 1 (the sequence looks like 1 1 2 3 5 8 etc...) so when it enters the function with n being 0 or 1 (which can happen for both the n-2 recursive call and the n-1 recursive call), the result is 1. For all other values it just keeps adding the numbers.
(Note that the values for the first 2 in the sequence can be 0 1 or 1 1, depending on your definition of the sequence. For this one it's apparently assumed the first 2 are both 1.)
I have been trying to get my head around this perticular complexity computation but everything i read about this type of complexity says to me that it is of type big O(2^n) but if i add a counter to the code and check how many times it iterates per given n it seems to follow the curve of 4^n instead. Maybe i just misunderstood as i placed an count++; inside the scope.
Is this not of type big O(2^n)?
public int test(int n)
{
if (n == 0)
return 0;
else
return test(n-1) + test(n-1);
}
I would appreciate any hints or explanation on this! I completely new to this complexity calculation and this one has thrown me off the track.
//Regards
int test(int n)
{
printf("%d\n", n);
if (n == 0) {
return 0;
}
else {
return test(n - 1) + test(n - 1);
}
}
With a printout at the top of the function, running test(8) and counting the number of times each n is printed yields this output, which clearly shows 2n growth.
$ ./test | sort | uniq -c
256 0
128 1
64 2
32 3
16 4
8 5
4 6
2 7
1 8
(uniq -c counts the number of times each line occurs. 0 is printed 256 times, 1 128 times, etc.)
Perhaps you mean you got a result of O(2n+1), rather than O(4n)? If you add up all of these numbers you'll get 511, which for n=8 is 2n+1-1.
If that's what you meant, then that's fine. O(2n+1) = O(2⋅2n) = O(2n)
First off: the 'else' statement is obsolete since the if already returns if it evaluates to true.
On topic: every iteration forks 2 different iterations, which fork 2 iterations themselves, etc. etc. As such, for n=1 the function is called 2 times, plus the originating call. For n=2 it is called 4+1 times, then 8+1, then 16+1 etc. The complexity is therefore clearly 2^n, since the constant is cancelled out by the exponential.
I suspect your counter wasn't properly reset between calls.
Let x(n) be a number of total calls of test.
x(0) = 1
x(n) = 2 * x(n - 1) = 2 * 2 * x(n-2) = 2 * 2 * ... * 2
There is total of n twos - hence 2^n calls.
The complexity T(n) of this function can be easily shown to equal c + 2*T(n-1). The recurrence given by
T(0) = 0
T(n) = c + 2*T(n-1)
Has as its solution c*(2^n - 1), or something like that. It's O(2^n).
Now, if you take the input size of your function to be m = lg n, as might be acceptable in this scenario (the number of bits to represent n, the true input size) then this is, in fact, an O(m^4) algorithm... since O(n^2) = O(m^4).
I'm trying to understand the binary operators in C# or in general, in particular ^ - exclusive or.
For example:
Given an array of positive integers. All numbers occur even number of times except one number which occurs odd number of times. Find the number in O(n) time and constant space.
This can be done with ^ as follows: Do bitwise XOR of all the elements. Finally we get the number which has odd occurrences.
How does it work?
When I do:
int res = 2 ^ 3;
res = 1;
int res = 2 ^ 5;
res = 7;
int res = 2 ^ 10;
res = 8;
What's actually happening? What are the other bit magics? Any reference I can look up and learn more about them?
I know this is a rather old post but I wanted simplify the answer since I stumbled upon it while looking for something else.
XOR (eXclusive OR/either or), can be translated simply as toggle on/off.
Which will either exclude (if exists) or include (if nonexistent) the specified bits.
Using 4 bits (1111) we get 16 possible results from 0-15:
decimal | binary | bits (expanded)
0 | 0000 | 0
1 | 0001 | 1
2 | 0010 | 2
3 | 0011 | (1+2)
4 | 0100 | 4
5 | 0101 | (1+4)
6 | 0110 | (2+4)
7 | 0111 | (1+2+4)
8 | 1000 | 8
9 | 1001 | (1+8)
10 | 1010 | (2+8)
11 | 1011 | (1+2+8)
12 | 1100 | (4+8)
13 | 1101 | (1+4+8)
14 | 1110 | (2+4+8)
15 | 1111 | (1+2+4+8)
The decimal value to the left of the binary value, is the numeric value used in XOR and other bitwise operations, that represents the total value of associated bits. See Computer Number Format and Binary Number - Decimal for more details.
For example: 0011 are bits 1 and 2 as on, leaving bits 4 and 8 as off. Which is represented as the decimal value of 3 to signify the bits that are on, and displayed in an expanded form as 1+2.
As for what's going on with the logic behind XOR here are some examples
From the original post
2^3 = 1
2 is a member of 1+2 (3) remove 2 = 1
2^5 = 7
2 is not a member of 1+4 (5) add 2 = 1+2+4 (7)
2^10 = 8
2 is a member of 2+8 (10) remove 2 = 8
Further examples
1^3 = 2
1 is a member of 1+2 (3) remove 1 = 2
4^5 = 1
4 is a member of 1+4 (5) remove 4 = 1
4^4 = 0
4 is a member of itself remove 4 = 0
1^2^3 = 0Logic: ((1^2)^(1+2))
(1^2) 1 is not a member of 2 add 2 = 1+2 (3)
(3^3) 1 and 2 are members of 1+2 (3) remove 1+2 (3) = 0
1^1^0^1 = 1 Logic: (((1^1)^0)^1)
(1^1) 1 is a member of 1 remove 1 = 0
(0^0) 0 is a member of 0 remove 0 = 0
(0^1) 0 is not a member of 1 add 1 = 1
1^8^4 = 13 Logic: ((1^8)^4)
(1^8) 1 is not a member of 8 add 1 = 1+8 (9)
(9^4) 1 and 8 are not members of 4 add 1+8 = 1+4+8 (13)
4^13^10 = 3 Logic: ((4^(1+4+8))^(2+8))
(4^13) 4 is a member of 1+4+8 (13) remove 4 = 1+8 (9)
(9^10) 8 is a member of 2+8 (10) remove 8 = 2
1 is not a member of 2+8 (10) add 1 = 1+2 (3)
4^10^13 = 3 Logic: ((4^(2+8))^(1+4+8))
(4^10) 4 is not a member of 2+8 (10) add 4 = 2+4+8 (14)
(14^13) 4 and 8 are members of 1+4+8 (13) remove 4+8 = 1
2 is not a member of 1+4+8 (13) add 2 = 1+2 (3)
To see how it works, first you need to write both operands in binary, because bitwise operations work on individual bits.
Then you can apply the truth table for your particular operator. It acts on each pair of bits having the same position in the two operands (the same place value). So the leftmost bit (MSB) of A is combined with the MSB of B to produce the MSB of the result.
Example: 2^10:
0010 2
XOR 1010 8 + 2
----
1 xor(0, 1)
0 xor(0, 0)
0 xor(1, 1)
0 xor(0, 0)
----
= 1000 8
And the result is 8.
The other way to show this is to use the algebra of XOR; you do not need to know anything about individual bits.
For any numbers x, y, z:
XOR is commutative: x ^ y == y ^ x
XOR is associative: x ^ (y ^ z) == (x ^ y) ^ z
The identity is 0: x ^ 0 == x
Every element is its own inverse: x ^ x == 0
Given this, it is easy to prove the result stated. Consider a sequence:
a ^ b ^ c ^ d ...
Since XOR is commutative and associative, the order does not matter. So sort the elements.
Now any adjacent identical elements x ^ x can be replaced with 0 (self-inverse property). And any 0 can be removed (because it is the identity).
Repeat as long as possible. Any number that appears an even number of times has an integral number of pairs, so they all become 0 and disappear.
Eventually you are left with just one element, which is the one appearing an odd number of times. Every time it appears twice, those two disappear. Eventually you are left with one occurrence.
[update]
Note that this proof only requires certain assumptions about the operation. Specifically, suppose a set S with an operator . has the following properties:
Assocativity: x . (y . z) = (x . y) . z for any x, y, and z in S.
Identity: There exists a single element e such that e . x = x . e = x for all x in S.
Closure: For any x and y in S, x . y is also in S.
Self-inverse: For any x in S, x . x = e
As it turns out, we need not assume commutativity; we can prove it:
(x . y) . (x . y) = e (by self-inverse)
x . (y . x) . y = e (by associativity)
x . x . (y . x) . y . y = x . e . y (multiply both sides by x on the left and y on the right)
y . x = x . y (because x . x = y . y = e and the e's go away)
Now, I said that "you do not need to know anything about individual bits". I was thinking that any group satisfying these properties would be enough, and that such a group need not necessarily be isomorphic to the integers under XOR.
But #Steve Jessup proved me wrong in the comments. If you define scalar multiplication by {0,1} as:
0 * x = 0
1 * x = x
...then this structure satisfies all of the axioms of a vector space over the integers mod 2.
Thus any such structure is isomorphic to a set of vectors of bits under component-wise XOR.
This is based on the simple fact that XOR of a number with itself results Zero.
and XOR of a number with 0 results the number itself.
So, if we have an array = {5,8,12,5,12}.
5 is occurring 2 times.
8 is occurring 1 times.
12 is occurring 2 times.
We have to find the number occurring odd number of times. Clearly, 8 is the number.
We start with res=0 and XOR with all the elements of the array.
int res=0;
for(int i:array)
res = res ^ i;
1st Iteration: res = 0^5 = 5
2nd Iteration: res = 5^8
3rd Iteration: res = 5^8^12
4th Iteration: res = 5^8^12^5 = 0^8^12 = 8^12
5th Iteration: res = 8^12^12 = 8^0 = 8
The bitwise operators treat the bits inside an integer value as a tiny array of bits. Each of those bits is like a tiny bool value. When you use the bitwise exclusive or operator, one interpretation of what the operator does is:
for each bit in the first value, toggle the bit if the corresponding bit in the second value is set
The net effect is that a single bit starts out false and if the total number of "toggles" is even, it will still be false at the end. If the total number of "toggles" is odd, it will be true at the end.
Just think "tiny array of boolean values" and it will start to make sense.
The definition of the XOR (exclusive OR) operator, over bits, is that:
0 XOR 0 = 0
0 XOR 1 = 1
1 XOR 0 = 1
1 XOR 1 = 0
One of the ways to imagine it, is to say that the "1" on the right side changes the bit from the left side, and 0 on the right side doesn't change the bit on the left side. However, XOR is commutative, so the same is true if the sides are reversed.
As any number can be represented in binary form, any two numbers can be XOR-ed together.
To prove it being commutative, you can simply look at its definition, and see that for every combination of bits on either side, the result is the same if the sides are changed. To prove it being associative, you can simply run through all possible combinations of having 3 bits being XOR-ed to each other, and the result will stay the same no matter what the order is.
Now, as we proved the above, let's see what happens if we XOR the same number at itself. Since the operation works on individual bits, we can test it on just two numbers: 0 and 1.
0 XOR 0 = 0
1 XOR 1 = 0
So, if you XOR a number onto itself, you always get 0 (believe it or not, but that property of XOR has been used by compilers, when a 0 needs to be loaded into a CPU register. It's faster to perform a bit operation than to explicitly push 0 into a register. The compiler will just produce assembly code to XOR a register onto itself).
Now, if X XOR X is 0, and XOR is associative, and you need to find out what number hasn't repeated in a sequence of numbers where all other numbers have been repeated two (or any other odd number of times). If we had the repeating numbers together, they will XOR to 0. Anything that is XOR-ed with 0 will remain itself. So, out of XOR-ing such a sequence, you will end up being left with a number that doesn't repeat (or repeats an even number of times).
This has a lot of samples of various functionalities done by bit fiddling. Some of can be quite complex so beware.
What you need to do to understand the bit operations is, at least, this:
the input data, in binary form
a truth table that tells you how to "mix" the inputs to form the result
For XOR, the truth table is simple:
1^1 = 0
1^0 = 1
0^1 = 1
0^0 = 0
To obtain bit n in the result you apply the rule to bits n in the first and second inputs.
If you try to calculate 1^1^0^1 or any other combination, you will discover that the result is 1 if there is an odd number of 1's and 0 otherwise. You will also discover that any number XOR'ed with itself is 0 and that is doesn't matter in what order you do the calculations, e.g. 1^1^(0^1) = 1^(1^0)^1.
This means that when you XOR all the numbers in your list, the ones which are duplicates (or present an even number of times) will XOR to 0 and you will be left with just the one which is present an odd number of times.
As it is obvious from the name(bitwise), it operates between bits.
Let's see how it works,
for example, we have two numbers a=3 and b=4,
the binary representation of 3 is 011 and of 4 is 100, so basically xor of the same bits is 0 and for opposite bits, it is 1.
In the given example 3^4, where "^" is a xor symbol, will give us 111 whose decimal value will be 7.
for another example, if you've given an array in which every element occurs twice except one element & you've to find that element.
How can you do that? simple xor of the same numbers will always be 0 and the number which occur exactly once will be your output. because the output of any one number with 0 will be the same name number because the number will have set bits which zero don't have.