9

我想知道是否可以在 python 中使用 list 来解决 Josepheus 问题。

简单来说,约瑟夫斯问题就是在循环排列中找到一个位置,如果使用预先知道的跳过参数处理执行,这将是安全的。

例如:给定一个圆形排列,例如[1,2,3,4,5,6,7]跳过参数为 3,人员将按顺序执行,3,6,2,7,5,1并且位置4将是安全的。

一段时间以来,我一直在尝试使用 list 来解决这个问题,但是索引位置对我来说变得难以处理。

 a=[x for x in range(1,11)]
 skip=2
 step=2
 while (len(a)!=1):
   value=a[step-1]
   a.remove(value)
   n=len(a)
   step=step+skip
   large=max(a)
   if step>=n:        
      diff=abs(large-value)
      step=diff%skip
   print a

用代码片段更新了问题,但我认为我的逻辑不正确。

4

8 回答 8

18

很简单,您可以使用list.pop(i)循环删除每个受害者(并获取他的 ID)。然后,我们只需要担心包装索引,您可以通过将跳过的索引 mod 剩余囚犯的数量来做到这一点。

那么,问题的解决方案就变成了

def josephus(ls, skip):
    skip -= 1 # pop automatically skips the dead guy
    idx = skip
    while len(ls) > 1:
        print(ls.pop(idx)) # kill prisoner at idx
        idx = (idx + skip) % len(ls)
    print('survivor: ', ls[0])

测试输出:

>>> josephus([1,2,3,4,5,6,7], 3)
3
6
2
7
5
1
survivor:  4
于 2012-09-16T07:10:12.937 回答
4
In [96]: def josephus(ls, skip):
    ...:     from collections import deque
    ...:     d = deque(ls)
    ...:     while len(d)>1:
    ...:         d.rotate(-skip)
    ...:         print(d.pop())
    ...:     print('survivor:' , d.pop())
    ...:     

In [97]: josephus([1,2,3,4,5,6,7], 3)
3
6
2
7
5
1
survivor: 4

如果不想计算索引,可以使用deque数据结构。

于 2017-03-11T06:26:02.240 回答
4

我的解决方案使用了我在网上找到的一个数学技巧:https ://www.youtube.com/watch?v=uCsD3ZGzMgE 它使用二进制方式来写圆圈中的人数和幸存者所在的位置。结果是一样的,代码更短。

代码是这样的:

numar_persoane = int(input("How many people are in the circle?\n")) #here we manually insert the number of people in the circle

x='{0:08b}'.format(int(numar_persoane)) #here we convert to binary

m=list(x) #here we transform it into a list

for i in range(0,len(m)): #here we remove the first '1' and append to the same list

    m.remove('1')

    m.append('1')

    break

w=''.join(m) #here we make it a string again

print("The survivor sits in position",int(w, 2)) #int(w, 2) makes our string a decimal number
于 2019-06-13T21:47:02.613 回答
2

对于初学者来说,它看起来更糟但更容易理解

def last(n):
    a=[x for x in range(1,n+1)]
    man_with_sword = 1
    print(a)
    while len(a)!=1:   
        if man_with_sword == a[len(a)-2]:  #man_with_sword before last in circle
            killed = a[len(a)-1]
            a.remove(killed)
            man_with_sword=a[0]
        elif man_with_sword==a[len(a)-1]:  #man_with_sword last in circle
            killed = a[0]
            a.remove(killed)
            man_with_sword=a[0]
        else:
            i=0
            while i < (len(a)//2): 
                i=a.index(man_with_sword)
                killed = a[a.index(man_with_sword)+1]
                a.remove(killed)
                #pass the sword 
                man_with_sword=a[i+1] # pass the sword to next ( we killed next)
                print (a, man_with_sword) #show who survived and sword owner
                i+=1
        print (a, man_with_sword,'next circle') #show who survived and sword owner
于 2018-10-24T14:13:33.323 回答
2

如果您只寻找最终结果,这里有一个简单的解决方案。

def JosephusProblem(people):
  binary = bin(people)  # Converting to binary
  winner = binary[3:]+binary[2]  # as the output looks like '0b101001'. removing 0b and adding the 1 to the end
  print('The winner is',int(winner,2))  #converting the binary  back to decimal

如果您正在寻找此代码背后的数学原理,请观看此视频: Josephus Problem(youTube)

于 2019-10-02T18:06:18.247 回答
1

总人数n和一个数字k,表示k-1跳过的人,在圈子里杀了第k个人。

def josephus(n, k): 
  if n == 1: 
    return 1
  else: 
    return (josephus(n - 1, k) + k-1) % n + 1

n = 14
k = 2            
print("The chosen place is ", josephus(n, k))
于 2019-07-24T12:57:08.143 回答
0

这是我对您的问题的解决方案:

# simple queue implementation<ADT>
class Queue:
    def __init__(self):
        self.q = []
    def enqueue(self,data):
        self.q.insert(0,data)
    def dequeue(self):
        self.q.pop()
    def sizeQ(self):
        return len(self.q)
    def printQ(self):
        return self.q


lists = ["Josephus","Mark","Gladiator","Coward"]
to_die = 3
Q = Queue()
# inserting element into Q
for i in lists:
    Q.enqueue(i)
# for size > 1 
while Q.sizeP() > 1:
    for j in range(1,3): 
# every third element to be eliminated
         Q.enqueue(Q.dequeue())
    Q.dequeue()
print(Q.printQ())
于 2018-02-11T03:29:06.747 回答
0
def Last_Person(n):
    person = [x for x in range(1,n+1)]
    x = 0
    c = 1
    while len(person) > 1:
        if x == len(person) - 1:
            print("Round ", c, "- Here's who is left: ", person, "Person ", person[x], "killed person", person[0])
            person.pop(0)
            x = 0
            c = c+1
        elif x == len(person) - 2:
            print("Round ", c, "- Here's who is left: ", person, "Person ", person[x], "killed person", person[x + 1])
            person.pop(x+1)
            x = 0
            c = c + 1
        else:
            print("Round ", c, "- Here's who is left: ", person, "Person ", person[x], "killed person", person[x + 1])
            person.pop(x + 1)
            x = x + 1
            c = c + 1
    print("Person", person[x], "is the winner")

Last_Person(50)
于 2018-03-05T03:50:28.397 回答