The issue is that in the last line, the term (+ (car l) (car r))
is entirely incorrect; (car l)
is the first element of the input list, which might not affect the output at all; while r
shouldn't even matter if n
is not equal to 1. Instead, that term should be the left-overs from the recursive call to vide
, i.e. (car (vide (- n 1) (cdr l)))
. Since you also use the cadr
, I bound the recursive call in a let
to avoid calling it twice. In addition, I put the binding of r
to the result of distribue
inside the (if (= n 1) ...)
because it isn't used in the else clause now.
Here is the corrected implementation (distribue
is left unchanged):
(define vide
(lambda (n l)
(if (null? l)
(list n l)
(if (= n 1)
(let ((r (distribue (car l) (cdr l))))
(list (car r) (cons 0 (cadr r))))
(let ((v (vide (- n 1) (cdr l))))
(list (car v) (cons (car l) (cadr v))))))))
As a side note to anyone else who comes by this question, I believe the rule implemented by vide
here is akin to a single part of a move in the game Kalah, known as Mancala in the US.