Reputation: 21
Write a function that takes a list and a length as input and returns two lists: (1) The first length elements of the input list, and (2) the remainder of the input list. Hint: Use a helper method with an "accumulator" parameter. I'm stuck guys and could really use some help.
I keep getting error when I try to do (split-list '(a b c d e f g) 7) which is the number equal to length otherwise any number less than than that does what its supposed to do :
Argument #1 '()' to 'car' has wrong type (empty-list)
(split-list '(a b c d e f g) 0)
should return '(() (a b c d e f g))
(split-list '(a b c d e f g) 1)
should return '((a) (b c d e f g))
(split-list '(a b c d e f g) 3)
should return '((a b c) (d e f g))
(define (split-list lst length)
(define(split-list-head accum length)
(if (= length 0)
(cdr '(accum))
(cons (car accum) (split-list-head (cdr accum)(- length 1)))
)
)
(define(split-list-tail accum length)
(if (= length 0)
(cons (car accum)(cdr accum))
(split-list-tail (cdr accum)(- length 1))
)
)
(if (eq? length 0)
(append(list (list))(list lst))
(append(list(split-list-head lst length)) (list(split-list-tail lst length)))
)
)
Upvotes: 0
Views: 550
Reputation: 71065
Try this. It makes use of three accumulating parameters. A subtraction is also kind of accumulation.
(define (split n xs k)
(define (loop xs n k)
(if
(and (> n 0) (not (null? xs)))
(loop (cdr xs) (- n 1)
(lambda (a b) (k (cons (car xs) a) b)))
(k '() xs)))
(loop xs n k))
Can you see how it is to be called?
Can you explain how it works?
Or a bit shorter,
(define (split n xs k)
(define ((+ f a) b) (f (cons (car a) b)))
(define (loop xs n k)
(if
(and (> n 0) (not (null? xs)))
(loop (cdr xs) (- n 1) (+ k xs))
((k '()) xs)))
(loop xs n k))
Can you find a way how should this function be called? I'll give you a hint, how should this function
(define ((add a) b) (list a b))
be called?
Upvotes: 0
Reputation: 1732
Unless you are particularly attached to GNU Scheme, I would consider moving to Dr Racket.
Although it was written for a similar language called Racket, it can be set up to run vanilla Scheme, by putting in a first line #lang scheme
The nice about Dr Racket is that it has a very nice debugger.
My code, with the #lang line at the start, and the erroring line at the bottom:
#lang scheme
(define (split-list lst length)
(define(split-list-head accum length)
(if (= length 0)
(cdr '(accum))
(cons (car accum) (split-list-head (cdr accum)(- length 1)))
)
)
(define(split-list-tail accum length)
(if (= length 0)
(cons (car accum)(cdr accum))
(split-list-tail (cdr accum)(- length 1))
)
)
(if (eq? length 0)
(append(list (list))(list lst))
(append(list(split-list-head lst length)) (list(split-list-tail lst length)))
)
)
(split-list '(a b c d e f g) 7)
If I just run the code, it highlights the error in split-list-tail
, where car
causes a contract violation. It also shows the call sequence.
That's probably enough to identify the fault, but I can also run the debugger. By clicking on the Debug button I move to the debug mode. By moving the mouse pointer over a parenthesis, and right clicking, I can enable or disable a pause at this point - show by a pink circle. The variables are shown on the right hand side. When I run the code in the debugger, variable accum
is empty, hence car accum
fails.
My suggestion is that you use pair?
or null?
to test accum
before calling car
on it.
Upvotes: 1