CodeWars-Tribonacci Sequence

這是記錄CodeWars的第二篇文章

今天這題挺有意思的,借這題正好可以理解Python的靈活剥悟。

一.題目

Tribonacci Sequence

Well met with Fibonacci bigger brother, AKA Tribonacci.

As the name may already reveal, it works basically like a Fibonacci, but summing the last 3 (instead of 2) numbers of the sequence to generate the next. And, worse part of it, regrettably I won't get to hear non-native Italian speakers trying to pronounce it :(

So, if we are to start our Tribonacci sequence with [1, 1, 1] as a starting input (AKA signature), we have this sequence:

[1, 1 ,1, 3, 5, 9, 17, 31, ...]

But what if we started with [0, 0, 1] as a signature? As starting with [0, 1] instead of [1, 1] basically shifts the common Fibonacci sequence by once place, you may be tempted to think that we would get the same sequence shifted by 2 places, but that is not the case and we would get:
[0, 0, 1, 1, 2, 4, 7, 13, 24, ...]

Well, you may have guessed it by now, but to be clear: you need to create a fibonacci function that given a signature array/list, returns the first n elements - signature included of the so seeded sequence.

Signature will always contain 3 numbers; n will always be a non-negative number; if n == 0, then return an empty array and be ready for anything else which is not clearly specified ;)

一些英語(yǔ)單字:
1.Fibonacci 和 Tribonacci
Fibonacci 即 斐波那契數(shù)列,即從第三項(xiàng)開(kāi)始,每一項(xiàng)都由該項(xiàng)前兩位加起來(lái)得到,例如
[1,2,3,5,8,13]
第三項(xiàng)1+2=3
第四項(xiàng)2+3=5
第五項(xiàng)3+5=8
而Tribonacci數(shù)列則是由前三項(xiàng)加起來(lái)得到的夺溢。(本題就是在介紹Tribonacci數(shù)列)

2.AKA
又叫做,亦稱(Also Known As的縮寫)

3.That is not the case
事實(shí)并非如此

4.tempted
原型是tempt v.吸引烛谊,誘惑风响。
you may be tempted to think that...
查字典是吸引和誘惑的意思,但覺(jué)得怎樣都翻譯的不是很通順丹禀,后來(lái)想起來(lái)一個(gè)詞——誘導(dǎo)状勤。
你也許被(Fibonacci的例子)誘導(dǎo),認(rèn)為...blahblah
??

上面這段英文翻譯起來(lái)就是

好的双泪,我們現(xiàn)在遇到了Fibonacci(斐波那契數(shù)列)的哥哥持搜,Tribonacci。

也許從它的名字你就能想到焙矛,它和Fibonacci的計(jì)算機(jī)制很像葫盼,但是!它通過(guò)累加序列的最后三個(gè)數(shù)字(而不是兩個(gè))而去形成下一個(gè)數(shù)字村斟。而且贫导,更糟的部分是,我不想聽(tīng)母語(yǔ)不是意大利語(yǔ)的人發(fā)這個(gè)單詞的音蟆盹。
(??這么傲嬌的嘛)

所以如果我們以序列[1,1,1]作為起始序列輸入(這個(gè)序列又稱signature)孩灯,我們可以得到下面這個(gè)序列

[1, 1 ,1, 3, 5, 9, 17, 31, ...]

但是,如果我們以[0,0,1]作為signature呢逾滥?在Fibonacci序列中以[0,1]開(kāi)頭而不是[1峰档,1]開(kāi)頭的話,僅僅只是整個(gè)序列右移了一位寨昙,你也許被誘導(dǎo)就覺(jué)得我們會(huì)得到同樣的序列只是整個(gè)序列向右移了兩位面哥。圖樣圖森破!我們會(huì)得到
[0, 0, 1, 1, 2, 4, 7, 13, 24, ...]
( ??真的是跟[1,1,1]作為輸入的完全不一樣耙愦)

好的,你也許已經(jīng)猜到了我們要做什么归榕,但需要申明的是:你需要?jiǎng)?chuàng)造一個(gè)fibonacci function尸红,這個(gè)函數(shù)輸入序列,返回前n個(gè)元素。

Signature總是包含3個(gè)數(shù)字外里;n一定是非數(shù)整數(shù)怎爵。如果n等于0,就返回一個(gè)空列表盅蝗。

初始代碼

def tribonacci(signature, n)

