Je suis intéressé par l'écriture d'une fonction Haskell efficace triangularize :: [a] -> [[a]]
qui prend une liste (peut-être infinie) et la "triangularise" en une liste de listes. Par exemple, triangularize [1..19]
devrait retourner
[[1, 3, 6, 10, 15]
,[2, 5, 9, 14]
,[4, 8, 13, 19]
,[7, 12, 18]
,[11, 17]
,[16]]
Par efficace, je veux dire que je veux qu'il fonctionne en O(n)
le moment où n
est la longueur de la liste.
Notez que cela est assez facile à faire dans un langage comme Python, car l'ajout à la fin d'une liste (tableau) est une opération en temps constant. Une fonction Python très impérative qui accomplit ceci est :
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
Ce problème est apparu parce que j'ai utilisé Haskell pour écrire des séquences "tabl" dans la base de données de l'UE. Encyclopédie en ligne des séquences de nombres entiers (OEIS), et je veux pouvoir transformer une séquence ordinaire (à une dimension) en une séquence de séquences (à deux dimensions) exactement de cette manière.
Peut-être qu'il y a une façon intelligente (ou pas si intelligente) de foldr
sur la liste d'entrée, mais je n'ai pas réussi à la démêler.