Page 1 of 1

Add 1 to the middle element of a list

PostPosted: Fri Nov 09, 2018 10:12 am
by andrewcmunroe
Hi. Can I please get some help?

"Write a function MID-ADD1 that adds 1 to the middle element of a
three-element list.
For example, (MID-ADD1 ’(TAKE 2
COOKIES)) should return the list (TAKE 3 COOKIES). Note: You
are not allowed to make MID-ADD1 a function of three inputs. It
has to take a single input that is a list of three elements."

Here's what I came up with:
(defun mid-add1 (l) (+ 1 (car (cdr l))))

This only returns the modified element. How can I get the modified list?

Re: Add 1 to the middle element of a list

PostPosted: Sat Nov 10, 2018 3:21 pm
by nuntius
Construct a new list. Include the original head, new middle, and original tail.

There are ways to destructively modify the middle value in the original list (setf ...), but I think the new list is what your instructor is looking for.
If done right, the amount of code is about the same either way.

Re: Add 1 to the middle element of a list

PostPosted: Sun Nov 11, 2018 7:20 am
by sylwester
The clearest would be to
Code: Select all
(defun mid-add1 (list)
  "Adds 1 to the middle element of a
three-element list."
  (assert (and (listp list) (= (length list) 3))  (list) "~a must be a 3 element list" list)
  (destructuring-bind (first-element mid-num third-element) list
    (assert (numberp mid-num) (list mid-num) "The second element of ~a must be a number. Got ~a" list mid-num)
    (list first-element (1+ mid-num) third-element)))


Of course you can just use accessors:

Code: Select all
(defun mid-add1 (list)
  "Adds 1 to the middle element of a
three-element list."
  (assert (and (listp list)
                    (= (length list) 3)
                    (numberp (second list)))  (list) "~a must be a 3 element list with the second element being numeric" list)
  (list (first list) (1+ (second list)) (third list)))