舉個(gè)栗子

Test.describe("Basic tests")
Test.assert_equals(tribonacci([1, 1, 1], 10), [1, 1, 1, 3, 5, 9, 17, 31, 57, 105])
Test.assert_equals(tribonacci([0, 0, 1], 10), [0, 0, 1, 1, 2, 4, 7, 13, 24, 44])
Test.assert_equals(tribonacci([0, 1, 1], 10), [0, 1, 1, 2, 4, 7, 13, 24, 44, 81])
Test.assert_equals(tribonacci([1, 0, 0], 10), [1, 0, 0, 1, 1, 2, 4, 7, 13, 24])
Test.assert_equals(tribonacci([0, 0, 0], 10), [0, 0, 0, 0, 0, 0, 0, 0, 0, 0])
Test.assert_equals(tribonacci([1, 2, 3], 10), [1, 2, 3, 6, 11, 20, 37, 68, 125, 230])
Test.assert_equals(tribonacci([3, 2, 1], 10), [3, 2, 1, 6, 9, 16, 31, 56, 103, 190])
Test.assert_equals(tribonacci([1, 1, 1], 1), [1])
Test.assert_equals(tribonacci([300, 200, 100], 0), [])
Test.assert_equals(tribonacci([0.5, 0.5, 0.5], 30), [0.5, 0.5, 0.5, 1.5, 2.5, 4.5, 8.5, 15.5, 28.5, 52.5, 96.5, 177.5, 326.5, 600.5, 1104.5, 2031.5, 3736.5, 6872.5, 12640.5, 23249.5, 42762.5, 78652.5, 144664.5, 266079.5, 489396.5, 900140.5, 1655616.5, 3045153.5, 5600910.5, 10301680.5])

二.思路和代碼

思路:

剛弄懂題目大意的時(shí)候鳖链,首先想到啊。
傳入?yún)?shù):一個(gè)列表(signature)墩莫,一個(gè)非負(fù)整數(shù)(n)芙委。
返回:列表
n=0 不用操作返回空列表
n=1 不用操作返回列表第一個(gè)
n=2 不用操作返回列表前兩個(gè)
n=3 不用操作返回列表前三個(gè)
n>3開(kāi)始 進(jìn)行加法操作 返回n個(gè)

開(kāi)始覺(jué)得用一個(gè)新的列表記錄數(shù)值,然后用if判斷分別分成這五部分操作狂秦,
但是灌侣!
在寫最后一個(gè)情況n>3的時(shí)候,計(jì)算新一項(xiàng)的時(shí)候發(fā)現(xiàn)如果用下面這個(gè)覺(jué)得好麻煩裂问。

signature[-1]+signature[-2]+signature[-3]

我們有sum()這個(gè)內(nèi)置函數(shù)啊
把一個(gè)數(shù)值列表用sum()我們可以直接得到列表和侧啼,但這里我們只需要后三項(xiàng)啊,
沒(méi)錯(cuò)堪簿,就在這時(shí)想起了一個(gè)概念——分片(Slicing)痊乾。
signature[-1]這種稱為索引,用-1找到對(duì)應(yīng)位置的值
而像signature[2:5]這種被稱為分片椭更,代表一個(gè)列表哪审,該列表第一個(gè)元素是signature列表中索引2的元素,第二個(gè)元素是signature列表中索引3的元素甜孤,但不包括索引5的元素协饲。
例如列表
L=[4,5,6,7,8,9,10,11,12]
L[2:5]代表了一個(gè)列表,即[6,7,8] 沒(méi)有9是因?yàn)長(zhǎng)[5]=9,但我們不包括索引5.
除此之外缴川,還有L[2:5:-1]茉稠,即[8,7,6],在原有基礎(chǔ)上翻轉(zhuǎn)。
L[2:5:2]把夸,即[6,8],找到索引2后+2而线,找索引4。
非常的靈活恋日,不是嗎膀篮。

那我們就不用新的列表來(lái)記錄數(shù)值也不用if判斷不同情況
最后返回直接使用這句

   return signature[:n]

一句話解決了n=0到n=3的所有情況??????

代碼:

def tribonacci(signature,n):
    while len(signature) < n:
        signature.append(sum(signature[-3:]))
    return signature[:n]

代碼解析:

