how can I make a Lisp program that checks if a character, string or number is in a list?
(list-contains '(1 a 2 d 2 5) 'a) => T
(list-contains '(1 a 2 d 2 5) 'x) => NIL
You can use (find x the-list) which returns x if x is in the list or NIL if it is not.
(find 'a '(1 a 2 d 2 5)) ; A
(find 'x '(1 a 2 d 2 5)) ; NIL
Since this is homework, your professor would probably like to see you implement an algorithm. Try this:
Take the car of the list and compare it against the input symbol.
If it's the same, return true; you're done.
If it's empty, return false; you're done.
Recurse back to #1, using the cdr of the list. (Here, implied that the car was not empty and was not the comparison symbol)
Greg's solution is what you should implement. But I want to add that, in case you hadn't head of it, The Little Schemer is a great introduction to this sort of thing. Try to get a copy, or even just open the preview up in Google Books and search for "member?". They do what you'd expect (that is, check if car is equal, recur on cdr if it isn't) but they trace it and ask you questions at each step.
It's not a very long or expensive book, but once you read it, you will have a natural feel for how to approach this sort of problem. They all boil down to the same thing, which for lists amounts to asking if we've hit the empty list yet, and if not, either doing something with car or recurring on cdr.
I recommend you the position function. It returns the position of the element in the list (the first position is 0) or NIL if it is not.
(position 'a '(1 a 2 d 2 5)) ; 1
(position 'x '(1 a 2 d 2 5)) ; NIL
position has an advantage over find. You can know if the symbol 'NIL in a list.
(position 'NIL '(1 a NIL d 2 5)) ; 2
(position 'NIL '(1 a 2 d 2 5)) ; NIL
However,
(find 'NIL '(1 a NIL d 2 5)) ; NIL
(find 'NIL '(1 a 2 d 2 5)) ; NIL
So with find there is no way to distinguish one case from the other.
Related
According to the book, this is what the function definition is,
The function scramble takes a non-empty tuple in which no argument is greater than its own index and returns a tuple of same length. Each number in the argument is treated as a backward index from its own position to a point earlier in tuple. The result at each position is obtained by counting backward from the current position according to this index.
And these are some examples,
; Examples of scramble
(scramble '(1 1 1 3 4 2 1 1 9 2)) ; '(1 1 1 1 1 4 1 1 1 9)
(scramble '(1 2 3 4 5 6 7 8 9)) ; '(1 1 1 1 1 1 1 1 1)
(scramble '(1 2 3 1 2 3 4 1 8 2 10)) ; '(1 1 1 1 1 1 1 1 2 8 2)
Here is the implementation,
(define pick
(λ (i lat)
(cond
((eq? i 1) (car lat))
(else (pick (sub1 i)
(cdr lat))))))
(define scramble-b
(lambda (tup rev-pre)
(cond
((null? tup) '())
(else
(cons (pick (car tup) (cons (car tup) rev-pre))
(scramble-b (cdr tup)
(cons (car tup) rev-pre)))))))
(define scramble
(lambda (tup)
(scramble-b tup '())))
This is a case where using a very minimal version of the language means that the code is verbose enough that understanding the algorithm is not perhaps easy.
One way of dealing with this problem is to write the program in a much richer language, and then work out how the algorithm, which is now obvious, is implemented in the minimal version. Let's pick Racket as the rich language.
Racket has a function (as does Scheme) called list-ref: (list-ref l i) returns the ith element of l, zero-based.
It also has a nice notion of 'sequences' which are pretty much 'things you can iterate over' and a bunch of constructs whose names begin with for for iterating over sequences. There are two functions which make sequences we care about:
in-naturals makes an infinite sequence of the natural numbers, which by default starts from 0, but (in-naturals n) starts from n.
in-list makes a sequence from a list (a list is already a sequence in fact, but in-list makes things clearer and there are rumours also faster).
And the iteration construct we care about is for/list which iterates over some sequences and collects the result from its body into a list.
Given these, then the algorithm is almost trivial: we want to iterate along the list, keeping track of the current index and then do the appropriate subtraction to pick a value further back along the list. The only non-trivial bit is dealing with zero- vs one-based indexing.
(define (scramble l)
(for/list ([index (in-naturals)]
[element (in-list l)])
(list-ref l (+ (- index element) 1))))
And in fact if we cause in-naturals to count from 1 we can avoid the awkward adding-1:
(define (scramble l)
(for/list ([index (in-naturals 1)]
(element (in-list l)))
(list-ref l (- index element))))
Now looking at this code, even if you don't know Racket, the algorithm is very clear, and you can check it gives the answers in the book:
> (scramble '(1 1 1 3 4 2 1 1 9 2))
'(1 1 1 1 1 4 1 1 1 9)
Now it remains to work out how the code in the book implements the same algorithm. That's fiddly, but once you know what the algorithm is it should be straightforward.
If the verbal description looks vague and hard to follow, we can try following the code itself, turning it into a more visual pseudocode as we go:
pick i [x, ...ys] =
case i {
1 --> x ;
pick (i-1) ys }
==>
pick i xs = nth1 i xs
(* 1 <= i <= |xs| *)
scramble xs =
scramble2 xs []
scramble2 xs revPre =
case xs {
[] --> [] ;
[x, ...ys] -->
[ pick x [x, ...revPre],
...scramble2 ys
[x, ...revPre]] }
Thus,
scramble [x,y,z,w, ...]
=
[ nth1 x [x] (*x=1..1*)
, nth1 y [y,x] (*y=1..2*)
, nth1 z [z,y,x] (*z=1..3*)
, nth1 w [w,z,y,x] (*w=1..4*)
, ... ]
Thus each element in the input list is used as an index into the reversed prefix of that list, up to and including that element. In other words, an index into the prefix while counting backwards, i.e. from the element to the left, i.e. towards the list's start.
So we have now visualized what the code is doing, and have also discovered requirements for its input list's elements.
The standard says that
(equal x y) implies (= (sxhash x) (sxhash y)). Let us check it:
(defun sxhash-test ()
(let ((obj1 (list 1 2 (list 1 1)))
(obj2 (list 1 2 (list 1 2))))
(format t "are objects equal?: ~a~%" (equal obj1 obj2)) ;; => NIL
(format t "are their hashes equal?: ~a~%"(= (sxhash obj1) (sxhash obj2))))) ;; => T
The function equal works as expected but sxhash doesn't. Could you please explain what I am doing wrong? I use SBCL 2.1.9.
Thank you.
sxhash has to satisfy four requirements:
objects which are equal (and hence objects which are eql, eq, but not necessarily equalp will have the same sxhash value;
the sxhash value of an object must not change during the life of single image unless the object is changed in such a way as to not make it equal to a copy of it before the change;
objects of various types which have a well-defined notion of similarity between images then their sxhash value must be the same in each image.
computation of sxhash must always terminate.
(There is another vague requirement of 'being a good hash code').
(1) means that two objects which are not equal may have the same code but may not, but two objects which are equal must have the same value. A terrible but possible implementation of sxhash would be:
(defun sxhash/terrible (it)
(declare (ignore it))
0)
This fails the 'being a good hash code' test, but that's not something that can really be enforced.
What you are seeing is that two objects which are not equal do have the same sxhash value: that's fine.
Indeed, (1) together with (4) mean that if an implementation is going to compute sxhash on conses in such a way that it walks the graph, then it has to be pretty careful about that: it either needs an occurs check or it needs to only go so deep.
However it is quite possible that sxhash does descend into cons trees. As an example here is LispWorks doing just that:
> (sxhash '(1 2 3))
11890816076270616
> (sxhash '(1 2 3 (4)))
369102953153702944
> (sxhash '(1 2 3 (4)))
740958182301008344
> (sxhash '(1 2 3 (5)))
740958455027237144
> (sxhash '(1 2 3 (5 6)))
741326672350173760
> (sxhash '(1 2 3 (5 (6))))
925006242171775434
Equally it is quite plausible that sxhash treats all instances of a given structure class (or of a given instance of standard-class) as having the same value, because the address of such an object is not constant and there's no obvious place to store the hash code without burning memory. But that's in no way a requirement.
The reason why this effect is observed is that two things are required for the values to be equal:
The two values are the same, meaning that have the same hash.
The two values have the same address
The two lists tested have the same hash, because sxhash doesn't follow nesting. In fact, two structures will always have the same hash.
(sxhash (list 1 2 3)); => 3971322300187561939
(sxhash (list 1 2 3)); => 3971322300187561939 (so, repeatable)
(sxhash (list 1 2 3 (list 4))) ; => 3180777146619076709
(sxhash (list 1 2 3 (list 5))) ; => 3180777146619076709 (ok ...)
Why does `sxhash` return a constant for all structs?
As for equal addresses, if I create two values like 'a they in fact turn out to be one item with one address, and is only stored on the first time that it is seen. Whereas (list 1 2 (list 1 1)) and (list 1 2 (list 1 2)) are different things and are stored at separate addresses.
(sb-kernel:get-lisp-obj-address 'a) ; => 68772678703
(sb-kernel:get-lisp-obj-address 'a) ; => 68772678703 (same...)
(sb-kernel:get-lisp-obj-address (list 1 2 3 (list 4))) ; => 68772925863
(sb-kernel:get-lisp-obj-address (list 1 2 3 (list 5))) ; => 68772805335
Testing these two lists for equality pass using sxhash, but fail with different addresses.
Im trying to make a non-tail recursive function returns the last element of a list without using reverse, map, iteration, mutation of any sort (built in or user-built). So far I have successfully made a tail-recursive version and a non-tail version that uses reverse func. But I just cannot figure how to make a non-tail recursive function.
I really appreciate your help!
Imagine you have the tail recursive version like this:
(define (last-element lst)
(if base-case-expression
result-expression
recursion-expression))
Now in order to not make it tail recursive you just make your function do something with the result. eg. cache it in a binding and then return:
(define (last-element lst)
(if base-case-expression
result-expression
(let ((result recursion-expression))
result)))
Here the recursive call is not the tail position. However a sufficiently smart compiler might make compiled code that is tail recursive. Eg. a lot of Scheme implementations transform code to continuation passing style and then every call becomes a tail call and stack is replaced with growing closures. The result of that on both versions will be very similar.
Note: for some reason I wrote this answer using Common Lisp, before noticing that the question was tagged with scheme, racket, and lisp. In any case, Common Lisp falls under the latter tag, and the code is easily adapted to either Scheme or Racket.
For a function to be non-tail recursive, you need to place recursive calls so that they are not in tail position, i.e., so that no further operations are needed on the results of the recursive call before it is returned. So, you need a recursive strategy for getting to the last element of a list that does further operations on the result of recursive calls.
One strategy would be to build a "reversed list" on the way back up from the base case, taking that list apart at the same time so that the desired result is left at the end. Here is a reversal function to show the idea without taking anything apart:
(defun reversal (xs)
(if (cdr xs)
(cons (reversal (cdr xs)) (car xs))
xs))
The above function builds a nested dotted list with the elements of the input list in reverse:
CL-USER> (reversal '(1 2 3 4 5))
(((((5) . 4) . 3) . 2) . 1)
Now, the car function could be called numerous times on this result to get the last element of the input, but we can just do this as the new list is constructed:
(defun my-last (xs)
(car (if (cdr xs)
(cons (my-last (cdr xs)) (car xs))
xs)))
Here the my-last function is called after calling (trace my-last):
CL-USER> (trace my-last)
(MY-LAST)
CL-USER> (my-last '(1 2 3 4 5))
0: (MY-LAST (1 2 3 4 5))
1: (MY-LAST (2 3 4 5))
2: (MY-LAST (3 4 5))
3: (MY-LAST (4 5))
4: (MY-LAST (5))
4: MY-LAST returned 5
3: MY-LAST returned 5
2: MY-LAST returned 5
1: MY-LAST returned 5
0: MY-LAST returned 5
5
This solution requires two operations on the result of calling my-last, i.e., cons and car. It does seem possible that an optimizer could notice that car is being called on the result of a cons, and optimize my-last to something like:
(defun my-last-optimized (xs)
(if (cdr xs)
(my-last-optimized (cdr xs))
(car xs)))
If this were the case, then the optimized code would be tail recursive, and tail call optimizations could then be applied. I do not know if any lisp implementations can do this sort of optimization.
An alternate strategy would be to store the original list and then to take it apart on the way back up from the base case using cdr. Here is a solution using a helper function:
(defun my-last-2 (xs)
(car (my-last-helper xs xs)))
(defun my-last-helper (xs enchilada)
(if (cdr xs)
(cdr (my-last-helper (cdr xs) enchilada))
enchilada))
This also works as expected. Here is an example, again using trace to see the function calls. This time both my-last-2 and my-last-helper have been traced:
(trace my-last-2 my-last-helper)
(MY-LAST-2 MY-LAST-HELPER)
CL-USER> (my-last-2 '(1 2 3 4 5))
0: (MY-LAST-2 (1 2 3 4 5))
1: (MY-LAST-HELPER (1 2 3 4 5) (1 2 3 4 5))
2: (MY-LAST-HELPER (2 3 4 5) (1 2 3 4 5))
3: (MY-LAST-HELPER (3 4 5) (1 2 3 4 5))
4: (MY-LAST-HELPER (4 5) (1 2 3 4 5))
5: (MY-LAST-HELPER (5) (1 2 3 4 5))
5: MY-LAST-HELPER returned (1 2 3 4 5)
4: MY-LAST-HELPER returned (2 3 4 5)
3: MY-LAST-HELPER returned (3 4 5)
2: MY-LAST-HELPER returned (4 5)
1: MY-LAST-HELPER returned (5)
0: MY-LAST-2 returned 5
5
In this case, the only operation required after recursive calls to my-last-2 return is cdr, but that is enough to prevent this from being a tail call.
I am trying to format an arbitrary expression, say (+ 2 3), and at the same time, its result, 5.
I have the following:
(defun expr-and-result (expr)
(format t "~a returns ~a~%" expr (eval expr)))
CL-USER> (expr-and-result '(+ 2 3))
(+ 2 3) returns 5
Though it's a simple matter by using eval, I'm curious if this effect can be accomplished without it (because I heard a lot that eval is to be avoided).
I understand that quoting the argument is necessary, because otherwise the given expression will be evaluated as the first step in calling expr-and-result, and only its result could be used inside expr-and-result. Therefore, any possible solution requires the input to be quoted, right?
I thought a bit about macros but I feel like it's the wrong approach to what I am looking for.
Edit: My intent was to construct a simple test-suite, such as:
(progn
(mapcar #'expr-and-result
'((= (my-remainder 7 3) 1)
(= (my-remainder 7 3) 2)))
'end-of-tests)
Outputs:
(= (MY-REMAINDER 7 3) 1) returns T
(= (MY-REMAINDER 7 3) 2) returns NIL
END-OF-TESTS
After reading Paulo's comment, it seems that eval is the shortest and cleanest solution for my purposes.
Here is a simple macro:
(defmacro exec-and-report (form)
`(format t "~S returns ~S~%" ',form ,form))
(macroexpand '(exec-and-report (+ 1 2)))
==>
(FORMAT T "~S returns ~S~%" '(+ 1 2) (+ 1 2)) ;
T
(exec-and-report (+ 1 2))
==>
(+ 1 2) returns 3
NIL
PS. I second #Sylvester's suggestion not to reinvent the wheel
I have been searching everywhere for the following functionality in Lisp, and have gotten nowhere:
find the index of something in a list. example:
(index-of item InThisList)
replace something at a specific spot in a list. example:
(replace item InThisList AtThisIndex) ;i think this can be done with 'setf'?
return an item at a specific index. example:
(return InThisList ItemAtThisIndex)
Up until this point, I've been faking it with my own functions. I'm wondering if I'm just creating more work for myself.
This is how I've been faking number 1:
(defun my-index (findMe mylist)
(let ((counter 0) (found 1))
(dolist (item mylist)
(cond
((eq item findMe) ;this works because 'eq' checks place in memory,
;and as long as 'findMe' was from the original list, this will work.
(setq found nil)
(found (incf counter))))
counter))
You can use setf and nth to replace and retrieve values by index.
(let ((myList '(1 2 3 4 5 6)))
(setf (nth 4 myList) 101); <----
myList)
(1 2 3 4 101 6)
To find by index you can use the position function.
(let ((myList '(1 2 3 4 5 6)))
(setf (nth 4 myList) 101)
(list myList (position 101 myList)))
((1 2 3 4 101 6) 4)
I found these all in this index of functions.
find the index of something in a list.
In Emacs Lisp and Common Lisp, you have the position function:
> (setq numbers (list 1 2 3 4))
(1 2 3 4)
> (position 3 numbers)
2
In Scheme, here's a tail recursive implementation from DrScheme's doc:
(define list-position
(lambda (o l)
(let loop ((i 0) (l l))
(if (null? l) #f
(if (eqv? (car l) o) i
(loop (+ i 1) (cdr l)))))))
----------------------------------------------------
> (define numbers (list 1 2 3 4))
> (list-position 3 numbers)
2
>
But if you're using a list as a collection of slots to store structured data, maybe you should have a look at defstruct or even some kind of Lisp Object System like CLOS.
If you're learning Lisp, make sure you have a look at Practical Common Lisp and / or The Little Schemer.
Cheers!
Answers:
(position item sequence &key from-end (start 0) end key test test-not)
http://lispdoc.com/?q=position&search=Basic+search
(setf (elt sequence index) value)
(elt sequence index)
http://lispdoc.com/?q=elt&search=Basic+search
NOTE: elt is preferable to nth because elt works on any sequence, not just lists
Jeremy's answers should work; but that said, if you find yourself writing code like
(setf (nth i my-list) new-elt)
you're probably using the wrong datastructure. Lists are simply linked lists, so they're O(N) to access by index. You might be better off using arrays.
Or maybe you're using lists as tuples. In that case, they should be fine. But you probably want to name accessors so someone reading your code doesn't have to remember what "nth 4" is supposed to mean. Something like
(defun my-attr (list)
(nth 4 list))
(defun (setf my-attr) (new list)
(setf (nth 4 list) new))
+2 for "Practical Common Lisp". It is a mixture of a Common Lisp Cookbook and a quality Teach Yourself Lisp book.
There's also "Successful Common Lisp" (http://www.psg.com/~dlamkins/sl/cover.html and http://www.psg.com/~dlamkins/sl/contents.html) which seemed to fill a few gaps / extend things in "Practical Common Lisp".
I've also read Paul Graham's "ANSI Common Lisp" which is more about the basics of the language, but a bit more of a reference manual.
I have to agree with Thomas. If you use lists like arrays then that's just going to be slow (and possibly awkward). So you should either use arrays or stick with the functions you've written but move them "up" in a way so that you can easily replace the slow lists with arrays later.