Vorwort: Ich mache gerade einen komprimierten Kurs, der anscheinend in LISP gelehrt wird und ich habe nie mit LISP in meinem Leben gearbeitet, also musste ich die Sprache über eine lernen Wochenende. Ich entschuldige mich im Voraus für den abgründigen Code. Ich kenne LISP nur so gut, dass der Code funktioniert und nicht viel mehr.Common LISP (SBCL): Rückgabe von Werten innerhalb von Schleifen
Ich arbeite gerade an einem Programm, das das Problem der Karteneinfärbung löst. Dieser Code nimmt eine Sequenz an, bei der das erste Element jeder Untersequenz ein Zustand und das zweite Element eine Farbe darstellt. ex: '((A R) (B G) (C G) (D Y) (E B) (F B)) und überprüft dann, ob kein Zustand die gleiche Farbe hat wie ein durch ihn eingeschränkter Zustand (definiert durch die Beschränkungsliste). Ich weiß, dass es wahrscheinlich viel sauberere und einfachere Wege gibt, dies zu tun, aber was ich momentan damit zu tun habe, ist, dass meine Dolist-Schleifen sofort den Wert T zurückgeben, wenn die if-Anweisung erfüllt wird. Bisher konnte ich die Funktionen nicht einfach einen Wert zurückgeben und musste auf diese wirklich hässliche/falsche Methode zurückgreifen, um eine Variable auf "true" zu setzen und darauf zu warten, dass die Schleife beendet wird, damit der Code funktioniert. Ich habe versucht, Return und nur T innerhalb der if-Anweisungen verwenden, aber in beiden Fällen würde die Schleife beenden statt einen Wert zurückgeben und ich habe keine Ahnung warum.
(setq constraint '((A (B C E)) (B (A E F)) (C (A E F)) (D (F)) (E (A B C F)) (F (B C D E))))
(defun check_constraint (f s)
(setf ans nil)
(dolist (state constraint)
(if (eq (first state) f)
(if (search (list s) (second state))
(setf ans T) ;;where I want it to just return T
)
)
)
ans
)
;;ex: ((A R) (B R) (C B) (D R) (E B) (F G))
(defun check_conflict (lst)
(setf anb nil)
(dolist (state lst)
(dolist (neighbor (remove state lst))
(if (check_constraint (first state) (first neighbor))
(if (eq (second state) (second neighbor))
(setf anb T)) ;;where I want it to just return T
)
)
)
anb
)
EDIT: Ich endete nur dies mit Rekursion zu beheben. Der Code ist jetzt sauberer, aber ich würde immer noch gerne wissen, was mein Problem ist. Dies ist der rekursive Code.
(setq constraint '((A (B C E)) (B (A E F)) (C (A E F)) (D (F)) (E (A B C F)) (F (B C D E))))
(defun check_constraint (lst f s)
(COND
((null lst) nil)
((search (list (car (car lst))) f)
(if (search s (second (car lst))) T))
(t (check_constraint (cdr lst) f s))
)
)
(defun check_neighbor (check lst)
(COND
((null lst) nil)
((check_constraint constraint (list (car check)) (list (first (first lst))))
(if (eq (second check) (second (car lst))) T))
(t (check_neighbor check (cdr lst)))
)
)
;;(check_state '((A R) (B R) (C B) (D R) (E B) (F G)))
(defun check_state (lst)
(COND
((null lst) nil)
((check_neighbor (car lst) (cdr lst)) T)
(t (check_state (cdr lst)))
)
)
Es gibt viele lisp Dialekte, und Sie sagen nicht, welche. In den meisten Dialekten gibt es eine spezielle Form 'return', die verwendet werden kann, um einen Wert von einer höheren Form zurückzugeben.Leider, welche Formen es betrifft, ist eines der Dinge, die sich zwischen Dialekten unterscheiden. Also mit '(return T)' an diesem Punkt würde arbeitet die meisten der Dialekte ich weiß, [und Sie tun können, weg mit dem Vars 'ans' und' anb' und nur noch 'NIL' nach der Schleife]. – MAP
@MAP Es ist allgemeines Lispeln und wenn ich das versuche, konnte ich es nicht in SBCL arbeiten lassen. – Metasyntactic