we have a 16 player league and a 15 week round robin schedule. Each player plays against each other (round robin)once.
I want to see if each member can play in the same foursome with another player exactly 3 times.
Every round robin program I've run ends up with some players playing with each other 5 times and others only once.
is there a way for this to work so within the round robin format all players play in the same foursome exactly 3 times.
thanks
Here's how I would tackle this problem in C++. This is a simple program that randomizes teams into leagues, and then generates a randomized schedule where every team plays three other teams an even amount of times. You could further customize it however you wanted.
#include <vector>
#include <string>
std::vector<std::string> createSchedule(std::vector<std::string> teams, int numberOfGames)
{
//Create the randomized schedule
std::vector<std::string> schedule;
int counter = 0;
for (int i = 0; i < numberOfGames; i++) {
std::string game1;
std::string game2;
if (counter == 0) {
game1 = teams[0] + " vs " + teams[1];
game2 = teams[2] + " vs " + teams[3];
}
else if (counter == 1) {
game1 = teams[0] + " vs " + teams[2];
game2 = teams[1] + " vs " + teams[3];
}
else if (counter == 2) {
game1 = teams[0] + " vs " + teams[3];
game2 = teams[1] + " vs " + teams[2];
}
schedule.push_back(game1);
schedule.push_back(game2);
if (counter == 2) {
counter = 0;
}
else {
counter++;
}
}
return schedule;
}
int main()
{
std::vector<std::string> teams = { "Team1", "Team 2", "Team 3", "Team 4", "Team 5", "Team 6", "Team 7", "Team 8", "Team 9", "Team 10", "Team 11", "Team 12", "Team 13", "Team 14", "Team 15", "Team 16" };
std::vector<std::string> group1;
std::vector<std::string> group2;
std::vector<std::string> group3;
std::vector<std::string> group4;
//randomize teams into groups
for (int i = 0; i < teams.size(); i++) {
int num = rand() % 15;
if (num >= 0 && num < 4 && group1.size() < 4) {
group1.push_back(teams[i]);
}
else if (num >= 4 && num < 8 && group2.size() < 4) {
group2.push_back(teams[i]);
}
else if (num >= 8 && num < 12 && group3.size() < 4) {
group3.push_back(teams[i]);
}
else if (num >= 12 && num < 16 && group4.size() < 4) {
group4.push_back(teams[i]);
}
else {
if (group1.size() < 4) {
group1.push_back(teams[i]);
}
else if (group2.size() < 4) {
group2.push_back(teams[i]);
}
else if (group3.size() < 4) {
group3.push_back(teams[i]);
}
else if (group4.size() < 4) {
group4.push_back(teams[i]);
}
}
}
//Create a schedule of 15 games for each group
std::vector<std::string> schedule1 = createSchedule(group1, 15);
std::vector<std::string> schedule2 = createSchedule(group2, 15);
std::vector<std::string> schedule3 = createSchedule(group3, 15);
std::vector<std::string> schedule4 = createSchedule(group4, 15);
//Combine them into one big master schedule group by each set of games
//The first 8 games would be the first week of games for the whole league, etc...
std::vector<std::string> masterSchedule;
for (int i = 0; i < schedule1.size(); i += 2) {
masterSchedule.push_back(schedule1[i]);
masterSchedule.push_back(schedule1[i + 1]);
masterSchedule.push_back(schedule2[i]);
masterSchedule.push_back(schedule2[i + 1]);
masterSchedule.push_back(schedule3[i]);
masterSchedule.push_back(schedule3[i + 1]);
masterSchedule.push_back(schedule4[i]);
masterSchedule.push_back(schedule4[i + 1]);
}
return 0;
}
I think you might be looking for a Whist design. Go here and click on 'Whist' and '16 items'. Tables become foursomes, the pairs are games of your round-robin. The same 15 round schedule is repeated below.
[(16 1) ( 9 14)] [( 2 4) ( 5 8)] [( 3 10) (12 13)] [( 6 15) ( 7 11)]
[(16 2) (10 15)] [( 3 5) ( 6 9)] [( 4 11) (13 14)] [( 7 1) ( 8 12)]
[(16 3) (11 1)] [( 4 6) ( 7 10)] [( 5 12) (14 15)] [( 8 2) ( 9 13)]
[(16 4) (12 2)] [( 5 7) ( 8 11)] [( 6 13) (15 1)] [( 9 3) (10 14)]
[(16 5) (13 3)] [( 6 8) ( 9 12)] [( 7 14) ( 1 2)] [(10 4) (11 15)]
[(16 6) (14 4)] [( 7 9) (10 13)] [( 8 15) ( 2 3)] [(11 5) (12 1)]
[(16 7) (15 5)] [( 8 10) (11 14)] [( 9 1) ( 3 4)] [(12 6) (13 2)]
[(16 8) ( 1 6)] [( 9 11) (12 15)] [(10 2) ( 4 5)] [(13 7) (14 3)]
[(16 9) ( 2 7)] [(10 12) (13 1)] [(11 3) ( 5 6)] [(14 8) (15 4)]
[(16 10) ( 3 8)] [(11 13) (14 2)] [(12 4) ( 6 7)] [(15 9) ( 1 5)]
[(16 11) ( 4 9)] [(12 14) (15 3)] [(13 5) ( 7 8)] [( 1 10) ( 2 6)]
[(16 12) ( 5 10)] [(13 15) ( 1 4)] [(14 6) ( 8 9)] [( 2 11) ( 3 7)]
[(16 13) ( 6 11)] [(14 1) ( 2 5)] [(15 7) ( 9 10)] [( 3 12) ( 4 8)]
[(16 14) ( 7 12)] [(15 2) ( 3 6)] [( 1 8) (10 11)] [( 4 13) ( 5 9)]
[(16 15) ( 8 13)] [( 1 3) ( 4 7)] [( 2 9) (11 12)] [( 5 14) ( 6 10)]
Related
I have an img in binary format format.
Each pixel is 10bit.
They are putted consecutively, like [9-2] in first byte and [1:0] in second byte.
Where 9 IS MSB bit, 0 - LSB.
How to convert them to 16bit array?
E.g:
Store like 8 bit:
0b10000011,
0b10101100,
0b10011001,
0b11000000,
0b10101000,
Actual data which contains real pixels and which I want convert to 16bit:
0b1000001110,
0b1011001001,
0b1001110000,
0b0010101000,
It seems you want to convert data like this
img[0] = AAAAAAAA
img[1] = AABBBBBB
img[2] = BBBBCCCC
img[3] = CCCCCCDD
img[4] = DDDDDDDD
to data like this:
array[0] = 000000AAAAAAAAAA
array[1] = 000000BBBBBBBBBB
array[2] = 000000CCCCCCCCCC
array[3] = 000000DDDDDDDDDD
It can be done like this:
array[0] = ((img[0] << 2) | (img[1] >> 6)) & 0x3ff;
array[1] = ((img[1] << 4) | (img[2] >> 4)) & 0x3ff;
array[2] = ((img[2] << 6) | (img[3] >> 2)) & 0x3ff;
array[3] = ((img[3] << 8) | img[4] ) & 0x3ff;
To convert multiple blocks, for loop is useful like this:
for (int i = 0; (i + 1) * 5 <= num_of_bytes_in_img; i++) {
array[i * 4 + 0] = ((img[i * 5 + 0] << 2) | (img[i * 5 + 1] >> 6)) & 0x3ff;
array[i * 4 + 1] = ((img[i * 5 + 1] << 4) | (img[i * 5 + 2] >> 4)) & 0x3ff;
array[i * 4 + 2] = ((img[i * 5 + 2] << 6) | (img[i * 5 + 3] >> 2)) & 0x3ff;
array[i * 4 + 3] = ((img[i * 5 + 3] << 8) | img[i * 5 + 4] ) & 0x3ff;
}
(this loop won't convert last a few bytes, so you should treat them separately or add padding to img not to read out-of-range while using this loop to end of the image)
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 4 years ago.
Improve this question
I have the following equation :
8 ? 7 ? 6 ? 5 ? 4 ? 3 ? 2 ? 1 = 36 and I need to make a C program that finds which operators ( from +, -, *, /) go instead of ? in order to make the equation true.
My initial thought is that I have 4*7=28 different combinations. So I started making arrays adding first all + then reduce the number of + by 1 and add another symbol and see if the equation is true. But I'm confused about the direction I took.
Also I haven't found anything similar in my many google searches, so this is my last resort.
Thanks!
What a nice puzzle...
Here is my solution (which became smaller as I myself expected).
findOps.c:
#include <assert.h>
#include <stdio.h>
/* too lazy to type this everytimes out... */
typedef unsigned int uint;
/* enumeration of all supported operators */
enum {
Add, Sub, Mul, Div
};
/* It is also used as encoding for compact storage with 2 bits. */
/* extracts operator i from ops. */
uint getOp(uint ops, uint i) { return (ops >> 2 * i) & 3; }
/* solves the equation with nValue values and (nValue - 1) ops
* and returns the result.
* This considers operator precedences appropriately.
*/
int solve(uint nValues, int values[], uint ops)
{
int sum = 0; /* accu for add, subtract */
int prod = values[0]; /* accu for multiply, divide */
for (int i = 1; i < nValues; ++i) {
int arg2 = values[i];
switch (getOp(ops, i - 1)) {
case Add:
sum += prod;
prod = arg2;
break;
case Sub:
sum += prod;
prod = -arg2;
break;
case Mul:
prod *= arg2;
break;
case Div:
prod /= arg2;
break;
}
}
sum += prod;
return sum;
}
/* pretty prints the equation out of internal representation. */
void print(uint nValues, int values[], uint ops, int result)
{
char chrOp[4] = { '+', '-', '*', '/' };
printf("%d", values[0]);
for (uint i = 1; i < nValues; ++i) {
printf(" %c %d", chrOp[getOp(ops, i - 1)], values[i]);
}
printf(" == %d\n", result);
}
/* main function */
int main()
{
/* assume some kind of input which provides the arguments and intended result */
int values[] = { 8, 7, 6, 5, 4, 3, 2, 1 };
enum { nValues = sizeof values / sizeof *values };
int result = 36;
/* check all combinations of operators */
uint opsEnd = 1 << 2 * (nValues - 1);
assert(8 * sizeof opsEnd >= 2 * (nValues - 1)); /* paranoid check whether opsEnd has enough bits */
uint ops = 0;
do {
if (solve(nValues, values, ops) == result) {
print(nValues, values, ops, result);
}
} while (++ops != opsEnd);
/* done */
return 0;
}
Test in cygwin on Windows 7:
$ gcc -std=c11 -o findOps findOps.c
$ ./findOps
8 + 7 + 6 + 5 + 4 + 3 + 2 + 1 == 36
8 * 7 - 6 * 5 + 4 + 3 + 2 + 1 == 36
8 * 7 - 6 - 5 * 4 + 3 + 2 + 1 == 36
8 + 7 * 6 - 5 * 4 + 3 + 2 + 1 == 36
8 * 7 - 6 - 5 - 4 * 3 + 2 + 1 == 36
8 + 7 * 6 - 5 - 4 * 3 + 2 + 1 == 36
8 + 7 + 6 * 5 - 4 * 3 + 2 + 1 == 36
8 * 7 / 6 * 5 - 4 * 3 + 2 + 1 == 36
8 * 7 / 6 * 5 / 4 * 3 + 2 + 1 == 36
8 / 7 * 6 * 5 + 4 + 3 - 2 + 1 == 36
8 + 7 * 6 / 5 * 4 - 3 - 2 + 1 == 36
8 + 7 - 6 + 5 * 4 + 3 * 2 + 1 == 36
8 + 7 / 6 + 5 * 4 + 3 * 2 + 1 == 36
8 * 7 / 6 + 5 * 4 + 3 * 2 + 1 == 36
8 * 7 - 6 - 5 - 4 - 3 * 2 + 1 == 36
8 + 7 * 6 - 5 - 4 - 3 * 2 + 1 == 36
8 + 7 + 6 * 5 - 4 - 3 * 2 + 1 == 36
8 * 7 / 6 * 5 - 4 - 3 * 2 + 1 == 36
8 + 7 + 6 + 5 * 4 - 3 * 2 + 1 == 36
8 / 7 * 6 + 5 + 4 * 3 * 2 + 1 == 36
8 / 7 * 6 * 5 + 4 + 3 / 2 + 1 == 36
8 + 7 + 6 * 5 * 4 / 3 / 2 + 1 == 36
8 * 7 - 6 * 5 / 4 * 3 + 2 - 1 == 36
8 * 7 + 6 - 5 * 4 - 3 - 2 - 1 == 36
8 + 7 / 6 * 5 + 4 * 3 * 2 - 1 == 36
8 - 7 + 6 * 5 + 4 * 3 / 2 - 1 == 36
8 / 7 + 6 * 5 + 4 * 3 / 2 - 1 == 36
8 - 7 + 6 + 5 * 4 * 3 / 2 - 1 == 36
8 / 7 + 6 + 5 * 4 * 3 / 2 - 1 == 36
8 - 7 / 6 + 5 * 4 * 3 / 2 - 1 == 36
8 - 7 + 6 * 5 + 4 + 3 - 2 * 1 == 36
8 / 7 + 6 * 5 + 4 + 3 - 2 * 1 == 36
8 * 7 - 6 - 5 - 4 - 3 - 2 * 1 == 36
8 + 7 * 6 - 5 - 4 - 3 - 2 * 1 == 36
8 + 7 + 6 * 5 - 4 - 3 - 2 * 1 == 36
8 * 7 / 6 * 5 - 4 - 3 - 2 * 1 == 36
8 + 7 + 6 + 5 * 4 - 3 - 2 * 1 == 36
8 + 7 + 6 + 5 + 4 * 3 - 2 * 1 == 36
8 * 7 - 6 * 5 + 4 * 3 - 2 * 1 == 36
8 + 7 + 6 + 5 + 4 + 3 * 2 * 1 == 36
8 * 7 - 6 * 5 + 4 + 3 * 2 * 1 == 36
8 * 7 - 6 - 5 * 4 + 3 * 2 * 1 == 36
8 + 7 * 6 - 5 * 4 + 3 * 2 * 1 == 36
8 * 7 + 6 - 5 * 4 - 3 * 2 * 1 == 36
8 - 7 + 6 + 5 + 4 * 3 * 2 * 1 == 36
8 / 7 + 6 + 5 + 4 * 3 * 2 * 1 == 36
8 - 7 / 6 + 5 + 4 * 3 * 2 * 1 == 36
8 - 7 + 6 * 5 + 4 + 3 / 2 * 1 == 36
8 / 7 + 6 * 5 + 4 + 3 / 2 * 1 == 36
8 / 7 * 6 * 5 + 4 * 3 / 2 * 1 == 36
8 / 7 * 6 + 5 * 4 * 3 / 2 * 1 == 36
8 * 7 - 6 * 5 * 4 / 3 / 2 * 1 == 36
8 - 7 + 6 * 5 + 4 + 3 - 2 / 1 == 36
8 / 7 + 6 * 5 + 4 + 3 - 2 / 1 == 36
8 * 7 - 6 - 5 - 4 - 3 - 2 / 1 == 36
8 + 7 * 6 - 5 - 4 - 3 - 2 / 1 == 36
8 + 7 + 6 * 5 - 4 - 3 - 2 / 1 == 36
8 * 7 / 6 * 5 - 4 - 3 - 2 / 1 == 36
8 + 7 + 6 + 5 * 4 - 3 - 2 / 1 == 36
8 + 7 + 6 + 5 + 4 * 3 - 2 / 1 == 36
8 * 7 - 6 * 5 + 4 * 3 - 2 / 1 == 36
8 + 7 + 6 + 5 + 4 + 3 * 2 / 1 == 36
8 * 7 - 6 * 5 + 4 + 3 * 2 / 1 == 36
8 * 7 - 6 - 5 * 4 + 3 * 2 / 1 == 36
8 + 7 * 6 - 5 * 4 + 3 * 2 / 1 == 36
8 * 7 + 6 - 5 * 4 - 3 * 2 / 1 == 36
8 - 7 + 6 + 5 + 4 * 3 * 2 / 1 == 36
8 / 7 + 6 + 5 + 4 * 3 * 2 / 1 == 36
8 - 7 / 6 + 5 + 4 * 3 * 2 / 1 == 36
8 - 7 + 6 * 5 + 4 + 3 / 2 / 1 == 36
8 / 7 + 6 * 5 + 4 + 3 / 2 / 1 == 36
8 / 7 * 6 * 5 + 4 * 3 / 2 / 1 == 36
8 / 7 * 6 + 5 * 4 * 3 / 2 / 1 == 36
8 * 7 - 6 * 5 * 4 / 3 / 2 / 1 == 36
$
Live Demo on coliru
In ful trust on my coding abilities, I choosed randomly one line and checked it with the Windows calculator – it was correct.
Notes:
To iterate through all possible combinations of operators, the operators +, -, *, / are mapped to 0 ... 3. As these four values can be stored with exactly 2 bits, the sequence of all operators is stored in one unsigned. This makes iteration through all possible combinations extremely easy – it's just incrementing the resp. unsigned.
To solve the equation, I remembered how ancient pocket calculators (without support of ()) did this (with very limited resources). I didn't remember clearly (as it's decades ago somebody explained it to me) but was able to re-invent it. As there are only two possible precedences in +, -, *, /, it is fully sufficient to work with two buffers – one for the accumulated intermediate product, one for the accumulated intermediate sum.
The computations are done in int arithmetic. That means these computations are mathematical correct with the constraint to Natural numbers and integer operations. (I didn't check for overflow/underflow/wrap-around but I've a "good feeling" for the sample numbers. According to how solve() works, division by 0 cannot be an issue as long as there is no 0 in input.)
What I left out: parsing the text into the data structures I used in my sample. I leave this as exercise...
I have a data structure like this:
(defparameter *test*
#(#(3)
#(7 4)
#(2 4 6)
#(8 5 9 3)))
which represents a triangle of integers and a function
(defun get-node (i j triangle)
"Returns the value of the node I J of TRIANGLE."
(assert (<= j i) (i j) "~&J has to be smaller than I! I: ~D J: ~D~%" i j)
(svref (svref triangle i) j))
which allows me to access each node of the triangle easily (at least I think it does).
I thought using these two it would be easy to build up the sum along different paths through the triangle from top (3) to bottom, e.g. 8 --> 3 + 7 + 2 + 8 = 20. The next path would be 3 + 7 + 2 + 5 = 17.
Unfortunately, I totally fail to generate the indices of my vector of vectors in a reasonable way to find all the eight path in this simple example. This is not about brute-force vs. dynamic programming, etc. I am just looking for a way to iterate through the columns and rows of *test* which assures that each path was found.
How could one iterate the two indices, e.g. i and j in such a way that the correct combinations are found?
I think i now better understand what you want to enumerate so here is
another answer to your question for the alternative definition of
a “path”: a path can be described as a sequence of directions,
either down (0) or down right (1). That is trivially mapped
to an unsigned integer 0 ≤ path < 2path-directions
where each bit represents the successive directions. Each path is
conveniently represented by the pair (path-directions, number)
where path-directions is the number of directions, and number
encodes the successive directions in bits 0 through path-directions-1.
(defun gen-paths (path-directions)
(loop for i below (expt 2 path-directions)
collect i))
(gen-paths 3) => (0 1 2 3 4 5 6 7)
(defun path-to-directions (path-directions path)
(loop for i downfrom (- path-directions 1) to 0
collect (elt #(:down :down-right)
(ldb (byte 1 i) path))))
(loop for path in (gen-paths 3) collect (path-to-directions 3 path)) =>
((:DOWN :DOWN :DOWN) (:DOWN :DOWN :DOWN-RIGHT)
(:DOWN :DOWN-RIGHT :DOWN) (:DOWN :DOWN-RIGHT :DOWN-RIGHT)
(:DOWN-RIGHT :DOWN :DOWN) (:DOWN-RIGHT :DOWN :DOWN-RIGHT)
(:DOWN-RIGHT :DOWN-RIGHT :DOWN) (:DOWN-RIGHT :DOWN-RIGHT :DOWN-RIGHT))
Note that path-directions is one less than the size of the
triangle. When you represent the path as the list of nodes you
have an extra element, the starting node (0, 0).
(defun path-to-ref (path-directions path)
"Map a path to the list of (I J) pairs as understood by `get-node`."
(loop for i upto path-directions
for j = 0 then (+ j (ldb (byte 1 (- path-directions i)) path))
collect (list i j)))
(loop with path-directions = (- (length *test*) 1)
for path in (gen-paths path-directions)
collect (path-to-ref path-directions path))
=>
(((0 0) (1 0) (2 0) (3 0)) ((0 0) (1 0) (2 0) (3 1))
((0 0) (1 0) (2 1) (3 1)) ((0 0) (1 0) (2 1) (3 2))
((0 0) (1 1) (2 1) (3 1)) ((0 0) (1 1) (2 1) (3 2))
((0 0) (1 1) (2 2) (3 2)) ((0 0) (1 1) (2 2) (3 3)))
(defun get-path-nodes (path triangle)
"Returns the values of the nodes along PATH in TRIANGLE"
(loop with path-directions = (- (length triangle) 1)
for (i j) in (path-to-ref path-directions path)
collect (get-node i j triangle)))
You can then easily get the values:
(loop with path-directions = (- (length *test*) 1)
for path in (gen-paths path-directions)
collect (get-path-nodes path *test*))
=>
((3 7 2 8) (3 7 2 5) (3 7 4 5) (3 7 4 9)
(3 4 4 5) (3 4 4 9) (3 4 6 9) (3 4 6 3))
or sum them
(loop with path-directions = (- (length *test*) 1)
for path in (gen-paths path-directions)
collect (loop for v in (get-path-nodes path *test*)
sum v))
=>
(20 17 19 23 16 20 22 16)
Lisp unsurprisingly has friendlier support for lists, so I went with:
(defparameter *pyre*
'((3)
(7 4)
(2 4 6)
(8 5 9 3)))
My first stab just collects a tree and is repetitive but perhaps easier to follow:
(defun summit (n levels)
(destructuring-bind (this . more) levels
(let ((me (nth n this)))
(if more
(list
(list* me (summit n more))
(list* me (summit (1+ n) more)))
(list me)))))
Test by evaluating:
(summit 0 *pyre*)
Now tighten it up and compute the sums:
(defun summit (n levels)
(destructuring-bind (this . more) levels
(let ((me (nth n this)))
(if more
(loop for fork below 2
nconc (summit (+ n fork) more) into fork-sums
finally (return (loop for fs in fork-sums
collecting (+ me fs))))
(list me)))))
If recomputing paths concerns you, we could have some fun and rplaca the cons at one level with the sum of the existing car and each value computed at the next level. Left as an exercise.
Addendum: OK, no need for rplaca to avoid repeated calculations, to my great disappointment (but the moral is that recursion makes explicit path management unnecessary by funneling data along the paths implicit in the data):
(defun summit-ex (levels)
(destructuring-bind (level . lower-levels) levels
(if lower-levels
(loop with next-result = (let ((nr (summit-ex lower-levels)))
(print nr)
nr)
for pos upfrom 0
for value in level
for next-values = (loop for fork below 2
append (nth (+ pos fork) next-result))
collect (loop for next-value in next-values
collecting (+ value next-value)))
(mapcar 'list level))))
The debug printing was left in place because I like how they make clear what is going on:
((8) (5) (9) (3))
((10 7) (9 13) (15 9))
((17 14 16 20) (13 17 19 13))
((20 17 19 23 16 20 22 16))
Meanwhile, yes, some languages are more vector-friendly, such as Clojure:
(def pyre [[3]
[7 4]
[2 4 6]
[8 5 9 3]])
(defn summit-ex [[level & lower-levels]]
(if lower-levels
(let [next-result (summit-ex lower-levels)]
(for [pos (range (count level))]
(let [value (nth level pos)
next-values (mapcat #(nth next-result (+ pos %))
[0 1])]
(map #(+ value %) next-values))))
(map list level)))
Me, I prefer Lisp.
To generate the “paths”, that is the sequence of (i j)s you can do:
(defun gen-paths (depth)
(if (plusp depth)
(loop for p in (gen-paths (- depth 1))
nconc (loop for j to depth
collect (append p (list (list depth j)))))
'(((0 0)))))
For example (gen-paths 3) =>
(((0 0) (1 0) (2 0) (3 0)) ((0 0) (1 0) (2 0) (3 1)) ((0 0) (1 0) (2 0) (3 2)) ((0 0) (1 0) (2 0) (3 3))
((0 0) (1 0) (2 1) (3 0)) ((0 0) (1 0) (2 1) (3 1)) ((0 0) (1 0) (2 1) (3 2)) ((0 0) (1 0) (2 1) (3 3))
((0 0) (1 0) (2 2) (3 0)) ((0 0) (1 0) (2 2) (3 1)) ((0 0) (1 0) (2 2) (3 2)) ((0 0) (1 0) (2 2) (3 3))
((0 0) (1 1) (2 0) (3 0)) ((0 0) (1 1) (2 0) (3 1)) ((0 0) (1 1) (2 0) (3 2)) ((0 0) (1 1) (2 0) (3 3))
((0 0) (1 1) (2 1) (3 0)) ((0 0) (1 1) (2 1) (3 1)) ((0 0) (1 1) (2 1) (3 2)) ((0 0) (1 1) (2 1) (3 3))
((0 0) (1 1) (2 2) (3 0)) ((0 0) (1 1) (2 2) (3 1)) ((0 0) (1 1) (2 2) (3 2)) ((0 0) (1 1) (2 2) (3 3)))
You can then map get-node into this to transform these indexes into the corresponding values:
(loop for path in (gen-paths 3)
collect (loop for (i j) in path
collect (get-node i j *test*)))
=>
((3 7 2 8) (3 7 2 5) (3 7 2 9) (3 7 2 3)
(3 7 4 8) (3 7 4 5) (3 7 4 9) (3 7 4 3)
(3 7 6 8) (3 7 6 5) (3 7 6 9) (3 7 6 3)
(3 4 2 8) (3 4 2 5) (3 4 2 9) (3 4 2 3)
(3 4 4 8) (3 4 4 5) (3 4 4 9) (3 4 4 3)
(3 4 6 8) (3 4 6 5) (3 4 6 9) (3 4 6 3))
or sum the values of each “path”
(loop for path in (gen-paths 3)
collect (loop for (i j) in path
summing (get-node i j *test*)))
=>
(20 17 21 15 22 19 23 17 24 21 25 19 17 14 18 12 19 16 20 14 21 18 22 16)
I don't get this loop why is the output 52
public static void main(String[] args)
{
int k=3, tot=0;
while (k<11)
{ tot=tot+k;
k++;
}
System.out.print(tot);
}
}
What happens:
It loops eight times (11 - 3), since at each iteration k is incremented
tot = 0 + 3
tot = 3 + 4
tot = 7 + 5
tot = 12 + 6
tot = 18 + 7
tot = 25 + 8
tot = 33 + 9
tot = 42 + 10
For a given input N, how many times does the enclosed statement executes?
for i in 1 … N loop
for j in 1 … i loop
for k in 1 … j loop
sum = sum + i ;
end loop;
end loop;
end loop;
Can anyone figure out an easy way or a formula to do this in general. Please explain.
First, I written a C code to generate sum:
int main(){
int i =0, k =0, j =0, n =0;
int N =0;
int sum =0;
N =10;
for (n=1; n <= N; n++){
// unindented code here
sum =0;
for (i=1; i<=n; i++)
for (j=1; j<=i; j++)
for (k=1; k<=j; k++)
sum++;
printf("\n N=%d sum = %d",n, sum);
}
printf("\n");
}
Simple compile and generate result for N=1 to N=10 :
$ gcc sum.c
$ ./a.out
N=1 sum = 1
N=2 sum = 4
N=3 sum = 10
N=4 sum = 20
N=5 sum = 35
N=6 sum = 56
N=7 sum = 84
N=8 sum = 120
N=9 sum = 165
N=10 sum = 220
Then, Tried to explore How this works? with some diagrams:
For, N=1:
i<=N, (i=1)
|
j<=i, (j=1)
|
k<=j, (K=1)
|
sum=0. sum++ ---> sum = 1
That is (1) = 1
For, N=2:
i<=N, (i=1)-------(i=2)
| |-----|-----|
j<=i, (j=1) (j=1) (j=2)
| | |----|----|
k<=j, (K=1) (K=1) (K=1) (K=2)
| | | |
sum=0, sum++ sum++ sum++ sum++ --> sum = 4
That is (1) + (1 + 2) = 4
For, N=3:
i<=N, (i=1)-------(i=2)--------------------(i=3)
| |-----|-----| |---------|-------------|
j<=i, (j=1) (j=1) (j=2) (j=1) (j=2) (j=3)
| | |----|----| | |----|----| |-----|-----|
k<=j, (K=1) (K=1) (K=1) (K=2) (K=1) (K=1) (K=2) (K=1) (K=2) (K=3)
| | | | | | | | | |
sum=0, sum++ sum++ sum++ sum++ sum++ sum++ sum++ sum++ sum++ sum++
--> sum = 10
That is (1) + (1 + 2) + ( 1 + 2 + 3 ) = 10
N = 1, (1) = 1
N = 2, (1) + (1 + 2) = 4
N = 3, (1) + (1 + 2) + (1 + 2 + 3) = 10
N = 4, (1) + (1 + 2) + (1 + 2 + 3) + (1 + 2 + 3 + 4) = 20
N = 5, (1) + (1 + 2) + (1 + 2 + 3) + (1 + 2 + 3 + 4) + (1 + 2 + 3 + 4 + 5) = 35
Finally, I could understood that sum of N in three loop is:
(1) + (sum 0f 1 to 2) + ... + (sum of 1 to (N-2)) + (sum of 1 to (N-1) ) + (sum of 1 to N)
or we can write it as:
=> (1) + (1 + 2) + ...+ (1 + 2 +....+ i) + ... + (1 + 2 + ....+ N-1) + (1 + 2 + ....+ N)
=> ( N * 1 ) + ( (N-1) * 2) + ( (N-2) * 3) +...+ ( (N -i+1) * i ) +... + ( 1 * N)
You can refer here for simplification calculations: (I asked HERE )
[YOUR ANSWER]
= ( ((N) * (N+1) * (N+2)) / 6 )
And, I think its correct. I checked as follows:
N = 1, (1 * 2 * 3)/6 = 1
N = 2, (2 * 3 * 4)/6 = 4
N = 3, (3 * 4 * 5)/6 = 6
N = 4, (4 * 5 * 6)/6 = 10
N = 5, (5 * 6 * 7)/6 = 35
Also, The complexity of this algorithm is O(n3)
EDIT:
The following loop also has same numbers of count, that is = ( ((N) * (N+1) * (N+2)) / 6 )
for i in 1 … N loop
for j in i … N loop
for k in j … N loop
sum = sum + i ;
end loop;
end loop;
end loop;