Python:每日一题 130
本帖最后由 jerryxjr1220 于 2017-12-11 10:45 编辑首先我们的玩法做了一下改变:
1. 楼主不再提供答案。
2. 请大家先独立思考”,再参考其他鱼油的解答,这样才有助于自己编程水平的提高。
3. 鼓励大家积极答题,奖励的期限为出题后24小时内。
4. 根据答案的质量给予1~3鱼币的奖励。
题目:特别的生日
我们知道任何一个日期都可以用8个数字写成“yyyymmdd”这种形式,例如“20010101”表示2001年1月1日,小明发觉自己的生日非常特别,因为当自己的生日写成“yyyymmdd”的形式后,发觉这8个数字各不相同,而且从自己的生日以后,一直到今天就再也没有出现这样的日期了。请问小明的生日是哪年的哪天?请用程序解答。
给点提示好了,看到不少鱼油都是自己手动写日期循环,非常麻烦,其实可以利用datetime的python内置库,算日期这种小事就交给它吧^_^ 贫穷限制了我的想象!!!
不知小明同学可以活多久?
不知“再也没有出现过这样的日期”中的“这样”是哪种程度的“这样”?
{:10_266:} 本帖最后由 wyp02033 于 2017-12-7 22:02 编辑
from time import perf_counter
def is_leap_year(year):
if (year % 4 == 0 and year % 100 != 0) or year % 400 == 0:
return True
else:
return False
def find_the_birthday():
year = 2017
months =
days =
i = 11
while True:
for day in range(days, 0, -1):
birthday = str(year) + "%02d" % months + "%02d" % day
if len(set(birthday)) == len(birthday):
return birthday
i -= 1
if i < 0:
year -= 1
i = 11
if is_leap_year(year):
days = 29
if __name__ == '__main__':
start = perf_counter()
print(find_the_birthday())
end = perf_counter()
print("time uesd:", end - start)
19870625
time uesd: 0.012000967581096625 结果是:19870625 即1987年6月25日
stor=[]
for d1 in range(10):
for d2 in range(10):
if d1!=d2:
for d3 in range(10):
if (d1!=d3)&(d2!=d3):
for d4 in range(10):
if(d1!=d4)&(d2!=d4)&(d3!=d4):
for d5 in range(10):
if(d1!=d5)&(d2!=d5)&(d3!=d5)&(d4!=d5):
for d6 in range(10):
if(d1!=d6)&(d2!=d6)&(d3!=d6)&(d4!=d6)&(d5!=d6):
for d7 in range(10):
if(d1!=d7)&(d2!=d7)&(d3!=d7)&(d4!=d7)&(d5!=d7)&(d6!=d7):
for d8 in range(10):
if(d1!=d8)&(d2!=d8)&(d3!=d8)&(d4!=d8)&(d5!=d8)&(d6!=d8)&(d7!=d8):
data=d1+d2*10+d3*100+d4*1000+d5*10000+d6*100000+d7*1000000+d8*10000000
day=d1+d2*10
month=d3+d4*10
if (month in {1,3,5,7,8,10,12})&(data <=20171207)&(day<=31):
stor.append(data)
if (month in {4,6,11})&(data <=20171207)&(day<=30):
stor.append(data)
if (data <=20171207)&(day<=29)&(month==2):
stor.append(data)
print max(stor)
本帖最后由 小宏~ 于 2017-12-7 22:51 编辑
print("+++++++++小宏最帅+++++++\n")
a={1:0,2:0,3:0,4:0,5:0,6:0,7:0,8:0}
m=2017
count=0
#假设小明在100岁之内
for i in range(100):
n=int(m-i)
a=(n//1000)
a=(n%1000//100)
a=(n%100//10)
a=(n%10)
for j in range(1,13):
a=(j//10)
a=(j%10)
for x in range(1,32):
a=(x//10)
a=(x%10)
for i in range(1,9):
for j in range(i+1,9):
if(a!=a):
count=count+1
if(count==28):
print("他的生日是:%d %d %d %d年 %d %d月 %d %d日" %(a,a,a,a,a,a,a,a))
exit()
count=0
{:10_269:}得到好多个答案,因为“从自己的生日以后,一直到今天就再也没有出现这样的日期了。” 好些符合这句话的答案,让老师见笑了。期待看到精选答案~
我的程序如下:
def DifferentNumber(string):
#判断字符串中字符各不相同
temp =0#用于所有字符是否各不相同
for char in string:
if string.count(char) == 1:
temp += 1
else:
continue
if temp == 8:
return True
else:
return False
for year in range(1950,2018): #年份
for month in range(1,13): #月份
if month < 10:
month = '0' + str(month)
else:
month = str(month)
for day in range(1,32): #日期
if day < 10:
day = '0' + str(day)
else:
day = str(day)
#8位数字各不相同,即每位数字只出现过一次
birthday = str(year) + month + day
if DifferentNumber(birthday):
print(birthday) 本帖最后由 shigure_takimi 于 2017-12-8 08:44 编辑
def isRunnian(year):
return year%400==0 or (year%4==0 and year%100!=0)
def getThatDay():
for year in range(2017,1000,-1): #1988,1989,1990-1999,2000-2017都很显然不符合要求,本来可以不用循环的。
daysOfYear = if isRunnian(year) else\
for monthin range(12,0,-1):
for day in range(daysOfYear,0,-1):
if len(set(str(year).zfill(4)+str(month).zfill(2)+str(day).zfill(2))) == 8:
return str(year).zfill(4)+'-'+str(month).zfill(2)+'-'+str(day).zfill(2)
print(getThatDay())
## >>>
## 1987-06-25
改进了一下,可以求输入日期以前最后一个符合要求的日期
def isRunnian(year):
return year%400==0 or (year%4==0 and year%100!=0)
def getThatDay(yearNow,monthNow,dayNow):
for year in range(yearNow,1000,-1): #1988,1989,1990-1999,2000-2017都很显然不符合要求,本来可以不用循环的。
daysOfYear = if isRunnian(year) else\
for monthin range(12,0,-1):
for day in range(daysOfYear,0,-1):
if len(set(str(year).zfill(4)+str(month).zfill(2)+str(day).zfill(2))) == 8 and\
(year < yearNow or (year == yearNow and month < monthNow) or (year == yearNow and month == monthNow and day<=dayNow)):# 确保得到日期早于当日
return str(year).zfill(4)+'-'+str(month).zfill(2)+'-'+str(day).zfill(2)
print(getThatDay(2017,12,8))
print(getThatDay(10000,12,31))
print(getThatDay(1987,6,25))
print(getThatDay(1900,12,31))
## >>>
## 1987-06-25
## 9876-12-30
## 1987-06-25
## 1897-06-25
from itertools import permutations
result = [''.join(i) for i in permutations('0123456789',8)]
r = )<32 and int(i[-4:-2])<13 and int(i)<2]
print(r[-1]) 本帖最后由 lihw 于 2017-12-8 08:05 编辑
xuei 排序,是不是答案不止一个呀? kent_allen 发表于 2017-12-7 23:19
得到好多个答案,因为“从自己的生日以后,一直到今天就再也没有出现这样的日期了。” 好些符 ...
19860524 kent_allen 发表于 2017-12-7 23:19
得到好多个答案,因为“从自己的生日以后,一直到今天就再也没有出现这样的日期了。” 好些符 ...
我应该是思路错了... bush牛 发表于 2017-12-7 23:51
t = 20171207
while t:
if len(set(str(t))) == 8 and int(str(t)[-4:-2]) < 12 and int(str(t)[-2:]) < 32:
print(t)
break
t -= 1
这样写的效率比上面要高,上面运行2s左右,下面0.35s左右。
但是当t=23171207的时候(下一次出现这样的数会是2345年),运行会达到3.9s左右。
当然这个t是逐减一,应该还能简洁一下。
===================
下面是有单独针对这个题的,目前发现最快。
主要根据1yyy0m2d只有这样符合
def func():
result = []
for i in range(2000,1000,-1):
for j in range(9,1,-1):
for g in range(31,20,-1):
r = str(i)+'0'+str(j)+str(g)
if len(set(r)) == 8:
result.append(r)
return result def check(day):
num = []
for i in range(4):
num.append(day % 10)
day //= 10
for i in range(2):
num.append(day % 10)
day //= 10
for i in range(2):
num.append(day % 10)
day //= 10
num.sort()
if num != num != num != num != num != num != num != num:
return True
else:
return False
def yestoday(today):
if today != 1:
today -= 1
elif (today in ) == True:
today = 31
today -= 1
elif (today in ) == True:
today = 30
today -= 1
elif today == 1:
today = 31
today = 12
today -= 1
else:
if (((today % 400) ==0) or (((today % 100) != 0) and ((today % 4) == 0))) == True:
today = 29
else:
today = 28
today = 2
return today
day =
birthday = day[:]
while True:
result = check(birthday)
if result == True:
break
else:
day = yestoday(day)
birthday = day[:]
print('小明的生日是%d年%d月%d日' % (day, day, day)) import datetime
n=0
while 1:
now=datetime.datetime.now()-datetime.timedelta(days=n)
a=now.strftime('%Y%m%d')
if len(set(a))==8:
print('小明的生日为{}'.format(a))
break
n+=1
我的另外一个想法:能够组成月的十位数只能是01,能够组成日的的十位数0123,所以必须其中0123必然会被使用掉2个数字。然后因为年的千位只能由12组成,所以12也必须使用在千位上
经过排列组合计算得出
1 0 2
1 0 3
2 0 1
2 0 3
2 1 0
2 1 3
然后计算年的百位,当年千位为2的时候年的百位只能为0,所以直接排除其他月和日的有0的排列组合。同时也排除了日的个位数为0的可能性
1 0 2
1 0 3
2 1 3
继续 日的十位数为3的时候其他位数不能为1。所以所有后只能得出1 0 2
这一个排列组合,那么最终的结果就是年千位等于1,月十位等于0,日十位等于2组成的一个其他位数不重复的数字。
不知道是不是偷懒的算法
l=('9','8','7','6','5','4')
a=['1','2']
b=['0','1']
c=['0','1','2','3']
for y in a:
for m in b:
for d in c:
if d != m and d != y and m !=y:
if (y == '2' and d !='0' andm !='0' and d !='3' ) or (y=='1' and d != '3'):
print(y+l+l+l+m+l+d+l) list5=[]
list1=[]
list2=[]
list3=[]
list4=[]
for year in range (1900,2018):
if len ((str(year))) ==len(set(str(year))):
list1.append(str(year))
for mud in range (101,1231):
if len ((str(mud))) ==len(set(str(mud))):
list2.append(str(mud))
for nu in list2:
if len(str(nu))==3:
for j in range (3):
if str(0) in nu:
list3.append(nu)
for i in list3:
list2.remove(i)
for j in range(len(list2)):
if len(list2)==3:
list2=str(0)+str(list2)
for t in list2:
if t <= str(3):
if t<=str(2):
list4.append(t)
if t==str(3) and t <=str(1):
list4.append(t)
for i in list1:
for j in list4:
if len(str(i)+str(j)) == len(set(str(i)+str(j))):
list5.append(str(i)+str(j))
list5.sort()
print(list5[-1])
19870625 这个是一边想一边写的, 思路有点凌乱, 总体就是先比较年份, 把单个的年份看成一个数列,比较他数列的长度和集合的长度, 如果相同 就是没有重复的数字, 然后是月和日连在一起相同的方法比较, 但是要在个位数的月份前添加0, 最后把两个列表和在一起按照相同的方法比较, 这里没有考虑大月小月, 2月, 和闰月, 需要进一步的完善, 但是能算出结果。 本帖最后由 solomonxian 于 2017-12-8 21:26 编辑
出这题的点不是在日期上吗···
为什么要给个工具绕过去{:10_257:}
def is_leap_feb(y, m):
return 1 if ((not y%4 and y%100) or not y%400) and m == 2 else 0
def fun(n):
data = (31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31)
return sorted((i*10000 + j*100 + k for i in range(123, n//10000)
for j in range(1, 13)
for k in range(1, data + is_leap_feb(i, j) + 1)
if len(set(('0' + str(i*10000 + j*100 + k))[-8:])) == 8),
key=lambda x: (x - n) % n)[-1]
print(fun(20171208)) from datetime import date, timedelta
def daterange(begin, end):
while 1:
yield begin
begin -= timedelta(days=1)
for d in daterange(date.today(),date.min):
if len(d.strftime('%Y%m%d')) == len(set(d.strftime('%Y%m%d'))):
print(d)
break
1987-06-25 now = datetime.date.today()#今天
gridday = datetime.timedelta(days=20000)#n天以前
past = now - gridday#n天以前的日期是多少
a = []
for i in range(20000):
if len(str(past))-1 == len(set(str(past))):
a.append(past)
oneday = datetime.timedelta(1)
past += oneday
else:
oneday = datetime.timedelta(1)
past += oneday
print(a[-1])
页:
[1]
2