patterncMinor
Program to solve variations of the seven thieves & diamonds riddle
Viewed 0 times
variationsthesevendiamondsprogramriddlesolvethieves
Problem
I answered a question yesterday on SO based on this riddle, but the code was so hard to read/follow to actually understand what was going on it was easier to write my own code to test the scenario and debug the program.
I wrote it pretty fast, but I want to make sure the program I wrote is easy to follow and adheres to basic C practices to avoid someone else have the same problem reading and following my code as I did in the original question. The program itself was a variation of the following riddle:
There are seven thieves who steal diamonds from a diamond merchant and run away in the jungle. While running, night sets in and they decide to rest in the jungle. When everybody is sleeping, two of the best friends get up and decide to distribute the diamonds among themselves and run away. So they start distributing but find that one diamond was extra. So they decide to wake up 3rd one and divide the diamonds again...only to their surprise they still find one diamond extra. So they decide to wake up the fourth one. Again one diamond is spare. 5th woken up...still one extra. 6th still one extra. Now they wake up 7th and diamonds are distributed equally.
The solution is as follows:
Lets say there are x diamonds, now these diamonds are exactly
divisible by 7 and:
x = 1 + N1*2;
x = 1 + N2*3;
x = 1 + N3*4;
x = 1 + N4*5;
x = 1 + N5*6;
x = N6*7;
Where N1, N2, N3, N4 and N5 are
integers. From above we can also say:
N12 = N23 = N34= N45 = N5*6 =y
Now y should be divisible by 2, 3, 4, 5 and 6, its nothing but
common multiple of all.
LCM of 2, 3, 22, 5, 23 => 232*5 => 60
At the same time common multiple + 1 should be divisible by 7 as well.
60 + 1 is not divisible by 7 120(60*2) + 1 is not divisible by 7
180(603) + 1 is not divisible by 7 240(604) + 1 is not divisible by
7 300(60*5) + 1 is divisible by 7
Thus they must have stolen minimum 301 diamonds.
The generalization i
I wrote it pretty fast, but I want to make sure the program I wrote is easy to follow and adheres to basic C practices to avoid someone else have the same problem reading and following my code as I did in the original question. The program itself was a variation of the following riddle:
There are seven thieves who steal diamonds from a diamond merchant and run away in the jungle. While running, night sets in and they decide to rest in the jungle. When everybody is sleeping, two of the best friends get up and decide to distribute the diamonds among themselves and run away. So they start distributing but find that one diamond was extra. So they decide to wake up 3rd one and divide the diamonds again...only to their surprise they still find one diamond extra. So they decide to wake up the fourth one. Again one diamond is spare. 5th woken up...still one extra. 6th still one extra. Now they wake up 7th and diamonds are distributed equally.
The solution is as follows:
Lets say there are x diamonds, now these diamonds are exactly
divisible by 7 and:
x = 1 + N1*2;
x = 1 + N2*3;
x = 1 + N3*4;
x = 1 + N4*5;
x = 1 + N5*6;
x = N6*7;
Where N1, N2, N3, N4 and N5 are
integers. From above we can also say:
N12 = N23 = N34= N45 = N5*6 =y
Now y should be divisible by 2, 3, 4, 5 and 6, its nothing but
common multiple of all.
LCM of 2, 3, 22, 5, 23 => 232*5 => 60
At the same time common multiple + 1 should be divisible by 7 as well.
60 + 1 is not divisible by 7 120(60*2) + 1 is not divisible by 7
180(603) + 1 is not divisible by 7 240(604) + 1 is not divisible by
7 300(60*5) + 1 is divisible by 7
Thus they must have stolen minimum 301 diamonds.
The generalization i
Solution
Given that this was quick and dirty program to solve a simple problem, it's understandable that some things aren't as "polished" as could be. Here are some things I spotted:
gcd()
I'm guessing you copy and pasted this function because the style of the braces, the indentation, and the spacing doesn't match the rest of your code.
Overflow
When I ran your program (on a 32-bit system) I couldn't get an answer for 23 thieves because it overflowed. Here where you compute the lcm:
you can do slightly better like this:
With that change, I was able to get the answer for 23 (but not for 29). You might want to use
Spacing
I personally like more spaces between things such as
Minor ordering change
For this line:
I would rather it be like this:
That way you don't end up calling
gcd()
I'm guessing you copy and pasted this function because the style of the braces, the indentation, and the spacing doesn't match the rest of your code.
Overflow
When I ran your program (on a 32-bit system) I couldn't get an answer for 23 thieves because it overflowed. Here where you compute the lcm:
lcm = (lcm*i)/gcd(i,lcm);you can do slightly better like this:
lcm *= i/gcd(i,lcm);With that change, I was able to get the answer for 23 (but not for 29). You might want to use
uint64_t instead of long to get the largest range possible (I was able to get the answer for 43 thieves using uint64_t). Btw, that line was also indented too far for some reason.Spacing
I personally like more spaces between things such as
if(, but it's subjective. One place that was really hard for me to read was this:diamonds = lcm*++i + 1;Minor ordering change
For this line:
if(isPrime(thieves) && thieves > 1)I would rather it be like this:
if(thieves > 1 && isPrime(thieves))That way you don't end up calling
isPrime with some strange negative input that can have unintended consequences.Code Snippets
lcm = (lcm*i)/gcd(i,lcm);lcm *= i/gcd(i,lcm);diamonds = lcm*++i + 1;if(isPrime(thieves) && thieves > 1)if(thieves > 1 && isPrime(thieves))Context
StackExchange Code Review Q#96019, answer score: 5
Revisions (0)
No revisions yet.