Python-第一个自己编写的程序
Python 约瑟夫生者死者小游戏
前言
学习Python3有一两周的时间了,大学学的是C语言,而且学的不怎么样。现在步入中年,相比于那些陷入网剧、网文、钓鱼、花花草草什么的去打发时间的人来说,我现在倒是开始从头学习一门语言来充当这些事情。
当然作为一名佛系的学习菜鸟,在做一些简单的程序都会遇到很多很脑残的问题,这些问题可能在大神的眼中都是很简单无趣的,甚至根本不会碰到这些问题。但是如果有同样的初学者,可能就会遇到,这里我会在后期学习的过程中将各类问题总结、分享。
题目:约瑟夫生者死者小游戏
30 个人在一条船上,超载,需要 15 人下船。
于是人们排成一队,排队的位置即为他们的编号。
报数,从 1 开始,数到 9 的人下船。
如此循环,直到船上仅剩 15 人为止,问都有哪些编号的人下船了呢?
这个问题来自于
https://www.runoob.com/python3/python-joseph-life-dead-game.html
个人觉得是一个比较经典的题目,完成这个代码后学习到的内容也很多。
数学方案
1:建立数组,人的编号为1到30
2:每个人的编号后面,加上一个数的数字编号
3:第一轮循环,把0到30号喊道9的倍数的人去除,输出。
4:去除移除的人后,剩余人数里头,再次循环报数。
5:再执行步骤3
6:再执行步骤4
7:检验人数是否等于15人,如果等于break循环,出结果。
我的代码
#船上30个人,挨个循环报数,每报到9的倍数的人下船.直到还剩下15个人在船上
m = 1
n = 1
a=[]
temp2= 0
boat = []
out = []
inboat = []
for m in range(1,31):
n=m
a.append([m,n]) #m是人的编号,n是人喊的顺序
boat.append(a[m-1][0]) #在船上的人的编号。
print("最开始船上的人为",boat)
import copy #这里貌似和C语言不同,如果A=B B=C ,然后你如果对C进行操作,在Python中,实际上ABC都会变化,他们都是一个值。
i=30
while i>15:
aa=[]
aa = copy.deepcopy(a) #做一个中间变量,否则a会跟着变。
x= 0
len(a)
for x in range(0,len(a)): #对这些人报的数进行check
if (a[x][1]) % 9 == 0: #喊9的人输出,并从a中移除
out.append(a[x][0])
aa.remove(a[x]) #对中间变量的aa进行删除,但是不能对a进行删除,否则循环range(len(a))将报错out of range
i=len(aa)
print("下船的人为",a[x][0])
if i == 15 :
break
a=copy.deepcopy(aa) #再把中间变量返回给a
if i ==15: #任何时候i等于15都要break
break
y = 0
z0 =0
z1 =0
b=[]
z=[]
temp2= temp2+ len(a) + len(out) #再做一个循环,对已经下船了一轮的人的a进行重新赋值
for y in range(0,len(a)): #人的编号不变,喊的号码变化
z1=temp2+y+1
z0 = a[y][0]
z=[z0,z1]
b.append(z)
a = copy.deepcopy(b)
out = []
print("船上剩余",i,"人")
print(a)
x =0;boat=[] #专门做个循环,输入下船的人的编号集合。
for x in range(0,len(a)):
boat.append(a[x][0])
print("船上剩余",i,"人")
print("最后船上的人为",boat)
print("goodbye")
#船上30个人,挨个循环报数,每报到9的倍数的人下船.直到还剩下15个人在船上
m = 1
n = 1
a=[]
temp2= 0
boat = []
out = []
inboat = []
for m in range(1,31):
n=m
a.append([m,n]) #m是人的编号,n是人喊的顺序
boat.append(a[m-1][0]) #在船上的人的编号。
print("最开始船上的人为",boat)
import copy
i=30
while i>15:
aa=[]
aa = copy.deepcopy(a)
x= 0
temp1= len(a)
for x in range(0,temp1):
if (a[x][1]) % 9 == 0:
out.append(a[x][0])
aa.remove(a[x])
i=len(aa)
print("下船的人为",a[x][0])
if i == 15 :
break
a=copy.deepcopy(aa)
if i ==15:
break
y = 0
z0 =0
z1 =0
b=[]
z=[]
temp2= temp2+ len(a) + len(out)
for y in range(0,len(a)):
z1=temp2+y+1
z0 = a[y][0]
z=[z0,z1]
b.append(z)
a = copy.deepcopy(b)
out = []
print("船上剩余",i,"人")
print(a)
x =0;boat=[]
for x in range(0,len(a)):
boat.append(a[x][0])
print("船上剩余",i,"人")
print("最后船上的人为",boat)
print("goodbye")
其中涉及到的坑,提一下
- 这里貌似和C语言不同,如果A=B B=C ,然后你如果对C进行操作,在Python中,实际上ABC都会变化,他们都是一个值。
- 数组重新赋值比改变赋值编写效率更高。
看一下教材的代码(比我的简洁太多太多):
people={}
for x in range(1,31):
people[x]=1
# print(people)
check=0
i=1
j=0
while i<=31:
if i == 31:
i=1
elif j == 15:
break
else:
if people[i] == 0:
i+=1
continue
else:
check+=1
if check == 9:
people[i]=0
check = 0
print("{}号下船了".format(i))
j+=1
else:
i+=1
continue
笔记里更简洁的代码
a=[x for x in range(1,31)]
b=[]
for x in range(135): #x最少要数9*15次才能数够15名下船人数
if (x+1)%9==0:
b.append(a[x-len(b)]) #把a里面被淘汰的人加入到b列表中
y=len(b)-1 #列表b里面每增加一个元素,a里面对应的人员就会自动往前面进一位后面前进的位数刚好是列表b的长度-1
a.remove(a[x-y]) #同时册除列表a里面被点中的人
else:
a.append(a[x-len(b)]) #把没有被点中的人重新加入到列表a 的后面
print(b)
sum = list(range(1,31))
while len(sum) > 15:
print('{}号下船了'.format(sum.pop(8)))
for i in range(8):
sum.append(sum.pop(0))
s=list(range(1,31))
for i in s:
if len(s)>15:
print("下船的人是",s[8])
s=s[9:]+s[:8]
print(s)
s.sort()
print("在船上的人为",s)
别人程序的学习笔记
其中最下面这个是我个人最喜欢的形式,代码的顺序本身是有的,然后通过重新构造数组的形式进行重组。最后再循环编号,相当于一个循环实现了多个循环的目的。
s=list(range(1,31))
for i in s:
if len(s)>15:
print("下船的人是",s[8])
s=s[9:]+s[:8]
print(s)
s.sort()
print("在船上的人为",s)