The Logical Pattern behind Piracy

In this article, I will investigate and explain the Logical Pattern behind (in my opinion) one of the best questions in Computer Science: The Piracy Problem.

For all of you who hoped to find an article about downloading movies or software, I have to disappoint you. This is not about that kind of piracy. It's about one of the best algorithmic riddles that I have found so far. It's quite a read, but I hope you think it's worth it!

To start off, I'm going to send you here. This entire article is based upon that riddle.

Finished? Cool, isn't it? Logic and pattern recognition combined with a funny setting. There's a small extension to it on the same site here.

I thought about this riddle for a long time and decided to discover the logical pattern behind this problem. In the 6 pirates, 1 coin case, pirate number 5 dies if he would have to make the proposal, yet pirate number 6 lives, because he can count on 5's vote even if 5 gets no coins (because he would otherwise die). I was wondering, what other pirates would survive if there was only a single coin? Pirate 7, 8 and 9 would die again, since they can never convince resp. 4, 4 and 5 pirates to vote for them. Pirate 10 however, gets to live! Because 7, 8 and 9 would otherwise die, they vote for 10 even if they get nothing! Combined with 10's own vote and the vote of the pirate who gets the coin, 10 is able to secure 5 votes and gets to live another day.

Note that in this case, pirate 5 would not vote for pirate 10, because he knows he will get nothing anyway and if 10 walks the plank, so will 9, 8 and 7. 6 would then come to power and 5 would then vote for 6. He still gets nothing, but at least 4 other pirates have died. Him being a pirate, only his own life and getting gold pleases him more than seeing others die :-)

So, let's re-iterate the priorities that pirates use to vote, in order of importance:

  • Priority 1: Stay alive
  • Priority 2: Get as many gold coins as possible
  • Priority 3: Get as many other pirates killed as possible (given priority 1 and 2 are equally satisfied)
  • Priority 4: If a pirate is a senior and it doesn't matter to whom he gives a coin, he will give it to the LOWEST ranked pirate. So, if pirate number 6 can choose to give a coin to either 1 or 4, he will choose 1.
I added number 3 and 4 to make the problem deterministic in all cases.

I then started to make spreadsheets of the number of coins that each pirate would get, when there are c coins available. Below is the spreadsheet of the 1 coin case. The rows represent the situation where there are a certain number of pirates and the columns represent what each pirate would get in those situations. a value of -1 (and a red color) means that the pirate in question dies in that given situation. The green cells represent the pirates who would vote in favour of the proposal. Please click to enlarge.


The 1 coin case

And here are the spreadsheets for 2 and 3 coins:


The 2 coins case



The 3 coins case

A clear pattern emerges! I have defined so-called "life lines": lines on which the most senior pirate is able to survive by counting on the votes of the pirates who would otherwise die. I've marked those rows with a light green color. The patterns that emerge are as follows:

  • A life line occurs when the number of pirates is equal to a number in this set: For c number of coins and x > 1: 2x + 2c. So, for 1 coin, the life lines are 4, 6, 10, 18, 34...

  • Before the first life line: If the most senior is even, all even pirates get a coin, all odd pirates get nothing. The most senior keeps what's left. When the most senior is odd, it's the odd pirates who get a share of the bounty. Note that the "first" life line fits this pattern as well. It's kind of a transitional line.

  • After each life line, the most senior pirate dies and the others get the same as they got on the previous life line, until we get to the next life line.

  • On each life line, the most senior pirate gives the coins to the most junior pirates who would otherwise get nothing. Note that these alternate on each subsequent life line, because otherwise, those juniors have no incentive to vote (because they would get the coins anyway).
Note that these patterns also apply when there are 0 coins!


The 0 coins case

Then, I created an algorithm (in Java). For a certain number of pirates and a certain number of coins, what does a certain pirate get? (Scrolling to the right is possible)

  1. /**
  2.  * Avast, me hearties! This method returns me bounty, the number of dubloons me be gettin' when me be among these scurvy dogs! Yarr!
  3.  *
  4.  * @param numberOfCoins The total number of dubloons me and me mateys will divide...
  5.  * @param numberOfPirates The total number of scallywags in this bung hole!
  6.  * @param myIndex Me index! Big guys above me, sprogs below...
  7.  * @return
  8.  */
  9. public static int whatsMeBounty(int numberOfCoins, int numberOfPirates, int myIndex) {
  10.  
  11. int firstLifeLine = 2 + numberOfCoins*2;
  12. if(numberOfPirates < firstLifeLine) { //We're under the first life line
  13.  
  14. if(myIndex == numberOfPirates) { //Me be the most senior
  15. return numberOfCoins - (int) ((numberOfPirates-1)/2); //Integer division is floored, so me be gettin' what's left
  16. } else { //Me not be the most senior
  17. if(numberOfPirates % 2 == 0) { //The most senior is even
  18. if(myIndex % 2 == 0) { //Me be even
  19. return 1;
  20. } else { //Me be odd
  21. return 0;
  22. }
  23. } else { //The most senior is odd
  24. if(myIndex % 2 == 0) { //Me be even
  25. return 0;
  26. } else { //Me be odd
  27. return 1;
  28. }
  29. }
  30. }
  31.  
  32. } else { //We're over or on the first life line
  33.  
  34. double lifeLineIndex = Math.log(numberOfPirates - numberOfCoins*2) / Math.log(2);
  35. if(lifeLineIndex % 1 == 0) { //We're exactly on a life line
  36.  
  37. //If me be more senior than the most senior pirate on the preceding lifeLine (and this isn't the first life line), me be votin' to live, not to get coins
  38. int precedingLifeLineSenior = (int) Math.pow(2, (lifeLineIndex-1) + numberOfCoins*2);
  39. if(myIndex > precedingLifeLineSenior && numberOfPirates != firstLifeLine) { //Me be votin' to escape Fiddler's Green!
  40. return 0;
  41. } else { //Me only be votin' if me be gettin' a coin!
  42.  
  43. if(lifeLineIndex % 2 == 0) { //We're on an even life line, the first 'numberOfCoins' odd pirates get a coin
  44. if(myIndex % 2 == 1 && myIndex <= numberOfCoins*2) {
  45. return 1;
  46. } else {
  47. return 0;
  48. }
  49. } else { //We're on an odd life line, the first 'numberOfCoins' even pirates get a coin
  50. if(myIndex % 2 == 0 && myIndex <= numberOfCoins*2) {
  51. return 1;
  52. } else {
  53. return 0;
  54. }
  55. }
  56. }
  57.  
  58. } else { //We're NOT on a life line
  59. if(myIndex == numberOfPirates) { //Me be the most senior
  60. return -1; //Shiver me timbers! Me be walkin' the plank!
  61. } else { //Me not be the most senior, let's see what me be gettin' once that scurvy dog has visited Davy Jones's locker!
  62. return whatsMeBounty(numberOfCoins, numberOfPirates-1, myIndex);
  63. }
  64. }
  65. }
  66. }
And that's that: The Logical Pattern behind Piracy.

Thanks to:
  • Yarr for the crash course on Pirate Talk
  • WPClipart for the Pirate Image

Gert-Jan Schouten, MSc. is a Senior Software Architect / Engineer specialized in Java and Development Infrastructure. At this blog, he writes about his personal visions and thoughts.

Back to blog-index

Share |

2 thoughts on “The Logical Pattern behind Piracy

Leave a Reply

Your email address will not be published. Required fields are marked *

*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>