How to filter random number generator and not include 0 - racket

How do I fix the random: expects (or/c (integer-in 1 4294967087) pseudo-random-generator?) or a pseudo-random-generator, given 0 error?
(require 2htdp/universe)
(require 2htdp/image)
(define-struct sample(x))
(define BACKGROUND (empty-scene 100 100))
(define CIRCLE (ellipse 10 10 "solid" "red"))
(define (rand d)
(random d))
(define (randoll d)
(cond [(even? (rand d))(rand d)]
[(< (rand d) 6)7]
[(= (rand d) 0)7]
[else 7]))
(define (main ws)
(big-bang ws
(on-tick randoll)
(to-draw render)))
(define (render d)
(place-image CIRCLE (randoll d) 6 BACKGROUND))
(main 100)
random: expects (or/c (integer-in 1 4294967087) pseudo-random-generator?) or a pseudo-random-generator, given 0
Was expecting for it to continuously changing places at even numbers but this happened

How about adding 1 to the parameter passed to random? as long as the input is >= 0 it'll work fine - the error you're receiving is simply stating that you can't pass 0 as parameter to random:
(define (rand d)
(random (+ d 1)))
By the way, randoll doesn't look right. Why do you test if the random value is even, just to return another random value, which we don't know if it's going to be even? And it appears that if the random value is zero or in all the other cases you just want to return 7. Better try this, if it fits what you intended:
(define (randoll d)
(let ([r (rand d)]) ; call `rand` exactly once
(cond [(zero? r) 7] ; 0 is even, so check this first
[(even? r) r] ; return `r` only if it's even
[else 7]))) ; default case
I'm not sure what's the expected range of values for randoll, but it looks to me that most of the time it'll just return 7. Is this what you want?

Related

Building a random list

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

Function not assigning values in Racket

Why following function (match-redefine) is not working?
(define vlist (list 10 20 30))
(match-define (list aa bb cc) (list 1 2 3))
(define alist (list aa bb cc))
alist
vlist
(define (match-redefine dst_list src_list)
(for ((d dst_list)(s src_list)) (set! d s)) )
(rnmatch-redefine alist vlist)
alist
vlist
The output is:
'(1 2 3)
'(10 20 30)
'(1 2 3)
'(10 20 30)
The destination list (alist) remains unchanged. Can this function be made to work?
Edit: I tried vector as suggested by #OscarLopez in the answers, but it does not work:
(match-define (list a b c) (list 0 0 0 ) )
(define variable_vect (vector a b c))
a
b
c
(define valuelist (list 1 2 3) )
(for ((i variable_vect)(j valuelist)) ; does not work
(set! i j))
variable_vect
a
b
c
(set! variable_vect valuelist)
(println "------- after ----------")
variable_vect
a
b
c
Output is:
0
0
0
'#(0 0 0)
0
0
0
"------- after ----------"
'(1 2 3)
0
0
0
Edit: It seems I will have to use special class to apply this:
(define myob%
(class object%
(super-new)
(init-field val)
(define/public (getval) val)
(define/public (setval v) (set! val v)) ))
(define (copyvalues objlist valuelist)
(for ((a alist)(v valuelist)) (send a setval v)) )
(define (show_objlist alist)
(for ((a alist)) (println (send a getval))) )
; USED AS FOLLOWS:
(define ob1 (make-object myob% 5))
(define ob2 (make-object myob% 5))
(define ob3 (make-object myob% 5))
(define alist (list ob1 ob2 ob3))
(println "---------- first assignment -----------")
(define vlist (list 1 2 3))
(copyvalues alist vlist)
(show_objlist alist)
(println "---------- second assignment -----------")
(define ylist (list 10 20 30))
(copyvalues alist ylist)
(show_objlist alist)
(println "---------- individual access -----------")
(send ob1 getval)
(send ob3 getval)
Output is:
"---------- first assignment -----------"
1
2
3
"---------- second assignment -----------"
10
20
30
"---------- individual access -----------"
10
30
You ask why the function is not working.
The reason is that (set! d s) is doing something
you do not expect.
Observe:
#lang racket
(define vlist (list 10 20 30))
(match-define (list aa bb cc) (list 1 2 3))
(define alist (list aa bb cc))
alist
vlist
(define (match-redefine dst_list src_list)
(for ((d dst_list)(s src_list))
(set! d s)
(displayln (~a "d is now: " s))))
(match-redefine alist vlist)
The output is:
'(1 2 3)
'(10 20 30)
d is now: 10
d is now: 20
d is now: 30
This means that you change the value of d (not the value of the variable which corresponds to the symbols that d runs through.
See your previous question on the same topic.
Again, this is not the way we do things in Scheme. Besides, your code is simply reassigning a local variable that was pointing to an element in the list, the destination list remains unmodified.
You could use vectors instead of lists - those can be modified, exactly as you would modify an array in the most common programming languages, something like this:
(define value_list (list 1 2 3))
(define value_vect (vector 0 0 0))
value_vect
=> '#(0 0 0)
(for [(i (in-range (vector-length value_vect)))
(value value_list)]
(vector-set! value_vect i value))
value_vect
=> '#(1 2 3)
Anyway you should not modify a list of variables, just return a list with the new values. And don't think about mutating the list - although it is possible to do so using mutable pairs, that's not the correct way to deal with this situation, please stop thinking about mutating everything you encounter!

Pretty printing 2d array in racket

How to pretty print the contents of the 2d array b?
The code below only returns:
#<array:srfi-9-record-type-descriptor>
(require srfi/25)
(require racket/pretty)
(define (board x y)
(make-array (shape 0 x 0 y) 0))
(define b (board 7 7))
(pretty-print b)
also tried:
(array-map (lambda (n) (print n)) b) ...(i'm trying to mark this as code but it doesn't work)
but it returns:
0000000000000000000000000000000000000000000000000
is there any way for the print to insert a new line every x characters?
You can try rolling your own pretty-printing procedure, give this a try:
(define (pretty-print board)
(for ((i (in-range (array-length board 0))))
(for ((j (in-range (array-length board 1))))
(printf "~a\t" (array-ref board i j)))
(newline)))
For example:
(pretty-print (board 3 3))
0 0 0
0 0 0
0 0 0

Racket - comparing/analyzing two structures

So I have an assignment with the following criteria:
The definition of a function named euclidean-distance is given. This function computes the distance between two points in the xy-plane. The points are given as four separate numbers: x1, y1, x2, and y2.
Rewrite the function so that it takes two arguments, both of which are of type Posn, and run the same computation.
> (define the-origin (make-posn 0 0))
> (define some-point (make-posn 3 7))
> (euclidean-distance the-origin some-point)
#i7.615773105863909
> (euclidean-distance (make-posn 1 1) (make-posn 4 5))
5
My trouble here is that I'm not sure how to extract the information I need in order to compare square the differences and such. What I have so far:
(define (euclidean-distance posn1 posn2)
(sqrt (+ (sqr (- posn1-x posn2-x))
(sqr (- posn1-y posn2-y)))))
Not sure how to go about what I need to do.
Just use the accessor procedures of each position, like this:
(define (euclidean-distance posn1 posn2)
(sqrt (+ (sqr (- (posn-x posn1) (posn-x posn2)))
(sqr (- (posn-y posn1) (posn-y posn2))))))

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)))))