Search in a list with argument - list

I`m trying to implement a function that given an argument and a list, find that argument in the first element of the pair in a list
Like this:
#lang scheme
(define pairs
(list (cons 1 2) (cons 2 3) (cons 2 4) (cons 3 1) (cons 2 5) (cons 4 4)))
;This try only gets the first element, I need to runs o every pair on pairs
((lambda (lst arg)
(if (equal? (car (first lst)) arg) "DIFF" "EQ"))
pairs 2)
;This try below brings nok for every element, because Its not spliting the pairs
(define (arg) (lambda (x)2))
(map
(lambda (e)
(if (equal? arg (car e)) "ok" "nok"))
pairs)
The idea is simple, I have pair elements, and a given number. I need to see if the first element of the pairs (they are in a list) starts with that number
Thanks in advance

In Racket, this is easy to implement in terms of map. Simply do this:
(define (find-pair lst arg)
(map (lambda (e)
(if (equal? (car e) arg) "ok" "nok"))
lst))
Alternatively, you could do the same "by hand", basically reinventing map. Notice that in Scheme we use explicit recursion to implement looping:
(define (find-pair lst arg)
(cond ((null? lst) '())
((equal? (car (first lst)) arg)
(cons "ok" (find-pair (rest lst) arg)))
(else
(cons "nok" (find-pair (rest lst) arg)))))
Either way, it works as expected:
(find-pair pairs 2)
=> '("nok" "ok" "ok" "nok" "ok" "nok")
(find-pair pairs 7)
=> '("nok" "nok" "nok" "nok" "nok" "nok")

In Scheme, you should usually approach algorithms with a recursive mindset - especially when lists are involved. In your case, if you find the element in the car of the list then you are done; if not, then you've got the same problem on the cdr (rest) of the list. When the list is empty, you've not found the result.
Here is a solution:
(define (find pred list)
(and (not (null? list)) ; no list, #f result
(or (pred (car list)) ; pred on car, #t result
(find pred (cdr list))))) ; otherwise, recurse on cdr
With this your predicate function 'match if car of argument is n' is:
(define (predicate-if-car-is-n n)
(lambda (arg)
(eq? n (car arg))))
The above stretches your understanding; make sure you understand it - it returns a new function that uses n.
With everything together, some examples:
> (find (predicate-if-car-is-n 2) '((1 . 2) (2 . 3) (4 . 5)))
#t
> (find (predicate-if-car-is-n 5) '((1 . 2) (2 . 3) (4 . 5)))
#f

Related

Scheme/Racket: A function which separates a list into two lists of elements that match a certain predicate and those that don't match it

I wish to create a function in Scheme that takes in a predicate and a list of elements, and then outputs two separate lists. One with elements of the original list that MATCH the given predicate, and one with elements that DON'T match it.
The code I have right now I believe should isolate those which match the predicate and output a list of them but the code will not work.
(define tear
(lambda (pred xs)
(cond[(null? xs) '()]
[(list? (car xs))(cons((tear (pred (car xs)))(tear (pred (cdr xs)))))]
[(pred (car xs))(cons((car xs)(tear (pred (cdr xs)))))]
[else tear (pred (cdr xs))])))
(tear number? '(1 2 3 a b c))
The resulting output on my compiler is:
tear: arity mismatch;
the expected number of arguments does not match the given number
expected: 2
given: 1
arguments...:
#f
context...:
/home/jdoodle.rkt:2:4: tear
Command exited with non-zero status 1
Any help/info that you can give would be much appreciated.
Lets fix your code step by step. Adding indentation and whitespace to make it readable:
(define tear
(lambda (pred xs)
(cond
[(null? xs)
'()]
[(list? (car xs))
(cons ((tear (pred (car xs))) (tear (pred (cdr xs)))))]
[(pred (car xs))
(cons ((car xs) (tear (pred (cdr xs)))))]
[else
tear (pred (cdr xs))])))
(tear number? '(1 2 3 a b c))
The first problem I see is a problem of putting parentheses on the inside (around the arguments) of a function call instead on the outside. You do this with cons and with the recursive calls to tear. For instance in tear (pred (cdr xs)) you should move the first paren to before the function. Remember that parentheses in an expression almost always mean a function call in the shape of (function argument ...).
(cons (A B)) should be rewritten to (cons A B)
(tear (Pred Xs)) should be rewritten to (tear Pred Xs)
tear (Pred Xs) should be rewritten to (tear Pred Xs)
With these fixes your code looks like this:
(define tear
(lambda (pred xs)
(cond
[(null? xs)
'()]
[(list? (car xs))
(cons (tear pred (car xs)) (tear pred (cdr xs)))]
[(pred (car xs))
(cons (car xs) (tear pred (cdr xs)))]
[else
(tear pred (cdr xs))])))
(tear number? '(1 2 3 a b c))
;=> (1 2 3)
(tear number? '(1 2 "not a number" 3 4))
;=> (1 2 3 4)
However, it still does something weird when there's a nested list:
(tear list? (list '(1 2 3) "not a list" '(4 5)))
;=error> (() ())
To be consistent it should put the two lists into a list: ((1 2 3) (4 5)). To do that just remove the second cond case:
(define tear
(lambda (pred xs)
(cond
[(null? xs)
'()]
[(pred (car xs))
(cons (car xs) (tear pred (cdr xs)))]
[else
(tear pred (cdr xs))])))
(tear number? '(1 2 3 a b c))
;=> (1 2 3)
(tear list? (list '(1 2 3) "not a list" '(4 5)))
;=> ((1 2 3) (4 5))
It now seems to do exactly half of what you want. You want it to return two lists: one for elements that passed, and one for the elements that failed. It currently is returning just the first list.
The first thing you should do is document how it returns those two lists. Since there are always exactly two, you can return them as multiple values.
;; tear returns two values:
;; - a list of the elements of `xs` that passed `pred`
;; - a list of the elements of `xs` that failed `pred`
There are two parts of using multiple values: returning them and receiving them. Use (values A B) to return them, and (let-values ([(A B) ....]) ....) to match on a result, like the result of a recursive call.
That means every recursive call like this (f .... (tear ....) ....) should become
(let-values ([(A B) (tear ....)])
(values (f .... A ....)
???))
Applying that to your code:
;; tear returns two values:
;; - a list of the elements of `xs` that passed `pred`
;; - a list of the elements of `xs` that failed `pred`
(define tear
(lambda (pred xs)
(cond
[(null? xs)
(values '()
???)]
[(pred (car xs))
(let-values ([(A B) (tear pred (cdr xs))])
(values (cons (car xs) A)
???))]
[else
(let-values ([(A B) (tear pred (cdr xs))])
(values A
???))])))
Now to fill in the ??? holes, use examples.
(tear number? '()) should return two empty lists: () ()
(tear number? '(1 2)) should return a full list and an empty list: (1 2) ()
(tear number? '(a b)) should return an empty list and a full list: () (a b)
The first example corresponds to the first ??? hole, the second example corresponds to the second hole, and so on.
This tells us that the first hole should be filled in with '(), the second hole should be filled in with B, and the third hole should be filled in with (cons (car xs) B).
(define tear
(lambda (pred xs)
(cond
[(null? xs)
(values '() '())]
[(pred (car xs))
(let-values ([(A B) (tear pred (cdr xs))])
(values (cons (car xs) A)
B))]
[else
(let-values ([(A B) (tear pred (cdr xs))])
(values A
(cons (car xs) B)))])))
(tear number? '(1 2 3 a b c))
;=> (1 2 3)
; (a b c)
(tear list? (list '(1 2 3) "not a list" '(4 5)))
;=> ((1 2 3) (4 5))
; ("not a list")
This is a classic fold use-case. You're aggregating the list into two lists :
(define tear (lambda (pred lst)
(fold-right ; Aggregate over lst
(lambda (elem agg)
(let ((accepted (car agg))
(rejected (cadr agg)))
(if (pred elem)
; Create a new agg by adding the current element to the accepted list
`(,(cons elem accepted) ,rejected)
; Or, if the predicate rejected the element,
; Create a new agg by adding the current element to the rejected list
`(,accepted ,(cons elem rejected)))))
`(() ())
lst)))
So, if you use even? as your predicate, you can get:
> (tear even? `(1 2 3 4 5 6 7 8))
((2 4 6 8) (1 3 5 7))
Here's another way you can do it using continuation-passing style; this puts the recursive call in tail position.
(define (partition p xs (return list))
(if (null? xs)
(return null null)
(partition p
(cdr xs)
(lambda (t f)
(if (p (car xs))
(return (cons (car xs) t)
f)
(return t
(cons (car xs) f)))))))
(partition number? '())
;; => '(() ())
(partition number? '(a 1 b 2 c 3))
;; => '((1 2 3) (a b c))
(partition list? '(1 2 (3 4) (5 6) 7 8))
;; => '(((3 4) (5 6)) (1 2 7 8))
Above, we make use of Racket's default arguments. Below we show how to define partition using a helper function instead
;; procedure above, renamed to partition-helper
(define (partition-helper p xs return)
...)
;; new procedure without optional parameter
(define (partition p xs)
;; call helper with default continuation, list
(partition-helper p xs list))
Comments may help distill some of the style's mysterious nature
;; default continuation is `list`, the list constructor procedure
(define (partition p xs (return list))
(if (null? xs)
;; base case: empty list; return the empty result
(return null null)
;; inductive case: at least one x; recur on the tail...
(partition p
(cdr xs)
;; ...specifying how to continue the pending computation
(lambda (t f)
(if (p (car xs))
;; if predicate passes, cons x onto the t result
(return (cons (car xs) t)
f)
;; otherwise cons x onto the f result
(return t
(cons (car xs) f)))))))
#WillNess asks why we delay evaluating the predicate; I don't have a reason other than I think the readability above is pretty good. We can alter the implementation to check the predicate right away, if we please. The impact here is very subtle. If you don't see it, I encourage you to play pen-and-paper evaluator and compare the two processes to understand it.
;; default continuation is `list`, the list constructor procedure
(define (partition p xs (return list))
(if (null? xs)
;; base case: empty list; return the empty result
(return null null)
;; inductive case: at least one x; recur on the tail...
(partition p
(cdr xs)
;; ...specifying how to continue the pending computation
(if (p (car xs))
(lambda (t f)
;; if predicate passes, cons x onto the t result
(return (cons (car xs) t)
f))
(lambda (t f)
;; otherwise cons x onto the f result
(return t
(cons (car xs) f)))))))

How can I recursively check if a list is sorted in Lisp?

I want to write a recursive function that checks the list and either returns true if the list is in ascending order or NIL otherwise. If the list is empty it is still true. I am completely new to Lisp, so its still very confusing.
(defun sorted (x)
(if (null x)
T
(if (<= car x (car (cdr x)))
(sorted (cdr x))
nil)))
The recursive version:
(defun sorted (list)
(or (endp list)
(endp (cdr list))
(and (<= (first list) (second list))
(sorted (cdr list)))))
The more idiomatic loop-based predicate accepting a :test argument:
(defun sortedp (list &key (test #'<=))
(loop for (a b) on list
while b
always (funcall test a b)))
The version accepting a :key; we only call the key function once per visited element:
(defun sortedp (list &key (test #'<=) (key #'identity))
(loop for x in list
for old = nil then new
for new = (funcall key x)
for holdp = T then (funcall test old new)
always holdp))
Some tests:
(loop for k in '(()
((1))
((1) (2))
((2) (1))
((1) (2) (3))
((3) (2) (1)))
collect (sortedp k :test #'> :key #'car))
=> (T T NIL T NIL T)
This one also works with other kinds of sequences:
(defun sortedp (sequence &key (test #'<=) (key #'identity))
(reduce (lambda (old x &aux (new (funcall key x)))
(if (or (eq old t)
(funcall test old new))
new
(return-from sortedp nil)))
sequence
:initial-value t))
The above test gives:
(T 1 NIL 1 NIL 1)
... which is a correct result thanks to generalized booleans.
If you are doing your homework (seems so), then the above answers are fine. If you are just learning Lisp, and don't have constraints about recursivity, then the following might give you a glimpse about the power of Lisp:
(defun sorted (l)
(or (null l) (apply #'< l)))
The first problem with your solution is the base case You need to stop not at the end of the list, but when looking at the last to elements, as you need to elements to do the comparison. Also the parens are missing in the call to (car x)
(defun sorted (list)
(if (endp (cddr list))
(<= (car list) (cadr list))
(and (<= (car list) (cadr list))
(sorted (cdr list)))))
Bare in mind that recursive solutions are discouraged in CL

Finding the occurence element in the list in racket

Assume (list "apple" "orange" "apple" "grape" "orange")and produce (list (list 2 "apple") (list 2 "orange") (list 1 "grape")).
The most common fruit will occur first in the produced list.
In the case of ties, order the tied pairs with the fruit in increasing alphabetical order.
use abstract list function such as map,filter, foldr and quicksort in local. no recursion.
i'm not sure how to do it without recursion.
i wrote like this:
(define (function list)
(cond
[(empty? list) empty]
[else
(local
(define (helper1 a b)
(cond
[(equal? a b) a]
[else b]))
(define T (foldr helper1 (first list) (rest list)))
(define (count a)
(cond
[(equal? a T) true]
[else false]))
(define new-list (quicksort (length (filter count list)) >))]
The most efficient way is to use a (mutable) hash table:
(define (count-by-type lst)
; create hash
(define h (make-hash))
; update hash, creating entries if needed, otherwise adding 1 to existing entry
(map (lambda (e) (hash-update! h e add1 0)) lst)
; create list of (count key) elements from hash and sort accordingly
(sort (map (lambda (e) (list (cdr e) (car e))) (hash->list h))
(lambda (x y) (or (> (car x) (car y))
(and (= (car x) (car y)) (string<? (cadr x) (cadr y)))))))
testing:
> (count-by-type (list "apple" "orange" "apple" "grape" "orange"))
'((2 "apple") (2 "orange") (1 "grape"))
I just rehashed my own answer from a previous question. This seems to be a similar assignment, but without struct
Using a hash you could do it with only one pass through the unsorted list, then produced a list that then was sorted with a special <-function that sorts by count, then fruit.
These hints are for a functional solution. First sort the argument (sort list-of-fruits string>?). that the in descending order and oposite of your result. .
Given the list has at least one element:
(let rec ((cur (car sorted-fruits)) (cnt 1) (lst (cdr sorted-fruits)) (acc '()))
(cond ((equal? cur (car lst)) (rec cur (add1 cnt) (cdr lst) acc))
(else (rec (car lst) 1 (cdr lst) (cons (list cnt cur) acc)))))
This will produce a list in ascending order with counts.
If you sort again:
(sort list-of-counts-and-fruit (lambda (x y) (>= (car x) (car y)))
sort in Racket is stable. That means if you have two with equal counts in the list they will end up in their original order. The original order was the ascending animal order so the result is ordered by count descending, then name ascending.
I guess your procedure can be made by chaining these together, perhaps using let to store intermediates to make expressions shorter and more readable.

Two Element List Scheme

I need to write a function that determines if the given list is a pair of elements. The program will simply respond #t if the list contains exactly two elements or #f if it does not, such that:
(zipper? '((a 1)(b 2))) => #t
and
(zipper? '((foo 100)(bar 2 3))) => #f
I'm still fairly new to Scheme so any help would be much appreciated!
Thanks!
It isn't clear if the "correct" input for the procedure is an arbitrary list or a two-element list. If it's strictly a two-element list, this will work:
(define (is-two-element-list? lst)
(and (list? lst)
(= (length lst) 2)))
(define (zipper? lst)
(and (is-two-element-list? lst)
(is-two-element-list? (first lst))
(is-two-element-list? (second lst))))
… And if it's an arbitrary-length list whose elements we want to check, this will work in Racket, using andmap:
(define (zipper? lst)
(andmap is-two-element-list? lst))
If you are not using Racket, then this solution using every will work in any interpreter with SRFIs:
(require srfi/1)
(define (zipper? lst)
(every is-two-element-list? lst))
Either way, notice that the trick was defining the is-two-element-list? procedure, which verifies the two-element-list property, after that we can apply it as needed.
Think of it this way. If the zipper list is '() then the answer is #t. If the zipper list is not '() then if the first element is two elements and the rest is another zipper?, then return #t.
(define (zipper? list)
(or (null? list)
(and (= 2 (length (car list)))
(zipper? (cdr list)))))
or maybe you mean:
(define (zipper? list)
(or (not (pair? list))
(and (= 2 (length list))
(zipper? (list-ref list 0))
(zipper? (list-ref list 1)))))
every element, at any level, has two elements.
> (zipper? '((a 1 2) '(b)))
#f
> (zipper? '(a b))
#t
> (zipper? '(((a (b b)) c) (1 2)))
#t

How to break (11 (12 13)) using Car and Cdr in Scheme

I need to return from a list only those values which are odd so I am trying to break my list using car and cdr functions. I have a recursive funciton call that checks if the Car returns a list then further break it using car and cdr , otherwise just pass the first element to a function call check if Odd.
The problem with the special case (10 11 (12 13)) is that
car returns 10
cdr returns (11 (12 13))
then in second iteration
car returns (11 (12 13))
cdr returns (11 (12 13))
so How can i further break my list using car and cdr. I need to preserve the brackets in my final answer as well as only return the list having odd values of integers.
for a function that needs to work on an arbitrary nested list I find it easy to first write the flat list version (filter-odd in our case) and then edit it to produce the nested version (I will call it filter-odd*)
First for normal filter-odd
(define filter-odd
(lambda (ls)
(cond
[(null? ls) '()]
[(odd? (car ls)) (cons (car ls) (filter-odd (cdr ls)))]
[else (filter-odd (cdr ls))])))
Now for filter-odd* (one right-hand side will be left as an exercise (though it seems like you know the answer from your question))
(define filter-odd*
(lambda (ls)
(cond
[(null? ls) '()]
[(list? (car ls)) #| Do something with both car and cdr of ls |# ]
[(odd? (car ls)) (cons (car ls) (filter-odd* (cdr ls)))]
[else (filter-odd* (cdr ls))])))
As a note, this design pattern can be used to help write any recursive program and convert it from only working on flat lists to working on arbitrarily deep lists.
Here's a general solution, for lists with an arbitrary level of nesting:
(define (odds-list lst)
(cond ((null? lst) '()) ; the list is empty
((not (list? (car lst))) ; first element is not a list
(if (odd? (car lst)) ; element is odd
(cons (car lst) (odds-list (cdr lst))) ; build the returned list
(odds-list (cdr lst)))) ; element is even
(else (cons (odds-list (car lst)) ; first element is a list
(odds-list (cdr lst))))))
Notice that three cases need to be considered:
If the list is empty
If the first element of the list is not a list
If the first element of the list is a list
For the second case, two further cases need to be considered:
If the element is odd, then we add it to the list returned
If the element is even, we skip it and continue with the next element
Here's my take:
(define filter*
(lambda (e f)
(cond ((pair? e)
(append (filter* (car e) f)
(filter* (cdr e) f)))
((null? e) '())
((f e) (list e))
(else '()))))
and then you can do:
> (filter* '(1 (2 . 3) ((4 . 5))) even?)
(2 4)
> (filter* '(1 (2 . 3) ((4 . 5))) odd?)
(1 3 5)