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 8 days ago.
Improve this question
Could you pls. help with algorithm (I use C++) which seemed so simple at first glance.
I need a total enumeration of all combinations of N parameters to run some target function for all combination and choose one optimal combination.
Let say there are three parameters (it can be any number set by user but for this example let’s assume 3)
Possible values (can be any number for any parameter - NOT a fixed number - number of values set a user before program starts)
name
value
value
value
value
param1
1
2
..
param2
10
20
..
param3
100
200
300
..
So the number of combinations = 12 (2 * 2 * 3 = 12)
All combinations
#
param1
param2
param3
1
1
10
100
2
2
10
100
3
1
20
100
4
2
20
100
5
1
10
200
6
2
10
200
7
1
20
200
8
2
20
200
9
1
10
300
10
2
10
300
11
1
20
300
12
2
20
300
Ok – let say the order may be different
#
param1
param2
param3
1
1
10
100
2
1
20
100
3
1
10
200
4
1
20
200
5
1
10
300
6
1
20
300
7
2
10
100
8
2
20
100
9
2
10
200
10
2
20
200
11
2
10
300
12
2
20
300
However it’s obviously one counter should change while others fixed and after one counter finish increment next in the chain
This approach seems quite simple but I still can’t find an implementation. I thought use a list for the parameters and as one counter finish itereates it's values it call the next parameter and increment next parameter value and reset the first parameter counter. But how put it in couple of loops … ? I intuitively feels it should be quite simple solution.
The another approach I think – use all combinations to build a graph and after that traverse the whole graph and in the end get an optimal combination. But if I fill the graph it means I already solve this problem and building a graph just a waste of time and memory.
For now there is a sketch (in pseudo-code) like this:
std::list<param> params
bool isDone = false
func(node* n)
{
if(n->prev)
{
n->GetCurrentValue() // return current value and increment by one
n->prev->reset();
func(n->prev)
Run(); // target function
if(n->IsDone()) // finish end of the values
{
if(n->next)
func(n->next);
else
isDone = true;
}
}
else // first node in the list
{
while(n->IsDone()) // finish end of the values
{
n->GetCurrentValue() // return current value and increment by one
Run() // target function
}
n.reset() // set internal counter for the node to 0
func(n->next())
}
}
while(!isDone)
{
for(p : params)
{
func(p)
}
}
I think the best way to show the problem is with an example. Column A is what i have now, and column B is what I would want.
A
B
1
1
1
1
2
2
2
2
5
3
5
3
5
3
8
4
8
4
9
5
9
5
14
6
14
6
17
7
17
7
17
7
Update: Based on your comment, use this formula
=ArrayFormula(IF(ISNUMBER(A1:A), VLOOKUP(A1:A, {UNIQUE(A1:A), ArrayFormula(RANK(UNIQUE(A1:A), UNIQUE(A1:A), 1))}, 2, 0), ""))
Previous answer: Have you already used the SORT formula?
Try =SORT(A1:A, 1, 1) in cell B1
Assuming your data starts at row 2 through row 10 column A. In B2 :
=arrayformula(1/COUNTIF($A$2:$A$10,$A$2:$A$10))
in C2
=sumproduct(($B$1:$B1)*($A$1:$A1<A2))+1
Let's assume I have an array of years.
int year[20];
The plan is to make an if condition and work with a segment of the months in the year vector.
The segment I want to work with is from September to February. Therefore the range of year I always want to pick is (year >=9 && year <3)
Therefore I have two vectors. One is for the year, and another one is for that I count to count the entry.
For example:
vector <int> year{1,2,3,5,10,2,10,12,11,12,2,2,3,5,8,2,8,12,8,12};
vector <int> list{1,2,3,2,1,1,2,3,2,1,5,3,2,5,6,5,3,2,5,6};
the size of both the above vectors is 20. What I want to do is to count the vector entry from list in each year segment I'm looking into.
If we look at both vectors above, the first month segment in year vector would be:
from year[0] =1 to year[1] =2. and the count is 2.
The next segment would be: from year[4] =10 to year[5] =2. So the print out entries would be from the vector list: list[4]=1, and list[5] =1. and the total count is 2.
After the segment work is done I want to reassign the count to zero to start it again and iterate through out the whole vector of year.
Here is the some work I did. My problem is that, I can make the segment in the if statement, but I'm trying to assign the count =0 each time each year segment is complete.
#include <iostream>
#include <string>
#include <cstdlib>
#include <vector>
using namespace std;
int main()
{
unsigned int count =0;
vector <int> year{1,2,3,5,10,2,10,12,11,12,2,2,3,5,8,2,8,12,8,12};
vector <int> list;
for (int x =0; x<20; x++)
{
//cout << "random number" << (1+ rand()%12)<< endl;
list.push_back((1+ rand()%4));
}
for (int j=0; j<=20; j++)
{
if (year[j] >=9 && year[j]<3)
{
count++;
cout <<list[j]<< "counting the entry of each segment"<< count<<endl;
}
}
}
The way I want to select the segment if the entries in the vector year for example, 1= January, 2 = February satisfies the September to February conditions. So each segment would be greater or equal to 9 and less than 3.
As I increment to the vector year, I find a segment that satisfies the condition and goes to the next segment that satisfies the condition again.
Each time I' done with the operation in if condition with each segment, I want to assign the count =0, so I can recount how many entries in the next segment.
Since the month goes like in ascending order, from the example {11, 10}
will count as 1 with two segments instead of two. The segments will be {11}, and {10}, instead of {11, 10} where it counts the elements entry =2.
I propose to look at (year[j]+9)%12 instead of directly at year[j].
Everything >= 6 is in your range (6,7,8,9,10,11) , i.e. the unwanted other 6 months (0,1,2,3,4,5) are outside. That also makes detecting the start of a new segment much easier.
year[j] (year[j]+9)%12 wanted
1 10 x
2 11 x
3 0
4 1
5 2
6 3
7 4
8 5
9 6 x
10 7 x
11 8 x
12 9 x
The values in your vector become:
wanted reset
1 10 x
2 11 x
3 0 r
5 2
10 7 x
2 11 x
10 7 x r
12 9 x
11 8 x r
12 9 x
2 11 x
2 11 x
3 0 r
5 2
8 5
2 10 x
8 5 r
12 9 x
8 5 r
12 9 x
This shows where you want to reset the count and start working on a new segment, which is whenever (year[j]+9)%12 is not greater than at previous index.
The formula (year[j]+9)%12 works by shifting the "virtual month" you are looking at, by using the +9 part and making sure that the result still is in the 0-11 range for twelve months, by the %12 part. I.e. that "1" (seen as "10") is seen higher than "12" (seen as "9"). So that going from 12 (9) to 1 (10) does not trigger the reset, but going from 2 (11) to 3 (0) does trigger the reset, because the segment obviously ended. Also going from , 2 (11) to 10 (7), triggers the reset; which is needed, because (3-8) occur in between and hence a new segment needs to be started, even though 10 is higher than 2.
I'm trying to solve programming question, a term called "FiPrima". The "FiPrima" number is the sum of prime numbers before, until the intended prime tribe.
INPUT FORMAT
The first line is an integer number n. Then followed by an integer number x for n times.
OUTPUT FORMAT
Output n number of rows. Each row must contain the xth "FiPrima" number of each line.
INPUT EXAMPLE
5
1 2 3 4 5
OUTPUT EXAMPLE
2
5
10
17
28
EXPLANATION
The first 5 prime numbers in order are 2, 3, 5, 7 and 13.
So:
The 1st FiPrima number is 2 (2)
The 2nd FiPrima number is 5 (2 + 3)
The 3rd FiPrima number is 10 (2 + 3 + 5)
The 4th FiPrima number is 17 (2 + 3 + 5 + 7)
The 5th FiPrima number is 28 (2 + 3 + 5 + 7 + 13)
CONSTRAINTS
1 ≤ n ≤ 100
1 ≤ x ≤ 100
Can anyone create the code ?
I have a tricky question about conditional sum in SAS. Actually, it is very complicated for me and therefore, I cannot explain it by words. Therefore I want to show an example:
A B
5 3
7 2
8 6
6 4
9 5
8 2
3 1
4 3
As you can see, I have a datasheet that has two columns. First of all, I calculated the conditional cumulative sum of column A ( I can do it by myself-So no need help for that step):
A B CA
5 3 5
7 2 12
8 6 18
6 4 8 ((12+8)-18)+6
9 5 17
8 2 18
3 1 10 (((17+8)-18)+3
4 3 14
So my condition value is 18. If the cumulative more than 18, then it equal 18 and next value if sum of the first value after 18 and exceeds amount over 18. ( As I said I can do it by myself )
So the tricky part is I have to calculate the cumulative sum of column B according to column A:
A B CA CB
5 3 5 3
7 2 12 5
8 6 18 9.5 (5+(6*((18-12)/8)))
6 4 8 5.5 ((5+6)-9.5)+4
9 5 17 10.5 (5.5+5)
8 2 18 10.75 (10.5+(2*((18-7)/8)))
3 1 10 2.75 ((10.5+2)-10.75)+1
4 3 14 5.75 (2.75+3)
As you can see from example the cumulative sum of column B is very specific. When column CA is equal to our condition value (18), then we calculate the proportion of the last value for getting our condition value (18) and then use this proportion for computing cumulative sum of column B.
Looks like when the sum of A reaches 18 or more you want to split the values of A and B between the current and the next record. One way is to remember the left over values for A and B and carry them forward in your new cumulative variables. Just make sure to output the observation before resetting those variables.
data want ;
set have ;
ca+a;
cb+b;
if ca >= 18 then do;
extra_a=ca - 18;
extra_b=b - b*((a - extra_a)/a) ;
ca=18;
cb=cb-extra_b ;
end;
output;
if ca=18 then do;
ca=extra_a;
cb=extra_b;
end;
drop extra_a extra_b ;
run;