From 64ae51ba71724651802f1caf8370c140d18c35cd Mon Sep 17 00:00:00 2001 From: redxef Date: Sun, 26 Jan 2025 22:38:52 +0100 Subject: [PATCH] fix: qsort ran into an infinite loop when encountering duplicate values. --- .../Lisp/Interpreter.cs | 39 +++++++++++++++---- Tests/Tests.cs | 4 ++ 2 files changed, 36 insertions(+), 7 deletions(-) diff --git a/Jellyfin.Plugin.SmartPlaylist/Lisp/Interpreter.cs b/Jellyfin.Plugin.SmartPlaylist/Lisp/Interpreter.cs index 8cc0225..2b4adb1 100644 --- a/Jellyfin.Plugin.SmartPlaylist/Lisp/Interpreter.cs +++ b/Jellyfin.Plugin.SmartPlaylist/Lisp/Interpreter.cs @@ -90,25 +90,50 @@ namespace Jellyfin.Plugin.SmartPlaylist.Lisp { (lambda (list0) (car list0))) + ;(split + ; (lambda + ; (list0 pivot fc h0 h1) + ; (cond + ; ((null list0) (list list0 pivot fc h0 h1)) + ; ((fc (car list0) pivot) (split (cdr list0) pivot fc h0 (cons (car list0) h1))) + ; (t (split (cdr list0) pivot fc (cons (car list0) h0) h1))))) (split (lambda - (list0 pivot fc h0 h1) + (list0 pivot fc h0 h1 heq) (cond - ((null list0) (list list0 pivot fc h0 h1)) - ((fc (car list0) pivot) (split (cdr list0) pivot fc h0 (cons (car list0) h1))) - (t (split (cdr list0) pivot fc (cons (car list0) h0) h1))))) + ((null list0) (list list0 pivot fc h0 h1 heq)) + ((and + (fc (car list0) pivot) + (fc pivot (car list0))) (split (cdr list0) pivot fc h0 h1 (cons (car list0) heq))) + ((fc (car list0) pivot) (split (cdr list0) pivot fc h0 (cons (car list0) h1) heq)) + ((fc pivot (car list0)) (split (cdr list0) pivot fc (cons (car list0) h0) h1 heq)) + ((= (car list0) pivot) (split (cdr list0) pivot fc h0 h1 (cons (car list0) heq))) + (t (split (cdr list0) pivot fc h0 h1 heq))))) + ;(sort + ; (lambda + ; (fc list0) + ; (cond + ; ((null list0) nil) + ; ((null (cdr list0)) list0) + ; (t + ; (let* + ; (halves (split list0 (getpivot list0) fc nil nil)) + ; (h0 (car (cdr (cdr (cdr halves))))) + ; (h1 (car (cdr (cdr (cdr (cdr halves)))))) + ; (append (sort fc h0) (sort fc h1))))))) (sort (lambda (fc list0) - (cond + (begin t (cond ((null list0) nil) ((null (cdr list0)) list0) (t (let* - (halves (split list0 (getpivot list0) fc nil nil)) + (halves (split list0 (getpivot list0) fc nil nil nil)) (h0 (car (cdr (cdr (cdr halves))))) (h1 (car (cdr (cdr (cdr (cdr halves)))))) - (append (sort fc h0) (sort fc h1))))))) + (heq (car (cdr (cdr (cdr (cdr (cdr halves))))))) + (append (append (sort fc h0) heq) (sort fc h1)))))))) (sort fc list00))) """ ); diff --git a/Tests/Tests.cs b/Tests/Tests.cs index beb9bc6..f8d8b05 100644 --- a/Tests/Tests.cs +++ b/Tests/Tests.cs @@ -267,6 +267,10 @@ namespace Tests //Assert.Equal("", e.eval("(shuf (list 0 1 2 3 4 5 6))").ToString()); Assert.Equal("(1 2 3 4 5 6 7)", e.eval("(qsort (lambda (a b) (> a b)) '(5 4 7 3 2 6 1))").ToString()); Assert.Equal("(1 2 3 4 5 6 7)", e.eval("(qsort > (list 5 4 7 3 2 6 1))").ToString()); + Assert.Equal("(0 1 2 4 5 5)", e.eval("(qsort > '(2 4 1 5 5 0))").ToString()); + Assert.Equal("(5 5 4 2 1 0)", e.eval("(qsort < '(2 4 1 5 5 0))").ToString()); + Assert.Equal("(5 5 4 2 1 0)", e.eval("(qsort <= '(2 4 1 5 5 0))").ToString()); + Assert.Equal("(0 1 2 4 5 5)", e.eval("(qsort >= '(2 4 1 5 5 0))").ToString()); } } }