Some calculation error in racket programing language [closed] - functional-programming

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 2 days ago.
Improve this question
I have written the following code to calculate the total rectangular area
(define (make-rect x0 y0 x1 y1)
(list x0 y0 x1 y1))
(define (union-rect rect-list)
(let ((x0 (apply min (map rect-x0 rect-list)))
(y0 (apply min (map rect-y0 rect-list)))
(x1 (apply max (map rect-x1 rect-list)))
(y1 (apply max (map rect-y1 rect-list))))
(make-rect x0 y0 x1 y1)))
(define (total-rect-area rect-list)
(if (= (length rect-list) 1)
(rect-area (car rect-list))
(let ((intersects (rect-list-intersect rect-list)))
(if (or (= (rect-x0 intersects) (rect-x1 intersects))
(= (rect-y0 intersects) (rect-y1 intersects)))
0
(let ((subsets (cdr (power-set intersects))))
(if (= (length subsets) 1)
(rect-area (car subsets))
(let ((areas (map (lambda (subset)
(rect-area (union-rect subset)))
subsets)))
(let ((signs (map (lambda (k)
(if (even? k) 1 -1))
(range (length subsets)))))
(* 1/2 (apply + (map * areas signs)))))))))))
and when give input as
(total-rect-area '((rect 1 1 4 4) (rect 3 3 6 6) (rect 2 2 3 7)))
it gives output as 0 but the thing is my desired output is 20 can anybody help me to find the exact error.

Related

How to plot a matrix as an image in racket?

I would like to do something similar to matplotlib.pyplot.matshow with racket. I understand this is a trivial question and maybe I'm just being stupid, but I was unsuccessful after reading the Racket plotting documentation.
An example matrix that would be translated into the image of a circle:
#lang typed/racket
(require math/array)
(require plot)
(: sq (-> Integer Integer))
(define (sq [v : Integer])
(* v v))
(: make-2d-matrix (-> Integer Integer (Array Boolean)))
(define (make-2d-matrix [s : Integer] [r : Integer])
(let ([center : Integer (exact-round (/ s 2))])
(let ([a (indexes-array ((inst vector Integer) s s))])
(let ([b (inline-array-map (λ ([i : (Vectorof Index)])
(+
(sq (- (vector-ref i 0) center))
(sq (- (vector-ref i 1) center))))
a)])
(array<= b (array (sq r)))
))))
(array-map (λ ([i : Boolean]) (if (eq? i #f) 0 1)) (make-2d-matrix 20 6))
Can someone give me a hint?
Totally not a dumb question. This is one of those areas where it's hard to compete with an army of python library programmers. Here's how I'd do it in Racket:
#lang racket
(require 2htdp/image
math/array)
;; a 10x10 array
(define a
(build-array #(10 10)
(λ (e)
(match e
[(vector x y)
(cond [(= x y) x]
[else 0])]))))
;; map a value to a color
(define (cmap v)
(color (floor (* 255 (/ v 10)))
0
(floor (* 255 (- 1 (/ v 10))))))
(apply
above
(for/list ([y (in-range 10)])
(apply
beside
(for/list ([x (in-range 10)])
(rectangle 10 10 'solid (cmap (array-ref a (vector x y))))))))
Depending on you situation, you might be interested in flomaps:
http://docs.racket-lang.org/images/flomap_title.html?q=flbitmap
I'm not sure exactly what you want to plot. The plot library is designed around plotting functions, but I don't know what function you want to express.
Here are two ways of plotting a matrix:
(plot (points (cast (array->vector* m) (Vectorof (Vectorof Real)))
(plot3d (points3d (cast (array->vector* m) (Vectorof (Vectorof Real)))
The cast is needed because the type of array->vector* is not specific enough.

Need help finding second largest number in a list. Racket [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 5 years ago.
Improve this question
I've been struggling with this question for a lot now. Could someone please explain the logic behind the program by using the simplest way possible possibly recursion?
Thank you.
Have 2 variables (say x and y)
Move through the list of numbers
Keep largest in x and previous largest (previous x value) in y
At end return y value.
Remember to compare each value to current values of both x and y.
I have tested it and it works but I am sure you want to code it yourself. Take care to choose the starting values of x and y.
Edit
With reference to discussion in comments (using -inf.0 as initial value as in answer by #naomik) :
(define steps 0)
(define (gt x y)
(set! steps (add1 steps))
(> x y))
(define (lt x y)
(set! steps (add1 steps))
(< x y))
(define (2ndLargest L)
(let loop ((x -inf.0) ; largest
(y -inf.0) ; second largest
(L L))
(cond
[(empty? L)
(printf "steps=~a;~n" steps)
y]
[(or (= (first L) x)(= (first L) y))
(loop x y (rest L))]
[(gt (first L) x)
(loop (first L) x (rest L))]
[(gt (first L) y)
(loop x (first L) (rest L))]
[else
(loop x y (rest L))]
)))
(define (2ndLargest2 L)
(let loop ((x -inf.0) ; largest
(y -inf.0) ; second largest
(L L))
(cond
[(empty? L)
(printf "steps=~a;~n" steps)
y]
[(or (= (first L) x)(= (first L) y))
(loop x y (rest L))]
[(lt (first L) y) ; FIRST CHECK IF LESS THAN Y;
(loop x y (rest L))]
[(gt (first L) x)
(loop (first L) x (rest L))]
[(gt (first L) y)
(loop x (first L) (rest L))]
)))
(define L '(8 3 4 5 6 2 7 3 10 12 -1 11))
(2ndLargest L)
(2ndLargest2 L)
(set! L '(11 8 3 4 5 6 2 7 3 10 -1 12))
(2ndLargest L)
(2ndLargest2 L)
(set! L '(8 3 4 5 6 11 7 3 10 12 -1))
(2ndLargest L)
(2ndLargest2 L)
Output:
steps=21;
11
steps=48;
11
steps=70;
11
steps=88;
11
steps=107;
11
steps=131;
11
Steps are more if current is checked to be if less than y first.
I took a swing at this using foldl – It works similarly to mso's answer by keeping track of the two (distinct) highest numbers in the list using an accumulator (cons x1 x2), where x1 is the highest and x2 is the second highest
This answer will return -inf.0 for an input of an empty list or an input of a single-number list
#lang racket
(define (second-largest xs)
(cdr (foldl (lambda (y acc)
(let ((x1 (car acc))
(x2 (cdr acc)))
(cond ((> y x1) (cons y x1))
((= y x1) (cons y x2))
((> y x2) (cons x1 y))
(else (cons x1 x2)))))
(cons -inf.0 -inf.0)
xs)))
(second-largest '(8 3 4 5 6 2 12 7 3 10 12 -1 11))
;; => 11

Find main diagonal in matrix - Scheme

I need to extract the main diagonal from a square matrix
(1 2 3)
(4 5 6) -> (1 5 9)
(7 8 9)
I have the following code and I need to replace the ... with the appropriate functions.
(define (diag m)
(if (null? m) '()
(cons (... m)
(diag (map ... (... m))))))
Input: (diag '((1 2 3) (4 5 6) (7 8 9)))
Output: (1 5 9)
Any ideas? Thank you!
First of all I created a function that returns n-th element of list (I am not sure if you can use built-in function for it, that's why I created my own bicycle):
(define (nthItem l item currentItem)
(if (null? l) '()
(if (= currentItem item) (car l)
(nthItem (cdr l) item (+ currentItem 1)))))
Then I created a function that you need. I added a parameter "i" that contains current position on a diagonal:
(define (diagPrivate m i)
(if (null? m) '()
(cons (nthItem (car m) i 0)
(diagPrivate (cdr m) (+ i 1)))))
For better appearance I created a wrapper for this function (that looks like your initial function):
(define (diag m)
(diagPrivate m 0))
So you are asking, given you have the list '((1 2 3) (4 5 6) (7 8 9)) how do I get the value 1 from it?
Then you are asking given the same list, how do I get ((4 5 6) (7 8 9)) from it.
Then given that result how do I make a new list using map that only takes the rest of each element list so that the result is ((5 6) (8 9))
The question code looks like came from SO as an answer with VERY easy challenge on how to complete it. Am I right?
The answer is of course just list accessors every beginner schemer should know: cdr x 2 and caar, not necessarily in that order.
Using Racket which is a Scheme dialect:
(define diag '((1 2 3) (4 5 6) (7 8 9)))
(define (getDiagonal l)
(let loop ((l l)
(ol '())
(n 0))
(cond
[(empty? l) (reverse ol)]
[(loop (rest l)
(cons (list-ref (first l) n) ol)
(add1 n))])))
(getDiagonal diag)
Output:
'(1 5 9)
There is for/list loop in Racket which also can be used here:
(for/list ((i (length diag)))
(list-ref (list-ref diag i) i))

Generating a list of all possible combinations of true or false for n given variables in LISP

I want to define a function that takes an input "n" (the number of variables) and return all possible truth values. Here, I represent the truth values for a variable i (1 <= i <= n) with +i representing true, and -i representing false.
For example:
(generate-values 2)
should return:
((2 1)(2 -1)(-2 1)(-2 -1))
(generate-values 3)
should return:
((3 2 1)(3 2 -1)(3 -2 1)(3 -2 -1)(-3 2 1)(-3 2 -1)(-3 -2 1)(-3 -2 -1))
Here is my incorrect attempt:
(defun generate-values (n)
(cond
((equal n 0) nil)
(t (list (cons n (generate-values (- n 1)))
(cons (- 0 n) (generate-values (- n 1)))))))
I know why this is incorrect, but I am not able to find a way to generate (3 2 1) and then move on to (3 2 -1). My program outputs:
((3 (2 (1) (-1)) (-2 (1) (-1))) (-3 (2 (1) (-1)) (-2 (1) (-1))))
Any help with this question qould be thoroughly appreciated! Thanks!
It might be easiest to approach this in the easiest way possible, and then to figure out how to make it a bit simpler or more efficient afterward.
If you're doing this recursively, it's important to consider what the bases cases are. A reasonable base case here is probably when n = 0. The function is always supposed to return a list of lists. In the n = 0 case, there are no "variables", so the result has to be a list of the empty list: (()).
For the case that n is anything else, consider what the function returns for n-1. It's a list of all the combinations on n-1 "variables". All you need to do is prepend n to each of those, and prepend -n to each of those, and then make sure you end up with a list of all of those.
Encoding that directly, we end up with something like this:
(defun table (n)
(if (zerop n)
'(())
(let* ((table (table (1- n)))
(plus-pos-n (mapcar (lambda (subtable)
(list* n subtable))
table))
(plus-neg-n (mapcar (lambda (subtable)
(list* (- n) subtable))
table)))
(nconc plus-pos-n plus-neg-n))))
CL-USER> (table 3)
((3 2 1) (3 2 -1) (3 -2 1) (3 -2 -1) (-3 2 1) (-3 2 -1) (-3 -2 1) (-3 -2 -1))
Now, let's look at what your current implementation is doing differently, noting that it doesn't have to be exactly the same algorithm, of course.
(defun generate-values (n)
(cond
((equal n 0)
nil)
(t
(list (cons n
(generate-values (- n 1)))
(cons (- 0 n)
(generate-values (- n 1)))))))
Stylistically, since there are only two branches, I'd prefer if to cond here, but that's not a problem. Before attacking the base case, lets look at the recursive case, when n ≠ 0. First, you're calling generate-values twice; it would be more efficient to call it once and save the result. That could end up being important later if you're calling this function with big values of n, but it doesn't make the function incorrect. But remember what generate-values returns; it returns a list of the different combinations. That means that your call to (cons n (generate-values …)) is returning a list whose first element is n, and whose remaining elements are the combinations for n-1. E.g., you're doing something like:
CL-USER> (table 1)
((1) (-1))
CL-USER> (cons 2 (table 1))
(2 (1) (-1))
But that's not what you want. You really want to add n to each of those lists:
CL-USER> (mapcar (lambda (x)
(cons 2 x))
(table 1))
((2 1) (2 -1))
That's the issue in the recursive case. There's an issue in the base case, too. In the recursive case, you want to add n and -n to each of the sublists from the n-1 case. So what happens when you have n = 1? You want to be getting (cons 1 '()) and (cons -1 '()). But since the second argument to cons is going to be each list inside of the result of (generate-values 0), you really need to have something in the list returned by (generate-values 0). What needs to be there? The empty list needs to be there. So the base case needs to return (()), not (). So, after making those changes, your code would be:
(defun generate-values (n)
(cond
((equal n 0)
'(()))
(t
(list (mapcar (lambda (x)
(cons n x))
(generate-values (- n 1)))
(mapcar (lambda (x)
(cons (- 0 n) x))
(generate-values (- n 1)))))))
CL-USER> (generate-values 3)
(((3 (2 (1)) (2 (-1))) (3 (-2 (1)) (-2 (-1))))
((-3 (2 (1)) (2 (-1))) (-3 (-2 (1)) (-2 (-1)))))
That's closer, but it's still not quite right. There's another in the recursive case. You end up generating the values that have n in the beginning (a list of them), and the values that have -n in the beginning (a list of them), but then you're using list to combine them. That returns a single list with two values. Instead, you want a single list that has the values from each of them. You want to combine them with append (or, since all the structure is newly generated, you could use nconc):
(defun generate-values (n)
(cond
((equal n 0)
'(()))
(t
(append (mapcar (lambda (x)
(cons n x))
(generate-values (- n 1)))
(mapcar (lambda (x)
(cons (- 0 n) x))
(generate-values (- n 1)))))))
CL-USER> (generate-values 3)
((3 2 1) (3 2 -1) (3 -2 1) (3 -2 -1) (-3 2 1) (-3 2 -1) (-3 -2 1) (-3 -2 -1))
This final implementation isn't exactly what I started with, but it's essentially the same in terms of the algorithm. The differences are mostly stylistic, but there are some efficiency concerns, too. Using nconc instead of append would save some memory, and it really would be good to cache the results from the recursive call, rather than recomputing it. Stylistic issues that don't affect correctness might be using if instead of cond, using list* instead of cons (to indicate that we're working with lists, not trees of cons cells), and it's nice to note that you don't have to do (- 0 n), - with a single argument returns the argument's negation. That is, (- n) = -n.

Idiomatic clojure for ith and i+1th element looping

I have been trying to think how to implement an algorithm to compute the winding number of a polygon with respect to a point. Currently the implementation is as follows: (note updated so code works)
(defn winding-num
"Return winding number of polygon
see Alciatore "
[poly point]
; translate poly such that point is at origin
(let [translated-poly (map #(vec-f - % point) poly)]
; w is wind-num
(loop [vertices translated-poly w 0]
(cond
(= (count vertices) 1)
w
:else
(let [x1 (first (first vertices))
x2 (first (second vertices))
y1 (second (first vertices))
y2 (second (second vertices))]
(cond
(and (< (* y1 y2) 0)
(> (+ x1 (/ (* y1 (- x2 x1))
(- y1 y2)))
0))
(if (< y1 0)
(recur (rest vertices) (inc w))
(recur (rest vertices) (dec w)))
(and (zero? y1)
(> x1 0))
(if (> y2 0)
(recur (rest vertices) (+ w 0.5))
(recur (rest vertices) (- w 0.5)))
(and (zero? y2)
(> x2 0))
(if (< y1 0)
(recur (rest vertices) (+ w 0.5))
(recur (rest vertices) (- w 0.5)))
:else
(recur (rest vertices) w)))))))
My problems with this are
People say it's preferable when possible to use looping constructs which operate at a higher level than explicit recursion; for instance map, for, reduce, etc.
The rest function converts the vector into a list
I could think of an implementation using for and indices, but I also hear it is preferable to not use indices.
Is there an idiomatic way for dealing with vector algorithms which in each iteration need access to consecutive values?
In general if you want to access consecutive values of a sequence, two at a time, you can use the partition function. Partition allows you to specify a group size as well as a step size:
user> (partition 2 1 (range 10))
((0 1) (1 2) (2 3) (3 4) (4 5) (5 6) (6 7) (7 8) (8 9))
It really depends on the shape of your algorithm. Generally speaking higher-level constructs are more understandable than explicit recursion, but sometimes the shape of the problem makes this less clear.
Other things to note:
rest returns a sequence, not a list. This shouldn't matter here.
You should make use of destructuring. For example:
(let [x1 (first (first vertices))
x2 (first (second vertices))
y1 (second (first vertices))
y2 (second (second vertices))
This can be replaced by:
(let [[x1 y1] [x2 y2]] vertices] ... )
However this is not a very difficult algorithm to implement with reduce:
(defn inc-dec
"Convenience function for incrementing and decrementing"
([condition i] (if condition (inc i) (dec i)))
([condition i amount] (if condition (+ i amount) (- i amount))))
(defn winding-num
[poly point]
(let [translated-poly (map #(map - % point) poly)
winding-reducer
(fn winding-reducer [w [[x1 y1] [x2 y2]]]
(cond
(and (< (* y1 y2) 0)
; r
(> (+ x1 (/ (* y1 (- x2 x1))
(- y1 y2)))
0))
(inc-dec (< y1 0) w)
(and (zero? y1) (> x1 0))
(inc-dec (> y2 0) w 0.5)
(and (zero? y2) (> x2 0))
(inc-dec (< y1 0) w 0.5)
:else w))
]
(reduce winding-reducer 0 (partition 2 1 translated-poly))))
The following code is using (map func seq (rest seq)) to handle the pair of points used by the algorithm. It also fixes two problems with the original implementation:
It works whether or not the polygon is specified by repeating the first point as the last, i.e. giving the same result for both
[[1 1][-1 1][-1 -1][1 -1]] and
[[1 1][-1 1][-1 -1][1 -1][1 1]]
It also works for polygons that have successive points on the positive x-axis, whereas the original (and the refered pseudo code) will substract 1/2for each line segment along the x-axis.
(defn translate [vec point]
(map (fn [p] (map - p point)) vec))
(defn sign [x]
(cond (or (not (number? x)) (zero? x)) 0
(pos? x) 1
:else -1))
(defn winding-number [polygon point]
(let [polygon (translate (conj polygon (first polygon)) point)]
(reduce +
(map (fn [[x1 y1][x2 y2]]
(cond (and (neg? (* y1 y2))
(pos? (- x2 (* y2 (/ (- x2 x1) (- y2 y1))))))
(sign y2)
(and (zero? y1) (pos? x1))
(sign y2)
(and (zero? y2) (pos? x2))
(sign y1)
:else 0))
polygon (rest polygon)))))

Resources