bseb67 Posté(e) le 16 octobre 2007 Posté(e) le 16 octobre 2007 Et voilà, Mon premier challenge :)! En plus c'était mon numéro de maillot dans mon club de foot. Le but de ce challenge est de faire un petit jeu, on fera 2 parties. La première sera une préparation du terrain. Je vois déjà des :casstet: :o :exclam: . La première est je pense plus difficile que la seconde. Voilà le sujet de la première partie, qui est en fait deux fonctions: 1° (defun genere( nb)) => on doit renvoyé une liste de nb lettres de l'alphabetex: (genere 3) => '("a" "d" "p") 2° (defun combi( lst min)) => lst est une liste de nb lettres de l'alphabet, et on doit renvoyé toutes les listes possibles de sorte que les éléments de lst soient triés alphabétiquement et que l'on prenne de nb à min lettres. (Je sais pas trop si cela va être clair, alors voici la suite de l'exemple)ex: (combi '("a" "d" "p") 1) => '(("a" "d" "p") ("a" "d") ("a" "p") ("d" "p") ("a") ("d") ("p")) VOilà. On va attendre ce week-end pour donner des premiers jets. Bonne soirée. Tous pour lisp, Lisp pour tous!Avec Revit, cela ne vas trop vite...
(gile) Posté(e) le 16 octobre 2007 Posté(e) le 16 octobre 2007 Salut, Pour le premier, les lettres de la liste doivent elle être toutes différentes, ou peut_il y avoir des doublons, triplettes... ? Gilles Chanteau - gileCAD - GitHub Développements sur mesure pour AutoCAD
bseb67 Posté(e) le 16 octobre 2007 Auteur Posté(e) le 16 octobre 2007 Salut Gile, les lettres de la liste doivent elle être toutes différentes, Non, on peut avoir plusieurs fois la même, mais ce serai mieux d'avoir nb/2 lettres différentes.Sinon le jeu risque d'être balaise. [Edité le 16/10/2007 par bseb67] Tous pour lisp, Lisp pour tous!Avec Revit, cela ne vas trop vite...
(gile) Posté(e) le 16 octobre 2007 Posté(e) le 16 octobre 2007 Alors avec ("b" "a" "c" "a") la routine doit retourner : '(("a" "a" "b" "c")("a" "a" "b")("a" "a" "c")("a" "b" "c")("a" "b" "c")("a" "a")("a" "b")("a" "b")("a" "c")("a" "c")("b" "c")("a")("a")("b")("c")) ou doit-elle supprimer les doublons ? Gilles Chanteau - gileCAD - GitHub Développements sur mesure pour AutoCAD
bseb67 Posté(e) le 16 octobre 2007 Auteur Posté(e) le 16 octobre 2007 Re salut! Tu t'ennuies vraiment le soir? ;). Oui, on supprime les doublons. Tous pour lisp, Lisp pour tous!Avec Revit, cela ne vas trop vite...
bseb67 Posté(e) le 17 octobre 2007 Auteur Posté(e) le 17 octobre 2007 Petite précision ou explication: (combi '("b" "a" "c" "a") 2) =>'(("a" "a" "b" "c")("a" "a" "b")("a" "a" "c")("a" "b" "c")("a" "a")("a" "b")("a" "c")("b" "c")) et donc (combi '("b" "a" "c" "a") 3) =>'(("a" "a" "b" "c")("a" "a" "b")("a" "a" "c")("a" "b" "c")) Tous pour lisp, Lisp pour tous!Avec Revit, cela ne vas trop vite...
(gile) Posté(e) le 17 octobre 2007 Posté(e) le 17 octobre 2007 Salut, Ça marche. J'ai une réponse (voire deux), j'attends ce week-end pour poster ? Gilles Chanteau - gileCAD - GitHub Développements sur mesure pour AutoCAD
bseb67 Posté(e) le 17 octobre 2007 Auteur Posté(e) le 17 octobre 2007 Euh...... :o Oui, sinon tu risques de ne pas donner envie aux autres. Pour la génération des lettres, comme le tendre random n'existe pas en lisp, t'as pu en faire un?On pourrai utiliser aussi la fréquence des lettres dans la langue française. Et il faut que je prépare la suite ;). en mettant en ligne les données pour le jeu.J'ai bosser pas mal pour la "base de données" du jeu, mais elle pourra être compléter. Il faut bien un peu jouer avec autocad, pas que travailler :cool: , non? Pour le nom de ce jeu, on pourra l'appeler: connais-tu beaucoup de mots? Tous pour lisp, Lisp pour tous!Avec Revit, cela ne vas trop vite...
(gile) Posté(e) le 17 octobre 2007 Posté(e) le 17 octobre 2007 Pour la génération des lettres, comme le tendre random n'existe pas en lisp, t'as pu en faire un? Il existe une routine attribuée à différents auteurs (Kenny Ramage, Paul Furman, Steve Madsen...) et qui ne varie, suivant les auteurs, que par les valeurs données aux variables modulus, multiplier et increment.La seule certitude semble être qu'elle se sert d'un algorythme de Doug Cooper utilisée en Pascal. Je donne ici celle que j'utilise (une autre version sur afralisp) ;;; Retourne un nombre "pseudo-aléatoire" entre 0 et 1 ;;; (attribuée à de nombreux auteurs, algorythme de Doug Cooper) (defun rng (/ modulus multiplier increment random) (if (not seed) (setq seed (getvar "DATE")) ) (setq modulus 4294967296.0 multiplier 1664525 increment 1 seed (rem (+ (* multiplier seed) increment) modulus) random (/ seed modulus) ) ) Gilles Chanteau - gileCAD - GitHub Développements sur mesure pour AutoCAD
(gile) Posté(e) le 19 octobre 2007 Posté(e) le 19 octobre 2007 Le week end pointe son nez et toujours aucune réponse, je donne donc ce que j'avais fait, avec l'espoir que ça va relancer le jeu. Pour générer une liste "aléatoire" de lettres, j'utilise la routine ci dessus. ;;; Retourne un nombre "pseudo-aléatoire" entre 0 et 1 ;;; (attribuée à de nombreux auteurs, algorythme de Doug Cooper) (defun rng (/ modulus multiplier increment random) (or seed (setq seed (getvar "DATE"))) (setq modulus 4294967296.0 multiplier 1664525 increment 1 seed (rem (+ (* multiplier seed) increment) modulus) random (/ seed modulus) ) ) (defun genere (nb / ret) (repeat nb (setq ret (cons (chr (fix (+ 97 (* 26 (rng))))) ret)) ) ) Pour retourner toutes les combinaisons possibles triées par longueur et ordre alphabétique, je donne ce que j'avis fait mais j'ai le sentiment qu'on peut faire mieux et je n'arrive pas à me sortir de cet algorythme. (defun combi (lst mini / combi-1 first ret tmp) ;; COMBI-1 ;; Retourne toutes les combinaisons possibles avec 1 élément en moins ;; (combi-1 '("a" "b" "c")) -> (("b" "c") ("a" "b") ("c" "a")) (defun combi-1 (lst / ret) (repeat (length lst) (setq lst (append (cdr lst) (list (car lst))) ret (cons (cdr lst) ret) ) ) ) (setq lst (list lst)) (while ( (if (member first ret) (setq lst (cdr lst)) (if (= mini (length first)) (setq ret (cons first ret) lst (cdr lst) ) (setq ret (cons first ret) lst (append (cdr lst) (combi-1 first)) ) ) ) ) (vl-sort ret '(lambda (l1 l2) (if (= (length l1) (length l2)) ( (> (length l1) (length l2)) ) ) ) ) (combi '("c" "a" "b") 1) -> (("a" "b" "c") ("a" "b") ("a" "c") ("b" "c") ("a") ("b") ("c") ) (combi '("c" "a" "b" "a") 2) -> (("a" "a" "b" "c") ("a" "a" "b") ("a" "a" "c") ("a" "b" "c") ("a" "a") ("a" "b") ("a" "c") ("b" "c") )[Edité le 19/10/2007 par (gile)] [Edité le 20/10/2007 par (gile)] Gilles Chanteau - gileCAD - GitHub Développements sur mesure pour AutoCAD
bseb67 Posté(e) le 20 octobre 2007 Auteur Posté(e) le 20 octobre 2007 Salut (gile). Oui, c'est vrai qu'il n'y a pas grand monde pour mon challenge :( .Pour la suite, j'attends l'activation de mes pages persos chez free pour donner les fichiersnécessaires à la suite. J'ai déjà fait une partie de la seconde partie (et oui je triche ;), vu que je connais le sujet).Je vais me mettre sur la première partie cette aprem. En tout cas merci pour la fonction rng. Au départ je pensais aussi faire simplement un random entre 1 et 26, mais j'ai choisis de mettre la fréquence des lettres en jeu. (setq FREQ_LETTRES '(("A" 00.00 08.12 8.12) ("B" 08.12 08.94 00.82) ("C" 08.94 12.32 3.38) ("D" 12.32 16.61 4.29) ("E" 16.61 34.30 17.69) ("F" 34.30 35.43 1.13) ("G" 35.43 36.62 1.19) ("H" 36.62 37.36 00.74) ("I" 37.36 44.60 7.24) ("J" 44.60 44.78 0.18) ("K" 44.78 44.80 00.02) ("L" 44.80 50.79 5.99) ("M" 50.79 53.08 2.29) ("N" 53.08 60.76 07.68) ("O" 60.76 65.96 5.20) ("P" 65.96 68.89 2.93) ("Q" 68.89 69.73 00.84) ("R" 69.73 76.17 6.44) ("S" 76.17 85.05 8.88) ("T" 85.05 92.50 07.45) ("U" 92.50 97.74 5.24) ("V" 97.74 99.02 1.28) ("W" 99.02 99.08 00.06) ("X" 99.08 99.62 0.54) ("Y" 99.62 99.88 0.26) ("Z" 99.88 100.00 0.12) ) ) Les quadruplets sont: lettre - % départ - % arrivée - fréquence) Et donc j'obtiens alors: ;--------------------------------; ; nom: random_char ; ; role: retourne un caractère ; ; en utilisant la fréquence; ; param: aucun ; ; retour: un caractère ; ; date: 17/10/2007 ; ; BLAES Sébastien ; ;--------------------------------; (defun random_char( / res cpt find) (setq res (* (rng) 100.0) cpt 0 find nil) ; on parcourt les fréquences, pour trouver la lettre (while (= find nil) (if (and (>= (cadr (nth cpt FREQ_LETTRES)) res) (<= res (caddr (nth cpt FREQ_LETTRES)))) (setq res (car (nth cpt FREQ_LETTRES)) find t) ) ; if ; on incrémente cpt (setq cpt (1+ cpt)) ) ; while res ) ; random_char ;-----------------------------; ; nom: genere ; ; role: retourne nb caractères; ; sous forme d'une liste; ; param: nb => entier ; ; retour: entier ; ; date: 17/10/2007 ; ; BLAES Sébastien ; ;-----------------------------; (defun genere( nb / cpt res) (setq cpt 0 res '()) (while (< cpt nb) (setq res (cons (random_char) res) cpt (1+ cpt)) ) ; while res ) ; genere Il me reste plus qu'a faire combi :). A plus! Tous pour lisp, Lisp pour tous!Avec Revit, cela ne vas trop vite...
(gile) Posté(e) le 20 octobre 2007 Posté(e) le 20 octobre 2007 Salut, Je n'avais pas compris l'ennoncé comme ça, avec la fréquence des lettres. Il me semble bien qu'il y ait une erreur dans la fonction random_char, dans ton test, tu fais : (if (and (>= (cadr (nth cpt FREQ_LETTRES)) res) ( Ce qui revient à dire : si le nombre aléatoire est inférieur ou égal au "% départ" et au "% arrivée", ce qui fait retourner la lettre suivant celle qui devrait être retournée (F au lieu de E) et peut faire entrer la fonction dans une boucle sans fin si le nombre est compris entre 99.88 et 100.0. Si tu veux tester s'il est compris entre les deux, tu peux faire : (if ( mais comme tu boucles de façon incrémentale, un seul test suffit : (if ( Pour améliorer un petit peu les performances, on peut faire la liste en ordre de féquence, les lettres les plus probables seront trouvées plus vite (je n'ai conservé dans la liste que le "% arrivée"). (defun genere-gile (nb / pioche num n loop ret) (setq pioche '(("E" . 17.69) ("S" . 26.57) ("A" . 34.69) ("N" . 42.37) ("T" . 49.82) ("I" . 57.06) ("R" . 63.5) ("L" . 69.49) ("U" . 74.73) ("O" . 79.93) ("D" . 84.22) ("C" . 87.6) ("P" . 90.53) ("M" . 92.82) ("V" . 94.1) ("G" . 95.29) ("F" . 96.42) ("Q" . 97.26) ("B" . 98.08) ("H" . 98.82) ("X" . 99.36) ("Y" . 99.62) ("J" . 99.8) ("Z" . 99.92) ("W" . 99.98) ("K" . 100.0) ) ) (repeat nb (setq num (* 100 (rng)) n 0 loop T ) (while loop (if ( (setq loop nil ret (cons (car (nth n pioche)) ret) ) (setq n (1+ n)) ) ) ) ) [Edité le 20/10/2007 par (gile)] Gilles Chanteau - gileCAD - GitHub Développements sur mesure pour AutoCAD
bseb67 Posté(e) le 21 octobre 2007 Auteur Posté(e) le 21 octobre 2007 Salut gile! Et oui, j'ai fait une erreur :cool: :Il faut remplacer(>= (cadr (nth cpt FREQ_LETTRES)) res) par (>= res (cadr (nth cpt FREQ_LETTRES))). Et pour gagner un peu de temps le fait de ne garder que la borne max est plus rapide. Hier aprem, ma femme voulait faire les magasins, donc je m'y mets maintenant pour combi. PS: vive l'afrique du sud :)! je suis content que les anglais aient perdus. Tous pour lisp, Lisp pour tous!Avec Revit, cela ne vas trop vite...
bseb67 Posté(e) le 22 octobre 2007 Auteur Posté(e) le 22 octobre 2007 Re. J'ai encore un peu de mal, j'arrive à créer ma liste de résultats, mais c'est un peu cochon :( .Car, je fais du récursif (pour une fois que tu n'en fais pas Gile), mais l'ajout dans le résultat fait dessous-listes, donc je test le type pour savoir si je l'ajoute simplement, ou s'il je dois l'ajouter en tant que liste: ;-------------------------------; ; nom: combi ; ; role: retourne un ensemble de ; ; listes de combinaisons ; ; param: liste => liste d'entrée; ; nb => taille mini des ; ; listes résultats ; ; retour: liste de listes ; ; date: 21/10/2007 ; ; BLAES Sébastien ; ;-------------------------------; (defun combi( liste nb / res ) (setq res (append (sous_combi (vl-sort liste '<) nb 0) (list (vl-sort liste '<)))) (setq res (retire_doublons (reverse res))) ) ; combi (defun sous_combi( liste nb nb2 / res lg cpt tmp) (setq res '()) (cond ((or (= (setq lg (length liste)) nb) (= lg nb2)) (setq res liste) ) ; fin (t (setq cpt 0) (while (< cpt lg) (setq tmp (sous_combi (retire cpt liste) nb (1- lg))) [surligneur] (if (= (type (car tmp)) 'LIST) [/surligneur] (setq res (append res tmp)) (setq res (append res (list tmp))) ) (setq tmp (sous_combi (retire cpt liste) nb 0)) (if (= (type (car tmp)) 'LIST) (setq res (append res tmp)) (setq res (append res (list tmp))) ) (setq cpt (1+ cpt)) ) ; while ) ) ; cond res ) ; sous_combi L'autre problème, c'est que le résultat n'est pas trié. Un vl-sort ne marche pas, vu que les élément de la liste n'ont pas la même longueur (une chose que je sais :) ).Donc je cherchai comment faire avec un vl-sort appelant une fonction de trie, sauf que là, c'est un des mes points faibles, comme le mapcar où j'ai encore un peu de mal à utiliser sa puissance.Mais j'ai vu que tu avais fait cela, la seule chose c'est que je comprends pas tout :exclam: . (vl-sort (combi test 1)'(lambda (l1 l2)(if (= (length l1) (length l2))(< (apply 'strcat l1) (apply 'strcat l2))(> (length l1) (length l2))))) Les 3 premières lignes, c'est ok, le if c'est pour tester si les éléments ont même longueur, on trie "alphabétiquement", sinon par taille. Alors "apply 'strcat" il sert à quoi? PS: mes pages persos sous free ne sont tjs pas activées :mad: , pour mettre les fichiers pour la partie 2. A+ Tous pour lisp, Lisp pour tous!Avec Revit, cela ne vas trop vite...
(gile) Posté(e) le 22 octobre 2007 Posté(e) le 22 octobre 2007 Les 3 premières lignes, c'est ok, le if c'est pour tester si les éléments ont même longueur, on trie "alphabétiquement", sinon par taille.Alors "apply 'strcat" il sert à quoi? (apply 'fonc lst) permet d'appliquer la fonction "fonc" à la liste "lst", c'est équvalent à (eval (cons 'fonc lst)). Par exemple :(apply 'strcat '("a" "b" "c")) équivaut à :(eval (cons 'strcat '("a" "b" "c"))) -> (eval '(strcat '("a" "b" "c"))) -> (strcat '("a" "b" "c")) -> "abc" Ceci sert à trier '("a" "b" "c") et '("a" "c" "d"), par exemple, qui ne sont pas triables en l'état, en comparant "abc" et "acd". Donc si les listes ne font pas la même longueur elles sont triées par longueur, sinon on compare la concaténation des listes (qui, elles, sont déjà triées par ordre alphabétique). J'avais aussi fait une fonction récursive, mais elle est beaucoup plus lente dès que les listes s'allongent. (defun combi (lst mini / combi-1 subr) (defun combi-1 (lst / ret) (repeat (length lst) (setq lst (append (cdr lst) (list (car lst))) ret (cons (cdr lst) ret) ) ) ) (defun subr (lst mini) (if lst (if ( (cons (car lst) (subr (append (cdr lst) (combi-1 (car lst))) mini) ) ) ) ) (vl-sort (remove_doubles (mapcar '(lambda (x) (acad_strlsort x)) (subr (list lst) (1- mini)) ) ) '(lambda (l1 l2) (if (= (length l1) (length l2)) ( (> (length l1) (length l2)) ) ) ) ) [Edité le 22/10/2007 par (gile)] Gilles Chanteau - gileCAD - GitHub Développements sur mesure pour AutoCAD
bseb67 Posté(e) le 22 octobre 2007 Auteur Posté(e) le 22 octobre 2007 Resalut! Ok, donc le strcat te sert pour comparer alphabétiquement celles de longueurs différentes.C'est bon alors. C'était justement cela que je cherchais, donc je vais le garder ;). je poste aussi les deux fonctions que j'appelle (retire et retire_doublons) ;---------------------------------; ; nom: retire ; ; role: retire le pos_ième élément; ; de la liste ll ; ; param:pos => indice ; ; liste => liste d'entrée ; ; retour: liste ; ; date: 21/10/2007 ; ; BLAES Sébastien ; ;---------------------------------; (defun retire( pos ll / cpt lg res) (setq cpt 0 lg (length ll) res '()) (while (< cpt lg) (if (/= cpt pos) (setq res (append (list (nth cpt ll)) res)) ) ; if (setq cpt (1+ cpt)) ) ; while (reverse res) ) ; retire ;------------------------------; ; nom: retire_doublons ; ; role: retire les éléments en ; ; double de la liste ll ; ; param:pos => indice ; ; liste => liste d'entrée; ; retour: liste ; ; date: 21/10/2007 ; ; BLAES Sébastien ; ;------------------------------; (defun retire_doublons( ll / cpt lg res) (setq cpt 0 lg (length ll) res '()) (while (< cpt lg) (if (= (member (setq tmp (nth cpt ll)) res) nil) (setq res (append res (list tmp))) ) ; if (setq cpt (1+ cpt)) ) ; while res ) ; retire_doublons Et donc la version complète avec ton aide pour le trie: ;-------------------------------; ; nom: combi ; ; role: retourne un ensemble de ; ; listes de combinaisons ; ; param: liste => liste d'entrée; ; nb => taille mini des ; ; listes résultats ; ; retour: liste de listes ; ; date: 21/10/2007 ; ; BLAES Sébastien ; ;-------------------------------; (defun combi( liste nb / res ) (setq res (append (sous_combi (vl-sort liste '<) nb 0) (list (vl-sort liste '<)))) (setq res (retire_doublons (reverse res))) ; triage donné par (Gile) (vl-sort res '(lambda (l1 l2) (if (= (length l1) (length l2)) (< (apply 'strcat l1) (apply 'strcat l2)) (> (length l1) (length l2)) ) ) ) ) ; combi (defun sous_combi( liste nb nb2 / res lg cpt tmp) (setq res '()) (cond ((or (= (setq lg (length liste)) nb) (= lg nb2)) (if (= (type (car liste)) 'LIST) (setq res (append res liste)) (setq res (append res (list liste))) ) ) ; fin (t (setq cpt 0) (while (< cpt lg) (setq tmp (sous_combi (retire cpt liste) nb (1- lg))) (if (= (type (car tmp)) 'LIST) (setq res (append res tmp)) (setq res (append res (list tmp))) ) (setq tmp (sous_combi (retire cpt liste) nb 0)) (if (= (type (car tmp)) 'LIST) (setq res (append res tmp)) (setq res (append res (list tmp))) ) (setq cpt (1+ cpt)) ) ; while ) ) ; cond res ) ; sous_combi J'ai essayé avec: (setq test '("A" "C" "E" "B")) (combi test 4) => (("A" "B" "C" "E")) (combi test 3) => (("A" "B" "C" "E") ("A" "B" "C") ("A" "B" "E") ("A" "C" "E") ("B" "C" "E")) (combi test 2) => (("A" "B" "C" "E") ("A" "B" "C") ("A" "B" "E") ("A" "C" "E") ("B" "C" "E") ("A" "B") ("A" "C") ("A" "E") ("B" "C") ("B" "E") ("C" "E")) (combi test 1) => (("A" "B" "C" "E") ("A" "B" "C") ("A" "B" "E") ("A" "C" "E") ("B" "C" "E") ("A" "B") ("A" "C") ("A" "E") ("B" "C") ("B" "E") ("C" "E") ("A") ("B") ("C") ("E")) PS:Mes pages perso sont activées :), je vais mettre les fichiers pour la suite et donner les détails ce soir.a+ Tous pour lisp, Lisp pour tous!Avec Revit, cela ne vas trop vite...
bseb67 Posté(e) le 22 octobre 2007 Auteur Posté(e) le 22 octobre 2007 Resalut! Ok, donc le strcat te sert pour comparer alphabétiquement celles de longueurs différentes.C'est bon alors. C'était justement cela que je cherchais, donc je vais le garder ;). je poste aussi les deux fonctions que j'appelle (retire et retire_doublons) ;---------------------------------; ; nom: retire ; ; role: retire le pos_ième élément; ; de la liste ll ; ; param:pos => indice ; ; liste => liste d'entrée ; ; retour: liste ; ; date: 21/10/2007 ; ; BLAES Sébastien ; ;---------------------------------; (defun retire( pos ll / cpt lg res) (setq cpt 0 lg (length ll) res '()) (while (< cpt lg) (if (/= cpt pos) (setq res (append (list (nth cpt ll)) res)) ) ; if (setq cpt (1+ cpt)) ) ; while (reverse res) ) ; retire ;------------------------------; ; nom: retire_doublons ; ; role: retire les éléments en ; ; double de la liste ll ; ; param:pos => indice ; ; liste => liste d'entrée; ; retour: liste ; ; date: 21/10/2007 ; ; BLAES Sébastien ; ;------------------------------; (defun retire_doublons( ll / cpt lg res) (setq cpt 0 lg (length ll) res '()) (while (< cpt lg) (if (= (member (setq tmp (nth cpt ll)) res) nil) (setq res (append res (list tmp))) ) ; if (setq cpt (1+ cpt)) ) ; while res ) ; retire_doublons Et donc la version complète avec ton aide pour le trie: ;-------------------------------; ; nom: combi ; ; role: retourne un ensemble de ; ; listes de combinaisons ; ; param: liste => liste d'entrée; ; nb => taille mini des ; ; listes résultats ; ; retour: liste de listes ; ; date: 21/10/2007 ; ; BLAES Sébastien ; ;-------------------------------; (defun combi( liste nb / res ) (setq res (append (sous_combi (vl-sort liste '<) nb 0) (list (vl-sort liste '<)))) (setq res (retire_doublons (reverse res))) ; triage donné par (Gile) (vl-sort res '(lambda (l1 l2) (if (= (length l1) (length l2)) (< (apply 'strcat l1) (apply 'strcat l2)) (> (length l1) (length l2)) ) ) ) ) ; combi (defun sous_combi( liste nb nb2 / res lg cpt tmp) (setq res '()) (cond ((or (= (setq lg (length liste)) nb) (= lg nb2)) (if (= (type (car liste)) 'LIST) (setq res (append res liste)) (setq res (append res (list liste))) ) ) ; fin (t (setq cpt 0) (while (< cpt lg) (setq tmp (sous_combi (retire cpt liste) nb (1- lg))) (if (= (type (car tmp)) 'LIST) (setq res (append res tmp)) (setq res (append res (list tmp))) ) (setq tmp (sous_combi (retire cpt liste) nb 0)) (if (= (type (car tmp)) 'LIST) (setq res (append res tmp)) (setq res (append res (list tmp))) ) (setq cpt (1+ cpt)) ) ; while ) ) ; cond res ) ; sous_combi J'ai essayé avec: (setq test '("A" "C" "E" "B")) (combi test 4) => (("A" "B" "C" "E")) (combi test 3) => (("A" "B" "C" "E") ("A" "B" "C") ("A" "B" "E") ("A" "C" "E") ("B" "C" "E")) (combi test 2) => (("A" "B" "C" "E") ("A" "B" "C") ("A" "B" "E") ("A" "C" "E") ("B" "C" "E") ("A" "B") ("A" "C") ("A" "E") ("B" "C") ("B" "E") ("C" "E")) (combi test 1) => (("A" "B" "C" "E") ("A" "B" "C") ("A" "B" "E") ("A" "C" "E") ("B" "C" "E") ("A" "B") ("A" "C") ("A" "E") ("B" "C") ("B" "E") ("C" "E") ("A") ("B") ("C") ("E")) PS:Mes pages perso sont activées :), je vais mettre les fichiers pour la suite et donner les détails ce soir.a+ Tous pour lisp, Lisp pour tous!Avec Revit, cela ne vas trop vite...
bseb67 Posté(e) le 22 octobre 2007 Auteur Posté(e) le 22 octobre 2007 Resalut! Ok, donc le strcat te sert pour comparer alphabétiquement celles de longueurs différentes.C'est bon alors. C'était justement cela que je cherchais, donc je vais le garder ;). je poste aussi les deux fonctions que j'appelle (retire et retire_doublons) ;---------------------------------; ; nom: retire ; ; role: retire le pos_ième élément; ; de la liste ll ; ; param:pos => indice ; ; liste => liste d'entrée ; ; retour: liste ; ; date: 21/10/2007 ; ; BLAES Sébastien ; ;---------------------------------; (defun retire( pos ll / cpt lg res) (setq cpt 0 lg (length ll) res '()) (while (< cpt lg) (if (/= cpt pos) (setq res (append (list (nth cpt ll)) res)) ) ; if (setq cpt (1+ cpt)) ) ; while (reverse res) ) ; retire ;------------------------------; ; nom: retire_doublons ; ; role: retire les éléments en ; ; double de la liste ll ; ; param:pos => indice ; ; liste => liste d'entrée; ; retour: liste ; ; date: 21/10/2007 ; ; BLAES Sébastien ; ;------------------------------; (defun retire_doublons( ll / cpt lg res) (setq cpt 0 lg (length ll) res '()) (while (< cpt lg) (if (= (member (setq tmp (nth cpt ll)) res) nil) (setq res (append res (list tmp))) ) ; if (setq cpt (1+ cpt)) ) ; while res ) ; retire_doublons Et donc la version complète avec ton aide pour le trie: ;-------------------------------; ; nom: combi ; ; role: retourne un ensemble de ; ; listes de combinaisons ; ; param: liste => liste d'entrée; ; nb => taille mini des ; ; listes résultats ; ; retour: liste de listes ; ; date: 21/10/2007 ; ; BLAES Sébastien ; ;-------------------------------; (defun combi( liste nb / res ) (setq res (append (sous_combi (vl-sort liste '<) nb 0) (list (vl-sort liste '<)))) (setq res (retire_doublons (reverse res))) ; triage donné par (Gile) (vl-sort res '(lambda (l1 l2) (if (= (length l1) (length l2)) (< (apply 'strcat l1) (apply 'strcat l2)) (> (length l1) (length l2)) ) ) ) ) ; combi (defun sous_combi( liste nb nb2 / res lg cpt tmp) (setq res '()) (cond ((or (= (setq lg (length liste)) nb) (= lg nb2)) (if (= (type (car liste)) 'LIST) (setq res (append res liste)) (setq res (append res (list liste))) ) ) ; fin (t (setq cpt 0) (while (< cpt lg) (setq tmp (sous_combi (retire cpt liste) nb (1- lg))) (if (= (type (car tmp)) 'LIST) (setq res (append res tmp)) (setq res (append res (list tmp))) ) (setq tmp (sous_combi (retire cpt liste) nb 0)) (if (= (type (car tmp)) 'LIST) (setq res (append res tmp)) (setq res (append res (list tmp))) ) (setq cpt (1+ cpt)) ) ; while ) ) ; cond res ) ; sous_combi J'ai essayé avec: (setq test '("A" "C" "E" "B")) (combi test 4) => (("A" "B" "C" "E")) (combi test 3) => (("A" "B" "C" "E") ("A" "B" "C") ("A" "B" "E") ("A" "C" "E") ("B" "C" "E")) (combi test 2) => (("A" "B" "C" "E") ("A" "B" "C") ("A" "B" "E") ("A" "C" "E") ("B" "C" "E") ("A" "B") ("A" "C") ("A" "E") ("B" "C") ("B" "E") ("C" "E")) (combi test 1) => (("A" "B" "C" "E") ("A" "B" "C") ("A" "B" "E") ("A" "C" "E") ("B" "C" "E") ("A" "B") ("A" "C") ("A" "E") ("B" "C") ("B" "E") ("C" "E") ("A") ("B") ("C") ("E")) PS:Mes pages perso sont activées :), je vais mettre les fichiers pour la suite et donner les détails ce soir.a+ Tous pour lisp, Lisp pour tous!Avec Revit, cela ne vas trop vite...
(gile) Posté(e) le 22 octobre 2007 Posté(e) le 22 octobre 2007 Très bien, tu me donnes une idée pour améliorer mes routines en évitant des (acad_strlsort ...) À ce propos, ta routine ne marche pas avec les liste contenant des doublons, ceci est du à l'utilisation de (vl-sort ...) qui les supprime.Il faut juste remplacer : (setq res (append (sous_combi (vl-sort liste ' par (setq res (append (sous_combi (acad_strlsort liste) nb 0) (list (acad_strlsort liste)))) Gilles Chanteau - gileCAD - GitHub Développements sur mesure pour AutoCAD
bseb67 Posté(e) le 22 octobre 2007 Auteur Posté(e) le 22 octobre 2007 À ce propos, ta routine ne marche pas avec les liste contenant des doublons, ceci est du à l'utilisation de (vl-sort ...) qui les supprime Vrai d'après la doc: vl-sort:Return Values A list containing the elements of list in the order specified by comparison-function. Duplicate elements may be eliminated from the list. mais tiens c'est bizarre, car moi je l'avais essayé (je ne lis pas toujours la doc entièrement :cool: ) et bien ca marche :o !Car:(setq test '("A" "B" "A" "C"))(vl-sort test '<) => ("A" "A" "B" "C") et non ("A" "B" "C") comme dit dans la doc Donc je garde mon bout. Tous pour lisp, Lisp pour tous!Avec Revit, cela ne vas trop vite...
(gile) Posté(e) le 22 octobre 2007 Posté(e) le 22 octobre 2007 C'est très curieux le comportement de vl-sort :casstet: J'avais aussi remplacé les acad_strlsort par des vl-sort (plus rapide) mais de manière "aléatoire" vl-sort supprime ou non les doublons. Je dis aléatoire parceque je n'ai pas réussi à trouver de comportement logique.acad_strlsort semble avoir un comportement plus stable et ne jamais supprimer les doublons. Donc, voilà une nouvelle routine. qui fonctionne avec un seul acad_strlsort au début, toutes les autres combinaisons retournées par combi-1 sont triées. Sous routines ;; REMOVE_ELE ;; Retourne la liste privée de l'élément à l'indice spécifié ;; (premier élément = 0) (defun remove_ele (lst ind / tmp) (repeat ind (setq tmp (cons (car lst) tmp) lst (cdr lst) ) ) (append (reverse tmp) (cdr lst)) ) ;; COMBI-1 ;; Retourne toutes les combinaisons possibles avec 1 élément en moins ;; (combi-1 '("a" "b" "c")) -> (("a" "b") ("a" "c") ("b" "c")) (defun combi-1 (lst / n ret) (setq n -1) (repeat (length lst) (setq ret (cons (remove_ele lst (setq n (1+ n))) ret)) ) ) Combi itérative (while) (defun combi-gile (lst mini / first ret tmp) (setq lst (list (acad_strlsort lst))) (while ( (if (member first ret) (setq lst (cdr lst)) (if (= mini (length first)) (setq ret (cons first ret) lst (cdr lst) ) (setq ret (cons first ret) lst (append (cdr lst) (combi-1 first)) ) ) ) ) (vl-sort ret '(lambda (l1 l2) (if (= (length l1) (length l2)) ( (> (length l1) (length l2)) ) ) ) ) Combi récursive (avec remove_doubles donnée plus haut) (defun combi-rec (lst mini / subr) (defun subr (lst mini) (if lst (if ( (cons (car lst) (subr (append (cdr lst) (combi-1 (car lst))) mini) ) ) ) ) (vl-sort (remove_doubles (subr (list (acad_strlsort lst)) (1- mini))) '(lambda (l1 l2) (if (= (length l1) (length l2)) ( (> (length l1) (length l2)) ) ) ) ) [Edité le 22/10/2007 par (gile)] Gilles Chanteau - gileCAD - GitHub Développements sur mesure pour AutoCAD
(gile) Posté(e) le 22 octobre 2007 Posté(e) le 22 octobre 2007 Un exemple du comportement capricieux de vl-sort : http://img399.imageshack.us/img399/306/vlsortjt1.png où il semblerait que la façon dont est générée la liste (résultat d'une fonction ou liste quotée) les doublons sont supprimés ou non, mais c'est une supposition. Gilles Chanteau - gileCAD - GitHub Développements sur mesure pour AutoCAD
bseb67 Posté(e) le 23 octobre 2007 Auteur Posté(e) le 23 octobre 2007 :o :o :casstet: :P C'est n'importe quoi! Donc je vais quand même devoir changer mon code :( !Sinon il me reste à faire une fonction de trie. J'ai déjà fait le tri à bulles, mais c'est l'un des plus lent. Sinon, free ca coince encore. j'ai donc mis en partage un fichier zip: http:// http://dl.free.fr/bW9vkmWuu/bd_mots_challenge13.zip Le zip est protégé nom:bseb67mdp: cadxp.C'est un fichier contenant 6 fichiers txt: MOT3L.txt, MOT4L.txt, MOT5L.txt, MOT6L.txtMOT7L.txt, MOT8L.txt et MOT9L.txt. Deuxième partie: 1) il faut charger chaque fichier sous forme d'une liste par fichier. Les mots ne sont pas accentués.=> les fichiers contiennent plusieurs lignes. Pour les mots de 3 lettres (MOT3L.txt) les premières lignes sont celles-ci: AAA/AAB/AAC/AAD/ada/ Donc en majuscule on a une suite de lettres triées alphabétiquement. Puis un "/" pour séparer les mots. Ensuite en minuscule la liste des mots possibles pour cette suite. (Voilà le pourquoi de genere et de combi :) ).Pour ce mini exemple on aura alors une variable (MOT3L par exemple) qui vaudra:'(("AAA") ("AAB") ("AAC") ("AAD" "ada")) 2) faire une fonction qui renvoie tous les mots possibles avec la liste créer par genere.exemple: (setq lst (genere 4)) => '("A" "A" "D" "A")(setq lst_combi (combi lst 3)) => '(("A" "A" "A" "D") ("A" "A" "A") ("A" "A" "D"))(tous_les_mots lst_combi) => '("ada") 3) faire un petit main qui demande à l'utilisateur un nombre de lettre (utilisé pour genere) et on lancera combi avec 3 comme deuxième paramètre. Il faudra alors lui demander de taper tous lesmots qu'il connait et de donner un score. 4) Il sera possible, vu que je pense avoir oublier des mots, de créer un lisp pour ajouter de nouveau mot et sauvegarder les données dans les fichiers. 5) Une variante possible: le mot le plus long (vu que c'est 9 lettres pour le jeu) 6) Autre variante : le jeu du pendu. 7) Pour finir de faire une extension graphique : dessin dans autocad d'un tableau contenant les mots saisie et s'ils sont validés + ceux non trouvés. Voilà, j'espère enfin voir quelqu'un de plus que Gile, :( , ce n'est pas que je ne t'aimes pas Gile, mais à part nous deux il n'y a personne pour mon challenge. :( :( :( Tous pour lisp, Lisp pour tous!Avec Revit, cela ne vas trop vite...
bseb67 Posté(e) le 23 octobre 2007 Auteur Posté(e) le 23 octobre 2007 :o :o :casstet: :P C'est n'importe quoi! Donc je vais quand même devoir changer mon code :( !Sinon il me reste à faire une fonction de trie. J'ai déjà fait le tri à bulles, mais c'est l'un des plus lent. Sinon, free ca coince encore. j'ai donc mis en partage un fichier zip: http:// http://dl.free.fr/c3gj6Kooc/bd_mots_bseb67_challenge13.zip Le zip est protégé nom:bseb67mdp: cadxp.C'est un fichier contenant 6 fichiers txt: MOT3L.txt, MOT4L.txt, MOT5L.txt, MOT6L.txtMOT7L.txt, MOT8L.txt et MOT9L.txt. Deuxième partie: 1) il faut charger chaque fichier sous forme d'une liste par fichier. Les mots ne sont pas accentués.=> les fichiers contiennent plusieurs lignes. Pour les mots de 3 lettres (MOT3L.txt) les premières lignes sont celles-ci: AAA/AAB/AAC/AAD/ada/ Donc en majuscule on a une suite de lettres triées alphabétiquement. Puis un "/" pour séparer les mots. Ensuite en minuscule la liste des mots possibles pour cette suite. (Voilà le pourquoi de genere et de combi :) ).Pour ce mini exemple on aura alors une variable (MOT3L par exemple) qui vaudra:'(("AAA") ("AAB") ("AAC") ("AAD" "ada")) 2) faire une fonction qui renvoie tous les mots possibles avec la liste créer par genere.exemple: (setq lst (genere 4)) => '("A" "A" "D" "A")(setq lst_combi (combi lst 3)) => '(("A" "A" "A" "D") ("A" "A" "A") ("A" "A" "D"))(tous_les_mots lst_combi) => '("ada") 3) faire un petit main qui demande à l'utilisateur un nombre de lettre (utilisé pour genere) et on lancera combi avec 3 comme deuxième paramètre. Il faudra alors lui demander de taper tous lesmots qu'il connait et de donner un score. 4) Il sera possible, vu que je pense avoir oublier des mots, de créer un lisp pour ajouter de nouveau mot et sauvegarder les données dans les fichiers. 5) Une variante possible: le mot le plus long (vu que c'est 9 lettres pour le jeu) 6) Autre variante : le jeu du pendu. 7) Pour finir de faire une extension graphique : dessin dans autocad d'un tableau contenant les mots saisie et s'ils sont validés + ceux non trouvés. Voilà, j'espère enfin voir quelqu'un de plus que Gile, :( , ce n'est pas que je ne t'aimes pas Gile, mais à part nous deux il n'y a personne pour mon challenge. :( :( :( [Edité le 23/10/2007 par bseb67] Tous pour lisp, Lisp pour tous!Avec Revit, cela ne vas trop vite...
Patrick_35 Posté(e) le 23 octobre 2007 Posté(e) le 23 octobre 2007 Salut Voilà, j'espère enfin voir quelqu'un de plus que Gile Ce n'est pas la mauvaise volonté, mais en ce moment, je n'ai absolument pas le temps pour me plonger dans ce type de challengeQuand ce sera plus calme ;) @+ Les Lisps de PatrickLe but n'est pas toujours placé pour être atteint, mais pour servir de point de mire.Joseph Joubert, 1754-1824
Messages recommandés
Créer un compte ou se connecter pour commenter
Vous devez être membre afin de pouvoir déposer un commentaire
Créer un compte
Créez un compte sur notre communauté. C’est facile !
Créer un nouveau compteSe connecter
Vous avez déjà un compte ? Connectez-vous ici.
Connectez-vous maintenant