夢
「昨天還夢到妳呢!」我說。才發現,仍然在夢裡。
作者 newtonapple (newton and apple)
阿基米德的浴缸-突破性思考的藝術與邏輯
作者:大衛‧伯金斯/著
譯者:林志懋
---------------- 正題開始--------------------------兩個參賽者輪流挑選桌上寫桌上寫著有數字1到9的便條 紙,每次一人只能拿一張,看誰能搶在對手之前湊出來 任三個總合為15的數字,第一個參賽者先挑二,第二個 參賽者的最佳挑法為何??
還挺有趣的題目。在相信有「突破性思考」能解決的漂亮解答的前提下。花了我十分鐘左右才想到,而且還動手稍微算了一下。不過這類題目,花多久時間解答或是否被考倒,都無所謂,只是有趣而已,就像冷笑話一樣。
提示:(用滑鼠拉反白可看到)
438
951
276
(原始碼)稍微修改,也能夠計算其他的交錯級數。
from itertools import *
import sys
# a/b 的無窮位小數展開
def ldiv(a,b,p=0):
f=lambda x:x.append((x[0]%b)*10) or x.pop(0)/b
return iter(f.__get__([a*10**p]), -1)
# 比較上界ub 下界lb,然後將相同的位數傳回(p 是用來補前面的 0)
def digits(lb,ub,p):
u,l="%d"%ub, "%d"%lb
n,m=len(l),len(u)
common=takewhile(lambda i:l[i]==u[i], range(n))
return [] if m-n else chain(repeat(0, p-n), (int(l[i]) for i in common))
# 交錯級數計算(只算一個位數,要代入後面的模版)
def altseries(ub,lb, num, prec, a):
if num:
s, d=sum(a(i).next() for i in range(num-1)), a(num-1).next()
ub, lb= ub+s+max(d,0), lb+s+min(d,0)
for i in count(num):
d=a(i, prec).next()
if not d:
return ub, lb, i
ub,lb = (lb+d, lb) if d>0 else (ub, ub+d)
# 減法(只算一個位數,要代入後面的模版)
def subop(ub, lb, num, prec, a,b):
ub=lb+a.next()
return ub, ub-b.next(),1
# 減法以及交錯級數計算的模版
# 真正的上下界是 ub+num 和 lb-num
def opgen(ub,lb, num, precs, op, *a):
for prec in count():
ub,lb,num=op(ub*10,lb*10,num, prec, *a)
for x in digits(lb-num/2-1, ub+num/2+1, prec-precs):
yield x
precs+=1
ub,lb=[x%(10**(prec-precs)) for x in (ub,lb)]
# Pi 的交錯級數(其實是 pi(n) 是數列的第 n 項)
s=lambda k,p:opgen(0,0,0,-1,subop, ldiv(16, k*5**k, p), ldiv(4, k*239**k, p))
def pi(n, p=0, d={}):
return d.setdefault(n,imap(lambda x:-x, s(2*n+1,p)) if n%2 else s(2*n+1,p))
# 開始利用 generator 展開小數
for n in opgen(0,0,0,-1,altseries, pi):
sys.stdout.write("%d"%n)
sys.stdout.flush()
Copyright ©
松鼠博士的魔法眼鏡 | Powered by Blogger
Design by SimpleWpThemes | Blogger Theme by NewBloggerThemes.com