My question is how can i print the elements of a list two times, the code i have tried is given below
(define duplicate-list
(lambda (mylist n)
(cond ((null? mylist) '())
((< n 2) (cons (car mylist)
(duplicate-list mylist (+ n 1))))
(else
(duplicate-list (cdr mylist) 0)))))
(define duplicate
(lambda (mylist)
(duplicate-list mylist 0)))
The problem in this code is that, it works fine only when i give it a list as input, this fails to work when i give it an input of a nested list.
>(duplicate '(a 1 b 2 c 3 r x)) -> a a 1 1 b b 2 2 c c 3 3 r r x x
>(duplicate '( (a 1) b ((c)) 2)) ->((a 1) (a 1) b b ((c)) ((c)) 2 2)
Whereas, the expected outcome needed should be
(duplicate '( (a 1) b ((c)) 2 z 3) = ( (a a 1 1) b b ((c c)) 2 2 z z 3 3)
You're using the wrong approach to build the output list, you have to recur over the car and cdr parts, given that this is a list of lists. Try this:
(define (duplicate lst)
(cond ((null? lst)
'())
((not (pair? (car lst)))
(cons (car lst)
(cons (car lst) ; here we duplicate each element
(duplicate (cdr lst)))))
(else
(cons (duplicate (car lst))
(duplicate (cdr lst))))))
It works as expected:
(duplicate '((a 1) b ((c)) 2 z 3))
=> '((a a 1 1) b b ((c c)) 2 2 z z 3 3)
Here's another solution using pattern matching via match -
(define (duplicate l)
(match l
((list (list a ...) b ...) ; nested list
(cons (duplicate a)
(duplicate b)))
((list a b ...) ; flat list
(cons a
(cons a
(duplicate b))))
(_ ; otherwise
null)))
It works as expected -
(duplicate '((a 1) b ((c)) 2 z 3))
; '((a a 1 1) b b ((c c)) 2 2 z z 3 3)
(duplicate '())
; '()
Related
I'm trying to find an element in a list of lists and print the lists that contain that element.
For the test: (search-table '((1 2 3) (4 2) (3 3 4) (5 3 2 1)) 1), the output is:
'((1 2 3) (5 3 2 1))
This is my code in DrRacket so far:
(define (search-table table item)
(if(equal? table null)
'()
(cons(search-table first table item))(search-table rest table item)))
But this code is giving me an error message which says:
if: bad syntax;
has 4 parts after keyword in: (if (equal? table null) (quote ()) (cons (search-table first table item)) (search-table rest table item))
Please help me with this as I am very new to Racket.
If the value is a member of the list, cons the list onto the result
(define (search-table lists value)
(cond ((null? lists) '())
((member value (car lists))
(cons (car lists) (search-table (cdr lists) value)))
(else (search-table (cdr lists) value))))
(search-table '((a b c d) (b c) (c d e f) (a b c)) 'a)
;; '((a b c d) (a b c))
You tagged this with tail-recursion tho, so let's do it with constant space
(define (search-table lists value)
(let loop ((lists lists) (acc null))
(cond ((null? lists) acc)
((member value (car lists))
(loop (cdr lists) (cons (car lists) acc)))
(else (loop (cdr lists) acc)))))
(search-table '((a b c d) (b c) (c d e f) (a b c)) 'a)
;; '((a b c) (a b c d))
But that result is in reverse order; according to your question anyway – we can "fix" that using a continuation as our accumulator instead of a list
(define (search-table lists value)
(let loop ((lists lists) (acc identity))
(cond ((null? lists)
(acc null))
((member value (car lists))
(loop (cdr lists) (lambda (rest)
(acc (cons (car lists) rest)))))
(else
(loop (cdr lists) acc)))))
(search-table '((a b c d) (b c) (c d e f) (a b c)) 'a)
;; '((a b c d) (a b c))
You tagged this with functional-programming tho, so let's do it using higher order functions
(define (search-table lists value)
(filter (lambda (list) (member value list))
lists))
(search-table '((a b c d) (b c) (c d e f) (a b c)) 'a)
;; '((a b c d) (a b c))
When written this way the error says: 4 parts after if:
(define (rolling-window l size)
(if (< (length l) size) l
(take l size) (rolling-window (cdr l) size)))
and when there's another paranthesis to make it 3 parts:
(define (rolling-window l size)
(if (< (length l) size) l
((take l size) (rolling-window (cdr l) size))))
then it says: application: not a procedure;
How to write more than one expression in if's else in racket/scheme?
Well that's not really the question. The question is "How to build a rolling window procedure using racket?". Anyway, it looks like you're probably coming from another programming language. Processing linked lists can be a little tricky at first. But remember, to compute the length of a list, you have to iterate through the entire list. So using length is a bit of an anti-pattern here.
Instead, I would recommend you create an auxiliary procedure inside your rolling-window procedure which builds up the window as you iterate thru the list. This way you don't have to waste iterations counting elements of a list.
Then if your aux procedure ever returns and empty window, you know you're done computing the windows for the given input list.
(define (rolling-window n xs)
(define (aux n xs)
(let aux-loop ([n n] [xs xs] [k identity])
(cond [(= n 0) (k empty)] ;; done building sublist, return sublist
[(empty? xs) empty] ;; reached end of xs before n = 0, return empty window
[else (aux-loop (sub1 n) (cdr xs) (λ (rest) (k (cons (car xs) rest))))]))) ;; continue building sublist
(let loop ([xs xs] [window (aux n xs)] [k identity])
(cond ([empty? window] (k empty)) ;; empty window, done
([empty? xs] (k empty)) ;; empty input list, done
(else (loop (cdr xs) (aux n (cdr xs)) (λ (rest) (k (cons window rest)))))))) ;; continue building sublists
(rolling-window 3 '(1 2 3 4 5 6))
;; => '((1 2 3) (2 3 4) (3 4 5) (4 5 6))
It works for empty windows
(rolling-window 0 '(1 2 3 4 5 6))
;; => '()
And empty lists too
(rolling-window 3 '())
;; => '()
Here is an alternative:
#lang racket
(define (rolling-window n xs)
(define v (list->vector xs))
(define m (vector-length v))
(for/list ([i (max 0 (- m n -1))])
(vector->list (vector-copy v i (+ i n)))))
(rolling-window 3 '(a b c d e f g))
(rolling-window 3 '())
(rolling-window 0 '(a b c))
Output:
'((a b c) (b c d) (c d e) (d e f) (e f g))
'()
'(() () () ()) ; lack of spec makes this ok !
Following modification of OP's function works. It includes an outlist for which the initial default is empty list. Sublists are added to this outlist till (length l) is less than size.
(define (rolling-window l size (ol '()))
(if (< (length l) size) (reverse ol)
(rolling-window (cdr l) size (cons (take l size) ol))))
Testing:
(rolling-window '(1 2 3 4 5 6) 2)
(rolling-window '(1 2 3 4 5 6) 3)
(rolling-window '(1 2 3 4 5 6) 4)
Output:
'((1 2) (2 3) (3 4) (4 5) (5 6))
'((1 2 3) (2 3 4) (3 4 5) (4 5 6))
'((1 2 3 4) (2 3 4 5) (3 4 5 6))
Any improvements on this one?
(define (rolling-window l size)
(cond ((eq? l '()) '())
((< (length l) size) '())
((cons (take l size) (rolling-window (cdr l) size)))))
I need to write for school a function that can calculate numbers and ignore the letters. Do I need to make a case for every operation? I don't know how to start. For example:
(+ 1 A 2 X) = (3 A X)
(- A 5 1 A) = 4
(* 2 C 0) = 0
So I have done a part of the problem. The 2 functions DELNUM and DELSYM are for deleting the numbers respectively the symbol from a list. It's all working now, just for example like (- A 5 A) -> 5 isn't, because I need some conditions for that.
(defun delnum (l)
(remove-if-not #'symbolp l))
(delnum '(4 S 56 h ))
;;-> (S H)
(defun delsym (l)
(remove-if-not #'numberp l))
(delsym '(+ a 1 2 3 b))
;;-> (1 2 3)
(defun test (l)
(cond
((null l) nil)
((case (car l)
(+ (cons (apply #'+ (delsym l)) (delnum (cdr l))))
(- (cons (apply #'- (delsym l)) (delnum (cdr l))))
(* (cond ((eql (apply #'* (delsym l)) 0) 0)
( t (cons (apply #'* (delsym l)) (delnum (cdr l))))))
(/ (cond ((eql (car (delsym l)) 0) '(error division by zero))
((eql (find 0 (delsym l)) 0) '(error division by zero))
(t (cons (apply #'/ (delsym l)) (delnum (cdr l))))))))))
(test '(/ 0 )) ;-> (ERROR DIVISION BY ZERO)
(test '(+ 1 2 A)) ;-> (3 A)
(test '(- 6 5 A C)) ;-> (1 AC)
(test '(- 1 5 A C X 0)) ;-> (-4 A C X)
(test '(* 0 5 A C)) ;-> 0
(test '(* 10 5 A C)) ;-> (50 A C)
(test '(/ 12 0 V 1 2)) ;-> (ERROR DIVISION BY ZERO)
(test '(/ S 3 7 C)) ;-> (3/7 S C)
(test '(+ -A A 5)) ;-> it gotta display 5 or (5)
i have a function in scheme, this function calls another function many times, and every time this function appends return value of another function to result value.
but finally i want to get a result such that '(a b c), however i get a result such that '((a) (b) (c)) how can i fix this problem? i have searched but i couldn't find good solution.
my little code like that not all of them.
(append res (func x))
(append res (func y))
(append res (func z))
my code like this
(define (check a )
'(1)
)
(define bos '())
(define (func a)
(let loop1([a a] [res '()])
(cond
[(eq? a '()) res]
[else (let ([ x (check (car a))])
(loop1 (cdr a) (append res (list x)))
)]
)
))
Try this:
(define (func a)
(let loop1 ([a a] [res '()])
(cond
[(eq? a '()) res]
[else
(let ([ x (check (car a))])
(loop1 (cdr a) (append res x)))])))
Notice that the only change I made (besides improving the formatting) was substituting (list x) with x. That will do the trick! Alternatively, but less portable - you can use append* instead of append:
(append* res (list x))
As a side comment, you should use (null? a) for testing if the list is empty. Now if we test the procedure using the sample code in the question, we'll get:
(func '(a b c))
=> '(1 1 1)
It seems that instead of
(loop1 (cdr a) (cdr b) c (append res (list x)))
you want
(loop1 (cdr a) (cdr b) c (append res x))
Basically the trick is to use cons instead of list. Imagine (list 1 2 3 4) which is the same as (cons 1 (cons 2 (cons 3 (cons 4 '())))). Do you see how each part is (cons this-iteration-element (recurse-further)) like this:
(define (make-list n)
(if (zero? n)
'()
(cons n (make-list (sub1 n)))))
(make-list 10) ; ==> (10 9 8 7 6 5 4 3 2 1)
Usually when you can choose direction you can always make it tail recursive with an accumulator:
(define (make-list n)
(let loop ((x 1) (acc '()))
(if (> x n)
acc
(loop (add1 x) (cons x acc))))) ; build up in reverse!
(make-list 10) ; ==> (10 9 8 7 6 5 4 3 2 1)
Now this is a generic answer. Applied to your working code:
(define (func a)
(let loop1 ([a a] [res '()])
(cond
[(eq? a '()) (reverse res)]
[else
(let ([x (check (car a))])
(loop1 (cdr a) (cons (car x) res)))])))
(func '(a b c)) ; ==> (1 1 1)
append replaces the cons so why not put the car og your result to the rest of the list. Since you want the result in order I reverse the result in the base case. (can't really tell from the result, but I guessed since you ise append)
I was doing a problem from the HTDP book where you have to create a function that finds all the permutations for the list. The book gives the main function, and the question asks for you to create the helper function that would insert an element everywhere in the list. The helper function, called insert_everywhere, is only given 2 parameters.
No matter how hard I try, I can't seem to create this function using only two parameters.
This is my code:
(define (insert_everywhere elt lst)
(cond
[(empty? lst) empty]
[else (append (cons elt lst)
(cons (first lst) (insert_everywhere elt (rest lst))))]))
My desired output for (insert_everywhere 'a (list 1 2 3)) is (list 'a 1 2 3 1 'a 2 3 1 2 'a 3 1 2 3 'a), but instead my list keeps terminating.
I've been able to create this function using a 3rd parameter "position" where I do recursion on that parameter, but that botches my main function. Is there anyway to create this helper function with only two parameters? Thanks!
Have you tried:
(define (insert x index xs)
(cond ((= index 0) (cons x xs))
(else (cons (car xs) (insert x (- index 1) (cdr xs))))))
(define (range from to)
(cond ((> from to) empty)
(else (cons from (range (+ from 1) to)))))
(define (insert-everywhere x xs)
(fold-right (lambda (index ys) (append (insert x index xs) ys))
empty (range 0 (length xs))))
The insert function allows you to insert values anywhere within a list:
(insert 'a 0 '(1 2 3)) => (a 1 2 3)
(insert 'a 1 '(1 2 3)) => (1 a 2 3)
(insert 'a 2 '(1 2 3)) => (1 2 a 3)
(insert 'a 3 '(1 2 3)) => (1 2 3 a)
The range function allows you to create Haskell-style list ranges:
(range 0 3) => (0 1 2 3)
The insert-everywhere function makes use of insert and range. It's pretty easy to understand how it works. If your implementation of scheme doesn't have the fold-right function (e.g. mzscheme) then you can define it as follows:
(define (fold-right f acc xs)
(cond ((empty? xs) acc)
(else (f (car xs) (fold-right f acc (cdr xs))))))
As the name implies the fold-right function folds a list from the right.
You can do this by simply having 2 lists (head and tail) and sliding elements from one to the other:
(define (insert-everywhere elt lst)
(let loop ((head null) (tail lst)) ; initialize head (empty), tail (lst)
(append (append head (cons elt tail)) ; insert elt between head and tail
(if (null? tail)
null ; done
(loop (append head (list (car tail))) (cdr tail)))))) ; slide
(insert-everywhere 'a (list 1 2 3))
=> '(a 1 2 3 1 a 2 3 1 2 a 3 1 2 3 a)
In Racket, you could also express it in a quite concise way as follows:
(define (insert-everywhere elt lst)
(for/fold ((res null)) ((i (in-range (add1 (length lst)))))
(append res (take lst i) (cons elt (drop lst i)))))
This has a lot in common with my answer to Insert-everywhere procedure. There's a procedure that seems a bit odd until you need it, and then it's incredibly useful, called revappend. (append '(a b ...) '(x y ...)) returns a list (a b ... x y ...), with the elements of (a b ...). Since it's so easy to collect lists in reverse order while traversing a list recursively, it's useful sometimes to have revappend, which reverses the first argument, so that (revappend '(a b ... m n) '(x y ...)) returns (n m ... b a x y ...). revappend is easy to implement efficiently:
(define (revappend list tail)
(if (null? list)
tail
(revappend (rest list)
(list* (first list) tail))))
Now, a direct version of this insert-everywhere is straightforward. This version isn't tail recursive, but it's pretty simple, and doesn't do any unnecessary list copying. The idea is that we walk down the lst to end up with the following rhead and tail:
rhead tail (revappend rhead (list* item (append tail ...)))
------- ------- ------------------------------------------------
() (1 2 3) (r 1 2 3 ...)
(1) (2 3) (1 r 2 3 ...)
(2 1) (3) (1 2 r 3 ...)
(3 2 1) () (1 2 3 r ...)
If you put the recursive call in the place of the ..., then you get the result that you want:
(define (insert-everywhere item lst)
(let ie ((rhead '())
(tail lst))
(if (null? tail)
(revappend rhead (list item))
(revappend rhead
(list* item
(append tail
(ie (list* (first tail) rhead)
(rest tail))))))))
> (insert-everywhere 'a '(1 2 3))
'(a 1 2 3 1 a 2 3 1 2 a 3 1 2 3 a)
Now, this isn't tail recursive. If you want a tail recursive (and thus iterative) version, you'll have to construct your result in a slightly backwards way, and then reverse everything at the end. You can do this, but it does mean one extra copy of the list (unless you destructively reverse it).
(define (insert-everywhere item lst)
(let ie ((rhead '())
(tail lst)
(result '()))
(if (null? tail)
(reverse (list* item (append rhead result)))
(ie (list* (first tail) rhead)
(rest tail)
(revappend tail
(list* item
(append rhead
result)))))))
> (insert-everywhere 'a '(1 2 3))
'(a 1 2 3 1 a 2 3 1 2 a 3 1 2 3 a)
How about creating a helper function to the helper function?
(define (insert_everywhere elt lst)
(define (insert_everywhere_aux elt lst)
(cons (cons elt lst)
(if (empty? lst)
empty
(map (lambda (x) (cons (first lst) x))
(insert_everywhere_aux elt (rest lst))))))
(apply append (insert_everywhere_aux elt lst)))
We need our sublists kept separate, so that each one can be prefixed separately. If we'd append all prematurely, we'd lose the boundaries. So we append only once, in the very end:
insert a (list 1 2 3) = ; step-by-step illustration:
((a)) ; the base case;
((a/ 3)/ (3/ a)) ; '/' signifies the consing
((a/ 2 3)/ (2/ a 3) (2/ 3 a))
((a/ 1 2 3)/ (1/ a 2 3) (1/ 2 a 3) (1/ 2 3 a))
( a 1 2 3 1 a 2 3 1 2 a 3 1 2 3 a ) ; the result
Testing:
(insert_everywhere 'a (list 1 2 3))
;Value 19: (a 1 2 3 1 a 2 3 1 2 a 3 1 2 3 a)
By the way this internal function is tail recursive modulo cons, more or less, as also seen in the illustration. This suggests it should be possible to convert it into an iterative form. Joshua Taylor shows another way, using revappend. Reversing the list upfront simplifies the flow in his solution (which now corresponds to building directly the result row in the illustration, from right to left, instead of "by columns" in my version):
(define (insert_everywhere elt lst)
(let g ((rev (reverse lst))
(q '())
(res '()))
(if (null? rev)
(cons elt (append q res))
(g (cdr rev)
(cons (car rev) q)
(revappend rev (cons elt (append q res)))))))