By complex group I mean a group where not all values are distinct. That is, if an ordinary group would be 1,2,3,4,5,6,7 (In which the amount of different combinations is 7C0+7C1+7C2...=2^7), then an example for a complex group is 1,1,1,3,3,5,7. How to calculate how many different combinations (where order does not matter) can be generated from such groups?
EDIT: to clarify this. If for example we take 7C1=7, then we find that it cannot be applied to complex groups. That's because we get 7 different groups, but some of them are equal (1=1=1 and 3=3), so actually there are only 4 different groups (1,3,5,7).
In other words, in the simple case of 1,1,2, simple 2^3 would consider these groups:
{},{1},{1},{2},{1,1},{1,2},{1,2},{1,1,2} = 8
What I need, is a way to calculate the amount of different groups (I consider {1,2}={2,1}). That would consider these:
{},{1},{2},{1,1},{1,2},{1,1,2} = 6
It is the product of the (counts+1) of unique elements in the set.
Explanation : For each unique number it can occur from zero to k times where k is the number of repetition of the number. So there are [0..k] i.e. total (k+1) options for each unique number. So the it is the product of the (counts+1) of unique elements in the set.
For {1,1,2}: count+1 for 1 = 2+1 = 3 and count+1 for 2 = 1+1 = 2
So the answer is 3*2 = 6.
For {1,1,1,3,3,5,7} it is (3+1)*(2+1)*(1+1)*(1+1) = 4*3*2*2 = 48
A python3 code:
>>> import collections
>>> A = [1,1,1,3,3,5,7]
>>> def countComplexGroups(A):
... count = collections.Counter(A)
... rt = 1
... for i in count: rt*=count[i]+1
... return rt
...
>>> print(countComplexGroups(A))
48
Related
How many sum of repeatable combinations of length N ?
Like [1,3,5,10], N = 4.
And there gonna be
[1,1,1,1] -> sum is 4
[1,1,1,3] -> sum is 6
...
[10,10,10,10] -> sum is 40
I perform a backtracking algo. by python3
res = set()
n = 4
def backtrack(k, path):
if len(path) == n:
res.add(sum(path))
return
backtrack(k+1, path+[1])
backtrack(k+1, path+[3])
backtrack(k+1, path+[5])
backtrack(k+1, path+[10])
return
backtrack(0, list())
Is there has more efficient solution?
If n elements order be not important, then your code is wrong
for example [1,1,2,2] ~ [1,2,1,2]
You can create a new list and repeat each element of the original n times. then the question is how many ways we can select n item from new list which can be calculated easily
further more if you want the result set of all the sums i think there's no better way than iterating in all situations.
O(n*len(list)*numberofdistinctsums) approach.
We have two sets containing current possible sums for odd and even steps.
We calculate new sums formed with i+1 summands from previous step sums (with i summands).
For example, after two rounds we have all possible sums of two summands. Getting sum 8 from previous set, we put sums of three summands 8+1, 8+3,8+5, 8+10 into new set and so on.
a = [1,3,5,10]
n = 4
sums = [set(a), set()]
for i in range(1, n):
sums[i%2].clear
for j in sums[(i+1)%2]:
for x in a:
sums[i%2].add(j + x)
print(len(sums[(n-1)%2]))
Let's assume I have an N-bit stream of generated bits. (In my case 64kilobits.)
Whats the probability of finding a sequence of X "all true" bits, contained within a stream of N bits. Where X = (2 to 16), and N = (16 to 1000000), and X < N.
For example:
If N=16 and X=5, whats the likelyhood of finding 11111 within a 16-bit number.
Like this pseudo-code:
int N = 1<<16; // (64KB)
int X = 5;
int Count = 0;
for (int i = 0; i < N; i++) {
int ThisCount = ContiguousBitsDiscovered(i, X);
Count += ThisCount;
}
return Count;
That is, if we ran an integer in a loop from 0 to 64K-1... how many times would 11111 appear within those numbers.
Extra rule: 1111110000000000 doesn't count, because it has 6 true values in a row, not 5. So:
1111110000000000 = 0x // because its 6 contiguous true bits, not 5.
1111100000000000 = 1x
0111110000000000 = 1x
0011111000000000 = 1x
1111101111100000 = 2x
I'm trying to do some work involving physically-based random-number generation, and detecting "how random" the numbers are. Thats what this is for.
...
This would be easy to solve if N were less than 32 or so, I could just "run a loop" from 0 to 4GB, then count how many contiguous bits were detected once the loop was completed. Then I could store the number and use it later.
Considering that X ranges from 2 to 16, I'd literally only need to store 15 numbers, each less than 32 bits! (if N=32)!
BUT in my case N = 65,536. So I'd need to run a loop, for 2^65,536 iterations. Basically impossible :)
No way to "experimentally calculate the values for a given X, if N = 65,536". So I need maths, basically.
Fix X and N, obiously with X < N. You have 2^N possible values of combinations of 0 and 1 in your bit number, and you have N-X +1 possible sequences of 1*X (in this part I'm only looking for 1's together) contained in you bit number. Consider for example N = 5 and X = 2, this is a possible valid bit number 01011, so fixed the last two characteres (the last two 1's) you have 2^2 possible combinations for that 1*Xsequence. Then you have two cases:
Border case: Your 1*X is in the border, then you have (2^(N -X -1))*2 possible combinations
Inner case: You have (2^(N -X -2))*(N-X-1) possible combinations.
So, the probability is (border + inner )/2^N
Examples:
1)N = 3, X =2, then the proability is 2/2^3
2) N = 4, X = 2, then the probaility is 5/16
A bit brute force, but I'd do something like this to avoid getting mired in statistics theory:
Multiply the probabilities (1 bit = 0.5, 2 bits = 0.5*0.5, etc) while looping
Keep track of each X and when you have the product of X bits, flip it and continue
Start with small example (N = 5, X=1 - 5) to make sure you get edge cases right, compare to brute force approach.
This can probably be expressed as something like Sum (Sum 0.5^x (x = 1 -> 16) (for n = 1 - 65536) , but edge cases need to be taken into account (i.e. 7 bits doesn't fit, discard probability), which gives me a bit of a headache. :-)
#Andrex answer is plain wrong as it counts some combinations several times.
For example consider the case N=3, X=1. Then the combination 101 happens only 1/2^3 times but the border calculation counts it two times: one as the sequence starting with 10 and another time as the sequence ending with 01.
His calculations gives a (1+4)/8 probability whereas there are only 4 unique sequences that have at least a single contiguous 1 (as opposed to cases such as 011):
001
010
100
101
and so the probability is 4/8.
To count the number of unique sequences you need to account for sequences that can appear multiple times. As long as X is smaller than N/2 this will happens. Not sure how you can count them tho.
I am writing a solution for the following problem.
A is a list containing all elements 2^I * 3^Q where I and Q are integers in an ascending order.
Write a function f such that:
f(N) returns A[N]
The first few elements are:
A[0] = 1
A[1] = 2
A[2] = 3
A[3] = 4
A[4] = 6
A[5] = 8
A[6] = 9
A[7] = 12
My solution was to generate a list containing the first 225 elements by double looping in 15 times each, then sorted this list and return A[N]
Is there any way to generate the N'th element of this sequence without creating and sorting a list first?
Here are two approaches that solve your problem without creating such a large list. Each approach has its disadvantages.
First, you could set a counter to 0. Then scan all the integers from 1 on up. For each integer, divide out all the multiples of 2 and of 3 in its factorization. If 1 remains, increment the counter; otherwise, leave the counter unchanged. When the counter reaches N you have found the value of A[N]. For example, you increase the counter for integers 1, 2, 3, and 4, but not for 5. This approach uses very little memory but would take much time.
A second approach uses a min priority queue, such as Python's heapq. Again, set a counter to zero, but also initialize the priority queue to hold only the number 1 and note that the highest power of 3 seen so far is also 1. Increment the counter then peek at the minimum number in the queue. If the counter is N you just got your value of A[N]. Otherwise, pop that min value and immediately push double its value. (The pop and push can be done in one operation in many priority queues.) If that value was a the highest power of 3 seen so far, also push three times its value and note that this new value is now the highest power of 3.
This second approach uses a priority queue that takes some memory but the largest size will only be on the order of the square root of N. I would expect the time to be roughly equal to your sorting the large list, but I am not sure. This approach has the most complicated code and requires you to have a min priority queue.
Your algorithm has the advantage of simplicity and the disadvantage of a large list. In fact, given N it is not at all obvious the maximum powers of 2 and of 3 are, so you would be required to make the list much larger than needed. For example, your case of calculating "the first 225 elements by double looping in 15 times each" actually only works up to N=82.
Below I have Python code for all three approaches. Using timeit for N=200 I got these timings:
1.19 ms for sorting a long list (your approach) (powerof2=powerof3=30)
8.44 s for factoring increasing integers
88 µs for the min priority queue (maximum size of the queue was 17)
The priority queue wins by a large margin--much larger than I expected. Here is the Python 3.6.4 code for all three approaches:
"""A is a list containing all elements 2^I * 3^Q where I and Q are
integers in an ascending order. Write a function f such that
f(N) returns A[N].
Do this without actually building the list A.
Based on the question <https://stackoverflow.com/questions/49615681/
generating-an-item-from-an-ordered-sequence-of-exponentials>
"""
import heapq # min priority queue
def ordered_exponential_0(N, powerof2, powerof3):
"""Return the Nth (zero-based) product of powers of 2 and 3.
This uses the questioner's algorithm
"""
A = [2**p2 * 3**p3 for p2 in range(powerof2) for p3 in range(powerof3)]
A.sort()
return A[N]
def ordered_exponential_1(N):
"""Return the Nth (zero-based) product of powers of 2 and 3.
This uses the algorithm of factoring increasing integers.
"""
i = 0
result = 1
while i < N:
result += 1
num = result
while num % 2 == 0:
num //= 2
while num % 3 == 0:
num //= 3
if num == 1:
i += 1
return result
def ordered_exponential_2(N):
"""Return the Nth (zero-based) product of powers of 2 and 3.
This uses the algorithm using a priority queue.
"""
i = 0
powerproducts = [1] # initialize min priority queue to only 1
highestpowerof3 = 1
while i < N:
powerproduct = powerproducts[0] # next product of powers of 2 & 3
heapq.heapreplace(powerproducts, 2 * powerproduct)
if powerproduct == highestpowerof3:
highestpowerof3 *= 3
heapq.heappush(powerproducts, highestpowerof3)
i += 1
return powerproducts[0]
I have the following data structure:
Scope,Metric ID,Item ID,System,Color
TRUE,A1,123,A,Red
FALSE,A1,123,B,Red
FALSE,B1,234,C,Red
TRUE,B1,234,A,Red
FALSE,B1,415,A,Red
I'd like to group by Scope, filter on TRUE and get the unique list of Items, then count these Items and subtract from a total unique count for the Color = Red.
So, in the example above, I have 3 unique items for Color = Red and I have 2 unique items with Scope = TRUE, so the result should say 3 - 2 = 1.
Because of the data structure, simple filtering won't help. I realize I need to use a complex LOD syntax, but after having tried them for a few hours, I find them rather confusing.
Does anyone have an idea how to write an LOD expression to give me the desired count? Thanks!
Did you try using 3 calculated fields like this:
then doing a count distinct on them.
1:
if [Color]='Red' then [Item ID] end
2:
if [Scope]='TRUE' then [Item ID] end
3 :
subtract the 2 calculated fields i,e 2-1
It gives out 1.
So I need a way to figure out how to get 5 numbers, and when you add any 2 of them, it will result in a sum that you can only get by adding those specific two numbers.
Here's an example of what I'm talking about, but with 3 numbers:
1
3
5
1 + 3 = 4
1 + 5 = 6
3 + 5 = 8
Adding any two of those numbers will end up with a unique sum that cannot be found by adding any other pair of the numbers. I need to do this, but with 5 different numbers. And if you have a method of figuring out how to do this with any amount of numbers, sharing that would be appreciated as well.
Thank you
1, 10, 100, 10000, 100000 gives you five numbers like you desire.
In general, 1, 10, 100, 1000, ..., 10^k where k is the number of numbers that you need.
And even more general, you can say b^0, b^1, ..., b^k, where b >= 2. Note that you have the special property that not only are all the pairwise sums unique, but all the subset sums are unique (just look at representations in base b).
The set {1, 2, 5, 11, 21} also works.
You can start with a set of two or three elements that fit that property (any addition operation on two elements from the set {1,2,5} gives you an unique sum) and only include the next number being considered if additions of current elements and this new element also give you unique sums.
An example run-through:
Suppose our starting set S is S={1,2,5}. Let U be the set of all sums between two elements in S.
Elements in S give us unique sums 1+2=3, 1+5=6, 2+5=7, so U={3,6,7}.
Consider adding 11 to this set. We need to check that 1+11, 2+11, and 5+11 all give us sums that are not seen in U and are all unique among themselves.
1+11=12, 2+11=13, 5+11=17.
Since 12, 13, and 17 are all unique sums among themselves, and are not found in U, we can update S and U to be:
S1 = {1,2,5,11}
U1 = {3,6,7,12,13,17}.
You can do the same procedure for 21, and you should (hopefully) get:
S2 = {1,2,5,11,21}
U2 = {3,6,7,12,13,17,22,23,26,32}.
If all you need is a quick set though, the solution that Jason posted is a lot faster to produce.
1
2
4
8
16
1
3
9
27
81
suggests x ^ n where n is a member of a subset of Natural numbers