Racket - Filter even and odd integers into two separate lists - lisp

Function should take a list of integers and return a list containing two sublists -- the first containing the even numbers from the original list, the second containing the odd. My code gets the job done, but if I test it with a negative integer, such as the -5 in the second test, it just gets ignored by my code. Any ideas on how to fix?
(Side note - I know there are functions for even, odd, etc, but for this assignment I am to create them myself.)
(define (segregate lst)
(list(pullEven lst)(pullOdd lst)))
(define (pullEven lst)
(if (empty? lst)
'()
(if (isEven (first lst))
(cons (first lst) (pullEven (rest lst)))
(pullEven (rest lst)))))
(define (pullOdd lst)
(if (empty? lst)
'()
(if (isOdd (first lst))
(cons (first lst) (pullOdd (rest lst)))
(pullOdd (rest lst)))))
(define (isEven x)
(if (equal? (remainder x 2) 0) #t #f)
)
(define (isOdd x)
(if (equal? (remainder x 2) 1) #t #f)
)
;tests
"---------------------------------------------"
"Segregate Tests"
(segregate '(7 2 3 5 8))
(segregate '(3 -5 8 16 99))
(segregate '())
"---------------------------------------------"

Try substituting modulo instead of remainder.
Remainder will preserve the sign of the answer (a remainder of -1 doesn't match the value of 1 that you're checking for).
Modulo returns an answer with the same sign as the denominator.

Related

Racket: Product of even number

I am trying to produce the product of the even numbers in a given list.
I am trying to replicate the following example:
Example:
(product-even-numbers '(2 1 6 3 5))
==> 12
This is my version of the definition for product-even-numbers:
(define (product-even-numbers lst)
(define/match (recurse lst accumulator)
;; A _ pattern matches any syntax object
[(_ _) (* car (recurse cdr))])
(recurse lst 1))
I am getting the following error:
(product-even-numbers '(2 1 6 3 5))
. . recurse: arity mismatch;
the expected number of arguments does not match the given number
expected: 2
given: 1
arguments...:
I understand that i am missing the second argument, but I do not know what the second argument is supposed to be.
Why are you using pattern matching? this would be easier to understand without it, and first of all you need to get the recursion and the logic right:
(define (product-even-numbers lst)
(define (recurse lst acc)
(cond ((null? lst) acc)
((even? (car lst)) (recurse (cdr lst) (* (car lst) acc)))
(else (recurse (cdr lst) acc))))
(recurse lst 1))
In this case, it's clear that the second argument is the accumulated product we have so far. And we need to consider three cases: empty list, even element, odd element. For example:
(product-even-numbers '(2 1 6 3 5))
=> 12
(define (product-even-numbers lst)
(local [(define tmp (foldr * 1 (filter even? lst)))]
(if (= 1 tmp) 'nothing tmp)))
If output 1 means no any even number.
(define (product-even-numbers2 lst)
(foldr * 1 (filter even? lst))) ; or use (apply * (filter even? lst))

IN Racket Define a function that takes two arguments

I need some one can explain for me to how to do this please
Define a function that takes two arguments, a list of numbers and a single number (the threshold). It should return a new list that has the same numbers as the input list, but with all elements greater than the threshold number removed. You may not use the built-in filter function as a helper
function. Your implementation must be recursive.
INPUT: A list of numbers and a single atomic number.
OUTPUT: A new list of numbers that contains only the numbers from the original list that are strictly “less than” (<), i.e. below the threshold number.
Example:
> (upper-threshold '(3 6.2 7 2 9 5.3 1) 6)
'(3 2 5.3 1)
> (upper-threshold '(1 2 3 4 5) 4)
'(1 2 3)
> (upper-threshold '(4 8 5 6 7) 6.1)
'(4 5 6)
> (upper-threshold '(8 3 5 7) 2)
'()
This what I have so far but I receve error
(define (upper-threshold pred lst)
(cond [(empty? lst) empty]
[(pred (first lst))
(cons (first lst) (upper-threshold pred (rest lst)))]
[else (upper-threshold pred (rest lst))]))
; (threshold (lambda (x) (> x 5)) '(1 6 7))
Your implementation doesn't have the same arguments as your assignment.
You need something that compares the first element with the second argument so see it its larger or not, then either (cons (car lst) (upper-treshold (cdr lst) streshold)) to include the first element in the result or (upper-treshold (cdr lst) treshold) to not include it.
(define (upper-threshold lst treshold)
(cond [(empty? lst) empty]
[(> (car lst) treshold)
(cons (first lst) (upper-threshold (rest lst) treshold))]
[else (upper-threshold (rest lst) treshold)]))
I don't quite understand your code. However, you might be looking for something like this:
(define (upper-threshold lst theshold)
(cond
((null? lst) '())
((< (car lst) theshold)
(cons (car lst)
(upper-threshold (cdr lst) theshold)))
(else (upper-threshold (cdr lst) theshold))))
If your purpose is to implement the standard function filter, perhaps you should write the code some another way.
It appears that you've taken a filter function and renamed it as upper-threshold. It's true that these two are related. I would suggest trying to build upper-threshold from scratch, using the design recipe:
http://www.ccs.neu.edu/home/matthias/HtDP2e/
When you get confused, refer to existing functions that you have, including the definition of filter that you have here. Your example may be slightly harder to understand because it uses lambda.

How to use foldr in Racket to eliminate numbers in a list that are greater than any subsequent numbers

I have to write a function in Racket using foldr that will take a list of numbers and remove list elements that are larger than any subsequent numbers.
Example: (eliminate-larger (list 1 2 3 5 4)) should produce (1 2 3 4)
I can do it without using foldr or any higher-order functions but I can't figure it out with foldr. Here's what I have:
(define (eliminate-larger lst)
(filter (lambda (z) (not(equal? z null)))
(foldr (lambda (x y)
(cons (determine-larger x (rest lst)) y)) null lst))
)
(define (determine-larger value lst)
(if (equal? (filter (lambda (x) (>= x value)) lst) lst)
value
null)
)
determine-larger will take in a value and a list and return that value if it is greater than or equal to all elements in the list. If not, it returns null. Now the eliminate-larger function is trying to go through the list and pass each value to determine-larger along with a list of every number after it. If it is a "good" value it will be returned and put in the list, if it's not a null is put in the list. Then at the end the nulls are being filtered out. My problem is getting the list of numbers that follow after the current number in the foldr function. Using "rest lst" doesn't work since it's not being done recursively like that. How do I get the rest of the numbers after x in foldr?
I really hope I'm not doing your homework for you, but here goes ...
How do I get the rest of the numbers after x in foldr?
Because you're consuming the list from the right, you can structure your accumulator such that "the rest of the numbers after x" are available as its memo argument.
(define (eliminate-larger lst)
(foldr
(lambda (member memo)
(if (andmap (lambda (n) (<= member n)) memo)
(cons member memo)
memo))
'()
lst))
(eliminate-larger (list 1 2 3 5 4)) ;; (1 2 3 4)
This is admittedly a naive solution, as you're forced to traverse the entire accumulator with each iteration, but you could easily maintain a max value, in addition to your memo, and compare against that each time through.
Following works:
(define (el lst)
(define (inner x lsti)
(if(empty? lsti) (list x)
(if(<= x (apply max lsti))
(cons x lsti)
lsti)))
(foldr inner '() lst))
(el (list 1 2 3 5 4))
Output:
'(1 2 3 4)
The cond version may be preferable:
(define (el lst)
(define (inner x lsti)
(cond
[(empty? lsti) (list x)]
[(<= x (apply max lsti)) (cons x lsti)]
[else lsti] ))
(foldr inner '() lst) )

Write a Scheme function (sumList)

Write a Scheme function (sumList) that returns the sum of all the numbers in a list which should be passed as a parameter. The list can have numbers, non-numeric symbols, and other lists. Your function should select all the number in the sublists and add them to the total. You can assume that the total is 0 if the list is empty. Example Usage:
(sumList '((1 2 3) 5 a (10) ())
21
(define (sumList lst)
(cond
([empty? lst]
0)
([list? (car lst)]
(+ (sumList (car lst)) (sumList (cdr lst))))
((not(number? (car lst)))
(sumList (cdr lst)))
(else
(+ (car lst)(sumList (cdr lst))))))

racket postfix to prefix

I have a series of expressions to convert from postfix to prefix and I thought that I would try to write a program to do it for me in DrRacket. I am getting stuck with some of the more complex ones such as (10 (1 2 3 +) ^).
I have the very simple case down for (1 2 \*) → (\* 1 2). I have set these expressions up as a list and I know that you have to use cdr/car and recursion to do it but that is where I get stuck.
My inputs will be something along the lines of '(1 2 +).
I have for simple things such as '(1 2 +):
(define ans '())
(define (post-pre lst)
(set! ans (list (last lst) (first lst) (second lst))))
For the more complex stuff I have this (which fails to work correctly):
(define ans '())
(define (post-pre-comp lst)
(cond [(pair? (car lst)) (post-pre-comp (car lst))]
[(pair? (cdr lst)) (post-pre-comp (cdr lst))]
[else (set! ans (list (last lst) (first lst) (second lst)))]))
Obviously I am getting tripped up because (cdr lst) will return a pair most of the time. I'm guessing my structure of the else statement is wrong and I need it to be cons instead of list, but I'm not sure how to get that to work properly in this case.
Were you thinking of something like this?
(define (pp sxp)
(cond
((null? sxp) sxp)
((list? sxp) (let-values (((args op) (split-at-right sxp 1)))
(cons (car op) (map pp args))))
(else sxp)))
then
> (pp '(1 2 *))
'(* 1 2)
> (pp '(10 (1 2 3 +) ^))
'(^ 10 (+ 1 2 3))
Try something like this:
(define (postfix->prefix expr)
(cond
[(and (list? expr) (not (null? expr)))
(define op (last expr))
(define args (drop-right expr 1))
(cons op (map postfix->prefix args))]
[else expr]))
This operates on the structure recursively by using map to call itself on the arguments to each call.