funkcję:SBCL działa zawsze na drugim wywołaniu funkcji
Biorąc pod uwagę powrót lista LST wszystkie permutacje listy za treść dokładnie długości k, które domyślnie długość listy, jeśli nie są uregulowane.
(defun permute (lst &optional (k (length lst)))
(if (= k 1)
(mapcar #'list lst)
(loop for item in lst nconcing
(mapcar (lambda (x) (cons item x))
(permute (remove-if (lambda (x) (eq x item)) lst)
(1- k))))))
problem: Używam szlam w emacs podłączonych do SBCL, nie robiłem jeszcze zbyt wiele personalizacji. Funkcja działa dobrze na mniejszych wejściach, takich jak lst = '(1 2 3 4 5 6 7 8) k = 3, co jest najczęściej używane w praktyce. Jednak, gdy wywołuję go z dużym wejściem dwa razy z rzędu, drugie połączenie nigdy nie wraca, a sbcl nawet nie pojawia się na górze. Są to wyniki REPL:
CL-USER> (time (nth (1- 1000000) (permute '(0 1 2 3 4 5 6 7 8 9))))
Evaluation took:
12.263 seconds of real time
12.166150 seconds of total run time (10.705372 user, 1.460778 system)
[ Run times consist of 9.331 seconds GC time, and 2.836 seconds non-GC time. ]
99.21% CPU
27,105,349,193 processor cycles
930,080,016 bytes consed
(2 7 8 3 9 1 5 4 6 0)
CL-USER> (time (nth (1- 1000000) (permute '(0 1 2 3 4 5 6 7 8 9))))
I nigdy nie wraca z drugiego połączenia. Mogę się tylko domyślać, że z jakiegoś powodu robię coś okropnego śmieciarzowi, ale nie widzę co. Czy ktoś ma jakieś pomysły?
Coś ciekawego w twoim buforze * niższej selekcji *, kiedy to się dzieje? – Xach
dlaczego nie przerywać SBCL i nie patrzeć wstecz na to, co robi? –
Jako ogólne pytanie dla wszystkich, którzy odpowiedzieli.Wygląda na to, że ilość śmieci, które tworzę, jest problemem. Czy są jakieś dobre artykuły wyjaśniające, jak obejść takie rzeczy? Zrobiłem kilka rzeczy, które, jak sądziłem, pomogłyby, ale ogólnie sprawiły, że stało się to znacznie gorsze. – asm