Reputation: 62
So
(let loop ((p (- (length lst) 1)) (i 0) (l lst))
(cond
((= p 0)
lst)
((= i p)
(loop (+ p -1) 0 l))
((> (vector-ref (convert lst) i) (vector-ref (convert lst) p))
(loop (+ p 0) (+ i 1) (swap (convert l) i p)))
((< (vector-ref (convert lst) i) (vector-ref (convert lst) p))
(loop (+ p 0) (+ i 1) l)))
it will return original state on (= p 0)
when i send lst
of '#(3 2 1)
but when i run swap
function separately it will return '#(1 2 3)
. p
is the last array and i
is the first of the array.
Upvotes: 1
Views: 109
Reputation: 1413
'#(3 2 1)
is vector notation. A (list '#(3 2 1))
as input should return (#(1 2 3))
However that's not the worst thing here. Coverting between list and vector multiple times in the same cond case signals that something is wrong. You are spending lots of time and memory to make a vector you only use one. My suggestion is to convert to vector on the way in, and to a list on the way out.
And a few notation improvements could be made. Typically a lisp function that converts between types is denotated with a "->" between the types. So convert
should be (list->vector) and you should have a corresponding (vector->list). One function shouldn't do both at least not without explicit arguments to avoid getting the data type wrong.
Also swap
should be swap!
as it mutates the data structure in place.
Also there's a logic error. If two elements in the input list are equal, you'll fall through all your cond clauses and trigger an exception.
(let loop ((p (- (length lst) 1)) (i 0) (vec (list->vector l))
(cond
((= p 0)
(vector->list lst))
((= i p)
(loop (- p 1) 0 l))
((> (vector-ref vec i) (vector-ref vec p))
(loop p (+ i 1) (swap! vec i p)))
(else
(loop p (+ i 1) l)))
Upvotes: 1
Reputation: 71065
Use l
instead of lst
to have the final value returned, not the original.
You start from l = lst
, and progress in the loop changing the l
on each step.
When you hit the final condition, just return what you have built, l
.
Upvotes: 1