|
Publicité ' | ||||||||||||||||||||||||
|
|
#101 | |
|
Inactif
Inscription : juillet 2005 Messages : 1 958 ![]() |
Citation:
Je pense que tu dois passer par un let. Mais je vérifierais. |
|
|
|
00
|
|
|
#102 |
|
Membre à l'essai
![]() Inscription : avril 2008 Messages : 18 ![]() |
Mes recherches n'ont abouti à rien pour le Scheme standard, tandis que comme cité plus haut, il existe #!optional en MIT/GNU Scheme.
> http://www.gnu.org/software/mit-sche...pressions.html Hum, après relecture, le #!optional ne permet pas de donner une valeur par défaut de manière plus concise qu'avec un let. |
|
|
00
|
|
|
#103 | ||||
|
Invité régulier
![]() Inscription : novembre 2004 Messages : 8 ![]() |
bonjour,
voici un petit jeu de ping pong contre l'ordi touche flèches haut bas pour déplacer la raquette... je débute en scheme et mon but est de tester les approches impératives et fonctionnelles. je me demande comment programmer en style fonctionnel. j'ai fait un essai, mais le programme est plus "lourd" à mon gout. voici la version non fonctionnelle (classes + style impératif) les classes : figure% : image 2D pouvant monter ou descendre mobile% : figure% pouvant se déplacer dans toutes les directions mobile-rebondissant% : mobile% rebondissant contre les parois ou les raquettes joueur% : mobile% avec déplacement automatiqueles objets : la balle de type mobile-rebondissant% la raquette gauche de type joueur% (l'ordinateur) la raquette droite de type mobile% (vous) Code :
Code :
|
||||
|
|
00
|
|
|
#104 | ||||
|
Futur Membre du Club
![]() |
Écrire la lambda-expression pour la transformation de la liste (a b c d e), comprenant de cinq éléments, vers l'aspect correspondant à la variante
((d . a) b (e c)) Code :
ou Code :
|
||||
|
|
00
|
|
|
#105 | ||
|
Futur Membre du Club
![]() |
transformer la liste (asd123ddd34 ff23gg66 gg6h7) vers
(12334_asdddd 2366_ffgg 67_ggh) vloila le code Code :
|
||
|
|
00
|
|
|
#106 | ||
|
Inactif
Inscription : juillet 2005 Messages : 1 958 ![]() |
Alors là je suis perplexe… à quoi ceci peut-il servir ?
Le but n'est pas de mettre du code pour du code, mais des éléments pertinents comme des fonctions classiques par exemple. De surcroit, e n'est pas très bien présenté et certains morceaux sont douteux. Quel est l'intérêt de mettre un lambda ici ? Code :
|
||
|
|
00
|
|
|
#107 | ||
![]() ![]() Damien GuichardInscription : juin 2007 Messages : 1 513 ![]() |
Partie IX. Application aux tableaux extensibles
Code OCaml :
merci à bluestorm pour ses corrections et ses propositions d'amélioration.
__________________
Du même auteur: le cours OCaml, le dernier article publié, le projet, le blog dvp et le jeu vidéo. Avant de poser une question je lis les règles du forum. |
||
|
00
|
|
|
#108 | ||||
|
Membre Expert
![]() Inscription : avril 2007 Messages : 829 ![]() |
J'ai l'impression que le code actuel de l'opération set est faux :
Code OCaml :
Dans le cas Leaf, "grow" renvoie un arbre, qui n'est jamais utilisé puisque tu ignore. Pour avoir une version correcte il faut rendre les champs "plus" et "minus" mutable et faire : Code OCaml :
Au passage, toutes ces bidouilles de plus/minus sont assez laides et n'apportent pas grand chose. On pourrait pas s'en débarrasser ? Tu perdrais rien en pédagogie et gagnerait beaucoup en clarté. |
||||
|
|
00
|
|
|
#109 | ||||||||||||||
|
Membre Expert
![]() Inscription : avril 2007 Messages : 829 ![]() |
Bon, c'est mort. On regarde un code, on voit un truc à améliorer, on essaie. Puis un autre. Puis un autre. Puis après ça ressemble plus du tout, et on a perdu la trace de l'ordre des modifications. Donc, pavé en vrac avec tout d'un coup.
D'abord, on vire les "plus/minus". Comment ? Il suffit de considérer le type "t" comme équivalent au type "node" : on crée un noeud supplémentaire, en mettant les indices négatifs à gauche, et les indices positifs à droite. Ensuite, il suffit de faire une traduction "indice réel" (donné par l'utilisateur) vers "indice non signé" (servant à naviguer dans le noeud spécial de signe) : Code OCaml :
À quoi ressemblent nos types maintenant ? Code OCaml :
Pourquoi ('a option) dans l'item ? Parce qu'au lieu d'avoir des "defaults" laid, on met "None" quand aucune valeur n'a été choisie, et "Some ..." quand une valeur a été choisie. Ok, c'est légèrement couteux, mais le code est plus joli et la structure plus correcte à utiliser (en particulier to_alist arrête de se chier dessus quand on a créé plein de noeuds intermédiaires "vides" en ajoutant une valeur). Pourquoi ('a tree ref) au lieu du bon vieux mutable ? Parce que ça permet d'utiliser le même "objet", à la fois pour accéder à une branche de l'arbre, et pour la modifier. On peut donc factoriser les fonctions de navigation en fonction de l'indice (les opérations de bit shifting laides, là) : Code OCaml :
Vous avez remarqué l'analogie très classe avec les listes ? Moi aussi. Après ces petites modifications cosmétiques, voici la fonction get : Code OCaml :
Et la fonction set : Code OCaml :
On peut noter que l'"optimisation" est formulée en une seule ligne, mais actuellement complètement inutile, puisque l'utilisateur peut ajouter seulement des valeurs du type "Some ..", et pas de None. Il faudrait étendre l'interface de set pour prendre un type option, ou alors : Code OCaml :
La fonction foldi, et sans la duplication plus/minus, quand même. Code :
Au passage, on peut noter que le "fold" présenté ici n'est pas un vrai fold sur les arbres, c'est un fold sur les listes d'éléments de l'arbre (dans un sens arbitraire). C'est pour cela que l'on n'arrive pas à en construire map; il faudrait utiliser un fold qui respecte la structure de l'arbre. Cependant, ce serait sans doute aussi lourd à faire que le fold+map actuel, et surtout l'utilisateur a envie de voir seulement le fold linéaire actuel, et pas un "vrai" fold sur les arbres, qui révèle l'implémentation de la structure sous-jacente. |
||||||||||||||
|
|
00
|
|
|
#110 | ||||||
![]() ![]() Damien GuichardInscription : juin 2007 Messages : 1 513 ![]() |
Citation:
Citation:
Citation:
Citation:
(mais c'est pas testé non plus) Citation:
La partie précédente Partie VIII. Les types algébriques contenait déjà le fold sur les arbres binaires et le map construit avec. Citation:
Avec tes ref tu perds totalement la similitude que j'avais entretenue entre la version mutable et la version immutable, similitude dont je me sers (dans le texte) pour introduire le {r with a = b}.
__________________
Du même auteur: le cours OCaml, le dernier article publié, le projet, le blog dvp et le jeu vidéo. Avant de poser une question je lis les règles du forum. |
||||||
|
00
|
|
|
#111 | |||||||||||
|
Membre Expert
![]() Inscription : avril 2007 Messages : 829 ![]() |
Disclaimer : aucun des codes de ce post n'a été testé (ni même compilé).
Citation:
Ainsi, "map" s'écrit : let map f = fold (fun (a, li) -> Node (f a, li)) Citation:
Code :
Code :
else head i node := tree (tail i) !(head i node); Citation:
Code :
Code :
Cependant, cette version du code peut être adaptée en retour vers le code impératif : Code :
|
|||||||||||
|
|
00
|
|
|
#112 | |||
![]() ![]() Damien GuichardInscription : juin 2007 Messages : 1 513 ![]() |
Citation:
(je vais révoir ce passage) Sinon, il est vrai qu'il y a certains raccourcis, ce sont des arbitrages que j'ai fait, souvent volontairement. Par exemple, le prédicat ordered utilise une inégalité large: Code :
__________________
Du même auteur: le cours OCaml, le dernier article publié, le projet, le blog dvp et le jeu vidéo. Avant de poser une question je lis les règles du forum. |
|||
|
00
|
|
|
#113 |
![]() ![]() Damien GuichardInscription : juin 2007 Messages : 1 513 ![]() |
J'ai mis à jour la source du module Vect pour que ni le fold ni le foldi ne traversent les noeuds contenant la valeur par défaut (que cette valeur soit None ou autre).
Quant au module Shared, pour ne pas avoir à dupliquer la source (c'est pénible quand je dois faire des modifications en plusieurs endroits, souvent avec coloration syntaxique dans deux langages de balise différents), je vous renvoie à la lecture de mon billet blog : http://blog.developpez.com/damien-gu...noeud#more6857
__________________
Du même auteur: le cours OCaml, le dernier article publié, le projet, le blog dvp et le jeu vidéo. Avant de poser une question je lis les règles du forum. |
|
00
|
|
|
#114 | ||
![]() ![]() Damien GuichardInscription : juin 2007 Messages : 1 513 ![]() |
Un Mutable.Set higher-order module.
J'ai trop besoin de la fonction zip_intersect, c'est essentiellement ça qui m'empêche d'utiliser le module standard Set.Make. (voir mon billet blog pour plus de détails) Ce module ne contient que le minimum nécessaire pour implémenter les modules qui suivent, de ce fait il lui manque plein d'opérations qu'on serait en droit d'attendre d'un module Set. Je vous laisse compléter en cas de besoin. Code OCaml :
__________________
Du même auteur: le cours OCaml, le dernier article publié, le projet, le blog dvp et le jeu vidéo. Avant de poser une question je lis les règles du forum. |
||
|
00
|
|
|
#115 | ||
![]() ![]() Damien GuichardInscription : juin 2007 Messages : 1 513 ![]() |
Un module-type pour les plateaux de jeu.
Typiquement la fonction compare servira à placer les positions de jeu dans une table de transposition (à l'aide du module Set). Code OCaml :
__________________
Du même auteur: le cours OCaml, le dernier article publié, le projet, le blog dvp et le jeu vidéo. Avant de poser une question je lis les règles du forum. |
||
|
00
|
|
|
#116 | ||
![]() ![]() Damien GuichardInscription : juin 2007 Messages : 1 513 ![]() |
Un higher-order module pour solutionner des problèmes sur les plateaux de jeu.
Code OCaml :
__________________
Du même auteur: le cours OCaml, le dernier article publié, le projet, le blog dvp et le jeu vidéo. Avant de poser une question je lis les règles du forum. |
||
|
00
|
|
|
#117 | ||||||||||
![]() ![]() Damien GuichardInscription : juin 2007 Messages : 1 513 ![]() |
Un plateau de jeu pour le Rubik's Cube Pocket (La version 2 x 2 x 2 du cube classique).
Code OCaml :
Création du module solveur de pocket-cube : Code :
Code :
Oubli forcé du cheminement vers la position initiale : Code :
Code :
__________________
Du même auteur: le cours OCaml, le dernier article publié, le projet, le blog dvp et le jeu vidéo. Avant de poser une question je lis les règles du forum. |
||||||||||
|
00
|
|
|
#118 | ||||
![]() ![]() Damien GuichardInscription : juin 2007 Messages : 1 513 ![]() |
Petite analyse de complexité de la fonction Mutable.MakeSet.zip_intersect.
Vu que cette fonction est utilisée pour de la recherche bidirectionnelle les deux arbres à intersecter croisent dans les mêmes proportions, on va considérer qu'ils ont le même nombre d'éléments. Je note N ce nombre d'éléments. Code OCaml :
Chaque niveau dans l'arbre de recherche (soit 2 fois plus d'éléments) donne lieu à 3 appels récursifs à la fonction many. La complexité est donc de type Karatsuba c'est-à-dire N^(ln 3 / ln 2). Une alternative consisterait à traverser l'arbre ta pour en rechercher les éléments présents dans tb. La nouvelle complexité est N × ln N. Code OCaml :
Un test rapide montre que cette nouvelle version accélère d'au moins 20% la résolution du Pocket Cube. Même dans l'interpréteur de bytecode la très grande majorité des cubes sont résolus en moins d'une seconde
__________________
Du même auteur: le cours OCaml, le dernier article publié, le projet, le blog dvp et le jeu vidéo. Avant de poser une question je lis les règles du forum. |
||||
|
00
|
|
|
#119 | ||||||||
![]() ![]() Damien GuichardInscription : juin 2007 Messages : 1 513 ![]() |
J'ai volontairement effacé toutes les autres fonctions pour améliorer la lisibilité.
Code :
Les autres routines qui suivent sont applicables sur des arbres binaires ordonnés, dans un style 'mutable'. Evidemment ces routines ne sont pas applicables ni sur les arbres binaires qui implémentent des tas/files/queues ni sur les arbres de Braun. Dans le cas du style 'mutable' il faudra ajouter la référence, c'est-à-dire qu'il faudra changer loop t en loop !t ou bien en t := loop !t s'il y a modification de l'arbre. Le code peut facilement est modifié pour être fonctionnellement pur. Dans la plupart des cas il suffira par exemple d'écrire {n with left = r} au lieu de n.left <- r; n. Les trois routines suivantes permettent d'itérer sur un intervalle de clés dans un arbre binaire ordonné ('pur' ou bien 'mutable'). Code :
Code :
Une table de transposition est esentiellement une mémoisation pour la recherche. Pour les tables de transposition, j'ai utilisé cette fusion particulière qui itère sur les éléments insérés mais pas sur ceux qui étaient déjà présents dans la table. Code :
Code :
type 'a fold = (item -> 'a -> 'a) -> 'a -> t -> 'a La fonction merge_fold est un bi-itérateur, c'est-à-dire une fonction de type : Code :
type 'a fold2 = (item -> 'a -> 'a) -> 'a -> t -> t -> 'a Remarque: toutes les sources de ce message ont été testées.
__________________
Du même auteur: le cours OCaml, le dernier article publié, le projet, le blog dvp et le jeu vidéo. Avant de poser une question je lis les règles du forum. |
||||||||
|
00
|
|
|
#120 |
|
Membre Expert
![]() ![]() Inscription : septembre 2006 Messages : 1 036 ![]() |
Trois critiques, un peu dures, concernant tes AVL :
- ce ne sont pas des AVL : la grande caractéristique des AVL est qu'il n'est pas nécessaire de stocker la hauteur, mais juste l'équilibrage (gauche, équilibré ou droit). En effet, la différence de hauteur entre les deux jambes étant d'au plus un, cette information suffit. - je te conseille de commencer par les implanter dans un module entièrement fonctionnel, avec ds structures de données non modifiables. C'est 1000 fois plus facile à débugger. - les fonctions sur AVL ne sont d'aucune utilité si elles ne sont pas accompagnées d'une fonction de suppression d'élément (c'est en fait LA fonction difficile à implanter) Je connais très bien les AVL, pour en avoir fait plusieurs implantations tant en C, qu'en Haskell ou qu'en OCaml. Il est, malheureursement, très rare de voir une librairie complète contenant une véritable implantation efficace de cette merveilleurse structure de données. La seule, à mes yeux, réellement intéressante est la libAVLmap de GNU. Le gros avantage des AVL réside dans leur performance : il est donc inutile d'en implanter si on peut avoir mieux avec autre chose. Je te conseille de comparer ton module, au niveau performances, avec Set et Map de la librairie standard. Si il est plus lent, alors c'es que tu as foiré. Essaye avec des arbres d'au moins 4 millions d'éléments : en-dessous, c'est un peu pipeau comme test (en fait, jusqu'à bourrer toute la mémoire de ton ordi : c'est ce que je faisais à l'époque). De mémoire, mon implantation fonctionnelle des AVL était environ entre 20% et 30% plus rapide que Set et Map à données égales. Celle impérative, était environ 10 fois plus rapide. C'est normal : le temps GC est borné (O(1)), contrairement à l'implantation fonctionnelle. Autre conseil : ne suis pas les "conseils" de Knuth. Ses algorithmes sont inutilement compliqués. On peut faire tout aussi mieux sans pile ni impérativité.
__________________
When Colt produced the first practical repeating handgun, it gave rise to the saying God created men, but Colt made them equal. |
|
|
00
|
Copyright © 2000-2013 - www.developpez.com