APL實在是code golfing的利器。 今日突然想練一練code golf,馬上到 code-golf.io 看看,見到一道列印首二十行 Pascal Triangle 的題目,而排行第一的挑戰者居然使用了52個字元的答案。直覺告訴我APL應該可以更精煉,於是決定試試挑戰。 先公佈我的題解,只需要26個字元: 題目比預期中難,用了差不多半個小時仍然處理不好base case,即單一元素的陣列{1}。按下面來自維基的示範,當輸入為陣列V = {1, 3, 3, 1},應先將第1、2個元素相加並得出新元素1 + 3 = 4,如是者再重複相加第2、3及3、4個元素,得出新元素3 + 3 = 6與3 + 1 = 4: (圖片鏈結自 維基百科 ) 於是問題便轉化為產生陣列{1, 3, 3, 1}的指標的二元組(2-tuple) {1, 2},{2, 3},{3, 4}。用以存取陣列V的元素,並相加起來: 再費一些功夫抽取對角線上的元素{4, 6, 4}便可以了,感覺好像快將完成解答。 幾個想法突然湧現: 這樣的程式碼只是將程序式編程(procedural programming)的思維照搬不誤 程式碼極為欠缺美感,且勢必多於52個字元 致命的是,當陣列V為{1}的時候,會引致錯誤 原因係當V為{1}時, ⍴(¯1↓⍳⍴V) (1↓⍳⍴V) 的外積(outer product)是空的二維陣列,導致匿名函數 {+/V[⍺ ⍵]} 發生錯誤。縱使以常理推斷,陣列中沒有任何元素的時候,前述的函數應該不會被呼叫才對。例如python之中將必然拋出錯誤的lambda用於空陣列上: 再仔細思考,輸入陣列{1, 3, 3, 1}時只需要將輸入去掉頭、尾 (即{1, 3, 3}與{3, 3, 1})相加便可得出{4, 6, 4},再無條件地將{1}置於{4, 6, 4}的頭、尾,就可以得出Pascal Triangle的第五行{1, 4, 6, 4, 1}。 直觀地翻譯為APL,就得出題解使用的 匿名函數 {1,⍨1,(¯1↓⍵)+1↓⎕←⍵} ,最重要係當輸入為純量1或者陣列{1}時,輸出都會係{1, 1}。 不太理解為何其他參與者不用 J語言...
留言
張貼留言