Souvent, une tâche nécessite de vrais tableaux. Prenez par exemple la tâche d'implémenter Befunge ou> <>. J'ai essayé d'utiliser le Array
module pour cela, mais c'est vraiment lourd, car j'ai l'impression de coder beaucoup trop verbeux. Quelqu'un peut-il m'aider à résoudre ces tâches de code-golf moins verbeuses et plus fonctionnelles?
11
Réponses:
Tout d'abord, je recommande de regarder Data.Vector , une alternative plus agréable à Data.Array dans certains cas.
Array
etVector
sont idéales pour certains cas de mémorisation, comme démontré dans ma réponse à "Trouver des chemins maximaux" . Cependant, certains problèmes ne sont tout simplement pas faciles à exprimer dans un style fonctionnel. Par exemple, le problème 28 du projet Euler appelle à additionner les nombres sur les diagonales d'une spirale. Bien sûr, il devrait être assez facile de trouver une formule pour ces nombres, mais la construction de la spirale est plus difficile.Data.Array.ST fournit un type de tableau mutable. Cependant, la situation de type est un gâchis: il utilise une classe MArray pour surcharger chacune de ses méthodes à l'exception de runSTArray . Donc, à moins que vous ne prévoyiez de retourner un tableau immuable à partir d'une action de tableau mutable, vous devrez ajouter une ou plusieurs signatures de type:
Néanmoins, ma solution à Euler 28 s'est avérée assez bien et ne nécessitait pas cette signature de type parce que je l'ai utilisé
runSTArray
.Utilisation de Data.Map comme un "tableau mutable"
Si vous cherchez à implémenter un algorithme de tableau mutable, une autre option consiste à utiliser Data.Map . Lorsque vous utilisez un tableau, vous souhaitez en quelque sorte avoir une fonction comme celle-ci, qui change un seul élément d'un tableau:
Malheureusement, cela nécessiterait de copier l'intégralité du tableau, à moins que l'implémentation n'utilise une stratégie de copie sur écriture pour l'éviter lorsque cela est possible.
La bonne nouvelle est,
Data.Map
a une fonction comme celle-ci, insérez :Parce qu'il
Map
est implémenté en interne comme un arbre binaire équilibré,insert
ne prend que du temps et de l'espace O (log n) et conserve la copie d'origine. Par conséquent,Map
non seulement fournit un "tableau mutable" quelque peu efficace qui est compatible avec le modèle de programmation fonctionnelle, mais il vous permet même de "remonter dans le temps" si vous le souhaitez.Voici une solution pour Euler 28 utilisant Data.Map:
Les modèles de bang empêchent un débordement de pile provoqué par les éléments de l'accumulateur (curseur, nombre et carte) qui ne sont pas utilisés jusqu'à la fin. Pour la plupart des golfs de code, les cas d'entrée ne devraient pas être assez grands pour avoir besoin de cette disposition.
la source
La réponse simple est: n'utilisez pas de tableaux. La réponse n'est pas si simple: essayez de repenser votre problème afin qu'il n'ait pas besoin de tableaux.
Souvent, un problème avec une réflexion peut être fait sans aucune structure de type tableau du tout. Par exemple, voici ma réponse à Euler 28:
Ce qui est exprimé dans le code ici, c'est le modèle de la séquence des nombres qui se développent autour de la spirale rectangulaire. Il n'était pas nécessaire de représenter réellement la matrice des nombres elle-même.
La clé pour penser au-delà des tableaux est de réfléchir à la signification réelle du problème, et non à la façon dont vous pouvez le représenter sous forme d'octets dans la RAM. Cela vient juste avec la pratique (peut-être une raison pour laquelle je code tellement au golf!)
Un autre exemple est la façon dont j'ai résolu la recherche de codes maximaux de code-golf. Là, la méthode de passage des solutions partielles sous forme d'onde dans la matrice, ligne par ligne, s'exprime directement par l'opération de pliage. Rappelez-vous: Sur la plupart des CPU, vous ne pouvez pas traiter le tableau dans son ensemble à la fois: le programme devra fonctionner à travers lui au fil du temps. Il peut ne pas avoir besoin de l'ensemble du tableau à la fois à tout moment.
Bien sûr, certains problèmes sont énoncés de telle manière qu'ils sont intrinsèquement basés sur des tableaux. Des langues comme> <>, Befunge ou Brainfuck ont des tableaux à leur cœur. Cependant, même là, les tableaux peuvent souvent être supprimés. Par exemple, voir ma solution pour interpréter Brainfuck , le véritable noyau de sa sémantique est une fermeture éclair . Pour commencer à penser de cette façon, concentrez-vous sur les modèles d'accès et la structure plus proche de la signification du problème. Souvent, cela n'a pas besoin d'être forcé dans un tableau mutable.
Lorsque tout le reste échoue et que vous devez utiliser un tableau - les conseils de @ Joey sont un bon début.
la source