[TDD][Codewars]Number of People in the Bus

Codewars 上隨機挑到的題目:Number of People in the Bus

【題目描述】

Number of people in the bus

There is a bus moving in the city, and it takes and drop some people in each bus stop.

You are provided a list (or array in JS) of integer array. Each integer array has two items which represent number of people get into bus (The first item) and number of people get off the bus (The second item).

The first integer array has 0 number in the second item, since the bus is empty in the first bus stop.

Your task is to return number of people in the bus after the last bus station. Take a look on the test cases :)

Please keep in mind that the test cases ensure that the number of people in the bus is always >= 0. So the return integer can't be negative.

看測試案例比較好懂:

題目解釋:每一個 int[] 都有兩個正整數,第一個代表上車的乘客數,第二個代表下車的乘客數。最後的結果就是車子上還剩多少人。

Step 1: 新增測試案例,只有一個 station

【測試代碼】

【生產代碼】

Step 2: hard-code 回傳 p[0][0] - p[0][1]

【生產代碼】

先針對單一個 item hard-code 處理,等等只需要把 index = 0 的部分替換成 for loop 的 i 即可。

【重構測試代碼】擷取方法,將驗證行為封裝到 RemainPassengerShouldBe() 裡。

Step 3: 新增測試案例,有兩個 station 的情況

【測試代碼】

【生產代碼】hard-code,當還有第二個 station 時,累加 remainPassengerCount

Step 4: 新增測試案例,有三個 station 的情況

【測試代碼】重複了三次類似的處理,逼出生產代碼使用 loop。

【生產代碼】一樣先 hard-code,通過測試案例後,再重構出 for loop。

【重構】擷取方法,將 remainPassgerCount 的計算抽到 RemainPassengerCountOfCurrentStation() 中,避免同樣的計算重複三份。

【重構】以 for loop 取代 hard-code 的 [0], [1], [2] index。

【通過 Codewars 上所有測試案例】

【重構】使用 LINQ 的 Aggregate() 來取代這個 for loop 的行為,讓語意更加清楚。

一行搞定這個 Aggreate 的行為!

結論

寫 LeetCode 久了,突然看到這樣的題目,一直在想是不是哪邊有陷阱。結果真的是一題單純到爆炸,單純考會不會寫程式的考題。

但我還是決定用 TDD 一路驅動跟重構出最後版本的代碼,希望可以提供給剛入門的朋友當參考。 

GitHub commi history: Codewars_NumberOfPeopleInTheBus
大部分的 LINQ 都是在封裝 foreach loop 的巡覽行為,賦予其更簡單、有彈性、易讀的寫法,這種先寫出 loop 再重構成 LINQ,是學習 LINQ to object 本質很重要的一個脈絡。練久了,你就有火眼金睛,看到那些看似複雜的 foreach loop, 可以對照到是否可以重構成 LINQ 的 API 來表示。

對敏捷開發有興趣的朋友,可以參考我的粉絲專頁:91敏捷開發之路

若需要聯絡我,可以透過粉絲專頁私訊或是側欄的關於我。