triangularize :: [a] -> [[a]]
(おそらく無限の)リストを取り、それをリストのリストに「三角形化」する効率的なHaskell関数を書くことに興味があります。たとえば、triangularize [1..19]
返す必要があります
[[1, 3, 6, 10, 15]
,[2, 5, 9, 14]
,[4, 8, 13, 19]
,[7, 12, 18]
,[11, 17]
,[16]]
効率的には、リストの長さがO(n)
どこにあるのかを実行することを意味しn
ます。
リスト(配列)の末尾への追加は一定時間の操作であるため、これはPythonなどの言語で非常に簡単に実行できることに注意してください。これを実現する非常に命令的なPython関数は次のとおりです。
def triangularize(elements):
row_index = 0
column_index = 0
diagonal_array = []
for a in elements:
if row_index == len(diagonal_array):
diagonal_array.append([a])
else:
diagonal_array[row_index].append(a)
if row_index == 0:
(row_index, column_index) = (column_index + 1, 0)
else:
row_index -= 1
column_index += 1
return diagonal_array
これは、Haskellを使用して、整数シーケンスのオンラインエンサイクロペディア(OEIS)で「tabl」シーケンスを記述していて、通常の(1次元)シーケンスを(2-次元)シーケンスのシーケンスは、まさにこの方法で。
おそらくfoldr
、入力リストを整理するための巧妙な(またはそれほど賢くない)方法があるかもしれませんが、私はそれを整理することができませんでした。
foldr
場合よりも慣用的ですunfoldr (Just . combWith comb)
。悲しいかな私が私の回答の下で述べたようにcombWith
O(n)なので、受け入れられた回答の使用splitAt
は大幅に効率的です。