Generate stream in racket - racket

I'm trying to generate a stream in racket that contains a sequence of 1 or 2 element lists.
It should start with the number one in a list and every subsequent element of the stream is incremented by one with the added requirement of even numbers should be duplicated in the list.
For example: ((1)(2 2)(3)(4 4)(5)(6 6))
How would I be able to do that?

It's a 2-step process:
Create stream like 1, 2, 3, 4. ... using in-range or in-naturals
Map over each element to transform them into lists with stream-map
This code snippet shows a way to create infinite as well as bounded "even-odd" lazy streams:
#lang racket
; (-> Nat (U (list Nat Nat) (list Nat)))
; a pair of `nat` if nat is even, singleton list otherwise
(define (nat->stream-elem nat)
(if (even? nat) (list nat nat) (list nat)))
; (->* () (Nat) (stream-of (U (list Nat Nat) (list Nat))))
; a stream with `total`, infinite stream if no arg provided
(define (even-odd-stream [total false])
(stream-map nat->stream-elem (if total (in-range 1 (+ total 1)) (in-naturals 1))))
; (-> Nat Void)
; displays first `to-display` elements from `stream`
(define (display-stream to-display stream)
(for ([i to-display] [e stream])
(displayln e)))
; Displays all 6 elements of a 6-element even-odd-stream
(display-stream 6 (even-odd-stream 6))
(displayln "- - -")
; Displays first 10 elements of an infinite even-odd-stream
(display-stream 10 (even-odd-stream))

Write a function, sc, say, which takes one argument, n say. It should return:
if its argument is even (stream-cons (list n n) (sc (+ n 1)));
if its argument is odd (stream-cons (list n) (sc (+ n 1))).
(sc 1) is the stream you want.

Related

Nested lists in Lisp comparison

