이재찬
이재찬

Reputation: 62

Loop doesn't work properly

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

Answers (2)

WorBlux
WorBlux

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

Will Ness
Will Ness

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

Related Questions