LISP Easy questio about creating new lists - lisp

A function that receives a list with sublist's M*N and returns the sum of all elements of the sublist's
example: (solution '( (1 2 3) (4 5 6) ) )
return: (5 7 9)
Sry for the bad english
thks =)

A Common Lisp version is almost the same as in Scheme:
(defun solution (list)
(apply #'mapcar #'+ list))
(solution '((1 2 3) (9 10 11) (3 4 5)))
; ==> (13 16 19)

It depends on what Lisp interpreter you're using. In Scheme, this will work:
(define (solution lsts)
(apply map + lsts))
For example:
(solution '((1 2 3) (4 5 6)))
=> '(5 7 9)

Related

How would I write a function in Dr. Racket which consumes a list of list of integers and produces a new list of list of integers?

How would I write a function in Dr. Racket which consumes a list of list of integers and produces a new list of list of integers with a transformation (sqr) applied to each element.
Note: There is an equal number of elements in each list.
Here are two examples to show what I am saying:
Example 1:
(list (list 1 2) (list 3 -2))
Should produce:
(list (list 1 4) (list 9 4))
Example 2:
(list (list 3 4 5) (list 2 1 3) (list 2 3 7) (list 0 -3 2))
Should produce:
(list (list 9 16 25) (list 4 1 9) (list 4 9 49) (list 0 9 4))
Here is my code so far:
(define (transform-to-sqr b)
(map sqr b))
If I type in:
(transform-to-sqr (list (list 1 2) (list 3 -2)))
I get an error message saying:
sqr: expected a number; given (list 1 2).
Why is this happening. Can someone please tell me what I am doing wrong.
Thanks for your help.
The map higher-order procedure applies a procedure over the elements of a list, but in this case the elements are lists themselves. To operate on the nested elements, we need to nest calls to map:
(define (transform-to-sqr matrix)
(map (λ (row) (map sqr row))
matrix))
It works as expected:
(transform-to-sqr '((1 2) (3 -2)))
=> '((1 4) (9 4))
(transform-to-sqr '((3 4 5) (2 1 3) (2 3 7) (0 -3 2)))
=> '((9 16 25) (4 1 9) (4 9 49) (0 9 4))

How to simulate collecting in nested loop for [duplicate]

This question already has an answer here:
Nested Loops Using Loop Macro in Common Lisp
(1 answer)
Closed 2 years ago.
I want to create a list of pairs (a . b) with 1 < a < b <= n up to n, e.g. n = 5:
((2 . 3) (2 . 4) (3 . 4) (2 . 5) (3 . 5) (4 . 5))
(The order of the pairs is not critical.)
I came up with the code
(defun create-pairs (upper-bound)
(loop for i from 3 to upper-bound
for j from 2 to (1- upper-bound)
collecting (cons j i)))
but that doesn't do what I wanted
* (create-pairs 5)
((2 . 3) (3 . 4) (4 . 5))
since the loops are incrementing at the same time.
Therefore I tried this
(defun create-pairs (upper-bound)
(loop for i from 3 to upper-bound do
(loop for j from 2 to (1- upper-bound)
collecting (cons j i))))
with the result:
* (create-pairs 5)
NIL
I don't remember where but I read that it's not possible to use collecting in constructs like my second try.
So how do I get the result I want to have? Isn't it possible to solve this with loop for?
You are almost there - you just need to accumulate the results of the inner loop:
(defun create-pairs (upper-bound)
(loop for i from 3 to upper-bound nconc
(loop for j from 2 below i
collect (cons j i))))
(create-pairs 5)
==> ((2 . 3) (2 . 4) (3 . 4) (2 . 5) (3 . 5) (4 . 5))

cons two elements outputs the wrong result

#lang racket
I need to create a pair from an element and a list
however when I do (cons 2 (list 1 2 3)) I get (2 (1 2 3)), I want to get (2 . (1 2 3))
how do I get the dot in ?
Since (cons a b) is the same as (a . b) we get that (2 . (1 2 3)) is the same as (cons 2 (list 1 2 3) which is the same as (list 2 1 2 3). To confirm:
> (cons 2 (list 1 2 3))
'(2 1 2 3)
> '(2 . (1 2 3))
'(2 1 2 3)
Note that the printer prints (2 1 2 3) and not (2 . (1 2 3)). The printer attempts to use the dot only when absolutely needed.
There is a difference between the syntax that explains the structure, how it's stored and how display would represent it.
For a list of two elements there are two ways you can represent it (1) and (1 . ()). When this list is displayed it will always prefer the one with the least parentheses. Thus '(2 . (1 2 3)) will always be printed as (2 1 2 3) by display. If you don't want that you can make yourself a cons-write like:
;; displays cons always as dotted
(define (cons-write x)
(if (pair? x)
(begin
(display "(")
(cons-write (car x))
(display " . ") ; spaces are important
(cons-write (cdr x))
(display ")"))
(write x)))
(cons-write '(1 2 3 4)) ; prints (1 . (2 . (3 . (4 . ()))))

Find and remove a list item based on the item's third element

I need to find and return the first item in a list when that item's third element matches a value passed into the function. I then need that item to be permanently removed from the list.
I have written this function to do it and am wondering if there are any built-in functions that might accomplish the same without this fairly messy implementation:
(defun find-remove-third (x)
(let ((item (first (member x *test-list* :key #'third))))
(setf *test-list* (remove item *test-list* :test #'equal))
item))
Operation:
CL-USER> *test-list*
((1 2 3) (2 3 4) (3 4 5) (4 4 4) (5 4 3) (6 5 4) (2 2 2))
CL-USER> (find-remove-third 4)
(2 3 4)
CL-USER> *test-list*
((1 2 3) (3 4 5) (4 4 4) (5 4 3) (6 5 4) (2 2 2))
CL-USER> (find-remove-third 4)
(4 4 4)
CL-USER> *test-list*
((1 2 3) (3 4 5) (5 4 3) (6 5 4) (2 2 2))
For example pop mutates and returns from a list, though is more limited, but I'm wondering if anything more elegant than my function above might be possible, or if this implementation is normal and idiomatic?
Your implementation scans the list twice, so it is suboptimal.
I don't think you can write what you need without an explicit loop (or, equivalently, recursion):
(defun pop-from-list (object list &key (key #'identity) (test #'eql) kept)
"Like `remove', but return the object removed as the second value."
(let ((1st (car list)))
(if (funcall test object 1st)
(values (revappend kept (rest list))
1st)
(pop-from-list object (rest list) :key key :test test
:kept (cons 1st kept)))))
Now you can define your function like this:
(defun find-remove-third (x)
(multiple-value-bind (list object)
(pop-from-list x *test-list* :key #'third)
(setq *test-list* list)
object))
Edit - Deleting this doesn't seem right so I'll leave it up, but as noted by #sds and #WillNess in the comments, this has serious issues.
Here's a destructive version which only scans the list once. It has the potential benefit that you don't have to hardcode the name of the list you're operating on.
CL-USER> (defun find&remove (list obj &key (key #'identity) (test #'eql))
(loop with last = nil
for cons on list
when (funcall test obj (funcall key (first cons))) do
(progn (setf (rest last) (rest cons))
(return (first cons)))
do (setf last cons)))
CL-USER> (defvar test-list (list (list 1 2 3)
(list 3 4 5)
(list 5 6 7)
(list 8 9 10)))
CL-USER> (find&remove test-list 5 :key #'third)
(3 4 5)
CL-USER> test-list
((1 2 3) (5 6 7) (8 9 10))
CL-USER> (find&remove test-list 7 :key #'third)
(5 6 7)
CL-USER> test-list
((1 2 3) (8 9 10))
The key is to traverse the list by cons cell rather than by item (loop for ... on rather than loop for ... in) and keep a pointer to the parts of the list we've already looked at (last). Then, when we find what we're looking for, we connect the cdr of what we'd already seen to the next cons (so now the list omits the "hit") and finally return the result.

Lisp Recreating a Temporary Variable

I'm having a bit of trouble with Lisp. What i'm attempting to do, is keep track of the amount of times a number appears in x number of lists. However, running this over and over again, lisp isn't recreating the variable, but using the ending value from the last time I called the function. So I'm wondering how can I get past the 'binding' powers of let?
So, I've got some list like this
(((8 7) (3)) ((8 3) (2)) ((7 3) (6)) ((7 2) (8)) ((6 7) (4 1))
((6 6) (4 1)) ((6 2) (2)) ((5 6) (3)) ((5 3) (8 3)) ((4 6) (4))
((4 4) (6)) ((4 1) (7)) ((3 7) (5 3)) ((3 4) (1)) ((3 3) (3)) ((3 1) (9))
((2 7) (7)) ((2 5) (2)) ((2 2) (5 2)) ((1 7) (1)) ((1 6) (6 1))
((1 1) (2 1)) ((1 0) (3)) ((0 7) (8 1)) ((0 5) (6)) ((0 3) (9 6))
((0 1) (1)))
Then I'm calling some function like this, (declaring var here doesn't seem to do anything, past the initial function call)... I guess some kind of binding from let.
(defun counter (possibleValues)
(let ((var '(0 0 0 0 0 0 0 0 0 0)))
(loop for i from 0 to (list-length possibleValues) do
(loop for j in (cdr (nth i possibleValues)) do
(loop for k in j do
(incf (nth k var)))))
var))
So I can run my list through the function and get something like
(0 8 5 6 3 2 5 2 3 2)
Each position referring to the number found in the list. So the value 8 would refer to how many times 1 was found in all the lists (i'm considering the second list only). Now the problem.... run it twice and...
(0 16 10 12 6 4 10 4 6 4)
I was using an associative list earlier, but in trying to figure this out and keep things simple, i'm now using a list. I guess another question I have is, how can I create associative list elements on the fly? I don't like declaring 'var' like that, but I'm just trying to get around 'let' for the moment. I haven't had much luck with 'setq' or 'setf' either....
Thanks in advance for your help!
Change the initialization form for VAR to be an expression that creates new lists, such as (make-list 10 :initial-element 0) or even (list 0 0 0 0 0 0 0 0 0 0).
Basically, do not ever use quoted objects if you have intentions on modifying them, as the consequences are undefined if you do. In fact, evaluating that function definition gives a warning about that:
; in: LAMBDA NIL
; (INCF (NTH K VAR))
; --> LET*
; ==>
; (SB-KERNEL:%SETNTH #:TMP5 #:TMP4 #:NEW3)
;
; caught WARNING:
; Destructive function SB-KERNEL:%SETNTH called on constant data.
; See also:
; The ANSI Standard, Special Operator QUOTE
; The ANSI Standard, Section 3.2.2.3
;
; compilation unit finished
; caught 1 WARNING condition