I have a original allocated SGL array of structures that contain buffer address and lengths. We need to prepare a temporary SGL array based off original SGL structure array meeting few requirements and later use the temporary SGL array for crypto operations.
Requirement: Ignore the first 8 bytes and last 10 bytes
// Buffer data structure
typedef struct
{
void *data_addr;
int data_len;
}T_BUF_DATA;
Final Array:
T_BUF_DATA final_array[100];
Case1:
Original array: T_BUF_DATA[0] = buf_addr = 0xabc, buf_len = 1
T_BUF_DATA[1] = buf_addr = 0xdef, buf_len = 10
T_BUF_DATA[2] = buf_addr = 0x123, buf_len = 23
final_array[0] = buf_addr =( 0xdef + 7 ), buf_len = ( 10 - 7 ) // since we need to ignore the first 8 bytes from original list, adjust the buf_Addr by offset of 7 bytes
final_array[1] = buf_addr = 0x123, buf_len = ( 23 - 10 ) .. since we need to ignore the last 10 bytes
Case2:
Original array: T_BUF_DATA[0] = buf_addr = 0xabc, buf_len = 100
final_array[0] = buf_addr = ( 0xabc + 8 ), buf_len = 100 - ( 8 + 10 );
We need to implement a generic solution that can handle all the varying buffer length original array structures while preparing the final array. Can someone please assist me here ? I am able to handle the case 2, but stuck on attempting case 1 and any few other unknown corner cases.
void adjust_my_original_buffer ( T_BUF_DATA *data, int num_bufs )
{
T_BUF_DATA final_array[100];
int idx = 0;
for ( int i = 0 ; i < num_bufs; i++ )
{
// prepare the final array
}
}
Something like the following should work. The idea is to skip whole SG entries at the start (keeping track of remaining initial bytes to be skipped in initial_skip) and skip whole SG entries at the end (keeping track of remaining final bytes to be skipped in final_skip) in order to simplify the problem.
After the simplification, there may be 0, 1 or more SG entries remaining, indicated by the adjusted num_bufs, and the adjusted orig points to the first remaining entry. If there is at least one remaining SG entry, the first entry's data_len will be greater than initial_skip and the last entry's data_len will be greater than final_skip. If there is exactly one remaining SG entry, an additional test is required to check that its data_len is greater than initial_skip + final_skip, reducing the number of remaining SG entries to zero if that is not the case.
A loop copies the remaining SG entries from orig to final and the if statements within the loop adjust the first and last SG entries (which might be a single SG entry).
Finally, the function returns the length of the final SG list, which could be 0 if everything was skipped.
int adjust_my_original_buffer ( const T_BUF_DATA * restrict orig, T_BUF_DATA * restrict final, int num_bufs )
{
int initial_skip;
int final_skip;
// Skip initial bytes.
initial_skip = 8;
while ( num_bufs && orig[0].data_len <= initial_skip )
{
initial_skip -= orig[0].data_len;
orig++;
num_bufs--;
}
// Skip final bytes.
final_skip = 10;
while ( num_bufs && orig[num_bufs - 1].data_len <= final_skip )
{
final_skip -= orig[num_bufs - 1].data_len;
num_bufs--;
}
// If single SG entry remaining, check its length.
if ( num_bufs == 1 && data[0].data_len <= initial_skip + final_skip )
{
// Singleton SG entry is too short.
num_bufs = 0;
}
// Copy SG entries to final list, adjusting first and last entry.
for ( int i = 0; i < num_bufs; i++ )
{
final[i] = orig[i]; // Copy SG entry.
if ( i == 0 )
{
// Adjust first SG entry.
final[i].data_addr = (char *)final[i].data_addr + initial_skip;
final[i].data_len -= initial_skip;
}
if ( i == num_bufs - 1 )
{
// Adjust last SG entry.
final[i].data_len -= final_skip;
}
}
return num_bufs;
}
Related
I have a number (for example 301, but can be even 10^11).
n = lenght of that number
I have to break it down to sum of max n components. Those components are 0^n, 1^n, 2^n, 3^n...9^n.
How can I do that?
Since you have 1^n included in your options, this becomes a really simple problem solvable through Greedy Approach.
Firstly, let me clarify that the way I understand this, for an input N of length n, you want some solution to this equation:
A.1^n + B.2^n + C.3^n + ... + H.8^n + I.9^n
There are infinitely many possible solutions (just by theory of equations). One possible solution can be found as follows:
a = [x ** n for x in range(0,10)]
consts = [0] * 10
ctr = 9
while N > 0:
consts[ctr] = N // a[ctr]
N = N % a[ctr]
ctr -= 1
return consts
This consts array will have the constant values for the above equation at respective indices.
PS: I've written this in python but you can translate it to C++ as you want. I saw that tag later. If you have any confusion regarding the code, feel free to ask in the comments.
You could use the following to determine the number of components.
int remain = 301; // Target number
int exp = 3; // Length of number (exponent)
int total = 0; // Number of components
bool first = true; // Used to determinie if plus sign is output
for ( int comp = 9; comp > 0; --comp )
{
int count = 0; // Number of times this component is needed
while ( pow(comp, exp) <= remain )
{
++total; // Count up total number of components
++count; // Count up number of times this component is used
remain -= int(pow(comp, exp));
}
if ( count ) // If count is not zero, component is used
{
if ( first )
{
first = false;
}
else
{
printf(" + ");
}
if ( count > 1 )
{
printf("%d(%d^%d)", count, comp, exp);
}
else
{
printf("%d^%d", comp, exp);
}
}
}
if ( total == exp )
{
printf("\r\nTarget number has %d components", exp);
}
else if ( total < exp )
{
printf("\r\nTarget number has less than %d components", exp);
}
else
{
printf("\r\nTarget number has more than %d components", exp);
}
Output for 301:
6^3 + 4^3 + 2(2^3) + 5(1^3)
Target number has more than 3 components
Output for 251:
6^3 + 3^3 + 2^3
Target number has 3 components
I am writing a program that reads a text document of 200,000 dictionary words. I will compare it with another document of 2,000,000 words to count the lines that are not in the dictionary. I will only be storing alphabetical characters a-z (26 characters). Thus I only need 5 bits to represent each one. The maximum length of a character is 29 (30 including the null character). I will also need to consider later on if the dictionary only contains words that at less than 7 characters.
The conditions for this system are that it has its own custom allocator that I must use. So whenever I use the "new" (or any other sort of heap memory allocation) to dynamically allocate memory, it will use up AT LEAST 32 bytes of memory each time the new keyword is used. To save memory, I would need to initialize larger sizes of char arrays.
I am also not allowed to read the dictionary words in the file directly. They will be provided to me in an array called dictionaryWords and will be destroyed after I am done constructing my hash table. So pointing to the words given to me is not plausible.
The program must run in less than 1 second.
I.E.
Dictionary:
abc
lkas
ddjjsa
dada
Word Doc:
abc
lkas
weee
dada
jajaja
Wrong Numbers List: 3, 5
It will put numbers 3 and 5 into an array for the line numbers in Word Doc that are not in the dictionary.
I am keeping the 200,000 dictionary words in a Hash Table, so lookup from the word document to the hash table is O(n) for n number of words. The problem is that my hash table needs to rehash with a load factor of 0.5, so it must rehash and double its size whenever it is half full. This leaves me with a wasted 200,000 empty hash entries that take up memory. Since the maximum word length is 30, and a char takes 1 byte, it will cost 30 bytes per word in my hash entry. I am wasting 30 characters * 1 byte * 200,000 empty entries = 6000000 bytes / 6MB of memory space in the heap while the program is running. I want to minimize the space usage as much as possible, but be able to run in O(n) time.
This is my hash entry for my hash table. You can see here, for a table size of 200,000 words, I will need 400,000 of these entries to keep a load factor of 0.5
struct HashElement
{
char element[30];
HashElement(char * word)
{
memset(element, '\0', 30); //Set all bits to NULL for collision checking
if (e != NULL)
{
strcpy(element, word);
}
}
};
If I represented each character with only 5 bits, I would be able to save 3/8's of my wasted space.
I have considered the pointer approach for my Hash Entries:
struct HashElement
{
char * element;
HashElement(char * word)
{
element = NULL;
if (e != NULL)
{
element = word;
}
}
};
But using the new keyword will use up AT LEAST 32 bytes for this system. So each time I initialized the hash entry's element, it will cost 32 bytes no matter what the word length size is. If I wanted to diverge this problem to only containing 7 characters per line in the word document, I would be in trouble because I only need 8 bytes for each word, and I am using 32 bytes.
You're working on a hard problem when there are lots of easy problems you need to solve first. Solving all the easy problems will likely be sufficient, so you don't need to work on the hard problem of compacting bits into fewer bytes.
Why allocate 30 bytes just because you might need up to that many?
Why allocate elements for empty hash buckets?
Here a simple string compressor class that will take a string of characters between 'a' and 'z' inclusive and compress each 8 bit representation to 5 bit and splitting the resulting binary, back into 7 bit representations. Since each character is still represented by a unique number the hash of the word should still be as unique as expected:
class StringCompressor
{
public:
static string Compress( string );
static string ToBinary( long long input , int length );
static int ToInt( string input );
static string Decompress( string );
};
string StringCompressor::Compress( string input )
{
stringstream ss;
for ( char c : input )
{
string temp = ToBinary( ( c - 'a' ) , 5 );
ss << temp;
}
ss << string( ( 7 - ( ss.str().length() % 7 ) ) , '0' );
string temp = ss.str();
ss.str( "" );
for ( int i = 0; i < temp.length(); i += 7 )
{
string temp2 = temp.substr( i , 7 );
ss << (char)ToInt( temp2 );
}
return ss.str();
}
string StringCompressor::Decompress( string input )
{
stringstream ss;
for ( char c : input )
{
string temp = ToBinary( c , 7 );
ss << temp;
}
string temp = ss.str().substr( 0 , ss.str().length() - ( ss.str().length() % 5 ) );
ss.str( "" );
for ( int i = 0; i < temp.length(); i += 5 )
{
ss << (char)( ( ToInt( temp.substr( i , 5 ) ) ) + 'a' );
}
return ss.str();
}
string StringCompressor::ToBinary( long long input , int length )
{
string output( length , '0' );
for ( int i = length - 1; i >= 0; i-- )
{
long long test = pow( 2.0 , i );
if ( input >= test )
{
output[( length - 1 ) - i] = '1';
input -= test;
}
}
return output;
}
//Take a string representation of a binary number and return the base10 representation of it.
//There's no validation of the string
int StringCompressor::ToInt( string input )
{
int length = input.length();
int output = 0;
double temp = 0;
for ( int i = 0; i < length; i++ )
{
temp = ( input[( length - 1 ) - i] - '0' );
output += pow( 2.0 , i ) * temp;
}
return output;
}
I can use 2 bits to every 3-states bit to implement it, [00 - first, 10 - second, 11\01 - third], but when the second bit is enabled then the first one is useless. In theory there's implementation that will outperform this method (The 2 bits I mentioned) in size by 37%. (Which is 1-log3(2))
The code I already tried:
#define uint unsigned int
uint set( uint x, uint place, uint value ) {
double result = ( double )x;
result /= pow( 3, place );
result += value - ( ( uint )result ) % 3;
return result * pow( 3, place );
}
uint get( uint x, uint place ) {
return ( ( uint )( ( ( double )x ) / pow( 3, place ) ) ) % 3;
}
int main( ) {
uint s = 0;
for ( int i = 0; i < 20; ++i )
s = set( s, i, i % 3 );
for ( int i = 0; i < 20; ++i )
printf( "get( s, %d ) -> %u\n", i, get( s, i ) );
}
Which prints:
get( s, 0 ) -> 0
get( s, 1 ) -> 1
get( s, 2 ) -> 2
get( s, 3 ) -> 0
...
get( s, 16 ) -> 1
get( s, 17 ) -> 2
get( s, 18 ) -> 0
get( s, 19 ) -> 1
This method saves 20% in size. (1-32/40 - 40 bits is required to do it with the first method I mentioned) In theory when the capacity grows the effectivity grows too. (Towards 37% of course)
How I can implement similar 3-states bitwise method to data of any-size and to maximize size effectivity? If I will use the data as array of uints and use this method on them, I will only get 20% effectivity. (Or lower if the data's size isn't multiplied by 4)
NOTE: The only thing I need is size effectivity, I don't care about speed performance. (Well except if you choose to use BigInteger instead of uint)
log32 is irrelevant.
The maximal possible efficiency for representing 3-valued units is log23 bits per unit, and the compression from 2 bits per unit is (2-log23))/2, which is roughly 20.75%. So 20% is pretty good.
You shouldn't use pow for integer exponentiation; aside from being slow, it is sometimes off by 1ULP which can be enough to make it off by 1 once you coerce it to an integer. But there's no need for all that work either; you can compress five 3-state values into a byte (35 = 243 < 256), and its straightforward to build a lookup table with 256 entries, one for each possible byte value.
With the LUT, you can extract a 3-state value from a large vector:
/* All error checking omitted */
uint8_t LUT[243][5] = { {0,0,0,0,0}, {1,0,0,0,0}, ... };
uint8_t extract(const uint8_t* data, int offset) {
return LUT[data[offset/5]][offset%5];
}
By the way, if a 1215-byte lookup-table is to be considered "big" (which seems odd, given that you're talking about a data vector of 1GB), it's easy enough to compress it by a factor of 4, although it complicates the table construction
/* All error checking omitted */
uint8_t LUT[] = { /* Left as an exercise */ };
uint8_t extract(const uint8_t* data, unsigned offset) {
unsigned index = data[offset/5] * 5 + offset % 5;
return (LUT[index / 4] >> (2 * (index % 4))) & 3;
}
In additional to rici's answer I want to post the code I did, which can help too: (simplified one)
uint8_t ft[ 5 ] = { 1, 3, 3 * 3, 3 * 3 * 3, 3 * 3 * 3 * 3 };
void set( uint8_t *data, int offset, int value ) {
uint8_t t1 = data[ offset / 5 ], t2 = ft[ offset % 5 ], u8 = t1 / t2;
u8 += value - u8 % 3;
data[ offset / 5 ] = t1 + ( u8 - t1 / t2 )*t2;
}
uint8_t get( uint8_t *data, int offset ) {
return data[ offset / 5 ] / ft[ offset % 5 ] % 3;
}
Instead of the big look up table, I re-implemented the pow method just safer and faster one, and added set function too.
I want to uniform distribute traffic to various nodes depending on the configuration of each node.There can be max 100 nodes and percentage of traffic to be distributed to multiple nodes
can be configured .
So say,if there are 4 nodes :-
node 1 - 20
node 2 - 50
node 3 - 10
node 4 - 20
------------
sum - 100
------------
Sum of value of all nodes should be 100.
Example :-
node 1 - 50
node 2 - 1
node 3 - 1
node 4 - 1
.
.
.
node 100 - 1
In above configuration there are total 51 nodes. node 1 is 50 and rest 50 nodes are configured to 1.
In one senario , request can be distributed in below pattern :-
node1,node2,node3,node4,node5,....,node51,node1,node1,node1,node1,node1,node1,node1,......
Above distribution is inefficient because we are sending too much traffic continously to node1,
which may result in rejection of request by node1.
In another senario , request can be distributed in below pattern :-
node1,node2,node1,node3,node1,node4,node1,node5,node1,node6,node1,node7,node1,node8......
In above senario request is dributed more effciently.
I have found below code but not able to understand the idea behind it.
func()
{
for(int itr=1;itr<=total_requests+1;itr++)
{
myval = 0;
// Search the node that needs to be incremented
// to best approach the rates of all branches
for(int j=0;j<Total_nodes;j++)
{
if((nodes[j].count*100/itr > nodes[j].value) ||
((nodes[j].value - nodes[j].count*100/itr) < myval) ||
((nodes[j].value==0 && nodes[j].count ==0 )))
continue;
cand = j;
myval = abs((long)(nodes[j].count*100/itr - nodes[j].value));
}
nodes[cand].count++;
}
return nodes[cand].nodeID;
}
In above code , total_requests is total number of request received till now.
total_requests variable will be incremented everytime , consider it as a global value for understanding purpose.
Total_nodes , is the total number of nodes configured and each node is represented using following structure.
nodes is a struct :-
struct node{
int count;
int value;
int nodeID;
};
For example :-
If 4 nodes are configured :-
node 1 - 20
node 2 - 50
node 3 - 10
node 4 - 20
------------
sum - 100
------------
There will four nodes[4] created with following values:-
node1{
count = 0;
value = 20;
nodeID = 1;
};
node2{
count = 0;
value = 50;
nodeID = 2;
};
node3{
count = 0;
value = 10;
nodeID = 3;
};
node4{
count = 0;
value = 20;
nodeID = 4;
};
Could you please explain me the algorithm or idea of how it is actually distributing it efficiently.
nodes[j].count*100/itr is the floor of the percentage of requests that node j has answered so far. nodes[j].value is the percentage of requests that node j should answer. The code that you posted looks for the node lagging the furthest behind its target percentage (more or less, subject to the wobbliness of integer division) and assigns it the next request.
Hmmm. Seems that as you reach 100 nodes they must each take 1% of the traffic ?
I honestly have no idea what the function you provide is doing. I assume it's trying to find the node which is furthest from its long-term average load. But if total_requests is the total to date, then I don't get what the outer for(int itr=1;itr<=total_requests+1;itr++) loop is doing, unless that's actually part of some test to show how it distributes load ?
Anyway, basically what you are doing is similar to constucting a non-uniform random sequence. With up to 100 nodes, if I can assume (for a moment) that 0..999 gives sufficient resolution, then you could use an "id_vector[]" with 1000 node-ids, which is filled with n1 copies of node-1's ID, n2 copies of node-2's ID, and so on -- where node-1 is to receive n1/1000 of the traffic, and so on. The decision process is then very, very simple -- pick id_vector[random() % 1000]. Over time, the nodes will receive about the right amount of traffic.
If you are unhappy with randomly distributing traffic, then you seed the id_vector with node-ids so that you can select by "round-robin" and get a suitable frequency for each node. One way to do that would be to randomly shuffle the id_vector constructed as above (and, perhaps, reshuffle occasionally, so that if one shuffle is "bad", you aren't stuck with it). Or you could do a one-time leaky-bucket thing and fill the id_vector from that. Each time around the id_vector this guarantees each node will receive its allotted number of requests.
The finer grain you make the id_vector, the better control you get over the short term frequency of requests to each node.
Mind you, all the above rather assumes that the relative load for the nodes is constant. If not, then you would need to (very now and then ?) adjust the id_vector.
Edit to add more detail as requested...
...suppose we have just 5 nodes, but we express the "weight" of each one as n/1000, to allow for up to 100 nodes. Suppose they have IDs 1..5, and weights:
ID=1, weight = 100
ID=2, weight = 375
ID=3, weight = 225
ID=4, weight = 195
ID=5, weight = 105
Which, obviously, add up to 1000.
So we construct an id_vector[1000] so that:
id_vector[ 0.. 99] = 1 -- first 100 entries = ID 1
id_vector[100..474] = 2 -- next 375 entries = ID 2
id_vector[475..699] = 3 -- next 225 entries = ID 3
id_vector[700..894] = 4 -- next 195 entries = ID 4
id_vector[100..999] = 5 -- last 105 entries = ID 5
And now if we shuffle id_vector[] we get a random sequence of node selections, but over 1000 requests, the right average frequency of requests to each node.
For the amusement value I had a go at a "leaky bucket" to see how well it could maintain a steady frequency of requests to each node, by filling the id_vector using one leaky bucket for each node. The code to do this, and see how well it does, and how well the simple random version does, is enclosed below.
Each leaky bucket has a cc count of the number of requests that should be sent (to other nodes) before the next request is sent to this one. Each time a request is dispatched, all buckets have their cc count decremented, and the node whose bucket has the smallest cc (or smallest id, if the cc are equal) is sent the request, and at that point the node's bucket's cc is recharged. (Each request causes all the buckets to drip once, and the bucket for the chosen node is recharged.)
The cc is the integer part of the bucket's "contents". The initial value for cc is q = 1000 / w, where w is the node's weight. And each time the bucket is recharged, q is added to cc. To do things precisely, however, we need to deal with the remainder r = 1000 % w... or to put it another way, the "contents" have a fractional part -- which is is where cr comes in. The true value of the contents is cc + cr/w (where cr/w is a true fraction, not an integer division). The initial value of that is cc = q and cr = r. Each time the bucket is recharged, q is added to cc, and r is added to cr. When cr/w >= 1/2, we round up, so cc +=1, and cr -= w (adding one to the integer part is balanced by subtracting 1 -- ie w/w -- from the fractional part). To test for cr/w >= 1/2, the code actually tests (cr * 2) >= w. Hopefully the bucket_recharge() function will make sense (now).
The leaky-bucket is run 1000 times to fill the id_vector[]. The little bit of testing shows that this maintains a pretty steady frequency for all nodes, and an exact number of packets per node every time around the id_vector[] cycle.
The little bit of testing shows that the random() shuffle approach has much more variable frequency, within each id_vector[] cycle, but still provides an exact number of packets per node for each cycle.
The steadyness of the leaky bucket assumes a steady stream of incoming requests. Which may be an entirely unrealistic assumption. If the requests arrive in large (large compared to the id_vector[] cycle, 1000 in this example) bursts, then the variability of the (simple) random() shuffle approach may be dwarfed by the variability in request arrival !
enum
{
n_nodes = 5, /* number of nodes */
w_res = 1000, /* weight resolution */
} ;
struct node_bucket
{
int id ; /* 1 origin */
int cc ; /* current count */
int cr ; /* current remainder */
int q ; /* recharge -- quotient */
int r ; /* recharge -- remainder */
int w ; /* weight */
} ;
static void bucket_recharge(struct node_bucket* b) ;
static void node_checkout(int weights[], int id_vector[], bool rnd) ;
static void node_shuffle(int id_vector[]) ;
/*------------------------------------------------------------------------------
* To begin at the beginning...
*/
int
main(int argc, char* argv[])
{
int node_weights[n_nodes] = { 100, 375, 225, 195, 105 } ;
int id_vector[w_res] ;
int cx ;
struct node_bucket buckets[n_nodes] ;
/* Initialise the buckets -- charged
*/
cx = 0 ;
for (int id = 0 ; id < n_nodes ; ++id)
{
struct node_bucket* b ;
b = &buckets[id] ;
b->id = id + 1 ; /* 1 origin */
b->w = node_weights[id] ;
cx += b->w ;
b->q = w_res / b->w ;
b->r = w_res % b->w ;
b->cc = 0 ;
b->cr = 0 ;
bucket_recharge(b) ;
} ;
assert(cx == w_res) ;
/* Run the buckets for one cycle to fill the id_vector
*/
for (int i = 0 ; i < w_res ; ++i)
{
int id ;
id = 0 ;
buckets[id].cc -= 1 ; /* drip */
for (int jd = 1 ; jd < n_nodes ; ++jd)
{
buckets[jd].cc -= 1 ; /* drip */
if (buckets[jd].cc < buckets[id].cc)
id = jd ;
} ;
id_vector[i] = id + 1 ; /* '1' origin */
bucket_recharge(&buckets[id]) ;
} ;
/* Diagnostics and checking
*
* First, check that the id_vector contains exactly the right number of
* each node, and that the bucket state at the end is the same (apart from
* cr) as it is at the beginning.
*/
int nf[n_nodes] = { 0 } ;
for (int i = 0 ; i < w_res ; ++i)
nf[id_vector[i] - 1] += 1 ;
for (int id = 0 ; id < n_nodes ; ++id)
{
struct node_bucket* b ;
b = &buckets[id] ;
printf("ID=%2d weight=%3d freq=%3d (cc=%3d cr=%+4d q=%3d r=%3d)\n",
b->id, b->w, nf[id], b->cc, b->cr, b->q, b->r) ;
} ;
node_checkout(node_weights, id_vector, false /* not random */) ;
/* Try the random version -- with shuffled id_vector.
*/
int iv ;
iv = 0 ;
for (int id = 0 ; id < n_nodes ; ++id)
{
for (int i = 0 ; i < node_weights[id] ; ++i)
id_vector[iv++] = id + 1 ;
} ;
assert(iv == 1000) ;
for (int s = 0 ; s < 17 ; ++s)
node_shuffle(id_vector) ;
node_checkout(node_weights, id_vector, true /* random */) ;
return 0 ;
} ;
static void
bucket_recharge(struct node_bucket* b)
{
b->cc += b->q ;
b->cr += b->r ;
if ((b->cr * 2) >= b->w)
{
b->cc += 1 ;
b->cr -= b->w ;
} ;
} ;
static void
node_checkout(int weights[], int id_vector[], bool rnd)
{
struct node_test
{
int last_t ;
int count ;
int cycle_count ;
int intervals[w_res] ;
} ;
struct node_test tests[n_nodes] = { { 0 } } ;
printf("\n---Test Run: %s ---\n", rnd ? "Random Shuffle" : "Leaky Bucket") ;
/* Test run
*/
int s ;
s = 0 ;
for (int t = 1 ; t <= (w_res * 5) ; ++t)
{
int id ;
id = id_vector[s++] - 1 ;
if (tests[id].last_t != 0)
tests[id].intervals[t - tests[id].last_t] += 1 ;
tests[id].count += 1 ;
tests[id].last_t = t ;
if (s == w_res)
{
printf("At time %4d\n", t) ;
for (id = 0 ; id < n_nodes ; ++id)
{
struct node_test* nt ;
long total_intervals ;
nt = &tests[id] ;
total_intervals = 0 ;
for (int i = 0 ; i < w_res ; ++i)
total_intervals += (long)i * nt->intervals[i] ;
printf(" ID=%2d weight=%3d count=%4d(+%3d) av=%6.2f vs %6.2f\n",
id+1, weights[id], nt->count, nt->count - nt->cycle_count,
(double)total_intervals / nt->count,
(double)w_res / weights[id]) ;
nt->cycle_count = nt->count ;
for (int i = 0 ; i < w_res ; ++i)
{
if (nt->intervals[i] != 0)
{
int h ;
printf(" %6d x %4d ", i, nt->intervals[i]) ;
h = ((nt->intervals[i] * 75) + ((nt->count + 1) / 2))/
nt->count ;
while (h-- != 0)
printf("=") ;
printf("\n") ;
} ;
} ;
} ;
if (rnd)
node_shuffle(id_vector) ;
s = 0 ;
} ;
} ;
} ;
static void
node_shuffle(int id_vector[])
{
for (int iv = 0 ; iv < (w_res - 1) ; ++iv)
{
int is, s ;
is = (int)(random() % (w_res - iv)) + iv ;
s = id_vector[iv] ;
id_vector[iv] = id_vector[is] ;
id_vector[is] = s ;
} ;
} ;
There are n groups of friends staying in the queue in front of bus station. The i-th group consists of ai men. Also, there is a single bus that works on the route. The size of the bus is x, that is it can transport x men simultaneously.
When the bus comes (it always comes empty) to the bus station, several groups from the head of the queue goes into the bus. Of course, groups of friends don't want to split, so they go to the bus only if the bus can hold the whole group. In the other hand, none wants to lose his position, that is the order of groups never changes.
The question is: how to choose the size x of the bus in such a way that the bus can transport all the groups and everytime when the bus moves off the bus station there is no empty space in the bus (the total number of men inside equals to x)?
Input Format:
The first line contains the only integer n (1≤n≤10^5). The second line contains n space-separated integers a1,a2,…,an (1≤ai≤10^4).
Output Format:
Print all the possible sizes of the bus in the increasing order.
Sample:
8
1 2 1 1 1 2 1 3
Output:
3 4 6 12
I made this code:
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int main(void)
{
int max=0,sum=0,i,n;
cin>>n;
int values[100000];
for ( i = 0; i < n; i++ )
{
cin>>values[i];
sum = sum + values[i];
if ( values[i] > max )
max = values[i];
}
int p = 0,j;
int count = 0;
vector<int> final;
for ( i = 0; i < n; i++ )
{
p = p + values[i];
j = 0;
if ( p >= max && sum%p == 0)
{
flag = 0;
while ( j < n )
{
garb = p;
while (garb!= 0)
{
garb = garb - values[j++];
if ( garb < 0 )
flag = 1;
}
}
if ( flag == 0 )
{
final.push_back(p);
count++;
}
}
}
sort(final.begin(),final.end());
for ( j = 0; j < count; j++ )
{
cout<<final[j]<<"\t";
}
return 0;
}
Edit: I did this in which basically, I am checking if the found divisor satisfies the condition, and if at any point of time, I get a negative integer on taking difference with the values, I mark it by using a flag. However, it seems to give me a seg fault now. Why?
I firstly, calculated the maximum value out of the all possible values, and then, I checked if its a divisor of the sum of the values. However, this approach doesn't work for the input as:
10
2 2 1 1 1 1 1 2 1 2
My output is
2 7 14
whereas the output should be
7 14
only.
Any other approach that I can go with?
Thanks!
I can think of the following simple solution (since your present concern is correctness and not time complexity):
Calculate the sum of all ai's (as you are already doing).
Calculate the maximum of all ai's (as you are already doing).
Find all the factors of sum that are > max(ai).
For each factor, iterate through the ai's and check whether the bus condition is satisfied.