Let's Split!
這是2020年度的Dyalog APL的其中一道題目在,此分享一下解答過程的思考歷程。
先看看題目:
簡單解說一下:寫出函數 F,右引數 Y 可以為向量或陣列,左引數 X 為任何非零的數字,任何情況下返回一個陣列 C。當 X 為正數時,C 的第一個元素包含 Y 的首 X 個元素,C 的第二個因素為餘下之 Y 的元素;當 X 為負數時,C 的第一個元素包含 Y 的尾 X 個元素,C 的第二個因素為餘下之 Y 的元素。
好似越講越複雜,還是看看上圖的示例比較直觀,反正就係 "split" 嘛。
過往,要不使用 if-else 邏輯的情況下同時處理向量、陣列輸入會有點困難。不過題目裏面貼心地提示可以使用 ↑ (take) 函數。而 ↑ 函數正好可以"乾淨地"解決這問題。示範一下 ↑、↓ 的用法:
3 ↑ Y 意思即從 Y 中提取 (take) 頭3個元素。當左引數為負數時,將從 Y 的末端取出相應數量元素:
而另一個相反效應的函數係 ↓ (drop),果效正如其名字:
以同一個數字 X 同時 take、drop 同一個陣列,就可達到分開陣列的效果:
不過題目還要求左引數為負數時,末段的元素要放置在輸出的前方。抽象一點理解,即係有條件地反轉上面輸出的陣列的兩個元素。於是之前介紹過的 ⍣ (power) 運算子便派上用場,用於有條件地呼叫 ⊖ (rotate) 函數一次:
由於 take、drop 本身可以處理向量及陣列輸入,上面的表達式同樣可以正確分隔向量成為單一因素的陣列,以及一個空陣列(否則過不了 Dyalog 網頁的 test case):
綜合上述後的答案是: {(⊖⍣(⍺<0)) (⍺↑⍵) (⍺↓⍵)}
留言
張貼留言