Racket random list-ref function - scheme

Define a function that takes a non-empty list and returns an element of the list selected at random and with equal probability. (Do not use the built-in list-ref procedure.)
I'm stuck on this. I feel like you would need to count the number of times the function has run recursively and compare it to the random number you get, but I don't know how to do that in BSL+. Any help would be really great.

Here is a solution. To get the ball rolling the first element of the list is chosen as a candidate to be returned. Then for each element of the remaining elements in the list, we randomly choose if the candidate is to be replaced.
For example: For a list with two elements '(a b) first the element 'a is chosen.
The a coin is flipped: With probability 50% 'b is returned instead.
Examine the code to see how the algorithm works for larger lists:
(define (pick-random xs)
(pick-random/helper (rest xs) (first xs) 1))
(define (pick-random/helper xs chosen k)
(cond
[(empty? xs) chosen]
[else ; with probability 1/(k+1) choose the first element of xs
(if (= (random (+ k 1)) 0)
(pick-random/helper (rest xs) (first xs) (+ k 1))
(pick-random/helper (rest xs) chosen (+ k 1)))]))
If you want to google the theory, this type of algorithm belongs to "sampling algorithms".

I take the comment about not using list-ref as a direction to think about the problem recursively.
An assumption is made that 'equal probability' does not take into account the flaws of naive software-based RNGs.
Note that we use []-notation in the function definition to say that steps, unless specified, will have a (default) value of (random (length lst)). This means it will initially have a random amount of 'steps into' the list.
#lang racket
(define (random-element lst [steps (random (length lst))])
(if (= steps 0)
(first lst)
(random-element (rest lst)
(sub1 steps))))
Since steps is internally specified (as (sub1 steps), subtract one from steps) it will always have an explicit value except when the function is applied like so:
(random-element '(42 1337 128 256))
; 256

Related

Diagonal of a matrix in racket [duplicate]

This question already has answers here:
Find main diagonal in matrix - Scheme
(3 answers)
Closed 4 years ago.
I have a list of lists(matrix) and i would like to access using (map or apply) the main diagonal.
The problem is larger, to make a matrix of a list of images removing the duplicates but i did that part.
(make-list (length (filter (lambda (x) (<= (image-height x) max-height)) L))
(filter (lambda (x) (<= (image-height x) max-height)) L)) )
I don't have a clue how to access using map or apply the elements of the main diagonal..
Remember that map requires a procedure that takes as many arguments as you have lists to map. In this case we want to access the ith element of a list, this is the built-in procedure list-ref which takes a list L and an index i and returns the ith element of L. So then we just need the indexes of the diagonal elements. This is (list 0 1 2 ...) which we can generate using build-list.
(define (diagonal M)
(define indexes (build-list (length M) values))
(map list-ref M indexes))
You don't have to build the second list if you use recursion. In this case you build the diagonal in a recursive function where we take the leading element of the first row, then recur on the rest of the elements in the rest of the rows:
(define (diagonal M)
(if (null? M)
'()
(cons (caar M)
(diagonal (map cdr (cdr M))))))
It's going to take basically the same amount of operations in terms of building the diagonal, but the second one doesn't require a new list be generated up front and doesn't require determining the size of the matrix, so it's a little better.

Scheme - Return list of N Repetitions of said list

