Racket - arguments for procedure how to get all - racket

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

Related

Macros for generating functions

I'm trying to write some macros for constraint programming on integers and specifically I'm trying to expand
(int-constr (x y z)
(< 10
(+
(* x 4)
(* y 5)
(* z 6)))
(> 10
(+
(* x 1)
(* y 2)
(* z 3))))
into
(let ((x (in-between 0 1))
(y (in-between 0 1))
(z (in-between 0 1)))
(assert
(and (< 10
(+
(* x 4)
(* y 5)
(* z 6)))
(> 10
(+
(* x 1)
(* y 2)
(* z 3)))))
(list x y z))
When using syntax-rules recursively, I can create nested let at the beginning, but I think I lose the possibility of calling the list of arguments at the end. Is there any way to do it?
Even just sticking to syntax-rules, this macro is easy to write by using ellipses. Here’s an implementation of the behavior you describe:
(define-syntax int-constr
(syntax-rules ()
((_ (x ...) constr ...)
(let ((x (in-between 0 1)) ...)
(assert (and constr ...))
(list x ...)))))
Since ellipses can be used to repeat forms containing pattern variables, not just repeat plain pattern variables on their own, this macro is quite declarative, and it’s both simple to read and write.

SICP - Multiplication through addition

I am using the book SICP and attempting to solve this exercise:
1.2.4 Exponentiation
Exercise 1.18. Using the results of exercises 1.16 and 1.17, devise
a procedure that generates an iterative process for multiplying two
integers in terms of adding, doubling, and halving and uses a
logarithmic number of steps
I am trying to solve this with the following code:
(define (double x)
(+ x x))
(define (halve x)
(floor (/ x 2)))
(define (* a b)
(define (iter count accumulate)
(cond ((= count 1) accumulate)
((even? a) (iter (halve count) (+ accumulate (double b))))
(else empty)))
(iter a 0))
As you might see, I am trying to deal with even numbers first.
I am using the SICP wiki as my solutions-guide. They suggest some tests to see if the code works:
(* 2 4)
(* 4 0)
What I do not get is that my code passes on these two first tests, dealing only with even numbers.
However, when I try some big numbers which are multiples of two, the code fails. I checked the result using Python. For instance,
(IN PYTHON)
2**100
>> 1267650600228229401496703205376
2**98
>> 316912650057057350374175801344
a = 2**100
b = 2**98
a*b
>> 401734511064747568885490523085290650630550748445698208825344
When I use my function inside Dr. Racket with these values I get a different result:
(* 1267650600228229401496703205376 316912650057057350374175801344)
My result is: 63382530011411470074835160268800, which is wrong, as Python built-in functions suggest.
Why this is happening?
The recursive step seems wrong, and what's that empty doing there? also, what happens if b is negative? this solution should work:
(define (mul a b)
(define (iter a b acc)
(cond ((zero? b) acc)
((even? b) (iter (double a) (halve b) acc))
(else (iter a (- b 1) (+ a acc)))))
(if (< b 0)
(- (iter a (- b) 0))
(iter a b 0)))
For example:
(mul 1267650600228229401496703205376 316912650057057350374175801344)
=> 401734511064747568885490523085290650630550748445698208825344

Racket - Transform a natural number to a specific base [duplicate]

