It's very simple program which just return the input as a list shuffled. I wrote this program in python. Now I want to convert this program to lisp code. but I couldn't. How do I write down this program in lisp?
def my_shuffle(a, b, c, d):
return [b, c, d, a]
I tried the following code but an error occur.
(defun my_shuffle (a b c d) (list b c d a))
Thee are several things here that I think that need to be pointing out. First the code that you presented is correct but do shuffle a list, present a new list of four algorithms that you pass, allways with the same order. First of all shuffle a sequence is:
generating a random permutation of a finite sequence
From wikipedia you can find several algorithms for that:
https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle
Also in the rosseta code there is an implementation of the knuth shuffle:
(defun nshuffle (sequence)
(loop for i from (length sequence) downto 2
do (rotatef (elt sequence (random i))
(elt sequence (1- i))))
sequence)
Then if you apply this in the repl:
CL-USER> (nshuffle (list 1 2 3 4))
(3 1 4 2)
CL-USER> (nshuffle (list 1 2 3 4))
(3 1 2 4)
Note Two different results on the same list!!! (also the same can happen, because is a random order)
In python there are build algorithms for that:
https://docs.python.org/3/library/random.html#random.shuffle
also in the Common lisp library Alexandria:
CL-USER> (ql:quickload :alexandria)
To load "alexandria":
Load 1 ASDF system:
alexandria
; Loading "alexandria"
(:ALEXANDRIA)
CL-USER> (alexandria:shuffle (list 1 2 3 4))
(3 2 4 1)
(defun my_shuffle (a b c d) (list b c d a))
The above code defines a function which will take 4 items and return a rearranged list of those 4 items. It can take input of 4 lists, 4 atoms, 4 numbers, 4 anything, but it cannot separate sublists present inside a single list.
What you can do is:
(defun my_shuffle (myList)
(list (second myList) (third myList) (fourth myList) (first myList)))
or
(defun my_shuffle (myList)
(list (cadr myList) (caddr myList) (cadddr myList) (car myList)))
or
(defun my_shuffle (myList)
(list (nth 1 myList) (nth 2 myList) (nth 3 myList) (nth 1 myList)))
car returns the first element of a list
cdr returns the tail of a list (part of the list following car of the list)
I have used combinations of car and cdr to extract the different elements of the list. Find that in your textbook.
first, second, third, fourth are relatively easy to use and do the same thing as car, cadr, caddr and cadddr
(nth x list) returns the (x+1)th item of the list, counting from zero.
So,
(nth 3 (list a b c d)) => d
(nth 0 (list a b c d)) => a
and so on.
Related
I've been recently dealing with a nested for loops in SBCL. I discovered, that operations, which can be reduced to map, can easily be made parallel using pmap (or any similar function). I decided to try and make my double for loop parallel in the following way:
Basic loops:
(loop for element in list_of_lists
do (loop for element2 in list_of_lists2
...(random_function element element2)))
And this works fine, yet I was wondering if something like:
(defun supplementary_function (single_list list_collection)
"This function iterates through list_collection and executes (random_function) on pairs obtained"
(loop for element in list_collection
do (random_function single_list element)))
(map 'nil (lambda (x) (supplementary_function x list_of_lists2)) list_of_lists1)
I would like to this for performance boost, as map in this case can easily be replaced with pmap in my case. So to clarify a bit more, the question is:
Can one replace the first loop with map, where in each map operation, second loop is executed within a special function of some sort using a single element from first loop and whole second loop. I see no conceptual mistake as to why this should not be possible, yet it throws me some memory errors (?)
Thank you very much!
Does this help?
(loop for e1 in '(1 2 3 4 5)
do (loop for e2 in '(a b c d e)
do (print (list e1 e2))))
is
(mapc (lambda (e1)
(mapc (lambda (e2)
(print (list e1 e2)))
'(a b c d e)))
'(1 2 3 4 5))
is
(defun f (e1 e2s)
(mapc (lambda (e2)
(print (list e1 e2)))
e2s))
(mapc (lambda (e1)
(f e1 '(a b c d e)))
'(1 2 3 4 5))
I could manage following code to replaces items in a list using 2 other lists. Orilist and newlist have original and new terms in order. The replacement is done using orilist and newlist- if orilist items are present in slist, slist is changed to have corresponding new items from newlist:
(define (list-replace-from-lists slist orilist newlist)
(define replaced #f)
(define outl '())
(for ((item slist))
(set! replaced #f)
(for ((ori_ orilist) (i (in-naturals)) #:when (equal? item ori_))
(set! outl (cons (list-ref newlist i) outl))
(set! replaced #t))
(when (not replaced)
(set! outl (cons item outl))))
(reverse outl))
To replace 2 and 5 to 12 and 15, respectively, in (list 1 2 3 4 5 6) :
(list-replace-from-lists (list 1 2 3 4 5 6) (list 2 5) (list 12 15))
Output is:
'(1 12 3 4 15 6)
However, above code does not look functional and has many set! statements. How can this be converted to functional code? Should I use structures or some other data-types for above purpose?
Edit: items may recur in original list, e.g. (list 1 2 3 4 5 2 6)
You can still use lists and keep everything functional. :-) Here's my solution:
(define (replace-all haystack needles new-needles)
(define replace-alist (map cons needles new-needles))
(define (replace-one item)
(cond ((assoc item replace-alist) => cdr)
(else item)))
(map replace-one haystack))
Explanation of the code:
First, we build a replacement association list (alist). This is a list of pairs, of which the keys correspond to the needles and the values correspond to new-needles.
Then we define a replace-one function that takes an item, and sees if it matches any of the keys in the alist. If so, we return the corresponding value; otherwise, we return the original item.
Finally, we map the haystack through replace-one. Yay higher-order functions!
Note that this code is O(m*n) where m is the size of haystack and n is the size of needles, which is the same runtime as your version. If needles is large, you will want to use a hashtable instead of an alist, which will amortise the runtime of the function to O(m).
This is a functional solution that uses hash to keep the associations. That makes this solution O(haystack-length log needle-length) since immutable hashes are implemented with trees.
(define (list-replace-all haystack needles new-values)
;; make a dictionary of elements to be replaced
(define hash
(foldl (λ (needle new-value hash)
(hash-set hash needle new-value))
#hash()
needles
new-values))
;; do the replace. If not in hash the actual key is default
(map (λ (e) (hash-ref hash e e)) haystack))
(list-replace-all '(1 2 3 4 5 6) '(2 5) '(12 15))
; ==> (1 12 3 4 15 6)
I am working on program related to the different of dealing with even numbers in C and lisp , finished my c program but still having troubles with lisp
isprime function is defined and I need help in:
define function primesinlist that returns unique prime numbers in a lis
here what i got so far ,
any help with that please?
(defun comprimento (lista)
(if (null lista)
0
(1+ (comprimento (rest lista)))))
(defun primesinlist (number-list)
(let ((result ()))
(dolist (number number-list)
(when (isprime number)
( number result)))
(nreverse result)))
You need to either flatten the argument before processing:
(defun primesinlist (number-list)
(let ((result ()))
(dolist (number (flatten number-list))
(when (isprime number)
(push number result)))
(delete-duplicates (nreverse result))))
or, if you want to avoid consing up a fresh list, flatten it as you go:
(defun primesinlist (number-list)
(let ((result ()))
(labels ((f (l)
(dolist (x l)
(etypecase x
(integer (when (isprime x)
(push x result)))
(list (f x))))))
(f number-list))
(delete-duplicates (nreverse result))))
To count distinct primes, take the length of the list returned by primesinlist.
Alternatively, you can use count-if:
(count-if #'isprime (delete-duplicates (flatten number-list)))
It sounds like you've already got a primality test implemented, but for sake of completeness, lets add a very simple one that just tries to divide a number by the numbers less than it up to its square root:
(defun primep (x)
"Very simple implementation of a primality test. Checks
for each n above 1 and below (sqrt x) whether n divides x.
Example:
(mapcar 'primep '(2 3 4 5 6 7 8 9 10 11 12 13))
;=> (T T NIL T NIL T NIL NIL NIL T NIL T)
"
(do ((sqrt-x (sqrt x))
(i 2 (1+ i)))
((> i sqrt-x) t)
(when (zerop (mod x i))
(return nil))))
Now, you need a way to flatten a potentially nested list of lists into a single list. When approaching this problem, I usually find it a bit easier to think in terms of trees built of cons-cells. Here's an efficient flattening function that returns a completely new list. That is, it doesn't share any structure with the original tree. That can be useful, especially if we want to modify the resulting structure later, without modifying the original input.
(defun flatten-tree (x &optional (tail '()))
"Efficiently flatten a tree of cons cells into
a list of all the non-NIL leafs of the tree. A completely
fresh list is returned.
Examples:
(flatten-tree nil) ;=> ()
(flatten-tree 1) ;=> (1)
(flatten-tree '(1 (2 (3)) (4) 5)) ;=> (1 2 3 4 5)
(flatten-tree '(1 () () 5)) ;=> (1 5)
"
(cond
((null x) tail)
((atom x) (list* x tail))
((consp x) (flatten-tree (car x)
(flatten-tree (cdr x) tail)))))
Now it's just a matter of flatting a list, removing the number that are not prime, and removing duplicates from that list. Common Lisp includes functions for doing these things, namely remove-if-not and remove-duplicates. Those are the "safe" versions that don't modify their input arguments. Since we know that the flattened list is freshly generated, we can use their (potentially) destructive counterparts, delete-if-not and delete-duplicates.
There's a caveat when you're removing duplicate elements, though. If you have a list like (1 3 5 3), there are two possible results that could be returned (assuming you keep all the other elements in order): (1 3 5) and (1 5 3). That is, you can either remove the the later duplicate or the earlier duplicate. In general, you have the question of "which one should be left behind?" Common Lisp, by default, removes the earlier duplicate and leaves the last occurrence. That behavior can be customized by the :from-end keyword argument. It can be nice to duplicate that behavior in your own API.
So, here's a function that puts all those considerations together.
(defun primes-in-tree (tree &key from-end)
"Flatten the tree, remove elements which are not prime numbers,
using FROM-END to determine whether earlier or later occurrences
are kept in the list.
Examples:
(primes-in-list '(2 (7 4) ((3 3) 5) 6 7))
;;=> (2 3 5 7)
(primes-in-list '(2 (7 4) ((3 3) 5) 6 7) :from-end t)
;;=> (2 7 3 5)"
;; Because FLATTEN-TREE returns a fresh list, it's OK
;; to use the destructive functions DELETE-IF-NOT and
;; DELETE-DUPLICATES.
(delete-duplicates
(delete-if-not 'primep (flatten-tree list))
:from-end from-end))
I am practicing for my programming paradigms exam and working through problem sets I come to this problem. This is the first problem after reversing and joining lists recursively, so I suppose there is an elegant recursive solution.
I am given a list of lists and a permutation. I should permute every list including a list of lists with that specified permutation.
I am given an example:
->(permute '((1 2 3) (a b c) (5 6 7)) '(1 3 2))
->((1 3 2) (5 7 6) (a c b))
I have no idea even how to start. I need to formulate the problem in recursive interpretation to be able to solve it, but I can not figure out how.
Well, let's see how we can break this problem down. We are given a list of lists, and a list of numbers, and we want to order each list according to the order specified by the list of numbers:
=>(permute '((1 2 3) (4 5 6)) '(3 2 1))
'((3 2 1) (6 5 4))
We can see that each list in the list of lists can be handled separately, their solutions are unrelated to each other. So we can have a helper permute1 that handles the case of one list, then use map to apply this function to each of the lists (with the same ordering each time):
(define (permute lists ordering)
(map (lambda (xs) (permute1 xs ordering))
lists))
(define (permute1 items ordering)
...)
Now, to calculate (permute1 '(4 5 6) '(3 2 1)), what we mean is:
The first item of the new list will be the 3rd item of items, because the first number in ordering is 3.
The rest of the items of the new list will be determined by using the rest of the numbers in the ordering.
If the ordering is the empty list, return the empty list.
This forms the base case (3), the recursive case (1), and the steps to recur deeper (2). So a sketch of our solution would look like:
(define (permute1 items ordering)
(if (empty? ordering)
'()
(let ([next-item ???])
(??? next-item
(permute1 items (rest ordering))))))
Where the ???s represent getting the item based on the first number in ordering and combining this item with the remainder of the calculation, respectively.
Here's another option, using higher-order functions. This is the idiomatic way to think about a solution in a functional language - we split the problem in sub-problems, solve each one using existing procedures and finally we compose the answer:
(define (atom? x)
(and (not (null? x))
(not (pair? x))))
(define (perm lst order)
(foldr (lambda (idx acc)
(cons (list-ref lst (sub1 idx)) acc))
'()
order))
(define (permute lst order)
(if (atom? lst)
lst
(perm (map (lambda (x) (permute x order)) lst)
order)))
We start by defining atom?, a generic predicate and perm, a helper that will reorder any given list according to the ordering specified in one of its parameters. It uses foldr to build the output list and list-ref to access elements in a list, given its 0-based indexes (that's why we subtract one from each index).
The main permute function takes care of (recursively) mapping perm on each element of an arbitrarily nested input list, so we can obtain the desired result:
(permute '((1 2 3) (a b c) (5 6 7)) '(1 3 2))
=> '((1 3 2) (5 7 6) (a c b))
I am given an example:
(permute ('(1 2 3) '(a b c) '(5 6 7)) '(1 3 2))
((1 3 2) (5 7 6) (a c b))
The syntax you've given isn't correct, and will cause an error, but it's fairly clear what you mean. You want that
(permute '((1 2 3) (a b c) (5 6 7)) '(1 3 2))
;=> ((1 3 2) (5 7 6) (a c b))
Now, it's not clear how you're indicating the permutation. Is '(1 3 2) a permutation because it has some (1-based) indices, and indicates the way to rearrange elements, or is it because it is actually a permutation of the elements of the first list of the first list? E.g., would
(permute '((x y z) (a b c) (5 6 7)) '(1 3 2))
;=> ((x z y) (5 7 6) (a c b))
work too? I'm going to assume that it would, because it will make the problem much easier.
I have no idea even how to start. I need to formulate the problem in
recursive interpretation to be able to solve it, but I can not figure
out how.
You need to write a function that can take a list of indices, and that returns a function that will perform the permutation. E.g,.
(define (make-permutation indices)
…)
such that
((make-permutation '(3 1 2)) '(a b c))
;=> (c a b)
One you have that, it sounds like your permute function is pretty simple:
(define (permute lists indices)
(let ((p (make-permutation indices)))
(p (map p lists))))
That would handle the case you've given in your example, since (map p lists) will return ((1 3 2) (a b c) (5 7 6)), and then calling p with that will return ((1 3 2) (5 7 6) (a c b)). If you need to be able to handle more deeply nested lists, you'll need to implement a recursive mapping function.
Here's my take, which seems to be shorter than the previous examples:
(define (permute lst ord)
(define ord-1 (map sub1 ord)) ; change from 1-based to 0-based indexes
(define (perm elts) ; recursive sub-procedure
(if (list? elts)
(map perm (map (curry list-ref elts) ord-1)) ; list -> recurse
elts)) ; else return unchanged
(perm lst)) ; initial call
testing
> (permute '((1 2 3) (a b c) (5 6 7)) '(1 3 2))
'((1 3 2) (5 7 6) (a c b))
> (permute '((1 (i permute did) 3) (a b (scheme cool is)) (5 6 7)) '(1 3 2))
'((1 3 (i did permute)) (5 7 6) (a (scheme is cool) b))
If I have the following list:
(define thelist '(0 1 0 0 7 7 7))
How can I write a function that returns a new list in which the value in the requested cell is replaced.
Example:
(set-cell thelist 2 4)
This would return a new list with the same values, but in cell (2) there will be the value 4 instead of 1:
(0 4 0 0 7 7 7)
HtDP provides a really concrete methodology for solving this kind of problem. For this problem, your job is going to be to write down the template for lists, then to stare at it until you can see what the arguments to the recursive call should be, and what the results will be. I'm hoping that you've solved a bunch of warm-up problems on lists--compute the length of a list, count the number of 6's in the list, etc.
Although you can implement the requested functionality with lists, the natural way to solve that problem is to use a vector, and remember that in Scheme indexes start in 0 (that's why the second argument for vector-set! is a 1 and not a 2):
(define thevector (vector 0 1 0 0 7 7 7))
; thevector is #(0 1 0 0 7 7 7)
(vector-set! thevector 1 4)
; thevector is #(0 4 0 0 7 7 7)
Now, if you definitely need to use a list, something like this would work:
(define (set-cell lst idx val)
(cond ((null? lst) '())
((zero? idx) (cons val (cdr lst)))
(else (cons (car lst)
(set-cell (cdr lst) (sub1 idx) val)))))
And you'd call it like this:
(define thelist '(0 1 0 0 7 7 7))
(set-cell thelist 1 4)
> (0 4 0 0 7 7 7)
Again, I'm using 0-based indexing, as is the convention. Also notice that thelist was not modified, instead, set-cell returns a new list with the modification.
Other people have mentioned the 0-based indexes convention. I'll assume 0-based indexes, then.
The other answers you've gotten are wrong, given how you stated your problem. I'll cite the key point in your question (my emphasis):
This would return a new list with the same values, but in cell (2) there will be the value 4 instead of 1.
The answers you've been given are modifying a list in place, not returning a newly constructed list while leaving the original intact!
Here's a correct (though suboptimal) solution:
(define (set-list index new-value list)
(if (= index 0)
(cons new-value (cdr list))
(cons (car list)
(set-list (- index 1) new-value (cdr list))))))
I didn't bother to put in error checking here (e.g., if somebody passes in the empty list, or a list with too few elements relative to index, or a negative index).
Here is an approach using an auxiliary function that starts the count from 0. On each recursion, the count is incremented, and the list is shortened.
If the desired index is hit, the recursion can stop. If it gets to the end of the list without hitting the index, the original list is returned.
(define (set-cell ls ind val)
(define (aux c ls)
(cond ((null? ls) ls)
((= c ind) (cons val (cdr ls)))
(else (cons (car ls) (aux (+ c 1) (cdr ls))))))
(aux 0 ls))
What a mess above!! Keep it simple: Scheme has list-set! for this.
Example:
(define ls (list 1 2 3 4 5))
(list-set! ls 0 "new")
(list-set! ls 3 "changed")
(list-ref ls 0)
=> "new"
ls
=> '("new" 2 3 "changed" 5)
However, you might want to limit assignments on lists. Vectors are faster for this since you don't need to traverse the previous elements. Use lists whenever you can't specify the length before construction or when the length is continously changed.