Building a random list - racket

I am trying to write a function that takes in the length of a list and a maximum number value and returns a list that is the length given with numbers between 1 and the given max randomly.
so far I have
(define (randomlist n max)
(cond
[(= n 0)empty]
[else
(cons (build-list n (random 1 max))
(randomlist max (- n 1)))]))
I get an error when I run this and was wondering if anybody could help me out.

One can also use for/list to combine loop and list formation:
(define (randomlist n mx)
(for/list ((i n))
(add1 (random mx))))
Testing:
(randomlist 5 10)
Output:
'(5 9 10 4 7)
(random numbers, hence output is very likely to be different each time).

There are several bugs in your code:
It's a bad idea to call a parameter max, that clashes with a built-in procedure. So I renamed it to mx.
There's absolutely no reason to use build-list, that's not how we build an output list, just cons one element with the rest.
random receives zero or one parameters, not two. The single-parameter version returns an integer in the range 0..n-1, hence we have to add 1 to the result to be in the range 1..n.
You switched the order of the parameters when recursively calling randomlist.
This should take care of the problems:
(define (randomlist n mx)
(cond
[(= n 0) empty]
[else
(cons (+ 1 (random mx))
(randomlist (- n 1) mx))]))
It works as expected:
(randomlist 5 10)
=> '(10 7 1 4 8) ; results will vary, obviously

Related

Can anyone help me with a recursive function in racket?

I am writing a recursive function. But the question requires you not to use the exponential function. Can anyone show me how to get larger powers by multiplying smaller powers by a?
Input a=2 n=4. Then get[2, 4, 8, 16]
Input a=3 n=4. Then get[3 9 27 81].
I was trying to multiply a by a each time, so when I input 2 and 4. I get [2 4 16 256]. So what should I do?
Here is what I have written:
(define (input a n)
(if (= n 0)
'()
(append (cdr (list [* a a] a))
(let ((a (* a a)))
(input a (- n 1))))))
You are approaching the problem wrong, you really need two recursive functions (one to build the list and one to build each element). I am assuming you are allowed to use local, but if you aren't you could move that into a helper function.
(define (build-sqr-list a n)
(local [(define (sqr-recurse a n)
(if (= n 0)
1
(* a (sqr-recurse a (sub1 n)))))]
(if (= n 0)
'()
(cons (sqr-recurse a n) (build-sqr-list a (sub1 n))))))

DrRacket - Find Largest Number in a set

