Search This Blog

Sunday, March 27, 2016

萬丈高樓由地起

話說 Facebook 度出現咗一條小學生嘅題目:

   AB
-  CD
-----
   EF
+  GH
-----
  PPP


有人寫 Code 去計答案出嚟。趁假期得閒,貪得意玩埋一份。屋企唔想開 Visual Studio, 就走咗去 https://dotnetfiddle.net/.

因為多過一個答案,Brute force 難免,問題只係點樣解決得靚啲。觀察所得,係 AB-CD=EF 同 EF+GH=PPP 嘅解法一樣,Divide and Conquer, 即係解到 EF+GH=PPP, 就基本上解咗題。所以得出第一個版本係咁:


好快就可以意識到,只係 j 嘅計法唔同,加上
x.Add(n / 10);
x.Add(n % 10);
呢兩句太過累贅,於是就變成咁:


之後就見到擺入 HashSet 嗰嘅數字,只係作為 Validation 嘅準備,可以 Refactor 成一個 IsValid 嘅 Delegate; 然後再將 AddDigits() 簡化為 CountDigits():


睇住個 Calc(), 覺得 value 不大,因為只係一個 Loop 入面有個 if, 於是就直接將佢 Inline 入個 Main() 度; CountDigits() 用 LINQ 一句 KO 埋:


最後,想用最少嘅 Code 做嘢; 掉走埋 CountDigits(); 改返 ab, cd, ef, gh, ppp 做 variable 名; 執走第一個 if; fix 埋 p = 1 呢個已知數:


再貪玩少少,用 LINQ 代替兩個 Loop:


或者好多人會覺得寫一大段 Code 去解決一條小學生嘅題目係無聊,唔夠 Cost Effective. 但係每個 Software Engineer, 都要有解決問題嘅熱誠。呢個 Exercise, 由一開始 Divide and Conquer 嘅想法,Refactor 成一條 LINQ 攪掂,係完全意想不到。可能做唔到傳說中嘅 Python 咁5行攪掂 (到呢一刻都未搵到個傳說响邊),但其實 C# 一啲都唔失禮。Ceremony vs Essence 嚟講,C# 都算係咁 (斜視 Java 中)。

大慨,呢個世界上有多過一個方法去解決問題,而大家都想搵最好嘅方法,最好可以係最快、最少 Code, 最 readable, 最 reusable, 最 maintainable 等等,無絕對標準的 (最快都重要分寫得快同行得快),响各方面達致平衡,就係 Software Engineering 引人入勝嘅地方。

既然平時返工要趕 Project 無時間要左抄右抄,放假有時間偶爾寫吓完全屬於自己認為最好嘅 Code, 何樂而不為?

P.S. 有無人識將呢句 Fluent style 嘅 LINQ 變成 Query style: new int[]{ef, gh, ab, cd}.SelectMany(o => new int[]{ o / 10, o % 10}).Distinct().Where(o => o != 1)

No comments:

Popular Posts