Reputation: 75
I need to write a Scheme function that takes a list as an argument and returns a list of lists where every list is a cycle of the original list. By a cycle, I mean shifting the first element to the last position. I have the following functions:
(define (cycle lst)
(cond ((null? lst) '())
((null? (cdr lst)) lst)
(else (append (cdr lst) (list (car lst))))))
(define (shift lst)
(define (iter l cycles result)
(cond ((= cycles 0) (cons lst result))
((< cycles 1) result)
(else (iter (cycle-1 l) (- cycles 1) (cons result (cycle-1 l))))))
(iter lst (- (length lst) 1) '()))
Now, when I do: (shift '(1 2 3)) I get: '((1 2 3) (() 2 3 1) 3 1 2) I should get: '((1 2 3) (2 3 1) (3 1 2))
Upvotes: 2
Views: 550
Reputation: 7078
(define (shift lst)
(define (iter l cycles result)
(cond ((= cycles 0)
(cons lst result))
((< cycles 0) result)
(else (let ((cycled (cycle l)))
(iter cycled (- cycles 1) (cons cycled result))))))
(iter lst (- (length lst) 1) '()))
First, I've made a simple improvement to prevent calculate cycled form of the list twice(added let
). Second, you need to cons cycled
to result
since you need to append result
list, not cycled
list. In your code, you're adding last result to old results and then passing this wrongly appended results list to iter
functions as result
parameter.
Update: To get the results in your order you can simple just append result with cycled list, instead of adding cycled list to head of the result:
(define (shift lst)
(define (iter l cycles result)
(cond ((= cycles 0)
(cons lst result))
((< cycles 0) result)
(else (let ((cycled (cycle l)))
(iter cycled (- cycles 1) (append result (list cycled)))))))
(iter lst (- (length lst) 1) '()))
Upvotes: 1