Perform arithmetic operation based on 2 numbers and 1 operator - racket

(define (perform-op m n opt)
(cond
((eqv? opt #\+)(+ m n))
((eqv? opt #\-)(- m n))
)
)
This is a snippet of the function. m and n are integers, while opt is the operator (which is + or - in this case). Is this right? I am new to rackets.

Your function works, if you call it like this:
> (perform-op 1 2 #\+)
3
> (perform-op 1 2 #\-)
-1
If you expect only two operations (in this case, #\+ and #\-), you can simplify that code:
(define (perform-op m n opt)
(if (eqv? opt #\+)
(+ m n)
(- m n)))
If you want to call your function like this: (perform-op 1 2 +) (note that + is symbol here, not character), you can simply write:
(define (perform-op m n opt)
(opt m n))
and call:
> (perform-op 1 2 +)
3

Related

Racket Programming ;Write a recursive function to compute the summation sum( x^2, x=1..n

;Write a recursive function to compute the summation sum( x^2, x=1..n)
;You must write a recursive function.
;If you use any iterative commands (for/loop/sum/etc you will receive a 0)
I'm stuck on this
(define (expo base x)
(cond ((or (= base 1) (= x 0)) 1)
(else (* base (expo base (- x 1)))))
I wrote this but its not right
Your code is working but is only missing a bracket at the end. You will see an error expected a ) to close ( possible cause: indentation suggests a missing ) when you are missing a bracket.
If n equal 5. You want see this: 1^2 + 2^2 + 3^2 + 4^2 + 5^2 = 55
#lang racket
(define (summation from-n to-n fn)
(local [(define (aux n)
(if (< n from-n)
0
(+ (fn n) (aux (- n 1)))))]
(aux to-n)))
(define (1^2+2^2+3^2+...+n^2 n)
(summation 1 n sqr))
(define (1+2+3+...+n n)
(summation 1 n identity))
;;; TEST
(1+2+3+...+n 100) ; 5050
(1^2+2^2+3^2+...+n^2 5) ; 55

Iterative decompose-as-sum-of-squares in Racket

I already tried this problem multiple times but can't seen to get it right. I want to write an iterative procedure decompose-as-sum-of-squares which inputs a positive integer n and outputs the first integer p such that p^2 + q^2 = n, where q^2 = (n - p^2), and neither p nor n - p^2 is 1. If such p does not exist, the function should return n.
A sample output is (dss 65)returns 4.
This is my code so far.
(define (dss n)
(define (sum-of-squares n)
(if (zero? n) 0
(cons (expt n 2)
(sum-of-squares (- n 1)))))
(sum-of-squares 1))
The output I get is
(dss 65) ; (1 . 0)
Which is clearly wrong. Please help!
Lists have nothing to do with this problem, the solution follows from the definition: you have to test all p values starting from 2 and see if we can find an integer q greater than 1 that satisfies the formula p^2 + q^2 = n. Something like this:
(define (dss n)
(define (sum-of-squares p)
(cond ((>= p n) n)
((let ((q (sqrt (- n (sqr p)))))
(and (integer? q) (not (= q 1))))
p)
(else (sum-of-squares (add1 p)))))
(sum-of-squares 2))
(dss 65)
=> 4

Return the sum of odd digits of a number

For class, I have to write a function that takes positive integer n and returns the sum of n’s odd digits in scheme. So far, I have my base case such that if n equals 0 then 0. But I am not sure on how to continue.
(define sumOddDigits
(lambda (n)
(if (= n 0)
0
Test cases:
(sumOddDigits 0) → 0
(sumOddDigits 4) → 0
(sumOddDigits 3) → 3
(sumOddDigits 1984) → 10
You could do it efficiently using one functional loop:
(define (sumOddDigits n)
(let loop ([n n])
(cond [(zero? n) 0]
[else
(let-values ([(q r) (quotient/remainder n 10)])
(+ (if (odd? r) r 0)
(loop q)))])))
One can get list of digits using following function which uses 'named let':
(define (getDigits n)
(let loop ((ol '()) ; start with an empty outlist
(n n))
(let-values (((q r) (quotient/remainder n 10)))
(if (= q 0) (cons r ol)
(loop (cons r ol) q)))))
Then one can apply a filter using odd? function to get all odd elements of list- and then apply 'apply' function with '+' to add all those elements:
(apply + (filter
(lambda(x)
(odd? x))
digitList))
Together following can be the full function:
(define (addOddDigits N)
(define (getDigits n)
(let loop ((ol '())
(n n))
(let-values (((q r) (quotient/remainder n 10)))
(if (= q 0) (cons r ol)
(loop (cons r ol) q)))))
(define digitList (getDigits N))
(println digitList)
(apply + (filter
(lambda(x)
(odd? x))
digitList)))
Testing:
(addOddDigits 156)
Output:
'(1 5 6)
6
Your basecase is if n < 10. Because you are then on the last digit.
You then need to check if it's odd, and if so return it. Else, return the addition qualifier(0).
If n > 10, you remainder off the first digit, then test it for odd.
If odd, then add it to a recursive call, sending in the quotient of 10(shaves off the digit you just added).
Else, you recursively call add-odds with the quotient of 10, without adding the current digit.
Here it is in a recursive form(Scheme LOVES recursion) :
(define add-odds
(lambda (n)
(if(< n 10)
(if(= (remainder n 2) 1)
n
0)
(if(= (remainder (remainder n 10) 2) 1)
(+ (remainder n 10) (add-odds (quotient n 10)))
(add-odds(quotient n 10))))))
First get a (reversed) list of digits with simple recursive implementation:
(define (list-digits n)
(if (zero? n) '()
(let-values ([(q r) (quotient/remainder n 10)])
(cons r (list-digits q)))))
then filter the odd ones and sum them:
(define (sum-of-odd-digits n)
(apply + (filter odd? (list-digits n))))
Note: (list-digits 0) returns '() but it is ok for later usage.
More accurate list-digits iterative implementation (produce list of digits in right order):
(define (list-digits n)
(define (iter n acc)
(if (zero? n) acc
(let-values ([(q r) (quotient/remainder n 10)])
(iter q (cons r acc)))))
(iter n '()))

Shifting a range in ClojureScript?

How can I shift a range in ClojureScript ?
For example let's say we have the range:
(range 3)
Which gives: (0 1 2)
I'm looking for a function to shift the values to the left like this: (1 2 0) or like this (2 0 1)
I came up with an implementation which I'll share as an answer. I guess should be some built-in function to do this ? But I didn't found anything.
This is the function I wrote:
(defn <-range [n l]
(concat (drop n (range l)) (range n)))
A brief explanation:
(range l) create a range of length l
(drop n) drop n elements
(range n) create a new range until n
(concat) concat both the ranges
If I try:
(<-range 0 4) gives (0 1 2 3)
(<-range 2 4) gives (2 3 0 1)
(<-range 4 4) gives (0 1 2 3)
I've reversed the order of your args, as this feels closer to how range args work. lazy-cat is probably preferable to concat, as it won't even evaluate the second range until it's needed.
(defn <-range [length start-index]
(lazy-cat (range start-index length)
(range start-index)))
there is also a cycle function, that (unsurprisingly) cycles a collection (to avoid the concatenation):
user> (defn <-range [n l]
(->> (range l)
cycle
(drop n)
(take l)))
#'user/<-range
user> (<-range 0 4)
(0 1 2 3)
user> (<-range 2 4)
(2 3 0 1)
user> (<-range 4 4)
(0 1 2 3)
also you can do it even without any call to range, based on the remainder:
user> (defn <-range [n l]
(take l (iterate #(rem (inc %) l) (rem n l))))
or like this:
user> (defn <-range [n l]
(map #(rem (+ % n) l) (range l)))
I assume the range was just used as an example and you really want to be able to do this to any collection.
(defn rotate-left [c]
(lazy-cat (drop 1 c) (take 1 c)))
or with the ability to optionally specify more than 1 rotation,
(defn rotate-left
([c] (rot-left 1 c))
([n c] (lazy-cat (drop n c) (take n c))))
Using this,
(rotate-left (range 3)) yields (1, 2, 0) and
(rotate-left 2 (range 3)) yields (2, 0, 1)

I defined a new multiply function in Scheme which I think should be wrong, however, it works

In scheme, the new multiply function is:
( define ( iter b a n)
( cond (( = b 0) n)
(( even? b) ( iter ( / b 2) ( * 2 a) n))
( else ( iter ( - b 1) ( / ( * a b) ( - b 1)) ( + a ( * a ( - b 1)))))))
( define ( mul b a)
( iter b a 1))
the question requires me to use iterative method rather than recursive method to deal with this problem, my thinking is following:
for example: ( mul 2 3 )
b a n
begin: 2 3 1
1 : 1 6 1
2 : 0 6/0 6
Obviously, in step 2, a equals 6/0. That should be impossible. But the function works well. Could anyone explain this? Here is the example in an online Scheme interpreter.
No, the function doesn't work well. Copy a fresh definition of the procedure, run it again and you'll see the error:
(define (iter b a n)
(cond ((= b 0) n)
((even? b)
(iter (/ b 2) (* 2 a) n))
(else
(iter (- b 1) (/ (* a b) (- b 1)) (+ a (* a (- b 1)))))))
(define (mul b a)
(iter b a 1))
(mul 2 3)
=> /: division by zero
In fact, the expected solution would be more along these lines, and notice that special care must be taken in case that b is negative:
(define (iter a b n)
(cond ((zero? b) n)
((even? b)
(iter (+ a a) (/ b 2) n))
(else
(iter a (- b 1) (+ a n)))))
(define (mul a b)
(if (< b 0)
(- (iter a (- b) 0))
(iter a b 0)))
And following your example, here's how the parameters look in each iteration when we execute (mul 2 3):
a b n
begin: 2 3 0
1 : 2 2 2
2 : 4 1 2
3 : 4 0 6