當(dāng)列表和n傳進(jìn)來(lái)時(shí),
如果n是0~3 那么len(signature) < n則為False岂膳。不會(huì)進(jìn)入while循環(huán)誓竿,直接返回分片后的列表
如果n>3,例如n=5谈截,那么len(signature) < n (即3<5) 為真
用append方法添加新元素筷屡。新元素為sum(signature[-3:])即signature列表后三位求和涧偷,然后不斷循環(huán)直到打破條件。

三.最優(yōu)解代碼

Best Practices

可以看到毙死,排序第一名的想法和我們差不多燎潮。也是利用Python中分片的思想。
但是更多的人和我想的一樣用while循環(huán) len(signature) < n來(lái)做判斷條件扼倘。我覺(jué)得我們第二組的可讀性更好确封,你覺(jué)得哪個(gè)好呢?

四.總結(jié)

Python是非常靈活再菊,列表的分片就是其中能體現(xiàn)靈活的機(jī)制爪喘。

你可以從一個(gè)列表中截一部分出來(lái)
L[2:5]
也可以間隔一個(gè)截取
L[2:5:2]
還可以截取后翻轉(zhuǎn)過(guò)來(lái)
L[2:5:-1]

當(dāng)然還有其他的玩法,等等你去發(fā)現(xiàn)啦袄简,學(xué)Python吧少年腥放。。 ??

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末绿语,一起剝皮案震驚了整個(gè)濱河市秃症,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌吕粹,老刑警劉巖种柑,帶你破解...
    沈念sama閱讀 207,248評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異匹耕,居然都是意外死亡聚请,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,681評(píng)論 2 381
  • 文/潘曉璐 我一進(jìn)店門稳其,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)驶赏,“玉大人,你說(shuō)我怎么就攤上這事既鞠∶喊” “怎么了?”我有些...
    開(kāi)封第一講書人閱讀 153,443評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵嘱蛋,是天一觀的道長(zhǎng)蚯姆。 經(jīng)常有香客問(wèn)我,道長(zhǎng)洒敏,這世上最難降的妖魔是什么龄恋? 我笑而不...
    開(kāi)封第一講書人閱讀 55,475評(píng)論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮凶伙,結(jié)果婚禮上郭毕,老公的妹妹穿的比我還像新娘。我一直安慰自己函荣,他們只是感情好显押,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,458評(píng)論 5 374
  • 文/花漫 我一把揭開(kāi)白布链韭。 她就那樣靜靜地躺著,像睡著了一般煮落。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上踊谋,一...
    開(kāi)封第一講書人閱讀 49,185評(píng)論 1 284
  • 那天蝉仇,我揣著相機(jī)與錄音,去河邊找鬼殖蚕。 笑死轿衔,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的睦疫。 我是一名探鬼主播害驹,決...
    沈念sama閱讀 38,451評(píng)論 3 401
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼蛤育!你這毒婦竟也來(lái)了宛官?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書人閱讀 37,112評(píng)論 0 261
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤瓦糕,失蹤者是張志新(化名)和其女友劉穎底洗,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體咕娄,經(jīng)...
    沈念sama閱讀 43,609評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡亥揖,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,083評(píng)論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了圣勒。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片费变。...
    茶點(diǎn)故事閱讀 38,163評(píng)論 1 334
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖圣贸,靈堂內(nèi)的尸體忽然破棺而出挚歧,到底是詐尸還是另有隱情,我是刑警寧澤旁趟,帶...
    沈念sama閱讀 33,803評(píng)論 4 323
  • 正文 年R本政府宣布昼激,位于F島的核電站,受9級(jí)特大地震影響锡搜,放射性物質(zhì)發(fā)生泄漏橙困。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,357評(píng)論 3 307
  • 文/蒙蒙 一耕餐、第九天 我趴在偏房一處隱蔽的房頂上張望凡傅。 院中可真熱鬧,春花似錦肠缔、人聲如沸夏跷。這莊子的主人今日做“春日...
    開(kāi)封第一講書人閱讀 30,357評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)槽华。三九已至壹蔓,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間猫态,已是汗流浹背佣蓉。 一陣腳步聲響...
    開(kāi)封第一講書人閱讀 31,590評(píng)論 1 261
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留亲雪,地道東北人勇凭。 一個(gè)月前我還...
    沈念sama閱讀 45,636評(píng)論 2 355
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像义辕,于是被迫代替她去往敵國(guó)和親虾标。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,925評(píng)論 2 344

推薦閱讀更多精彩內(nèi)容