Error in beginning exercise in SICP (Exercise 1.3) - lisp

The prompt is to define a procedure that returns the sum of the squares of the two largest of three numbers.
I know this isn't exactly an elegant solution, but this is what I hacked together:
(define (largest-of-two-sum-of-squares x y z)
(cond ((and (< x y) (< x z)) (sum-of-squares y z))
((and (< y z) (< y x)) (sum-of-squares x z))
((and (< z x) (< z y)) (sum-of-squares x y)))))
What I'm wondering is why I'm getting an error.
;The object 85 is not applicable
The number that follows the word object is always the correct answer, btw. I am a scheme beginner, it must be something in my syntax?
Thanks

Here's another possible solution, this one works even in the cases where all three numbers are equal or if two are equal and lower than the other:
(define (sum-max a b c)
(define (sum x y)
(+ (* x x) (* y y)))
(if (>= a b)
(if (>= b c)
(sum a b)
(sum a c))
(if (>= a c)
(sum b a)
(sum b c))))

As sindikat pointed out, an excess closing bracket. Sorry about that.

What about
(define (largest-of-two-sum-of-squares x y z)
(+ (square x) (square y) (square z)
(- (square (min x y z)))))
?

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.

Lisp function call syntax

I am trying to write a recursive code to do x^y but the problem no mater how I update the code it gives me an error.
The Code:
(defun power(x y) (if(> y 0) (* x (power(x (- y 1)))) (1)))
Error:
CL-USER 11 : 5 >Power 2 3
Error: Undefined operator X in form (X (- Y 1)).
Error:
CL-USER 11 : 5 >power(2 3)
Illegal argument in functor position: 2 in (2 3).
You're calling the function in the wrong way. In lisps function calls have the form:
(f a b c)
not
f(a b c)
You had (power (x (- y 1))) in your recursive definition, which in turn had (x (- y 1)) hence the error: x is not a function.
Use (power x (- y 1)) so your definition becomes:
(defun power (x y)
(if (> y 0)
(* x
(power x (- y 1)))
1))
and call it as (power 2 3)
To expand slightly on the previous (correct) answer, this version uses some idiomatic functions:
(defun power (x y)
(if (plusp y)
(* x (power x (1- y)))
1))
You cannot use parenthesis for grouping since CL thinks you want to call function x and function 1. Remove the excess like this:
(defun power(x y)
(if (> y 0)
(* x (power x (- y 1)))
1))
Parenthesis goes on the outside, just as in your function:
(power 2 3) ;==> 8
When you write (X ...) in a Lisp expression, you are asserting that X is a function to be called on the arguments ....
Your problem is you have too many parentheses in your expression. When you write (power (x ..
you've made this assertion. Write (power x ... instead.
You're calling, among others, this code:
(power (x (- y 1)))
So power is called with (x (- y 1)) as a parameter. Are you sure you want to call x as a function?

A elementary Lisp procedure error

(define (sum-two-sqrt a b c)
(cond ((and (<= c a) (<= c b)) sqrt-sum(a b))
((and (<= a b) (<= a c)) sqrt-sum(b c))
((and (<= b a) (<= b c)) sqrt-sum(a c))
)
)
(define (sqrt-sum x y)
(+ (* x x) (*y y))
)
(define (<= x y)
(not (> x y))
(sum-two-sqrt 3 4 5)
This is my code
Please help me to fix the problem. :)
I just start studing Lisp today.
learned some C before but the two language is QUITE DIFFERENT!
This is the question
Define a procedure that takes three numbers as arguments and returns the sum of the squares of the two larger numbers.
If you have better algorithm
POST IT!
Thank you :)
There's no need to define <=, it's a primitive operation. After fixing a couple of typos:
sqrt-sum: you were incorrectly invoking the procedure; the opening parenthesis must be written before the procedure name, not after.
sqrt-sum: (*y y) is incorrect, you surely meant (* y y); the space(s) after an operator matter.
This should work:
(define (sqrt-sum x y)
(+ (* x x) (* y y)))
(define (sum-two-sqrt a b c)
(cond ((and (<= c a) (<= c b)) (sqrt-sum a b))
((and (<= a b) (<= a c)) (sqrt-sum b c))
((and (<= b a) (<= b c)) (sqrt-sum a c))))
Or another alternative:
(define (sum-two-sqrt a b c)
(let ((m (min a b c)))
(cond ((= a m) (sqrt-sum b c))
((= b m) (sqrt-sum a c))
(else (sqrt-sum a b)))))
Following up on a suggestion by #J.Spiral and seconded by #River, the following Racket code reads nicely to me:
#lang racket
(define (squares-of-larger l)
(define two-larger (remove (apply min l) l))
(for/sum ([i two-larger]) (* i i)))
(squares-of-larger '(3 1 4)) ;; should be 25
Please note that this solution is entirely functional, since "remove" just returns a new list.
Also note that this isn't even in the same neighborhood with HtDP; I just wanted to express this concisely, and show off for/sum.
I didn't have Scheme interpreter here, but below seems to be shorter then other suggestions :) So it's in CL, but should look very similar in Scheme.
(defun sum-two-sqrt (a b c)
(let ((a (max a b))
(b (max (min a b) c)))
(+ (* a a) (* b b))))
In Scheme this would translate to:
(define (sum-two-sqrt a b c)
(let ((a (max a b))
(b (max (min a b) c)))
(+ (* a a) (* b b))))
the algorithm seems to work, just turn
*y
to
* y
whitespace is important here, else you're telling the interpreter you want to usethe function *y
add a close paren after
(define (<= x y) (not (> x y))
sqrt-sum(a b)
turns to
(sqrt-sum a b)
and ditto for the other sqrt-sum calls
edit: also a possibility:
(define (square a) (* a a))
(define (square-sum a b c)
(- (+ (square a)
(square b)
(square c))
(square (min a b c))))

Lisp List Printing

I am having some troubles regarding the lisp format function. I have the following list:
((X X X)(X X X X X X)(X X X X X X X X X))
and I need to print it in the following format:
X X X
XX XX XX
XXXXXXXXX
Any thoughts on how to achieve this? The format function is kinda confusing and the HyperSpec documentation doesn't seem to do anything for me. Thanks.
Like every tool format has its limitations and it's not suited for such problems very well. Probably the best you can get with plain format without resorting to black magic tricks with ~? or ~/, that you or anyone else probably won't understand in the future, is this code:
CL-USER> (format t "~{~{~A ~}~%~}"
'((X X X) (X X X X X X) (X X X X X X X X X)))
X X X
X X X X X X
X X X X X X X X X
If you want to get your sophisticated output structure, try to do some pre-processing.
Like, if the format of the list is hard-coded, you can use this:
(format t "~{~{~6A~} ~%~}"
(mapcar (lambda (l)
(loop :for i :from 0 :to (1- (length l)) :by (/ (length l) 3)
:collect (format nil "~{~A ~}"
(subseq l i (+ i (/ (length l) 3))))))
'((X X X) (X X X X X X) (X X X X X X X X X))))
Here we first collect the items of a list into same number of groups for each list, print them and this way get 3 lists with the same number of elements, which can then be processed by format.
You can find out more about format in the appropriate chapter of Peter Seibel's excelent Lisp book: http://gigamonkeys.com/book/a-few-format-recipes.html
EDIT
If you have a variable number of lists, with each one being twice bigger than the previous one, you'll also need to prepare the format string beforehand:
CL-USER> (defun format-custom-list (list)
(format t (format nil "~~{~~{~~~DA~~} ~~%~~}" (* 2 (length list)))
(mapcar (lambda (l)
(let* ((len (length l))
(len/3 (/ len 3)))
(loop :for i :from 0 :to (1- len) :by len/3
:collect (format nil "~{~A ~}"
(subseq l i (+ i len/3))))))
list)))
CL-USER> (format-custom-list '((X X X) (X X X X X X) (X X X X X X X X X)
(X X X X X X X X X X X X)))
X X X
X X X X X X
X X X X X X X X X
X X X X X X X X X X X X
NIL
(The trailing nil is the output of format, which isn't printed to the output stream t. If you want to get a string out of this function use nil as format's output stream.)
I'm assuming you want to print each list, inserting spaces to make elements fit max list length.
Though I believe it is possible to print this with nearly single format call, it is better to split printing into several functions:
(defun format-list (stream lst space-count)
(let ((spaces (make-string 5 :initial-element #\Space))) ;; create string of spaces to insert
(let ((fmt (concatenate 'string "~{~a" spaces "~}~%")) ;; create formatting string
(format stream fmt lst)))))
(defvar full-list '((X X X)(X X X X X X)(X X X X X X X X X)))
(defvar max-list-length (max (mapcar length full-list))) ;; find length
(mapcar
#'(lambda (lst) (format-list t lst (/ (- max-list-length (length lst)) (length lst))))
full-list)
UPD.
For X + Space * (NumRows - CurrentRowNumber) condition you can next function instead of 2 last lines in my original code (in functional style, you can also use loop instead of reduce to make it less functional and more CL-like):
(format-list-of-lists (lst)
(let ((num-rows (length lst)))
(reduce #(lambda (cur-row sub-list) (format-list t sub-list (- num-rows cur-row)) (1+ cur-row))
lst)))

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