(for judges ([judge1 judge2 judge3 judge4 judge5 judge6 judge7 judge8])
(define i 0)
(define j 1)
(cond [(< judges[i] judges[j])
(cond [(equal? judges[j] judges(length))
(define highest-score judges[j])]
[else
(judges[i] judges[j])
(judges[j] judges[j +1])])]
[else
(cond [(equal? judges[i] judges[length -1])
(define highest-score judges[i])]
[else
(judges[j] judges[j +1])])]))
I want to be able to find the largest number in a set of values, which for this problem includes values from judge1, judge2... judge8. The way I'm trying to solve this problem is by taking the first two numbers on a list and comparing them; I can't seem to find much on DrRacket documentation on proper syntax for the type of operation I want to perform.
An easy way (in terms of writing code) to find the the maximum element is to sort the list, and grab the last element of that list. As #pdoherty926 mentioned, the easiest way to sort a list in Racket is with the sort function. You just give it a list and a comparitor, and it sorts the list for you:
> (sort '(5 2 6 1) <)
'(1 2 5 6)
And since you want the max value just grab the last element:
> (last (sort '(5 2 6 1) <))
6
Although if you want to find the maximum value of other (non-list) data structures, for is an attractive option. While your algorithm looks good, your syntax is off. In this particular case, I would actually recommend using for/fold. Basically, it lets you have an accumulator, which will hold your highest judge so far, as well as the list of judges you are iterating through, and the body for how you want to modify the accumulator. In this case, your loop will look something like:
;; A judge is a non-negative number
(define judges '(5 6 1 2))
(for/fold ([largest -1])
([j (in-list judges)])
...)
Where you replace the ... with the next value for largest. The entire loop evaluates to the final value for largest.
The interesting thing here is that j is an actual judge, not just an index to the judges list. So your body does not need to refer to the judges list at all. It should look something like:
(max j largest)
Since a judge is just a number. I will leave you to put the body in the loop as an exercise.
As an aside, since judges are just numbers, you can just use max directly with apply:
> (apply max '(5 6 1 2))
6
As one additional note, if for some reason you do want the actual index of the current judge you are examining, you can use in-naturals:
(for/fold ([largest -1])
([j (in-list judges)]
[index (in-naturals)])
...)
Following recursive function also works to find largest number in a list:
(define (largestnum slist)
(cond
((= (length slist) 2) ; if only 2 numbers, compare them
(if (> (car slist) (list-ref slist 1))
(car slist)
(list-ref slist 1)))
(else ; else recurse to compare car with largest of cdr
(let ((cdrLargest (largestnum (cdr slist))))
(if (> (car slist) cdrLargest)
(car slist)
cdrLargest)))))
(define judges '(5 6 1 2))
(largestnum judges)
Output:
6

Number Partitioning in R5RS

I was asked in an internship interview to do a R5RS program that creates a function, let's say two-subsets. This function has to return #t if the list L contains two subsets with equal sums of elements and with equal numbers of elements, otherwise it returns #f. It takes in entry the list L (only positive numbers) and some parameters (that I judge useful. There is no conditions on the number of parameters) all equal to 0 at the beginning.
The requirements as I still remember were as follow:
- Do not define other functions and call them inside the "two-subsets" function.
- It can only use the following constructs: null?, cond, car, cdr, else, + ,=, not, and, #t, #f, two-subsets (itself for recursive call), the names of the parameters, such as list, sum, ...etc, numeric constants and parentheses.
There were some given examples on the results that we are supposed to have, let's say:
(two-subsets '(7 7) 0 0 0) returns #t. The two subsets are {7} and {7}.
(two-subsets '(7 7 1) 0 0) returns #t. The two subsets are {7} and {7}.
(two-subsets '(5 3 2 4) 0 0) returns #t. The two subsets are {2, 5} and {3, 4}.
(two-subsets '(1 2 3 6 9) 0 0) returns #f.
I started by writing the signature that it looks to me it should be something like this:
(define two-subsets (lambda (L m n ... other parameters)
(cond
The problem is really complicated and it's complexity is obviously more than O(n), I read on it on https://en.wikipedia.org/wiki/Partition_problem .
I tried to start by defining the algorithm first before coding it. I thought about taking as parameters: sum of the list L so in my conditions I'll iterate only on the combinations which sum is <= sum(L)/2. By doing that I can reduce a little bit the complexity of the problem, but still I couldn't figure out how to do it.
It looks like an interesting problem and I really want to know more about it.
Here is a version which does not depend on the numbers being all positive. I am reasonably sure that, by knowing they are, you can do much better than this.
Note this assumes that:
the partition does not need to be exhaustive;
but the sets must not be empty.
I'd be very interested to see a version which relies on the elements of the list being +ve!
(define (two-subsets? l sl sld ssd)
;; l is the list we want to partition
;; sl is how many elements we have eaten from it so far
;; sld is the length difference in the partitions
;; ssd is the sum difference in the partitions
(cond [(and (not (= sl 0))
(= sld 0)
(= ssd 0))
;; we have eaten some elements, the differences are zero
;; we are done.
#t]
[(null? l)
;; out of l, failed
#f]
;; this is where I am sure we could be clever about the set containing
;; only positive numbers, but I am too lazy to think
[(two-subsets? (cdr l)
(+ sl 1)
(+ sld 1)
(+ ssd (car l)))
;; the left-hand set worked
#t]
[(two-subsets? (cdr l)
(+ sl 1)
(- sld 1)
(- ssd (car l)))
;; the right-hand set worked
#t]
[else
;; finally drop the first element of l and try the others
(two-subsets? (cdr l) sl sld ssd)]))

Racket function that returns all numbers whose sum is <= given number?

I'm taking an intro to computer science course and one question needs me to write a function that takes a list of numbers and a number and returns the numbers in the list whose sum is less than the given number. I've written the function signature, definition, and check-expects, but I'm stuck. The function needs to assume intermediate student with lambda. I don't want any direct answers here; just help so that I can reach the answer myself.
I know it needs to use recursion. Perhaps a helper function would be needed.
;; sum-up-to: lon, number -> lon
;; consumes a list of numbers and a number and
;; returns the numbers in the list whose sum is
;; less than or equal to the given number
(define the-numbers (list 1 2 3 4 5 6 7 8 9))
(check-expect (sum-up-to the-numbers 7) (list 1 2 3))
(check-expect (sum-up-to the-numbers 18) (list 1 2 3 4 5))
(check-expect (sum-up-to the-numbers 45) the-numbers)
This problem can be simplified if we sort the list first and if we define a helper function that keeps track of the accumulated sum. Here's a skeleton, fill-in the blanks with the missing expressions and you'll have the solution:
(define (sum-up-to lst n)
(helper <???> n 0)) ; sort the input list, pass it to the helper
(define (helper lst n sum)
(cond (<???> '()) ; if the list is empty, end the recursion
((> <???> n) '()) ; also end recursion if sum + current element > n
(else
(cons <???> ; otherwise cons current element
(helper <???> ; advance recursion over list
n
(+ <???> <???>)))))) ; update sum
Following recursive method keeps adding numbers from the list sequentially to an initially empty outlist, till the sum is reached:
(define the-numbers (list 1 2 3 4 5 6 7 8 9))
(define (f lst sum)
(let loop ((lst lst)
(ol '()))
(if (or (..ENTER CONDITION FOR EMPTY LIST..)
(..ENTER CONDITION WHEN SUM IS REACHED..)
(..ENTER HOW TO PUT THE NEW LIST OUT..)
(loop (..ENTER ARGUMENTS TO BE SENT TO NEXT LOOP..)
))))
(f the-numbers 7)
(f the-numbers 18)
(f the-numbers 45)
Output:
'(1 2 3)
'(1 2 3 4 5)
'(1 2 3 4 5 6 7 8 9)

Lisp, sub total of a numbers in a nested list

i have a problem that i just cant work out,
the user enters a list ie
(total-cost
'((anItem 2 0.01)
(item 3 0.10)
(anotherItem 4 4.10)
(item 5 2.51)))
i need to add the number on the end together and then return the result
my current code returns the code after each addition. and also throws a error about unexpected type
(defun total-cost (list)
(loop with sum = 0
for x in list
collect (setf sum (+ sum (last x)))
)
)
Error: (0.01)' is not of the expected typeNUMBER'
Any help is appreciated
Thanks Dale
Using LOOP:
CL-USER 19 > (loop for (nil nil number) in '((anItem 2 0.01)
(item 3 0.10)
(anotherItem 4 4.10)
(item 5 2.51))
sum number)
6.72
REDUCE is another option:
CL-USER 20 > (reduce '+
'((anItem 2 0.01)
(item 3 0.10)
(anotherItem 4 4.10)
(item 5 2.51))
:key 'third)
6.72
Loop has a keyword sum for summing so you don't have to have an explicit variable nor use setf:
(defun total-cost (list)
(loop for x in list sum (third x)))
As Chris said, use (car (last x)) if the number you're looking for is always the last one. Or you can use (third x) as in my example if it's always the third one.
Also, note that the use of collectis wrong if your aim is to return the sum only; your example (corrected) returns
(0.01 0.11 4.21 6.7200003)
whereas mine returns
6.7200003
Note that if you want so escape the rounding errors as much as possible you need to use an exponent marker to make them double-floats for example:
(total-cost '((anItem 2 0.01D0)
(item 3 0.10D0)
(anotherItem 4 4.10D0)
(item 5 2.51D0)))
=> 6.72D0
last returns the last cons cell in the list, not its value. You need to use (car (last x)) instead.
Just in case you want the code to give you a precise result rather then being short:
(defun kahan-sum (floats)
(loop
:with sum := 0.0 :and error := 0.0
:for float :in floats
:for epsilon := (- float error)
:for corrected-sum := (+ sum epsilon) :do
(setf error (- corrected-sum sum epsilon) sum corrected-sum)
:finally (return sum)))
(defun naive-sum (floats) (loop :for float :in floats :sum float))
(let ((floats (loop :repeat 1000 :collect (- (random 1000000.0) 1000000.0))))
(format t "~&naive sum: ~f, kahan sum: ~f" (naive-sum floats) (kahan-sum floats)))
;; naive sum: -498127420.0, kahan sum: -498127600.0
Read more about why it works like this here: http://en.wikipedia.org/wiki/Kahan_summation_algorithm
Coming late to the party... How about a little lisping instead of looping? ;-)
(defun sum-3rd (xs)
(let ((sum 0))
(dolist (x xs sum)
(incf sum (nth 2 x)))))