2016-05-12 7 views
-2
(defun combinations (&rest lists) (if (car lists) (mapcan (lambda (in-val) (mapcar (lambda (out-val) (cons out-val in-val)) (car lists))) (apply #'combinations (cdr lists))) (list nil))) 

Diese Funktion erstellt eine Kombination aus beliebig vielen Listen.So entfernen Sie Elemente eine Liste in einer Liste, die zwei Elemente enthält, die Sie nicht möchten?

(defun main() 
    (setq m-list (combinations '(Blacket Bluet Browning Greenfield Whitehall) '(four-leaf-clover penny rabbit-foot ribbon silver-dollar) '(center-field first-base right-field short-stop third-base))) 

    (setq constraints (list '(Browning penny) '(Browning silver-dollar) '(Browning right-field) '(Browning center-field) '(Bluet center-field) '(Bluet right-field) '(Greenfield first-base) '(Greenfield short-stop) 
    '(Greenfield third-base) '(Whitehall center-field) '(Whitehall right-field) '(Greenfield four-leaf-clover) '(Greenfield penny) '(Whitehall four-leaf-clover) '(Whitehall penny) 
    '(Blacket four-leaf-clover) '(Blacket penny) '(Blacket first-base) '(Blacket third-base) '(Blacket ribbon) '(Bluet ribbon) '(center-field rabbit-foot))) 
    (loop 
    (print m-list) 
    (setq n-constraint (car constraints)) 
    (setq m-list (remove-it m-list n-constraint)) 
    (setq constraints (cdr constraints)) 
    (when (null constraints) (return m-list)))) 

Die Hauptfunktion erstellt zwei Listen, eine Liste aller möglichen Kombinationen von Spielern, Charme, und Positionen sowie eine Liste von Einschränkungen, wo zwei Variablen in jeder Beschränkungsliste nicht zusammen sein können. Ich habe dann eine Schleife erstellt, um bei jeder Iteration eine Einschränkung zu übernehmen und aus der Hauptliste der Kombinationen die Kombination zu entfernen, die mit dem übereinstimmt, was die Einschränkung besagt, dass sie nicht existieren sollte.

(defun remove-it (x y) 
    (if (and (not (eq (find (nth 0 y) (car x)) nil) (not (eq (find (nth 1 y)(car x)) nil)))) (setq x (remove (car x) x :test #'equal))) 
    (return x)) 

Aus irgendeinem Grund die remove-it-Funktion verwaltet nur alles rund um die Einschränkung im Zusammenhang zu entfernen. Zum Beispiel ist eine Einschränkung (Browning Penny). Die Absicht ist, irgendeine Liste innerhalb der massiven Kombinationsliste zu entfernen, die die zwei Elemente Browning und Penny zusammen enthält. Die Funktion scheint jedoch jede Liste, die Browning separat und Penny enthält, zu entfernen. Ich will nur die Funktion, Listen zu entfernen, die Browning und Penny zusammen haben.

(defun remove-it (x y) 
    (if (and (not (eq (find (nth 0 y) (car x)) nil) 
       (not (eq (find (nth 1 y)(car x)) nil)))) 
     (setq x (remove (car x) x :test #'equal))) 
    (return x)) 

Das ist ziemlich unsinnig, wie Funktionen gehen:

+4

Lasen Sie [meine antwort] (http://stackoverflow.com/a/37164868/5747548) zu deiner vorherigen Frage? Du scheinst immer noch die gleichen Fehler zu machen, die ich bereits erwähnt habe. – jkiiski

+0

Prüfe auch die Verschachtelung deines booleschen Ausdrucks in 'remove-it '. –

Antwort

2

die mit Einrückungen Ihre remove-it Funktion Lassen Sie starten. Die not-Funktion nimmt in der Regel nur ein einziges Argument an. Sie haben (höchstwahrscheinlich) eine schließende Klammer nach dem ersten not-Aufruf verloren.

Sie überprüfen auch nur das allererste Element von x, wenn das in Ordnung ist, überprüfen Sie nicht den Rest der Liste.

Ihre Variablennamen sind weniger als klar (was bedeutet "x" und "y" eigentlich).

Sie brauchen keine explizite Rückgabe, nur x als einzelner Ausdruck am Ende funktionieren würde.

ein möglicherweise bessere Lösung sein könnte (basierend auf meinem Verständnis von dem, was Sie eigentlich tun wollen, nämlich „alle Kombinationen sammeln, die zwei verbotene Combos nicht wichtig):

(defun remove-constrained-combinations (combinations constraint-1 constraint-2) 
    (loop for combo in combinations 
     unless (and (member constraint-1 combinations) 
        (member constraint-2 combinations) 
     collect combo))