一道數學題,怎麼計算是最快速的?
Q:如果小明一天按照當天日期數給付小強一筆費用(如:一月一日,11元,五月二十一日,521元,如此類推)那麼小強一年(按照閏年計算)可獲得多少元?
身為小學奧數老師,就用小學奧數的思維解答一下吧-。-
每一天的費用由當天的月和日共同組成,計算的時候分開算比較簡單吧。。。
先算日:
不論哪一天,日所提供的錢數都是日這個數本身。例如今天5.22,那麼二十二日決定了522元中的22元,8.31中三十一日決定了831元中的31元。全年中29天的月份有1個,30天的月份有4個,31天的月份有7個。那麼全年中日所提供的錢數應為:
也就是元
再算月:
每個月前9天的日是一位數,那麼月所提供的錢數是月,從第10天開始日是兩位數,那麼月所提供的錢數是月。
一月中月所提供的總錢數為:
同理,二月為:
……
十二月為:
總錢數為:
元
那麼全年總計應為元
或許編個程算會比較快吧= = 只是提供一種用紙筆計算的思路。。
粗略一算也許有錯也許有更好的演算法╮(╯▽╰)╭
最後吐槽一下,知乎這個公式編輯器真是太特么的難用了。。。 (╯°Д°)╯︵ ┻━┻
看到樓上 @Zhong Robert 給了 Mathematica 的方案,但是太長,其實一行就夠了:
ToExpression @ StringJoin @ (ToString /@ DatePlus[{2004, 1, 1}, #][[2 ;; 3]]) /@ Range[366] // Total
這裡選 2004 年是因為 2004 年是個閏年
截個圖
評論中 曹洪(at不到抱歉)提供了更短的:
Sum[FromDigits@StringJoin[ToString/@Rest@DatePlus[{2004,1,1},i]],{i,366}]
人生苦短,我用python
sum([int((date(2000, 1, 1) + timedelta(x)).strftime("%m%d")) for x in range(366)])
給個Excel數組公式的角度
=SUMPRODUCT(--TEXT("2011/12/31"+ROW(1:366),"md"))
提供一個R代碼
library(data.table)
dd&<-seq(as.IDate("2016-1-1"),as.IDate("2016-12-31"),by="1 day")
sum(as.numeric(paste(month(dd),mday(dd),sep="")))
結果是180987
將時間格式強制轉化為int再求和。。。
寫了一段很醜陋的代碼:
m1 = {1, 3, 5, 7, 8, 10, 12};
m2 = {4, 6, 9, 11};
m3 = {2};
d1 = Range[1, 31];
d2 = Range[1, 30];
d3 = Range[1, 28];
list1 = Tuples[{m1, d1}];
list1 = IntegerDigits /@ list1;
list1 = Flatten /@ list1;
list1 = FromDigits /@ list1;
list2 = Tuples[{m2, d2}];
list2 = IntegerDigits /@ list2;
list2 = Flatten /@ list2;
list2 = FromDigits /@ list2;
list3 = Tuples[{m3, d3}];
list3 = IntegerDigits /@ list3;
list3 = Flatten /@ list3;
list3 = FromDigits /@ list3;
Total[list1] + Total[list2] + Total[list3]
運行結果是:180758
這裡把2月當成了28天,如果閏年則再加上229就好了。
修改了一下代碼,不知道是更好了,還是更難看懂了:
Total[Join[FromDigits /@
Map[Flatten,
Map[IntegerDigits,
Tuples[{{1, 3, 5, 7, 8, 10, 12}, Range[1, 31]}]]],
FromDigits /@
Map[Flatten,
Map[IntegerDigits, Tuples[{{4, 6, 9, 11}, Range[1, 30]}]]]
, FromDigits /@
Map[Flatten, Map[IntegerDigits, Tuples[{{2}, Range[1, 28]}]]]]]
Haskell version:
需要先
import Data.Time.Calendar.MonthDay
print $ sum $ map ((x,y) -&> read (show x ++ show y) :: Int) $ map (dayOfYearToMonthAndDay True) [1..366]
用vb算:
dim i as date
dim s as long
dim j as long
s=0
i="1999/12/31"
for j=1 to 366
s=s+val(format(i+j,"mmdd"))
next
for j=1 to 12
s=s-810*j
next
msgbox s
讓我慢慢算算…
(1+2+。。+9)*12 + (1+2+。。+12)*10*9 這是12個月1號到9號的錢
+(10+11+。。+30)*12 + (1+2+。。+12)*100 * 21這是12個月10號到30號的錢
+31*7+(1+3+5+7+8+10+12)*100 這是7個31號的錢
- 230-229 如果閏年減一個,否則減兩個。
11~19
110~131
21~29
210~229
30~39
310~331
……
91~99
910~930
101~109
1010~1031
111~119
1110~1130
121~129
1210~1231
然後110~130~~~~1210~1230(131、-230、331、531、731、831、1031、1231)
這樣看起來,不論怎麼算,都簡單明了~~
推薦閱讀: