Racket - comparing/analyzing two structures - racket

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

Related

How to specify addition and subtraction in a function?

I'm making a function that adds or subtracts x and y from the original coordinates.This function accepts a command ("left", "right", "up", "down") an (x, y) position, and a non-negative distance and produces a new point moving according to the command and distance.It's like "left" x-num, "right" x+num, "down" y+num, "up" y-num. For example, if you start at (2, 3), the command "left" 1 should produce (1, 3), whereas "down" 2.2 would produce (2, 5.2). Each part might works, but how can I add them into one function.
This is my code:
(define POSN-0 (make-posn 5 5))
(define POSN-1 (make-posn 10 10))
(define POSN-2 (make-posn 20 20))
(define (shift-left p)
(make-posn (- (posn-x p) num)
(posn-y p)))
(define (shift-right p)
(make-posn (+ (posn-x p) num)
(posn-y p)))
(define (shift-up p)
(make-posn (posn-x p)
(- (posn-y p) num)))
(define (shift-down p)
(make-posn (posn-x p)
(+ (posn-y p) num)))
How can I add all this in one function? Also, how can I define the add/subtract number?
After your edit, it's a little bit more clear what do you want, so here is my try.
Anyway, when you work with specific language (BSL in this case), you should mention that in the question. This will lead to answers more useful to you.
And see also this similar question- it seems that you're both attendees of the same course, so I suggest you to join forces and next time, post one well-thought question and not two similar.
(define (shift command p dist)
(cond
((string=? command "left")
(make-posn (- (posn-x p) dist)
(posn-y p)))
((string=? command "right")
(make-posn (+ (posn-x p) dist)
(posn-y p)))
((string=? command "up")
(make-posn (posn-x p)
(- (posn-y p) dist)))
((string=? command "down")
(make-posn (posn-x p)
(+ (posn-y p) dist)))))
Examples:
> (define p0 (make-posn 2 3))
> (shift "left" p0 1)
(make-posn 1 3)
> (shift "down" p0 2.2)
(make-posn 2 5.2)
You most certainly can have multiple parameters to a given function, and indeed you can see this with such built-in functions as + and -, as well as in the constructor (make-point) (which takes the four parameters as currently defined).
Speaking of which, what are the xp and yp members of the point structure for? A point in 2-dimensional space only need two coordinates. What are the other two for? Also, the (define-struct) form is deprecated in favor of the (struct) form, but that's not really important here.
As for how you would implement the 'commands', assuming that you are referring to the (command-point) function, you would have a parameter for the operation, another for the distance to move, and a case analysis (e.g., a (cond) form, or series of (if) forms, or in this instance, a (case) form) switching on the given command. Something like the following (untested code, you'll probably need to make adjustments):
(define (command-point p cmd dist)
(case cmd
(`left (make-point (- (point-x1 p) 1) (point-y1 p) (point-xp p) (point-yp p)))
(`right (make-point (+ (point-x1 p) 1) (point-y1 p) (point-xp p) (point-yp p)))
(`fwd (make-point (point-x1 p) (- (point-y1 p) 1) (point-xp p) (point-yp p)))
(`back (make-point (point-x1 p) (+ (point-y1 p) 1) (point-xp p) (point-yp p)))))
Note that this doesn't change the point passed through p; it instead generates a new point structure.
I hope this is what you were looking for, as to be honest your question wasn't entirely clear.

Treating a part of program as data in Racket

I must say that I don't know really know how to call what I'm looking for, so perhaps the title isn't that accurate.
I have a program that plots some points. The generate-list function produces a list of n (x,y) coordinates and get-points produces another list that has every x (from (x,y)) divisible by n.
I can definitely call points how many times I need, but I'm trying to reduce the process by writing the points function only once).
#lang racket
(require plot)
(define (generate-list n)
(if (= n 0)
empty
(cons (list (random 0 100) (random 0 100))
(generate-list (- n 1)))))
(define (get-points lst n)
(if (empty? lst)
empty
(if (= (remainder (caar lst) n) 0)
(cons (car lst) (get-points (cdr lst) n))
(get-points (cdr lst) n))))
(plot (list
(axes 0 0)
(points (get-points (generate-list 1000) 2)
#:color 2)
(points (get-points (generate-list 1000) 3)
#:color 3)
(points (get-points (generate-list 1000) 4)
#:color 4)
(points (get-points (generate-list 1000) 5)
#:color 5)))
Bellow is an example that doesn't produce anything useful, but I'm looking for something that simplifies the code in a similar manner.
(plot (list
(axes 0 0)
(for ([i (in-range 2 5)])
(points (get-points (generate-list 1000) i)
#:color i))))
Of course any alternative that only writes the points function once would help a lot.
Try for/list instead of for there:
(plot (list
(axes 0 0)
(for/list ([i (in-range 2 5)])
(points (get-points (generate-list 1000) i)
#:color i))))
A for loop throws away the values the body-expression produces on each iteration, while the for/list loop puts them into a list, and returns the list so that all the points are included in the input to plot.
(By the way, this nested list is okay because plot allows a renderer-tree as input.)

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

Racket - arguments for procedure how to get all

I need to write procedure for calculation of weighted sum in follow functionality:
((weighted-sum 1) 5)
5
((weighted-sum 1/2 1/2) 3 1)
2
etc..
So far I did only how to get parameters for procedure:
(define (weighted-sum x . xn) (cons x xs))
(weighted-sum 2 3)
> '(2 3)
How to get ((weighted-sum 2 3) X X) parameters?
Thank you.
Your question doesn't have one easy answer. It sounds like you're supposed to write a function that accepts a sequence of weights, and returns a function that accepts a sequence of weights, and sums the products of the weights and the sums (by the way, stating this yourself would have been really helpful...).
1) Is this your design, or someone else's? I would not design this function this way.
2) You can write functions that return functions in a bunch of different ways. E.g.:
;; these all do the same thing.
;; they all have the type (number -> (number -> number))
(define a (lambda (x) (lambda (y) (+ x y))))
(define ((a x) y) (+ x y))
(define (a x)
(define (b y) (+ x y))
b)
So weighted-sum takes a variable number of values as parameters (let's call them ws) , and returns a new procedures that, in its turn, takes a variable number of parameters (vs) and does the calculation.
In racket, the for/fold construct comes in handy:
(define (weighted-sum . ws)
(lambda vs
(for/fold ((res 0)) ((i (in-list ws))
(j (in-list vs)))
(+ res (* i j)))))
or even
(define ((weighted-sum . ws) . vs)
(for/fold ((res 0)) ((i (in-list ws))
(j (in-list vs)))
(+ res (* i j))))
Alternatively, using a more classic foldl returning a named inner procedure:
(define (weighted-sum . ws)
(define (sub . vs)
(foldl
(lambda (i j res) (+ res (* i j)))
0
ws
vs))
sub)
For any of those:
> ((weighted-sum 1) 5)
5
> ((weighted-sum 1/2 1/2) 3 1)
2

Learning LISP - Defining a stdev function

I am very new to LISP (so forgive me for any dumb mistakes) and the first lab of the year states:
Define a function, STDEV that will compute the standard deviation of a list of numbers (look up formula)
I wrote this code but I don't know why it refuses to work:
(defun stdev (x)
(sqrt (/ (apply '+ (expt (- x (/ (apply '+ x)
(length x)))
2))
(length x))))
(setq a '(1 2 3 4 5))
(STDEV a)
But on runtime it produces the error:
(1 2 3 4 5) is not a number
I believe that I have correctly emulated the standard deviation formula (though I wouldn't put it past myself to make a dumb mistake), but why does my program not like the list of numbers that I give it to evaluate? It is most likely a simple mistake with inputs from this new style of coding but any and all help is greatly appreciated!
Use indentation. I've edited your question:
(defun stdev (x)
(sqrt (/ (apply '+ (expt (- x (/ (apply '+ x)
(length x)))
2))
(length x))))
expt returns a number. You call (apply '+ some-number)?
Also you subtract a number from a list.
Why?
Generally I would recommend to use a Lisp listener (aka REPL) to get to working code:
Compute the mean value:
CL-USER 21 > (let ((l (list 1 2 3 4 5)))
(/ (reduce #'+ l)
(length l)))
3
Subtract the mean value and square using mapcar:
CL-USER 22 > (mapcar (lambda (item)
(expt (- item 3) 2))
(list 1 2 3 4 5))
(4 1 0 1 4)
Compute the variance as the mean value of above:
CL-USER 23 > (let ((l (list 4 1 0 1 4)))
(/ (reduce #'+ l)
(length l)))
2
Take the square root to get the standard deviation:
CL-USER 24 > (sqrt 2)
1.4142135
Then you only need to assemble it into a few functions: average, variance and standard-deviation.
You’re taking - a ..., when a is your list.
Not a complete answer, because this is homework, but: you want to calculate the mean first, you can implement a sum function, which you will need twice, with a fold, and you can apply a helper function or lambda expression to every element of a list using a map.