I have a function that can produce a list of n-element sublists from a list of elements but I am stuck in filtering out elements that are just permutations of each other. For example, f(A,B) -> ((A, B) (B,A)) is what I get but I just want ((A,B)) since (B,A) is a permutation. Is there a lisp function for this? I don't need the whole answer but a clue would be appreciated, note that A,B need not be atoms but can be string literals and even lists themselves.
I am doing this
(let (newlist '())
(loop :for x in l1 :do
(loop :for y in l2 :do
(push (list x y) newlist)))
... and I have another function that filters out these duplicates but it is clunky and probs won't scale for large inputs.
One interesting function is the (destructive) pushnew which pushes an element to a list only if it is not already existent in the set (list).
(defun pair-comb (l1 l2 &key (test #'eql) (key #'identity))
(let ((result '()))
(loop for x in l1 do
(loop for y in l2 do
(pushnew (list x y) result :test test :key key))
finally (return result))))
When we make the comparison between the elements in a way that it is order-agnostic, we would have the perfect function for us to collect different lists while ruling out the permutations of any of the already collected lists.
This can be done by #'sort-ing each list and compare by #'equalp or whatever equality function.
(pair-comb '(1 2 3) '(1 2 3 4 5) :test #'equalp :key (lambda (x) (sort x #'<)))
;;=> ((3 5) (3 4) (3 3) (2 5) (2 4) (2 3) (2 2) (1 5) (1 4) (1 3) (1 2) (1 1))
;; well, actually in this case #'eql would do it.
;; when using non-numeric elements, the `#'<` in sort has to be changed!

using basic build-in or standard function(s) to solve problems in racket?

I'm working with lists in Racket, and I was doing a function to sum the elements of a list.
for example
(define (mysum L)
(if (empty? L) 0
(+ (first L) (mysum (rest L))))
)
then the result will be
> (mysum'(5 4))
9
>
But I would like to know what to do to multiply the numbers inside the list, rather than add them. when I put the * sign instead of + then it gives me an output of zero.
(define (myproduct L)
(if (empty? L) 0
(* (first L) (myproduct (rest L))))
)
and the result is
> (myproduct'(3 5))
0
> enter code here
I'm trying to understand how to multiply numbers in a list.
The myproduct should use 1 instead of 0 in the base case, because the identity element of multiplication is 1.
(define (myproduct L)
(if (empty? L) 1
(* (first L) (myproduct (rest L)))))
> (myproduct'(3 5))
15
A nice way to think about this is that * and + are the two operations of the field of numbers. And in any field, the two operations have identities, which are objects such that (<op> x <identity-of-op>) is x. But they have different identities. So let's define a function which tells us what the identity of the two operations is:
(define (identity-of op)
(cond
[(eqv? op +)
0]
[(eqv? op *)
1]
[else
(error "there are only two operations for the field of numbers")]))
And now we can define a general function which, given an operator, will return a function which combines a bunch of numbers using it (this function will be correct, since both * and + are associative):
(define (make-combiner op)
(define id (identity-of op))
(define (combiner numbers)
(if (null? numbers)
id
(op (first numbers) (combiner (rest numbers)))))
combiner)
And now:
(define sum-numbers (make-combiner +))
(define multiply-numbers (make-combiner *))

LISP function fails and returns NIL when making a list of Nth items of other lists

I need to make a named function, which makes a new list from the 3rd item from three master lists. I made this code
(defun func (nth n))
(lambda (l1 l2 l3) '(H G (U J) (T R)) '(2 1 (+ 4 5)) '(TYPE CHAR REAL (H G)))
(write (func (lambda (l1 l2 l3) '(H G (U J) (T R)) '(2 1 (+ 4 5)) '(TYPE CHAR REAL (H G))) 2))
but it returns NIL. What do I do wrong?
You need to indent and format your code. Otherwise it's an unreadable blob of characters.
Here is what you have:
Your function func takes two arguments and does nothing. It always returns NIL.
Then there is a lambda expression which takes three arguments. It uses none of them. It has three body expressions. The first two are not used and the third is being returned.
The third expression calls the function func, which always returns NIL. WRITE then prints this NIL.
Your code, but formatted readably for humans, looks like this:
(defun func (nth n)
; no functionality, does nothing and returns NIL
)
(lambda (l1 l2 l3)
'(H G (U J) (T R))
'(2 1 (+ 4 5))
'(TYPE CHAR REAL (H G)))
(write (func (lambda (l1 l2 l3)
'(H G (U J) (T R))
'(2 1 (+ 4 5))
'(TYPE CHAR REAL (H G)))
2))
Hint: you would need to write actual functionality.

Can any one convert this code to Pseudo Code

#lang racket
(define (cartesian-product . lists)
(foldr (lambda (xs ys)
(append-map (lambda (x)
(map (lambda (y)
(cons x y))
ys))
xs))
'(())
lists))
(cartesian-product '(1 2 3) '(5 6))
I have racket lang code, that calculate cartesian product of two sets or lists, I don't understand the code well, can any one convert code to pseudo code.
The function corresponds to this definition of cartesian products.
The dot . in the argument means that lists will collect all the arguments (in a list) no matter how many are passed in.
How to call such a function? Use apply. It applies a function using items from a list as the arguments: (apply f (list x-1 ... x-n)) = (f x-1 ... x-n)
foldr is just an abstraction over the natural recursion on lists
; my-foldr : [X Y] [X Y -> Y] Y [List-of X] -> Y
; applies fun from right to left to each item in lx and base
(define (my-foldr combine base lx)
(cond [(empty? lx) base]
[else (combine (first lx) (my-foldr func base (rest lx)))]))
Applying the simplifications from 1), 2) and 3) and turning the "combine" function in foldr to a separate helper:
(define (cartesian-product2 . lists)
(cond [(empty? lists) '(())]
[else (combine-cartesian (first lists)
(apply cartesian-product2 (rest lists)))]))
(define (combine-cartesian fst cart-rst)
(append-map (lambda (x)
(map (lambda (y)
(cons x y))
cart-rst))
fst))
(cartesian-product2 '(1 2 3) '(5 6))
Let's think about "what" combine-cartesian does: it simply converts a n-1-ary cartesian product to a n-ary cartesian product.
We want:
(cartesian-product '(1 2) '(3 4) '(5 6))
; =
; '((1 3 5) (1 3 6) (1 4 5) (1 4 6) (2 3 5) (2 3 6) (2 4 5) (2 4 6))
We have (first lists) = '(1 2) and the result of the recursive call (induction):
(cartesian-product '(3 4) '(5 6))
; =
; '((3 5) (3 6) (4 5) (4 6))
To go from what we have (result of the recursion) to what we want, we need to cons 1 onto every element, and cons 2 onto every element, and append those lists. Generalizing this, we get a simpler reformulation of the combine function using nested loops:
(define (combine-cartesian fst cart)
(apply append
(for/list ([elem-fst fst])
(for/list ([elem-cart cart])
(cons elem-fst elem-cart)))))
To add a dimension, we consed every element of (first lists) onto every element of the cartesian product of the rest.
Pseudocode:
cartesian product <- takes in 0 or more lists to compute the set of all
ordered pairs
- cartesian product of no list is a list containing an empty list.
- otherwise: take the cartesian product of all but one list
and add each element of that one list to every
element of the cartesian product and put all
those lists together.

Trying to get this code to work, can't understand where to put the argument in and keep getting errors

Define the function iota1(n, m) that takes positive integers n, m with n < m as input, and outputs the list (n,n+1,n+2,...,m)
I've tried switching the code around multiple times but cannot seem to get it to function and display a list the right way
(define (iota1 n m)
(if (eq? n 0)
'()
(append (iota1 (< n m) (+ n 1)) (list n))))
There's a few oddities to the code you provided, which I've formatted for readability:
(define (iota1 n m)
(if (eq? n 0)
'()
(append (iota (< n m) (+ n 1))
(list n))))
The first is that the expression (< n m) evaluates to a boolean value, depending on whether n is less than m or not. When you apply iota to (< n m) in the expression (iota (< n m) (+ n 1)), you are giving iota a boolean value for its first argument instead of a positive integer.
Secondly, the use of append is strange here. When constructing a list in Racket, it's much more common to use the function cons, which takes as arguments a value, and a list, and returns a new list with the value added to the front. For example,
(append '(3) (append '(4) (append '(5) '()))) ==> '(3 4 5)
(cons 3 (cons 4 (cons 5 '()))) ==> '(3 4 5)
It's a good idea to opt for using cons instead of append because it's simpler, and because it is faster, since cons does not traverse the entire list like append does.
Since this sounds a bit like a homework problem, I'll leave you with a "code template" to help you find the answer:
; n : integer
; m : integer
; return value : list of integers
(define (iota1 n m)
(if (> n m) ; base case; no need to do work when n is greater than m
... ; value that goes at the end of the list
(cons ... ; the value we want to add to the front of the list
(iota1 ... ...)))) ; the call to iota, generating the rest of the list
Welcome to the racket world, my version is here:
#lang racket
(define (iota1 n m)
(let loop ([loop_n n]
[result_list '()])
(if (<= loop_n m)
(loop
(add1 loop_n)
(cons loop_n result_list))
(reverse result_list))))