First off, this is a homework question so just looking for guidance and not an answer.
Write a function named (cycle ALIST N) that accepts a list of elements ALIST and an integer N. This function returns a list containing N repetitions of the elements of ALIST. If N is non-positive, this function returns the empty list.
I will be honest in that I'm not sure how to begin solving this problem. I've been thinking of writing a helper function then using cons calling this n times but just looking if I'm on the correct track here.
One of the more common ways to tackle recursive problems is to begin thinking about it at the end. In other words, under what conditions should you stop? —When are you done? If you can write this base case down, then you only need to ask, what do I do when I am one step away from stopping? This is the recursive step, and for relatively simple recursive problems you are done as the whole problem is either "continue" to do the same thing or "stop."
Knowing the base case usually tells you what kind of extra information you may need to carry around, if any.
In the case of scheme and racket, which support tail call optimization, you may end up with different kinds of recursion. For example:
(define (normal-factorial n)
(if (zero? n)
1
(* n (normal-factorial (- n 1)))))
(define (tail-factorial n)
(letrec ((tf (lambda (product index)
(if (zero? index)
product
(tf (* product index) (- index 1))))))
(tf n (- n 1))))
In the first case, we build up a product without ever multiplying until the very end, while in the second we multiply as soon as possible and carry around this temporary product the whole time.
Not all problems easily lend themselves to one kind of recursion or the other.
You have different strategies you can make. The simplest is probably not the most effiecent but the one that produces less code:
(require srfi/26) ; cut
(define (cycle lst n)
(define dup-lst (map (cut make-list n <>) lst))
(foldr append '() dup-lst))
So what this does is that the map creates a list of lists where each is n elements of each. The foldr flattens it by using append.
With more hands on you can make it more efficient. I'm thinking roll your own recursion consing the elements from end to beginning in an accumulator:
(define (cycle lst n)
(let helper ((lst (reverse lst)) (c n) (acc '()))
(cond ((null? lst) acc)
((<= c 0) (helper ...))
(else (helper ...)))))
I've left out the recursive parts. What this does is a base case on the empty list, a reset recur with a c reset to n and the cdr when c is zero and the default case keeping lst while reducing c and cons-ing the first element of lst to acc. This is a O(n) solution.

Finding the largest list in a definition of lists in lists?

I have a question regarding finding the largest list in a group of lists in scheme.
For example, we define:
(define manylsts (list (list 9 (list 8 7)) 6 (list 5 (list 4 3 2) 1)))
How would I go about finding the largest list in manylsts?
Thank you
You make a procedure that evaluates to zero if it's argument is not a list. (eg. 9), then if its a list you foldl over the elements using length of the argument as accumulator with a lambda that does max between the recursion of the first argument with the accumulator. It would look something like this:
(define (max-children tree)
(if <??>
(foldl (λ (x acc)
(max <??> (max-children <??>)))
(length <??>)
<??>)
0))
Of course there are many ways of doing this, including explicit recursion, but this was the first thing I though of.
I will answer this question as you asked it.
You said you want to
finding the largest list in manylsts
Since you included a non-listed element inside manylsts you want to have a definition that tells you how big is an element (if is a list).
So I wrote the function elemenlen that returns the length of a list if the given element is a list and 0 otherwise.
(define elemenlen
(λ (a)
(if (list? a) (length a) 0)
))
Then I decided I was going to sort them in order of length and then return the first element. So I need a function that returns a boolean value to use it with sort function included in racket/base.
(define list<
(λ (listA listB)
(< (elemenlen listA) (elemenlen listB))))
(define list>
(λ (listA listB)
(not (list< listA listB))))
The first function returns #t if listA is smaller than listB. The second function returns #t if listA is bigger than listB.
Lastly, biggestElement does the whole trick, sorts the elements in list L in descending order (based on length) and returns the first element.
(define biggestElement
(λ (L)
(car (sort L list>)
)))
The function is used like this:
>(biggestElement '((3 2 1) 1 (1 (2 3) 3))
'(1 (2 3) 3)
That is just one way of doing it, there are other ways of doing it, keep it up and tell us if it helped you.
As you see, I decomposed the big problem into little problems. This is a very handy way of doing your DrRacket homework.

Racket recursive function for returning the sum of a list of squared numbers

I am new to Racket, and I am trying to write a recursive function that takes a number n and returns the sum of the squares of the first n integers. For example, (this-function 3) returns 14 because 14 is 9 + 4 + 1 + 0.
I tried creating two separate functions, one that squares each number and returns a list of the squared numbers, and a second that sums up the list. The function the squares each number is:
(define (squared my-list)
(cond [(empty? my-list) empty]
[(zero? my-list) 0]
[else (cons (expt my-list 2)
(cons (squared (sub1 my-list)) empty))]))
which if I run (squared 3) returns (cons 9 (cons (cons 4 (cons (cons 1 (cons 0 empty)) empty)) empty)).
When I run the second function (the sum function):
(define (sum numbers)
(cond
[(empty? numbers) 0]
[else (+ (first numbers) (sum (rest numbers)))]))
and run (sum (squared 3)) I get an error message because (squared 3) returns an extra "cons" in the list.
How can I fix this?
Your logic in squared is a little bit off. I'll explain the issues clause-by-clause.
[(empty? my-list) empty]
This doesn't make any sense since my-list will never even be a list. In fact, my-list is poorly named. The parameter squared takes is a number, not a list. This clause can be completely removed.
[(zero? my-list) 0]
This is what the actual terminating case should be, but it shouldn't return 0. Remember, squared has to return a list, not a number. This case should return empty.
[else (cons (expt my-list 2)
(cons (squared (sub1 my-list)) empty))]))
Finally, this clause is far too complicated. You have the right idea—to cons the new number onto the rest of the list—but you're cons'ing too many times. Remember, the result of (squared (sub1 my-list)) is itself a list, and the second argument of cons is the rest of the list. You don't need the extra cons—you can just eliminate it completely.
Combining these changes, you get this, which does what you want:
(define (squared my-list)
(if (zero? my-list) empty
(cons (expt my-list 2)
(squared (sub1 my-list)))))
(I also replaced cond with if since cond is no longer necessary.)
That said, this code is not very Racket-y. You had a good idea to break up your function into two functions—in functional programming, functions should really only ever do one thing—but you can break this up further! Specifically, you can leverage Racket's built-in higher-order functions to make this type of thing extremely easy.
You can replace your entire squared function by appropriately combining map and range. For example, the following creates a list of the squares from 0–3.
(map (curryr expt 2) (range 4))
(You need to call (range 4) because the list generated by range goes from 0 to n-1.)
Next, you can easily sum a list using apply. To sum the above list, you'd do something like this:
(apply + (map (curryr expt 2) (range 4)))
That gives you the appropriate result of 14. Obviously, you could encapsulate this in its own function for clarity, but it's a lot clearer what the above code is doing once you learn Racket's functional constructs.
(However, I'm not sure if you're allowed to use those, since your question looks a lot like homework. Just noted for future reference and completeness.)
The most straightforward solution is to use the closed form:
(define (sum-of-squares n)
(* 1/6 n (+ n 1) (+ n n 1)))
Credit: WolframAlpha
one function for providing a list of squares and one function for summing up the list is not necessary.
This will do the trick, and is recursive as required.
(define (my-sq n)
(cond [(zero? n) 0]
[else
(+ (* n n) (my-sq (- n 1)))]))
(my-sq 3) -> 14

Scheme,level intermediate student, find min without recursion

How can I write a function using abstract list functions (foldr, map, and filter) without recursion that consumes a list of numbers (list a1 a2 a3 ...) and produces a new list removing the minimum number from the original list?
The recursion code is:
(define (find-min lst)
(cond
[(empty? (rest lst)) (first lst)]
[else
(local [(define min-rest (find-min (rest lst)))]
(cond
[(< (first lst) min-rest) (first lst)]
[else min-rest]))]))
A fold applies a 2-argument function against a given value and the car of a list uses the result against the successive cars or the cdrs or the list. this is what we want.
Whereas map returns a new list by doing something with each element of a list.
And filter returns a smaller or equal list based on some predicate.
Now just to formulate a function that can choose the lessor of two arguments
(define (the-lessor x y)
(if (< x y)
x
y))
From there implementation is straightforward.
(define (min L) (fold the-lessor (car L) (cdr L)))
Since this looks like a homework question, I'm not going to provide all the code, but hopefully push you in the right direction.
From the HTDP book, we see that "The Intermediate Student language adds local bindings and higher-order functions." The trick here is probably going to using "local bindings".
Some assumptions:
(remove-min-from-list '()) => not allowed: input list must be non-empty
(remove-min-from-list '(1)) => '()
(remove-min-from-list '(1 2 3 1 2 3)) => '(2 3 2 3) ; all instances of 1 were removed
Somehow, we need to find the minimum value of the list. Call this function min-of-list. What are its inputs and outputs? It's input is a list of numbers and its output is a number. Of the abstract list functions, which ones allow us to turn a list of numbers into a number? (And not another list.) This looks like foldl/foldr to me.
(define (min-of-list lst)
(foldr some-function some-base lst))
Since you already showed that you could write min-of-list recursively, let's move on. See #WorBlux's answer for hints there.
How would we use this in our next function remove-min-from-list? What are the inputs and outputs of remove-min-from-list? It takes a list of numbers and returns a list of numbers. Okay, that looks like map or filter. However, the input list is potentially shorter than that output list, so filter and not map.
(define (remove-min-from-list lst)
....
(filter some-predicate list))
What does some-predicate look like? It needs to return #f for the minimum value of the list.
Let's pull this all together and use local to write one function:
(define (remove-min-from-list lst)
(local [(define min-value ...)
(define (should-stay-in-list? number) ...min-value ...)]
(filter should-stay-in-list? lst)))
The key here, is that the definition for should-stay-in-list? can refer to min-value because min-value came before it in the local definitions block and that the filter later on can use should-stay-in-list? because it is in the body of the local.
(define (comparator n) (local [(define (compare v) (not (equal? v n)))] compare))
(define (without-min list) (filter (comparator (foldr min (foldr max 0 list) list)) list))

Resources