Adjacent difference in Racket - scheme

C++ has a handy algorithm std::adjacent_difference which computes the differences between the next/previous of elements of the range.
The Racket implementation is straightforward:
(define (adjacent-difference f lst)
(if(null? (cdr lst))
'()
(cons (f (cadr lst)(car lst))
(adjacent-difference f (cdr lst)))))
however we have a lot of handy built-in algorithms inside the Racket so I wanted to reuse them.
The first idea was:
(map f (cdr lst) lst)
Oops, the sizes of the lists are different, we cannot use map in this way.
I can cheat like this:
(map f (append (cdr lst) '(0)) lst) ; do not use the last element
but it is a dirty solution.
Any ideas how to do it without writing a new function?

Here is a short version:
(define (adjacent-difference f xs)
(for/list ([x xs] [y (cdr xs)])
(f y x)))
Here x and y runs though the elements of xs and (cdr xs)
in parallel. Since (cdr xs) is the shorter than xs the loop
ends when there is no more elements in (cdr xs).

In the map defined in SRFI-1 List library different sized lists are allowed with the requirement that at least one is finite. It will only step as many times as the shortest list.
#lang racket
;; import map from srfi-1. This shadows the one from racket/base
(require (only-in srfi/1 map))
(define (adjacent-difference f lst)
(map f (cdr lst) lst))
For completeness I'll include the imports needed for the same code to work in Scheme:
#!r6rs
(import (except (rnrs) map)
(only (srfi :1) map))
In the next version of Scheme, R7RS, SRFI-1 is the standard list library. Thus this should work in the R7RS "red edition":
#!r7rs
(import (scheme)
(scheme list))

If I understand what you want, it isn't only "dirty" but it isn't a solution, since appending the zero at the end means you have more elements than you should. For a three-item list you should only have two differences, right? Or do you always want to pull in default elements?
How about making your own map?
(define (stalling-map proc . args)
(if (ormap null? args)
'()
(cons (apply proc (map car args))
(apply stalling-map proc (map cdr args)))))
;;;;
Welcome to DrRacket, version 6.12 [3m].
> (let ((lst '(1 3 7 10 11)))
(stalling-map - (cdr lst) lst))
'(2 4 3 1)
>

Related

Racket find shared elements between lists

I'm trying to create a specific response for a given list if it has shared elements with another list. As in if I have a list that is (My name is John) and I have another list of (John Adam Jacob) I would want the first list to be able to see that John is in the second list, and be able to print something along the lines of (this is a known name) or something similiar.
The code I have thought of uses map, and member.
(define (specific-reply user-list)
(cond (member (map (lambda (user-list)) '(John Adam Jacob)))
(write (this is a known name))
(else
(write (this is not a known name)))))
I'm extremely knew to both racket and scheme however and I haven't really gotten it to compile yet so I think I'm largely off.
Any help would be greatly appreciated.
You don't need to complicate the problem if your task is to just find if a is a member of (a b c),
Here's a piece of Scheme code that can tell if a is a member of lat.
It's just a simple recursive function that compares each element of lat with a for a match.
(define member?
(lambda (a lat)
(cond
((null? lat) #f)
((eq? a lat) #t)
(else
(member? a (cdr lat))))))
If you want to take this further and find the intersection of two lists, we can do something like this!
(define intersect
(lambda (set1 set2)
(letrec
((I (lambda (set)
(cond
((null? set) (quote ()))
((member? (car set) set2)
(cons (car set)
(I (cdr set))))
(else (I (cdr set)))))))
(I set1))))
You can use this code as such. Tested from guile compiler
(begin
(display (intersect `(1 2 3) `(1 3 4 5 2)))
(newline))
>> (1 2)
EDIT
I recommend you read The Little Schemer and the The Seasoned Schemer to get more familiar with these kind of concepts
Why not use set in racket:
(define (list-intersect-2 lst1 lst2)
(set->list
(set-intersect (list->set lst1)
(list->set lst2))))
For a solution that takes one or more lists:
(define (list-intersect lst1 . lstn)
(set->list
(foldl set-intersect
(list->set lst1)
(map list->set lstn))))
(list-intersect '(1 2 3) '(2 3 4) '(3 4 8))
; ==> (3)
One can also use built-in functions filter and member to find intersection of 2 lists:
(define (intersection l1 l2)
(remove-duplicates
(filter (λ (x) (member x l1))
l2)))
Above checks each item of l2 to keep it only if it is a member of l1 also.
One can also use for/list to check each element and return a list of common items:
(define (intersect l1 l2)
(remove-duplicates
(for/list ((i l1)
#:when (member i l2))
i)))
Both above function remove duplicates. Just avoiding use of remove-duplicates may result in different result if simply the order of l1 and l2 is interchaged. If one wants that the repeated elements to come repeatedly in outcome list, one can use following function in which common items are removed before proceeding:
(define (intersection2 l1 l2)
(let loop ((l1 l1)
(l2 l2)
(ol '()))
(cond
[(empty? l1) (reverse ol)]
[(member (first l1) l2) ; first item of l1 is common
(loop (rest l1) ; loop with rest of l1
(remove (first l1) l2) ; remove common item from l2
(cons (first l1) ol))] ; add common item to outlist
[else
(loop (rest l1)
l2
ol)])))
Testing:
(intersection2 '(2 4 2 7 2 10) '(10 2 9 2 0 11))
Output:
'(2 2 10)

Product of squares of odd elements in list in Scheme

I wanted to write a code in Scheme that writes the square odd elements in list.For example (list 1 2 3 4 5) for this list it should write 225.For this purpose i write this code:
(define (square x)(* x x))
(define (product-of-square-of-odd-elements sequence)
(cond[(odd? (car sequence)) '() (product-of-square-of-odd-elements (cdr sequence))]
[else ((square (car sequence)) (product-of-square-of-odd-elements (cdr sequence)))]))
For run i write this (product-of-square-of-odd-elements (list 1 2 3 4 5))
and i get error like this:
car: contract violation
expected: pair?
given: '()
What should i do to make this code to run properly? Thank you for your answers.
First of all, you need to do proper formatting:
(define (square x) (* x x))
(define (product-of-square-of-odd-elements sequence)
(cond
[(odd? (car sequence))
'() (product-of-square-of-odd-elements (cdr sequence))]
[else
((square (car sequence)) (product-of-square-of-odd-elements (cdr sequence)))]))
Now there are multiple issues with your code:
You are trying to work recursively on a sequence, but you are missing a termination case: What happens when you pass '() - the empty sequence? This is the source of your error: You cannot access the first element of an empty sequence.
You need to build up your result somehow: Currently you're sending a '() into nirvana in the first branch of your cond and put a value into function call position in the second.
So let's start from scratch:
You process a sequence recursively, so you need to handle two cases:
(define (fn seq)
(if (null? seq)
;; termination case
;; recursive case
))
Let's take the recursive case first: You need to compute the square and multiply it with the rest of the squares (that you'll compute next).
(* (if (odd? (car seq)
(square (car seq))
1)
(fn (cdr seq)))
In the termination case you have no value to square. So you just use the unit value of multiplication: 1
This is not a good solution, as you can transform it into a tail recursive form and use higher order functions to abstract the recursion altogether. But I think that's enough for a start.
With transducers:
(define prod-square-odds
(let ((prod-square-odds
((compose (filtering odd?)
(mapping square)) *)))
(lambda (lst)
(foldl prod-square-odds 1 lst))))
(prod-square-odds '(1 2 3 4 5))
; ==> 225
It uses reusable transducers:
(define (mapping procedure)
(lambda (kons)
(lambda (e acc)
(kons (procedure e) acc))))
(define (filtering predicate?)
(lambda (kons)
(lambda (e acc)
(if (predicate? e)
(kons e acc)
acc))))
You can decompose the problem into, for example:
Skip the even elements
Square each element
take the product of the elements
With this, an implementation is naturally expressed using simpler functions (most of which exist in Scheme) as:
(define product-of-square-of-odd-elements (l)
(reduce * 1 (map square (skip-every-n 1 l))))
and then you implement a helper function or two, like skip-every-n.

All: A Function Returning True if and only if All Elements of a List are True

I am looking for a built-in function in Racket that will return True iff all the items in a list are true.
I tried:
(define (all lst)
(when
(equal? lst '())
#t)
(if (not (car lst))
#f
(all (cdr lst))))
Giving error:
car: contract violation
expected: pair?
given: '()
A couple of testcases:
(all '(#t #f #t)) ; #f
(all '(#t #t #t)) ; #t
Could you please either fix it or point me to the built-in function?
(I googled, but got no meaningful result)
You've already accepted another answer that explains a nice way to do this, but I think it's worth pointing out what was wrong in your attempt, because it was actually very close. The problem is that true from the when block is completely ignored. It doesn't cause the function to return. So even when you have the empty list, you evaluate the when, and then keep on going into the other part where you call car and cdr with the same empty list:
(define (all lst)
(when ; The whole (when ...) expression
(equal? lst '()) ; is evaluated, and then its result
#t) ; is ignored.
(if (not (car lst))
#f
(all (cdr lst))))
A very quick solution would be to change it to:
(define (all lst)
(if (equal? lst '())
#t
(if (not (car lst))
#f
(all (cdr lst)))))
At that point, you can simplify a little bit by using boolean operators rather than returning true and false explicitly, and clean up a little bit by using empty?, as noted in the other answer:
(define (all lst)
(or (empty? lst)
(and (car lst)
(all (cdr lst)))))
You were actually very close at the start.
If you're looking for a builtin solution, you'll probably want to take a look at andmap, which applies a predicate over an entire list and ands the results together.
You could use this to implement all very simply.
(define (all lst)
(andmap identity lst))
By using identity from racket/function, all will just use the values in the list as-is. Instead of using identity explicitly, you could also use values, which is just the identity function on single values, so it's a somewhat common idiom in Racket.
There are two kinds of lists: empty ones and pairs.
Therefore we have the following structure:
(define (all xs)
(cond
[(empty? xs) ...]
[(pair? xs) ...]
[else (error 'all "expected a list, got: " xs)]))
Since all elements in the empty list are true, we get:
(define (all xs)
(cond
[(empty? xs) #t]
[(pair? xs) ...]
[else (error 'all "expected a list, got: " xs)]))
If a list begins with a pair, then all elements of the list are true,
if both the first element of the list and the rest of the elements of the list are true:
(define (all xs)
(cond
[(empty? xs) #t]
[(pair? xs) (and (first xs) (all (rest xs)))]
[else (error 'all "expected a list, got: " xs)]))
Note that part of the problem in your program is the use of when.
The result of
(when #t
'foo)
'bar
is 'bar. The construct when is only useful if you are using side effects (such as caused by set! and friends).
All is a higher order folding function. Scheme refers to these as "reductions" and reduce is available in SRFI-1
In Gauche Scheme:
(use srfi-1)
(define (all list-of-x)
(reduce (lambda (x y)
(and x y))
#t
list-of-x))
Will return #f or a value that evaluates to true. For example:
gosh> (all '(1 2 3))
1
If that's OK, then we're done. Otherwise we can always get #t with:
(use srfi-1)
(define (all-2 list-of-x)
(if (reduce (lambda (x y)
(and x y))
#t
list-of-x)
#t
#f))
And then wind up with:
gosh> (all '(1 2 3))
#t

recursive function accepts list in scheme

I'm new to Scheme and this is my very first Functional language. Implementing almost everything recursively seems to be awkward for me. Nevertheless, was able to implement functions of Factorial and Fibonacci problems having a single integer input.
However, what about when your function has an input of a list? Suppose this exercise:
FUNCTION: ret10 - extracts and returns as a list all the numbers greater than 10
that are found in a given list, guile> (ret10 ‘(x e (h n) 1 23 12 o))
OUTPUT: (23 12)
Should I have (define c(list)) as the argument of my function in this? or is there any other way?
Please help. Thanks!
Here's my derived solution based on sir Óscar López's answer below.. hope this helps others:
(define (ret10 lst)
(cond
((null? lst) '())
((and (number? (car lst)) (> (car lst) 10))
(cons (car lst)
(ret10 (cdr lst))))
(else (ret10 (cdr lst)))
)
)
This kind of problem where you receive a list as input and return another list as output has a well-known template for a solution. I'd start by recommending you take a look at The Little Schemer or How to Design Programs, either book will teach you the correct way to start thinking about the solution.
First, I'll show you how to solve a similar problem: copying a list, exactly as it comes. That'll demonstrate the general structure of the solution:
(define (copy lst)
(cond ((null? lst) ; if the input list is empty
'()) ; then return the empty list
(else ; otherwise create a new list
(cons (car lst) ; `cons` the first element
(copy (cdr lst)))))) ; and advance recursion over rest of list
Now let's see how the above relates to your problem. Clearly, the base case for the recursion will be the same. What's different is that we cons the first element with the rest of the list only if it's a number (hint: use the number? procedure) and it's greater than 10. If the condition doesn't hold, we just advance the recursion, without consing anything. Here's the general idea, fill-in the blanks:
(define (ret10 lst)
(cond (<???> <???>) ; base case: empty list
(<???> ; if the condition holds
(cons <???> ; `cons` first element
(ret10 <???>))) ; and advance recursion
(else ; otherwise
(ret10 <???>)))) ; simply advance recursion
Don't forget to test it:
(ret10 '(x e (h n) 1 23 12 o))
=> '(23 12)
As a final note: normally you'd solve this problem using the filter procedure - which takes as input a list and returns as output another list with only the elements that satisfy a given predicate. After you learn and understand how to write a solution "by hand", take a look at filter and write the solution using it, just to compare different approaches.
Solve the problem for the first element of the list and the recurse on rest of the list. Make sure you handle the termination condition (list is null?) and combine results (cons or append in the following)
(define (extract pred? list)
(if (null? list)
'()
(let ((head (car list))
(rest (cdr list)))
(cond ((pred? head) (cons head (extract pred? rest)))
((list? head) (append (extract pred? head)
(extract pred? rest)))
(else (extract pred? rest))))))
(define (ret10 list)
(extract (lambda (x) (and (number? x) (> x 10))) list))
> (ret10 '(0 11 (12 2) 13 3))
(11 12 13)

Simple Scheme, squaring all elements in a list

Okay, I'm new to Scheme and I thought I understood it, but got confused on this problem. I want to square all the elements of a list. So, (mapsq '(1 2 3)) returns (list 1 4 9).
my code:
(define mapsq
(lambda (ls)
(cond ((null? ls) 0)
(else (cons (car ls) (car ls))
(mapsq (cdr ls)))))))
In a practical (non-academic) context, this problem can be easily solved by using the map procedure:
(define mapsq
(lambda (ls)
(map (lambda (x) (* x x))
ls)))
Of course, if this is homework and you need to implement the solution from scratch, I shouldn't spoon-feed the answer. Better find out the solution by yourself, filling-in the blanks:
(define mapsq
(lambda (ls)
(cond ((null? ls) ; If the list is empty
<???>) ; ... then return the empty list.
(else ; Otherwise
(cons (* <???> <???>) ; ... square the first element in the list
(mapsq <???>)))))) ; ... and advance the recursion.
There are two problems in your solution: first, the base case should not return 0 - if we're building a list as an answer, then you must return the empty list. Second, in the recursive step you aren't actually squaring the current element in the list - to do that just multiply it by itself with the * operator.
You could write it like this:
(define (mapsq xs)
(define (square x) (* x x))
(map square xs))
Or this:
(define (mapsq xs)
(map (lambda (x) (* x x)) xs))
Or maybe like this:
(define (mapsq xs)
(let loop ((xs xs) (sqs '()))
(if (null? xs)
(reverse sqs)
(loop (cdr xs) (cons (* (car xs) (car xs)) sqs)))))
Or even like this:
(define (mapsq xs)
(if (null? xs)
'()
(cons (* (car xs) (car xs)) (mapsq (cdr xs)))))
My preference would be the first option. The second option is shorter, but the auxiliary function makes the first option easier to read. I would probably not use either the third or fourth options.
By the way, the solution by laser_wizard doesn't work, either.
I notice that you're new here. If you like an answer, click the up arrow next to the answer so the person who gave the answer gets points; this mark also lets the community of readers know that there is something of value in the answer. Once you have an answer that you are confident is correct, click the check mark next to the answer; that also gives points to the person that gave the answer, and more importantly lets other readers know that you believe this answer most correctly addresses your question.
(define (mapsq xs)
(map * xs xs))
> (mapsq '(1 2 3 4 5))
'(1 4 9 16 25)

Resources