All about flooble | fun stuff | Get a free chatterbox | Free JavaScript | Avatars    
perplexus dot info

Home > Logic
Maximus (Posted on 2024-04-20) Difficulty: 3 of 5
Maximus is one of 3 or more prisoners of war who have been lined up before the Roman Emperor. The prisoners are numbered from first in the line to last as 1, 2, 3, 4, ..., N. The Emperor orders the execution of the prisoners in the following manner:
1) The first and last are immediately executed.
2) If there are still 2 or more prisoners remaining, the half of the remaining prisoners with the lowest numbers (rounded up) are executed.
3) If there are still 3 or more prisoners remaining, start again from Step 1.

For example, if there were 5 prisoners to start then prisoners 1 and 5 would be executed in Step 2, and prisoners 2 and 3 would be executed in Step 3, leaving prisoner 4 alive.

Is there a strategy by which Maximus can save himself? What if Maximus also wants to save his friend Romulus?

No Solution Yet Submitted by K Sengupta    
Rating: 4.0000 (1 votes)

Comments: ( Back to comment list | You must be logged in to post comments.)
Solution Solution | Comment 3 of 7 |
[edit:  This post is incorrect, I had a flaw in the main algorithm.  Thanks to Charlie for pointing out the error.  See new post above for corrected algorithm and results.  Curiously, despite the error, "Strategy 1" remains intact] 

------------  Incorrect Below Here  ----------------
I found that the algorithm spares either 1, 2, or 3 prisoners depending on the starting number, N.  When more than one is spared, they are always adjacent to each other.  Romulus can be spared about 2/3 of the time.

I found two winning strategies.
Strategy 1:
To save one person, when there are N prisoners:  be in position
N - (int(log(n) - 1)   (where log is to base 2)
When N results in 1 life spared, Maximus is saved.  When 3 are saved, Maximus is in the middle of the 3.  When 2 are saved, Max is sometimes the larger number and sometimes the smaller.

The best place for Romulus is adjacent to Maximus:
    if N is exactly a power of 2 or slightly more, put Romulus behind Max
    if N is a little less than a power of 2, put Romulus just in front of Max.

Strategy 2:
The largest number position of those spared is N-k, where k is a complicated function of N.  First use the following formula to find the smallest N such that the largest position of those spared is N-k:  2^(k+2) - 2^k - 2.

i smallestN(i)
1 4
2 10
3 22
4 46
5 94
6 190
Maximus then compares N to this table, for example if N=50, he sees that 50 is larger than 46 but smaller than 94, so k=4.  So Maximus would go to position 46 and Romulus just in front of him at position 45.

Program output:
N [saved]  Strgy1   k
4 [3] 3 1
5 [4] 4 1
6 [4, 5] 5 1
7 [5, 6] 6 1
8 [5, 6, 7] 6 1
9 [6, 7, 8] 7 1
10 [8] 8 2
11 [9] 9 2
12 [10] 10 2
13 [11] 11 2
14 [11, 12] 12 2
15 [12, 13] 13 2
16 [13, 14] 13 2
17 [14, 15] 14 2
18 [14, 15, 16] 15 2
19 [15, 16, 17] 16 2
20 [16, 17, 18] 17 2
21 [17, 18, 19] 18 2
22 [19] 19 3
23 [20] 20 3
24 [21] 21 3
25 [22] 22 3
26 [23] 23 3
27 [24] 24 3
28 [25] 25 3
29 [26] 26 3
30 [26, 27] 27 3
31 [27, 28] 28 3
32 [28, 29] 28 3
33 [29, 30] 29 3
34 [30, 31] 30 3
35 [31, 32] 31 3
36 [32, 33] 32 3
37 [33, 34] 33 3
38 [33, 34, 35] 34 3
39 [34, 35, 36] 35 3
40 [35, 36, 37] 36 3
41 [36, 37, 38] 37 3
42 [37, 38, 39] 38 3
43 [38, 39, 40] 39 3
44 [39, 40, 41] 40 3
45 [40, 41, 42] 41 3
46 [42] 42 4
47 [43] 43 4
48 [44] 44 4
49 [45] 45 4
50 [46] 46 4

----------------------
import math
def calculateK(n):
    return int(math.log(n,2)) - 1

def smallestN(k):
    return 2**(k+2) - 2**k - 2
    
def wholives(N):
    peeps = [i for i in range(1,N+1)]
    executed = []
    for round in range(1000):
        remain = len(peeps)
        if remain > 3:
            leaving = int(remain/2 + (remain%2)/2)
            executed += peeps[:leaving]
            peeps = peeps[leaving:]
            executed.append(peeps.pop(-1))
        else:
            return  peeps
        remain = len(peeps)
        if remain < 3:
            return  peeps
            break

for n in range(4,51):
    who = wholives(n)
    print(n, who, n - calculateK(n), n - who[-1])

Edited on April 22, 2024, 5:17 pm
  Posted by Larry on 2024-04-20 10:26:04

Please log in:
Login:
Password:
Remember me:
Sign up! | Forgot password


Search:
Search body:
Forums (0)
Newest Problems
Random Problem
FAQ | About This Site
Site Statistics
New Comments (9)
Unsolved Problems
Top Rated Problems
This month's top
Most Commented On

Chatterbox:
Copyright © 2002 - 2024 by Animus Pactum Consulting. All rights reserved. Privacy Information