I want to show the result of my function as a list not as a number.
My result is:
(define lst (list ))
(define (num->base n b)
(if (zero? n)
(append lst (list 0))
(append lst (list (+ (* 10 (num->base (quotient n b) b)) (modulo n b))))))
The next error appears:
expected: number?
given: '(0)
argument position: 2nd
other arguments...:
10
I think you have to rethink this problem. Appending results to a global variable is definitely not the way to go, let's try a different approach via tail recursion:
(define (num->base n b)
(let loop ((n n) (acc '()))
(if (< n b)
(cons n acc)
(loop (quotient n b)
(cons (modulo n b) acc)))))
It works as expected:
(num->base 12345 10)
=> '(1 2 3 4 5)

More generic lisp code to generate combinations of pairs

Given this sad thing below, which generates all pairs of only two ranges -
[53]> (setq thingie '())
NIL
[54]> (loop for i in (generate-range 0 3) do
(loop for j in (generate-range 4 6) do
(push (list i j) thingie)))
NIL
[55]> thingie
((3 6) (3 5) (3 4) (2 6) (2 5) (2 4) (1 6) (1 5) (1 4) (0 6) (0 5) (0 4))
[56]>
Or, put another way, this generates sort of a two-dimensional discrete layout.
How would I go about building some sort of pairs-generating code that took arbitrary numbers of ranges? (Or generating an n-dimensional discrete layout).
Obviously one solution would be to have a defmacro that took a list-of-lists and built n loops for execution, but that doesn't feel a straightforward way to go.
(defun map-cartesian (fn bags)
(labels ((gn (x y)
(if y (mapc (lambda (i) (gn (cons i x) (cdr y))) (car y))
(funcall fn x))))
(gn nil (reverse bags))))
CL-USER> (map-cartesian #'print '((1 2) (a b c) (x y)))
(1 A X)
(2 A X)
(1 B X)
(2 B X)
(1 C X)
(2 C X)
(1 A Y)
(2 A Y)
(1 B Y)
(2 B Y)
(1 C Y)
(2 C Y)
If you prefer syntax sugar,
(defmacro do-cartesian ((item bags) &body body)
`(map-cartesian (lambda (,item) ,#body) ,bags))
CL-USER> (do-cartesian (x '((1 2) (a b c) (x y)))
(print x))
Edit: (brief explanation)
The first parameter of gn, x, is the partial tuple constructed so far; y is the remaining bags of elements. The function gn extends the partial tuple by iterating over each element i of one of the remaining bags, (car y), to form (cons i x). When there's no remaining bags (the else branch of the if statement), the tuple is completed, so we invoke the supplied function fn on the tuple.
The obvious thing for me would be a recursive function.
If you're thinking of this as a control structure, the macro route is the way to go. If you're thinking of this as a way of generating data, a recursive function is the way to go.
You don't need explicit recursion (or even a macro), this can also be done with a higher-order function:
(defun tuples-from-ranges (range &rest ranges)
(reduce (lambda (acc range)
(mapcan (lambda (sublist)
(mapcar (lambda (elt)
(append sublist (list elt)))
(apply #'generate-range range)))
acc))
ranges
:initial-value (mapcar #'list (apply #'generate-range range))))
The two nested inner higher-order functions (mapcan and mapcar) perform the same function that the two nested loops in your example did. The outer higher-order function reduce will then first combine the values of the first two ranges to pairs, and after that in each invocation of its argument function apply the some process again to the intermediate results from the preceding invocation and the next range.

How would I express this Scheme function more clearly?

(define (repeated f n)
if (= n 0)
f
((compose repeated f) (lambda (x) (- n 1))))
I wrote this function, but how would I express this more clearly, using simple recursion with repeated?
I'm sorry, I forgot to define my compose function.
(define (compose f g) (lambda (x) (f (g x))))
And the function takes as inputs a procedure that computes f and a positive integer n and returns the procedure that computes the nth repeated application of f.
I'm assuming that (repeated f 3) should return a function g(x)=f(f(f(x))). If that's not what you want, please clarify. Anyways, that definition of repeated can be written as follows:
(define (repeated f n)
(lambda (x)
(if (= n 0)
x
((repeated f (- n 1)) (f x)))))
(define (square x)
(* x x))
(define y (repeated square 3))
(y 2) ; returns 256, which is (square (square (square 2)))
(define (repeated f n)
(lambda (x)
(let recur ((x x) (n n))
(if (= n 0)
args
(recur (f x) (sub1 n))))))
Write the function the way you normally would, except that the arguments are passed in two stages. It might be even clearer to define repeated this way:
(define repeated (lambda (f n) (lambda (x)
(define (recur x n)
(if (= n 0)
x
(recur (f x) (sub1 n))))
(recur x n))))
You don't have to use a 'let-loop' this way, and the lambdas make it obvious that you expect your arguments in two stages.
(Note:recur is not built in to Scheme as it is in Clojure, I just like the name)
> (define foonly (repeat sub1 10))
> (foonly 11)
1
> (foonly 9)
-1
The cool functional feature you want here is currying, not composition. Here's the Haskell with implicit currying:
repeated _ 0 x = x
repeated f n x = repeated f (pred n) (f x)
I hope this isn't a homework problem.
What is your function trying to do, just out of curiosity? Is it to run f, n times? If so, you can do this.
(define (repeated f n)
(for-each (lambda (i) (f)) (iota n)))