Rechercher dans la communauté
Affichage des résultats pour « challenge » dans sujets.
-
Salut, votre challenge me fait penser à feu "Jeu Autocad du mois" mis en place par Eric sur son site, il y a fort longtemps, (https://www.caderix.com/journal/spip.php?rubrique13) mais qu'il avait arrêté faute de temps, à mon grand regret. Pour ce challenge nouvelle version, je ne participerai pas : je ne sais pas coder et je n'ai plus d'accès à Autocad, mais je continue de vous lire par curiosité et connaître les possibilités de réalisations. Bonne continuation. PS : puisque je le cite, j'en profite pour le féliciter (avec du retard) ! Bravo Eric https://www.caderix.com/journal/spip.php?article527 Erased.
-
Bonjour @didier Bien que je sois intimement convaincu que tu trouveras (à raison) toujours plus d'inspiration dans les lignes de (gile) que dans les miennes, si des fois il y en a une ou deux qui te conviennent en ce qui me concerne tout ce qui est sur les forums est libre de droit, être repris est toujours une forme de reconnaissance😉 Pour une date de dépôt je suis plus mitigé, l'esprit d'un challenge est un jeu entre vitesse d'écriture et optimisation des lignes de code, personnellement je n'ai pas d'état d'âme à poster rapidement si je pense que la solution n'est pas optimal (car elle sera facilement détrôner Cf ma réponse sur ce challenge). Par contre si je crois avoir là solution, je temporise au maximum avant de poster, bien qu'à ce petit jeu je me fait bien souvent prendre et m'en amuse😄 Il m'est aussi arrivé de faire une proposition au hasard d'un code, bien après l'émission d'un challenge, pour moi il n'y pas de date limite de temps. A+ Bruno
-
Bonjour @(gile) @VDH-Bruno Votre "bravo" me touche, je vous remercie sincèrement. En effet, je me suis un peu tracassé la tête, on trouve encore la trace de mon "impérativité" dans les définitions de L3,L4... De toute façon j'ai un résultat qui me plaît, maintenant s'il plaît aux autres et qu'il est efficient c'est "la cerise sur le ponpon". On se met d'accord pour le prochain challenge au niveau du dépôt des réponses, ça marche ? Je ne suis pas certain du tout de participer au prochain, car le sujet me parle ou pas et décide de mon implication (si je sens que je peux répondre in fine) À tous : Il est possible que je dédie une page de "da-code" à ces sujets, ai-je l'autorisation de vous citer et d'intégrer votre code ? Amicalement PS: Je dois vous quitter car il faut que je cherche des pokemon à imprimer pour faire du coloriage, on n'a pas une vie facile ...
-
(je vais me faire insulter mais c'est pas grave je vais le dire quand meme : ) Le F# Me fait pensé un peu au VBA / VB.NET c'est rigolo ^^ Si la démo de didier sur ces 10.000 points est rapide comme ça... le vba ne fera pâs mieux ! par contre je vais aller au bout de ce challenge et vous donnez du coup le temps nécessaire au code VBA pour traiter 10.000 point voir plus ! parce que la effectivement je pense qu'on pourra comparer "l'efficience de deux code" J'ai des entetiens a préparer, un véhicule à retaper donc je le ferais pas de suite mais je le ferais !
-
Coucou Ça y est je livre et me délivre, c'est tellement rare que je participe à un challenge... Exécution : le sablier flashe à partir de dix mille points Rendu : Code : avec commentaires (je demanderais volontiers aux autres de faire de même pour la formation des lecteurs) Amicalement (defun da:horaire (a b c / ) ;| calcul de la superficie du triangle qui est négative si les sommets tournent en sens horaire http://mathforum.org/library/drmath/view/54386.html (0.5)(x1*y2 - y1*x2 -x0*y2 + y0*x2 + x0*y1 - y0*x1) |; (minusp (* (- (+ (+ (- (- (* (car b) (cadr c))(* (cadr b) (car c)))(* (car a) (cadr c)))(* (cadr a) (car c)))(* (car a) (cadr b)))(* (cadr a) (car b)))0.5)) );fin defun da:horaire (defun da:makepoly2d (lstpt2d);dessin d'une poly 2D depuis une liste de points ((x1 y1)...(xn yn)) (entmake (append (list '(0 . "LWPOLYLINE") '(100 . "AcDbEntity") '(100 . "AcDbPolyline") (cons 90 (length lstpt2d)) '(70 . 1) ;1 pour fermée, 0 pour ouverte ) (mapcar '(lambda (p) (cons 10 p)) lstpt2d) ) ) (princ) );fin de da:makepoly2d ;fonction principale qui attend en unique argument une liste de points ((x1 y1 z1)...(xn yn zn)) (defun daqh (lstpt / l3 l4 l5 l6 ldalsthull lstpt pt ptpi) ; tri par Y croissants (setq lst (vl-sort lstpt '(lambda(a b) (if (eq (cadr a) (cadr b))(< (car a) (car b))(< (cadr a) (cadr b)))))) ; point avec le plus petit Y, point pivot (setq ptpi (car lst)) ; liste des angles depuis pivot depuis l'axe des X (setq lda (mapcar '(lambda (X Y) (angle ptpi y)) (reverse (cdr (reverse lst))) (cdr lst))) ;création liste des points avec la valeur d'angle en premier (angle x y z) (setq l3 (mapcar 'cons lda (cdr lst))) ; tri par premier élément de la liste "angle" (setq l4 (vl-sort l3 '(lambda(a b) (if (eq (cdr a) (cdr b))(< (car a) (car b))(< (car a) (car b)))))) ;liste des points triés en retirant l'angle en premier élément pour n'avoir que des points (x y z) (setq l5 (mapcar 'cdr l4)) ;rajout du point pivot dans la liste des points (setq l6 (cons ptpi l5)) (setq lsthull (list (cadr l6) (car l6))) ;liste sans les deux premiers points (setq l6 (cddr l6)) ;test sens horaire (foreach ptemp l6 (while (and (cdr lsthull) (da:horaire (cadr lsthull) (car lsthull) ptemp)) (setq lsthull (cdr lsthull)) ) (setq lsthull (cons ptemp lsthull)) ) ;(setq zaza (reverse lsthull)) ;suppression des z dans la liste des points (setq lsthull (mapcar '(lambda (pt) (list (car pt) (cadr pt))) (reverse lsthull))) ;dessin de la poly 2D d'enveloppe (da:makepoly2d lsthull) );fin defun daqh ;fonction pour test qui demande un choix de points filtré sur entité POINT (defun c:TestdaQH ( / ss lstpt n) (prompt "\nChoix des points à cerner...\n") (setq ss (ssget (list '(0 . "POINT")))) (repeat (setq n (sslength ss)) (setq lstpt (cons (cdr (assoc 10 (entget (ssname ss (setq n (1- n))))))lstpt)) ) (daqh lstpt) );fin de c:TestdaQH (prompt "\nTaper Testdaqh pour trouver l'enveloppe convexe des points\n") (princ) Amicalement
-
Super, ça démarre. @didier C'est pas grave si des réponses commencent à arriver, ce n'est pas un concours il s'agit juste d'apprendre en comparant différentes façon de faire et il me semble qu'il reste de place pour bien d'autres réponses. J'attendrai la tienne pour poster ma réponse en LISP. @VDH-Bruno Bravo, ça répond tout à fait à la demande. Je suis sûr que si tu as le temps tu pourras "optimiser" ta routine (ma réponse en LISP est proche de la tienne, mais plus concise). @Fraid Ça ne répond pas tout à fait à la demande donc on ne peut pas comparer directement avec les autres réponses et on est assez loin de l'algorithme du quicksort. En tout cas, c'est pas vraiment 'quick'. J'ai eu un peu peur quand vous parliez de "nuage de points", avec ta solution, il y a intérêt à ce que ce soit un cirrus de beau temps. Suivant la tâche à accomplir, certains langages sont plus ou moins bien adaptés. Dans ce cas là, parmi les langages que je connais F# est certainement le plus adapté. Je ne pense pas "divulgacher" le challenge en donnant une réponse en F# maintenant. let quickhull (pts: Point2d list) = let area (p1: Point2d) (p2: Point2d) (p3: Point2d) = ((p2.X - p1.X) * (p3.Y - p1.Y)) - ((p2.Y - p1.Y) * (p3.X - p1.X)) let rec rightPts p1 p2 min acc = function | [] -> acc | x :: xs -> match area p1 p2 x with | a when 0. <= a -> rightPts p1 p2 min acc xs | a -> match acc with | [] -> rightPts p1 p2 a [x] xs | y :: ys -> if a < min then rightPts p1 p2 a (x :: acc) xs else rightPts p1 p2 min (y :: x :: ys) xs let rec loop p1 p2 pts = match rightPts p1 p2 0. [] pts with | [] -> [p1] | h :: t -> loop p1 h t @ loop h p2 t let minX = pts |> List.minBy (fun p -> p.X) let maxX = pts |> List.maxBy (fun p -> p.X) loop minX maxX pts @ loop maxX minX pts
-
Bonjour, Je me permet de poster mais c'est tellement brut, que cela répond au challenge que part son résultat. pas son algorithme "Viking" (defun Quickhull (lpt / acdc mods oldosmode oldcmdecho lptmp ptrec zone sel ob ct) (vla-zoomextents (vlax-get-acad-object)) (setq acdc (vla-get-activedocument (vlax-get-acad-object)) mods (vla-get-modelspace acdc) oldosmode (getvar 'osmode) oldcmdecho (getvar 'cmdecho) zone (coordaffichage) lptmp (cdr lpt) ) (setvar 'osmode 0) (setvar 'cmdecho 0) (foreach pt1 lpt (foreach pt2 lptmp (vla-AddLine mods (vlax-3d-point (car pt1)(cadr pt1) 0) (vlax-3d-point (car pt2)(cadr pt2) 0)) ) (setq lptmp (cdr lptmp)) ) (setq ptrec (vlax-make-safearray vlax-vbDouble '(0 . 14))) (vlax-safearray-fill ptrec (list (1-(caar zone)) (1-(cadar zone)) 0 (1-(caar zone)) (1+(cadadr zone)) 0 (1+(caadr zone)) (1+(cadadr zone)) 0 (1+(caadr zone)) (1-(cadar zone)) 0 (1-(caar zone)) (1-(cadar zone)) 0 ) ) (vla-AddPolyline mods ptrec) (vla-zoomextents (vlax-get-acad-object)) (vla-regen acdc acActiveViewport) (vl-cmdf "_.-boundary" (car zone) "") (setq sel (ssget "_x" (list (cons 0 "*POLYLINE"))) ct -1) (while (setq ob (ssname sel (setq ct (1+ ct)))) (if (/= ct 1)(vla-delete (vlax-ename->vla-object ob))) ) (setq sel (ssget "_x" (list (cons 0 "LINE"))) ct -1) (while (setq ob (ssname sel (setq ct (1+ ct)))) (vla-delete (vlax-ename->vla-object ob)) ) (setvar 'osmode oldosmode) (setvar 'cmdecho oldcmdecho) (princ) ) (defun coordaffichage ( / viewctr viewsize screensize) (mapcar 'set '(viewctr viewsize screensize) (mapcar 'getvar '(viewctr viewsize screensize))) ((lambda (dimxy) (list (mapcar '- viewctr dimxy) (mapcar '+ viewctr dimxy))) (list (* viewsize (/ (car screensize) (cadr screensize) 2.)) (/ viewsize 2) 0.0) ) ) et un test un peux différent, puisque je dessine la polyligne (defun c:test (/ ss i pts) (if (setq ss (ssget '((0 . "point")))) (progn (repeat (setq i (sslength ss)) (setq pts (cons (cdr (assoc 10 (entget (ssname ss (setq i (1- i)))))) pts ) ) ) (quickhull pts) ) ) (princ) )
-
Désolé Didier, mais comme je voyais pas mal de commentaires, j'ai cru à tord que le challenge était un peu bloqué... Alors je m'y suis attelé ce matin. Amicalement aussi A+ Bruno
-
Bonjour Ah zut de zut Quelqu'un a répondu ! Pour une fois que je me mettais dans un challenge que j'avais compris ! (car les listes triées deux à deux dans l'ordre alphabétique hébreu médiéval avec quelques chiffres, très peu pour moi, ça ne me parle guère) Allez j'attends encore un peu pour peaufiner ma version et je dépose. Je pense que pour les prochains il faut donner une date de dépôt, qu'on le veuille ou non on lit les réponses, dans le cas présent j'ai sauté le message de @VDH-Bruno mais il existe et ça devrait pas pour l'égalité des chances. Amicalement
-
Outre que je ne vois pas bien le rapport avec ce challenge, cet algorithme n'est pas fiable à 100%. Tu n'envisages pas le cas où la droite passe par un sommet (point vert) ou deux sommets (point jaune), ni celui où elle est tangente à un arc (point rouge). Dans ces trois cas, les points sont à l'intérieur mais la droite a 3 intersections... Ça m'a toujours intrigué cette tendance à la verbosité dans la culture VB : Point_dans_Polyligne = False If NbrePoints Mod 2 = 0 Then Point_dans_Polyligne = False Else Point_dans_Polyligne = True End If Alors qu'on devrait pouvoir écrire tout simplement : Point_dans_Polyligne = NbrePoints Mod 2 <> 0
-
T'inquiète, c'est juste pour éviter de dessiner une volée cela ne résous en rien le challenge
-
Le but du challenge est de fournir une fonction qui prends en argument une collection de points 2D (je conseille des commencer avec une ou quelques dizaines de points pas plus) et qui renvoie les points qui constituent l'enveloppe convexe de cette collection. J'ai implémenté ce type de fonction en utilisant l'algorithme dit du parcours de Graham (en C# et F# ainsi qu'en LISP : gc:ConvHull dans MathGeom sur cette page). Je proposais de le faire avec ici avec QuickHull, mais après tout, toute solution est bienvenue.
-
Bonjour, Si il y a un argument en plus qui est la "résolution" (longueur max des faces du polygone) je sais faire. Mais sans, je ne vois pas comment déterminer si on doit rejoindre ou non un point...surtout si on a une volée en forme de croissant. Notamment avec l'algorithme que tu nous présente au début du message. Avant que tu poste ce challenge, je commençais à reprendre mon lisp qui me donne un profil dans un nuage de points. (l'outil Autocad est vraiment inutile...) en essayant d'intégrer l'algo que tu avais posté sur theswamp. du coup, il me semble que c'est la solution non?
-
Salut, En tombant sur cet article à propos d'un algorithme pour calculer l'enveloppe convexe d'une collection de points, je me suis dit que ça pourrait faire l'objet d'un nouveau challenge et que ça pourrait aussi être une base pour résoudre un problème plus complex posé par @Luna dans ce sujet : faire une enveloppe concave (concave hull). Donc, il s'agit toujours d'écrire un fonction (dans le langage de son choix) qui prend en argument une liste de points et qui renvoie la liste des points qui constituent l'enveloppe convexe (convex hull) des points passés en argument. Il existe au moins un autre algorithme bien connu pour extraire l'enveloppe convexe d'une collection de points, mais comme il a déjà été souvent implémenté, je trouve plus intéressant de se pencher sur celui-là et je suppute qu'il se prête mieux à la généralisation vers une enveloppe concave (mais c'est une autre histoire...). On doit pouvoir tester la fonction 'quickhull' via une sélection d'entités points (nodal) en dessinant une polyligne. Exemple en LISP : (defun c:test (/ ss i pts) (if (setq ss (ssget '((0 . "point")))) (progn (repeat (setq i (sslength ss)) (setq pts (cons (cdr (assoc 10 (entget (ssname ss (setq i (1- i)))))) pts ) ) ) (command "_pline") (foreach p (quickhull pts) (command "_non" p) ) (command "_close") ) ) (princ) )
-
Coucou, Pour commencer, je ne recherche aucunement des programmes tout fait, tout propre chat ne m'intéresse pas :3 Mon but est simplement de trouver une logique permettant de répondre à un problème afin que je puisse par la suite transposer en programme. Donc pour faire relativement simple, il existe bon nombre de programmes (LeeMac, TheSwamp, etc) permettant de générer un contour sur un jeu de sélection d'objets linéaires sécants (des images valent mieux que des mots donc voici une démonstration du programme de LeeMac). Les conditions à respecter pour que ce programme fonctionne c'est : - Les objets sont compatibles avec la commande "_BOUNDARY" (ou "CONTOUR") - Les objets se croisent donc sont coplanaires et possèdent des points d'intersections entre-eux J'avais déjà discuté de ce programme avec @didier mais je n'ai jamais vraiment eu le temps de me pencher plus en avant sur le sujet (le soucis, c'est que l'idée est toujours dans ma tête, d'où mon problème ^^). Le but étant d'avoir un principe similaire à une exception près parmi les conditions ci-dessus : les objets ne possèdent pas de points d'intersections entre-eux... Pour le contexte, je travaille dans un BE d'implantation de centrales photovoltaïques et donc on travaille constamment avec des modules et des structures qui sont espacés les uns des autres (les écarts ne sont pas fixes donc on ne peut pas fixer une valeur pour les recherches), cependant ces éléments sont très souvent regroupés via des zonages divers et variés (emprise PV, répartitions des puissances, types de modules, architecture élec', etc). Donc structurellement parlant, ces éléments sont distincts les uns des autres (pas de superposition ou autre) mais ils sont tous liés selon une propriété précise générant des zonages plus ou moins complexes. Le soucis, c'est que les itérations au sein d'un même projet sont nombreuses, donc ces zonages sont souvent modifiés et cela prend donc du temps. Mon idée est donc de pouvoir générer un contour à partir d'un jeu de sélection qui soit suffisamment précis pour englober l'ensembles des objets sélectionnés sans englober d'autres objets non concernés... Le programme devrait pouvoir fonctionner avec des objets linéaires (pour commencer disons simplement lignes et polylignes) puis s'étendre avec des blocs (mais si c'est possible de le faire avec des objets linéaires, cela ne posera pas de soucis de faire la même chose avec des blocs puisqu'il suffira de générer un contour précis au sein d'une définition de bloc pour ensuite utiliser ce contour dans la génération du contour en EO). Pour donner un exemple, je joins un fichier .dwg afin d'illustrer la chose. Dans ma logique, j'avais pensé à une analyse longue et fastidieuse qui s'apparente à la technique du drap. Le but étant de générer un contour global du jeu de sélection (par exemple (LM:ssboundingbox) qui permet de s'assurer que l'ensemble des objets sont présent dans ce rectangle). On définit un point M tel que M appartient à la polyline ABCD (fermée) et aux droites Dh et Dv, avec ABCD le contour du jeu de sélection, Dh la droite horizontale passant par M et Dv la droite verticale passant par M (selon la position du point M sur ABCD). Les droites Dh et Dv vont générer des points d'intersection avec les objets présents dans la surface ABCD, que l'on nommera M' tels que M' soit la projection horizontale ou verticale du point M sur les objets composants le jeu de sélection initial. On obtient donc une liste de points d'intersection pour chaque point M dont on peut récupérer facilement la borne inférieure et la borne supérieure donc on a pour tout points M, une liste de 2 points correspondant à la borne inférieure et supérieure (ou 1 point si la borne inférieure et supérieure sont confondue). En affectant un pas pour générer une liste de point M, on obtient tout un ensemble de couples de points correspondant à l'emprise réelle des objets (sous forme de dessin la forme est proche du zonage attendu, mais sous forme de liste, les points ne sont pas ordonnés correctement, à moins de ne choisir uniquement le point d'intersection le plus proche du point M (car (vl-sort M'-list '(lambda (e1 e2) (< (distance M e1) (distance M e2))))) mais auquel cas il faudra parcourir 100% du périmètre de la boundingbox, et non 50%). Si on affecte un lien entre le point et l'objet issu de cette intersection, il suffira ensuite de récupérer pour chaque projection le sommet réel des objets "coupés" le plus proche de la projection pour limiter le nombre d'objets (et limiter également un contour trop serré) et également éliminer les sommets situés à une distance beaucoup trop importante par rapport à ses voisins (cf. fichier .dwg). Je me rends compte que j'ai de vrais problèmes de concision dans mes explications moi...Donc pour ceux qui ont compris, j'aimerais savoir comment peut-on aborder un problème comme celui-ci sans avoir besoin de calculer les points d'intersection projetés de 2 milliard de points pour simplement générer un contour précis à un jeu de sélection...Car même si sur le papier, la technique du drap fonctionne, cela demande beaucoup de ressources et de temps, ce qui n'est pas le but non plus ! >n< Donc je me dis qu'il existe probablement un théorème mathématique ou une logique permettant de gagner du temps sur les calculs, mais pour un sujet comme celui-ci, ma logique propre ne me permet pas de réfléchir autrement qu'en analytique... Bref, merci pour les âmes charitables qui prendront non seulement le temps de me lire, mais également de me répondre ! (voyez chat comme...un challenge, sauf que je n'ai pas de solution toute faite :3) Bisous, Luna SSBoundingLine.dwg
-
[Challenge] Fonction "d'ordre supérieur"
VDH-Bruno a répondu à un(e) sujet de VDH-Bruno dans Pour aller plus loin en LISP
Bonjour, @Fraid append est moins efficient que un reverse + cons, j'ai beaucoup de mal à retrouver mes sujets sur ce forum, mais nous en avions déjà fait une démonstration dans de précédent challenges, pour les testes sur de grande liste les versions impératives qui utilisent reverse sont meilleurs que leurs versions récursives. @(gile)Bien que le (eval fun) soit exécuté à chaque appel, je préfère utiliser la "fonction lambda enveloppante" en bibliothèque (pas en challenge) par goût et par clarté avec l'habitude ce style de structure est devenu idiomatique, au premier coup d’œil, je sais comment s'exécute le traitement de haut en bas ou de bas en haut. Ne "lispant" plus que par loisir je suis moins dans l'optimisation de l'écriture. @Tous: Si on devait trouver une moral, pour moi elle est dans cette déclaration: Qui rejoint dans mon esprit la suivante: "Inverser une donné puis permuter ses termes 2 à 2, revient à grouper les termes 2 à 2 puis à inverser le résultat." Lors d'un récent challenge sur la manipulation de chaîne. Bien qu'en AutoLisp les versions impératives sont toujours meilleurs que les versions récursives équivalentes, la façon qu'à la récursivité de s'exprimer en partant du bas vers le haut, permet bien souvent de reformuler les hypothèses de départ pour écrire de façon plus efficiente les versions impératives. Rapidement un dernier lien que j'ai en tête ici pour illustrer cette approche, l'on pourrait les multiplier à travers le forum. En conclusion la récursivité est utile mais pas indispensable, mais utile 😉. Salutations Bruno -
[Challenge] Fonction "d'ordre supérieur"
VDH-Bruno a répondu à un(e) sujet de VDH-Bruno dans Pour aller plus loin en LISP
Bonjour, Visiblement il n’y a pas eu foule, ça ne me semblait pas un exercice trop dur à relever (j’espère tout de même qu’il y en a quelques-uns qui ont tenté de plancher de leurs coté). Dans ce challenge outre le fait que la fonction soit d’ordre supérieur (c’est-à-dire qu’elle accepte une fonction en argument), la fonction en argument comparant les éléments 2 à 2, l’éventuelle difficulté dans le traitement, c’est de vouloir construire la liste en retour par la queue (au moyen d’append), alors qu’une liste se construit plus simplement par la tête (avec cons)… En récursif dans la version que j’utilise en bibliothèque, cette difficulté est aisément contourné (en l’absence de fonction let qui contextualise les appels) par une fonction lambda enveloppante qui déroule la pile d’appel et permet de construire la liste à la remonté des appels donc par la queue de liste qui devient la tête (un tête à queue en quelque sorte 😄). Le code : (defun split-if-not (pred lst) (if (cdr lst) ((lambda (loop) (if ((eval pred) (car lst) (caar loop)) (cons (cons (car lst) (car loop)) (cdr loop)) (cons (list (car lst)) loop) ) ) (split-if-not pred (cdr lst)) ) (list lst) ) ) Et en interchangeant les 2 lignes du if on obtient l’autre fonction (defun split-if (pred lst) (if (cdr lst) ((lambda (loop) (if ((eval pred) (car lst) (caar loop)) (cons (list (car lst)) loop) (cons (cons (car lst) (car loop)) (cdr loop)) ) ) (split-if pred (cdr lst)) ) (list lst) ) ) Pour la version itérative en partant de la récursive ça devient tout de suite plus facile, car on comprend de suite que pour travailler sur la tête de liste, il suffit d’inverser la liste en argument. Version avec foreach : (defun split-if-not (fun lst / res) (setq fun (eval fun) lst (reverse lst) res (list (list (car lst))) ) (foreach x (cdr lst) (if (fun x (caar res)) (setq res (cons (cons x (car res)) (cdr res))) (setq res (cons (list x) res)) ) ) ) Ou la même en un peu moins lisible avec un cond : (defun split-if-not (fun lst / res) (setq fun (eval fun) lst (reverse lst) res (list (list (car lst))) ) (foreach x (cdr lst) (setq res (cond ((fun x (caar res)) (cons (cons x (car res)) (cdr res))) (T (cons (list x) res)) ) ) ) ) Version avec while : (defun split-if-not (fun lst / x res) (setq fun (eval fun) lst (reverse lst) res (list (list (car lst))) ) (while (cdr lst) (setq lst (cdr lst) x (car lst) res (cond ((fun x (caar res)) (cons (cons x (car res)) (cdr res))) (T (cons (list x) res)) ) ) ) ) (gile) à proposé une version plus efficiente dans sa récursive avec des (reverse (cons (reverse dans une forme terminale avec accumulateur et fonction auxiliaire, j’ai au premier abord pensé à tort, que c’était due au style enveloppant avec l’emploie d’une fonction lambda (plus lente) et le fait qu’à vouloir ne faire que fonction je ne pouvais optimiser l’appel à la fonction argument (eval pred). Qu’a cela ne tienne j’ai revu ma copie en nommant ma fonction lambda en foo et ma fonction split-if-not en bar (car je trouve toujours dommage de devoir employer reverse /append quant ça peut facilement être évité avec la liberté de raisonnement qu’offre la récursivité. Code révisé: (defun split-if-not (f l / bar foo) (defun bar (m) (if (f (car l) (caar m)) (cons (cons (car l) (car m)) (cdr m)) (cons (list (car l)) m) ) ) (defun foo (f l) (if (null (cdr l)) (list l) (bar (foo f (cdr l)))) ) (foo (eval f) l) ) Comme le résultat m’a permis de m’approcher de la récursive de (gile) mais pas de passer devant, en dernière tentative, j’ai fait le trajet inverse c.a.d de partir d’une version itérative (version foreach) pour la convertir en récursive (chose qu'habituellement je ne fait jamais), je suis arrivé à l’écriture suivante : (defun split-if-not (pred lst / loop) (defun loop (f l acc) (cond ((null l) acc) ((f (car l) (caar acc)) (loop f (cdr l) (cons (cons (car l) (car acc)) (cdr acc)))) (T (loop f (cdr l) (cons (list (car l)) acc))) ) ) (loop (eval pred) (cdr (setq lst (reverse lst))) (list (list (car lst)))) ) Ce qui finalement revient à peu de chose au même résultat que l’expression de (gile) en factorisant les reverse. Donc bravo à (gile) qui a été directement au plus efficace, malgré les reverse qui pour le coup se sont vu justifié. -
Il y a 10 types de personnes dans le monde : celles qui comptent en binaire et les autres
(gile) a répondu à un(e) sujet de (gile) dans Débuter en LISP
Je parlais d'autres environnements dans lesquels la couleur et la transparence sont exprimées en ARGB où A est le canal Alpha qui représente la transparence. De la même manière que pour le RGB, ça permet de stocker et de retrouver facilement 4 valeurs dans un seul nombre qu'on écrit le plus souvent en hexadécimal ce qui rend la décomposition entre les 4 canaux immédiatement visible : #80FF0000 est un rouge (R = 255, G = 0 B = 0) avec 50% de transparence (A = 128). La notation montrée dans le premier message, est appelé "notation en complément à 2". Elle est cohérente quand on utilise un nombre de bits déterminé (ici 32). Elle permet que l'addition d'un nombre positif et d'un nombre négatif soit juste parce qu'on ignore les dépassements (au delà du bit 31) 1 + -1 = 0 : 0 0 0 0 ... 0 0 0 1 + 1 1 1 1 ... 1 1 1 1 = 0 0 0 0 ... 0 0 0 0 En résumé, si on veut faire des opérations bit à bit sur les nombres, on utilise les fonctions décrites ci-dessus qui sont prévues pour ça. De ce côté là AutoLISP est aussi bien équipé que les autres langages de programmation. Essayer de transcrire en opérations arithmétiques sur les décimaux certaines des opérations bit à bit relèverait plus du challenge. -
[challenge] String pour injection
VDH-Bruno a répondu à un(e) sujet de Fraid dans Programmer en s'amusant
Bonjour Fraid, Pour ma part ce n'était pas un problème de passion, juste que le challenge proposé faisait appel à des connaissances que je n'avais pas sur le sujet, donc j'avoue que pour participer cela m'aurait demandé un peu (beaucoup) de recherche pour que je puisse me mettre au niveau de la difficulté à relever. Sur ce coup, j'ai préféré passer mon tour une prochaine fois peut-être. Personnellement je te remercie tout de même de l'avoir posé car qui sait si un jour je veux jouer avec des url ce post sera une bonne base de départ. Salutations Bruno -
[Challenge] Fonction "d'ordre supérieur"
VDH-Bruno a posté un sujet dans Pour aller plus loin en LISP
Bonjour à tous, Dans un challenge précédent il a été rappelé au moyen d'une fonction groupBy l’intérêt de définir des fonctions générique, dans cette esprit (et en plus simple je pense) je propose ici d'écrire une fonction de coupure "générique" (très pratique après une fonction de tri) qui prendrait en argument une fonction prédicat appliqué à une liste: (coupure-if-not predicate-function liste) Pour tester _$ (coupure-if-not '= '(0 0 0 1 1 0 1 1 1 0 0 0 0 1)) ((0 0 0) (1 1) (0) (1 1 1) (0 0 0 0) (1)) _$ (coupure-if-not '(lambda (x y) (= x (1- y))) '(1 2 3 4 6 6 7 8 10 11)) ((1 2 3 4) (6) (6 7 8) (10 11)) Et/ou la fonction symétrique (normalement si on a l'une des deux il est aisé de faire l'autre) (coupure-if predicate-function liste) Pour tester _$ (coupure-if '= '(0 0 0 1 1 0 1 1 1 0 0 0 0 1)) ((0) (0) (0 1) (1 0 1) (1) (1 0) (0) (0) (0 1)) _$ (coupure-if '(lambda (x y) (= x (1- y))) '(1 2 3 4 6 6 7 8 10 11)) ((1) (2) (3) (4 6 6) (7) (8 10) (11)) Le but de ce challenge est de ce familiariser avec l'écriture/utilisation des fonctions dite "d'ordre supérieur", pour laisser tout à chacun le loisir de réfléchir au problème , je ne pense pas remettre ma copie avant Mardi soir ou Mercredi en journée. Pour ceux qui ont déjà cette fonction en magasin prière d'attendre les premières propositions ou tentative de propositions. (En cas de difficulté regarder du coté des fonctions vl-remove-if-not, vl-remove-if, vl-member-if-not, vl-member-if. (gile) en à déjà proposé des équivalences sur le forum, si je retrouve le lien je le posterai). Bon WE à tous -
[challenge] String pour injection
Fraid a répondu à un(e) sujet de Fraid dans Programmer en s'amusant
Ok, tu t'éloigne un petit peu. On s’occupe que de la partie injection. (après le dernier / ) dans l'absolue, si on encode tous les caractères, c'est évidement accepté par le serveur. Mais la, le but, est de garder une lisibilité par un être humain de l'injection. Je vais reformuler le challenge en oubliant le javascript. Convertir les caractères spéciaux excepté "- _ . ! ~ * ' ( )" en caractères hexadécimal pour UTF-8 voir lien donné à Luna + haut. -
[challenge] String pour injection
Fraid a répondu à un(e) sujet de Fraid dans Programmer en s'amusant
bonjour Luna un petit lien pour comprendre caracteres et oui, ce challenge demande un peu de recherche -
Bonjour, Je viens de me souvenir d'un challenge perso qui m'avais bien tordu l'esprit. Convertir un texte pour injection d'URL. (ou requete HTML). Lorsque nous tapons une adresse internet dans la barre d'adresse d'un navigateur, c'est une injection. Exemple simple "https://www.openstreetmap.org/#map=16/48.4674/-2.5486" Ici nous arrivons directement au coordonnées injectées. Mais lorsque nous utilisons une URL en programmation, nous utilisons pas la barre du navigateur, cela va directement au serveur. Si l'injection contient des caractères spéciaux il faut les convertir en Caractères hexadécimales. Exemple "https://fr.wikipedia.org/wiki/Saint-Barthélemy-d'Anjou" doit devenir "https://fr.wikipedia.org/wiki/Saint-Barth%C3%A9lemy-d'Anjou" ou "aB 09_éùl'o @£" -> "aB%2009_%C3%A9%C3%B9l'o%20%40%C2%A3" Il existe des fonctions ou méthodes dans beaucoup de langage qui s'occupe très bien de cela, mais pas en Autolisp. Je me permet donc de vous proposer d'écrire l'équivalent de ces 2 fonctions Javascript encodeURIComponent decodeURIComponent Évidement sans énumération telle que '(("é" . "%C3%A9") ...) Je poste mes fonctions Dimanche soir. bonne exploration et à bientôt.
-
[Challenge] Grouper des points
(gile) a répondu à un(e) sujet de (gile) dans Programmer en s'amusant
Ces challenges ne poussent pas toujours à prendre du recul ni à faire les choses sereinement. On a un peu tendance à se focaliser (parfois avec des œillères) sur le problème posé (surtout quand il est mal posé comme ici) et à vouloir y répondre vite (avant les autres) en privilégiant la concision, l'élégance, l'efficience. C'est le jeu, et je m'y suis laissé prendre avec plaisir plus souvent qu'à mon tour. Là j'ai le beau rôle en lançant ce challenge avec une réponse quasiment toute faite à partir de fonctions écrites depuis longtemps. Mais, si je peux me permettre de tirer "la morale de cette histoire" ça serait : 1. Quand on est face à un problème "complexe" il faut essayer de le décomposer en plusieurs problèmes plus simples (et plus facile à résoudre et à tester séparément). 2. Quand on résout un problème, essayer de généraliser la solution afin qu'elle puisse resservir pour d'autres problèmes (une fonction de groupage générique peut avoir de nombreuses autres utilités). -
Bon ben, je vais avoir du travail pour étudier tout chat et comprendre la logique parce que ya pas à dire, c'est propre ! C'est une leçon très intéressante quoi qu'il en soit et qui démontre parfaitement l'importance de la logique appliquée par le développeur pour arriver à ses fins. Les routes sont nombreuses pour arriver à ses fins mais une bonne connaissance du chemin permet d'emprunter des raccourcis facilitant une utilisation généralisée (mais pouvant créer des nœuds au cerveau parfois !). J'avais justement essayé un développement similaire au début mais je me suis ratée sur la génération des clés de recherche, donc après quelques nœuds au cerveau, j'ai préférer me rabattre sur une logique plus...analytique mais avec cela, j'aurais de quoi apprendre à mieux les utiliser car cela peut servir en de nombreuses occasions ! Donc merci pour ce challenge et pour vos réponses à tous ! Bisous, Luna
