解决约瑟夫斯置换问题

时间:2018-02-09 10:20:17

标签: r for-loop

  

假设100个人以1到100的顺序站成一个圆圈.1号有一把剑。他杀死了下一个人(即第2号)并将剑交给下一个人(即第3号)。所有人都这样做,直到只有1人幸存。哪个号码最后幸存?

有100人从1到100开始。

我试过

persons <- c(1:100)
for (i in 1:100) {
  qu <- persons[seq_along(persons) %% 2 > 0]
  if (q2 == 2) {
    print(q2[2])
  }
}

以及

q=0
 while(q==0){ persons=persons[seq_along(persons) %% 2 > 0]
 if(length(persons)==2){ print(persons[2])
 q=1}}

但这给出了一个65的答案,这是错误的,并没有解决目的。

如何解决这个问题?

4 个答案:

答案 0 :(得分:15)

在此解决方案中,假设拥有剑的人是向量中的第一个人。那个人杀了下一个人,然后移到了最后一行。

如果有一个人,那么该人就是幸存者。

n

编辑:

对于大型kill_fast <- function(n) 2 * (n - 2 ^ (floor(log2(n)))) + 1 kill_fast(100) #> [1] 73 kill_fast(100000) #> [1] 68929 ,请使用以下solution

Traceback (most recent call last):
  File "pyinstaller.py", line 15, in <module>
    run()
  File "/home/akaroui/PyInstaller-3.3.1/PyInstaller/__main__.py", line 94, in run
    run_build(pyi_config, spec_file, **vars(args))
  File "/home/akaroui/PyInstaller-3.3.1/PyInstaller/__main__.py", line 46, in run_build
    PyInstaller.building.build_main.main(pyi_config, spec_file, **kwargs)
  File "/home/akaroui/PyInstaller-3.3.1/PyInstaller/building/build_main.py", line 791, in main
    build(specfile, kw.get('distpath'), kw.get('workpath'), kw.get('clean_build'))
  File "/home/akaroui/PyInstaller-3.3.1/PyInstaller/building/build_main.py", line 737, in build
    exec(text, spec_namespace)
  File "<string>", line 22, in <module>
  File "/home/akaroui/PyInstaller-3.3.1/PyInstaller/building/build_main.py", line 213, in __init__
    self.__postinit__()
  File "/home/akaroui/PyInstaller-3.3.1/PyInstaller/building/datastruct.py", line 161, in __postinit__
    self.assemble()
  File "/home/akaroui/PyInstaller-3.3.1/PyInstaller/building/build_main.py", line 472, in assemble
    module_hook.post_graph()
  File "/home/akaroui/PyInstaller-3.3.1/PyInstaller/building/imphook.py", line 414, in post_graph
    self._process_hook_func()
  File "/home/akaroui/PyInstaller-3.3.1/PyInstaller/building/imphook.py", line 433, in _process_hook_func
    self._hook_module.hook(hook_api)
  File "/home/akaroui/PyInstaller-3.3.1/PyInstaller/hooks/hook-_tkinter.py", line 245, in hook
    hook_api.add_datas(_collect_tcl_tk_files(hook_api))
  File "/home/akaroui/PyInstaller-3.3.1/PyInstaller/hooks/hook-_tkinter.py", line 208, in _collect_tcl_tk_files
    tcl_root, tk_root = _find_tcl_tk(hook_api)
  File "/home/akaroui/PyInstaller-3.3.1/PyInstaller/hooks/hook-_tkinter.py", line 159, in _find_tcl_tk
    bins = selectImports(hook_api.__file__)
  File "/home/akaroui/PyInstaller-3.3.1/PyInstaller/depend/bindepend.py", line 493, in selectImports
    xtrapath = [os.path.dirname(pth)]
  File "/usr/local/python/3.6.1/lib/python3.6/posixpath.py", line 154, in dirname
    p = os.fspath(p)
TypeError: expected str, bytes or os.PathLike object, not NoneType

答案 1 :(得分:5)

这里以保罗的优雅答案以非递归的方式重写,因此可能更容易理解。

people <- 1:100
while (length(people) > 1) {
  people <- c(people[-(1:2)], people[1])
}
print(people)
# [1] 73

答案 2 :(得分:2)

这让一个人活着,但我不确定问题的限制

persons=rep("ALIVE",100)
for(i in 1:100) {
  if(i+1<101){
    if(persons[i+1]=="ALIVE"){
      persons[i]<-"DEAD"
    }
  }
  print(persons)
}

答案 3 :(得分:2)

这不像我不喜欢递归,但这是一个更通用的解决方案,适用于任何人口规模:

kill <- function(n = 100) {
  seq1 <- 2 ^ seq_len(31)
  seq2 <- n / seq1
  seq2 <- c(n, floor(seq2[seq2 >= 3]))
  sum(seq1[1:length(seq2)][seq2 %% 2 == 1], 1)
}

现在你可以看到,如果我们在大约800万瑞士人中间玩这个,我应该排在位置7'611'393 ...(kill(8000000)