Simulating binary addition - DrRacket Intermediate Student with Lambda - recursion

As the title says, I'm a college student using DrRacket with Intermediate Student With Lambda language. My assignment is an algorithm that, given a string containing a binary number, displays as output the next number, operating only on the binary representation (thus, not converting to decimal, adding +1 and re-converting to binary). I've skipped the first three weeks of my course since I was abroad and now I'm trying to catch up and, as long I've understood, the professor's main goal now is to make us exercise on recursion (moreover, we are not allowed to use lists or cicles like the ones that are possible with do, only functions that are defined through lambda expressions).
I took several tries at the assignment and now my code looks like this:
; function called by the user
(define bin-succ
(lambda (bin) ; not-empty string of "0"s and "1"s
(let ( (k (- (string-length bin) 1)) (post (make-string 0)) )
(position bin k post)
)
)
)
; actual recursive function of the code: it searches from the least significant
; bit to the most significant bit if there is any "0" in the string
(define position
(lambda (bin k post)
(cond ( (= k -1)
(string-append "1" post) )
( (char=? (string-ref bin k) #\0)
(string-append (substring bin 0 k) "1" post) )
( (char=? (string-ref bin k) #\1)
((position bin (- k 1) post)
(string-append "0" post)) )
)
)
)
At the moment, the algorithm works with numbers which last digit is 0, such as 0, 10, 11010, etc..., but when I declare as input a number ending in 1, the program highlights the last part of the code, in particular
((position bin (- k 1) post)
(string-append "0" post))
and returns the error:
function call: expected a function after the open parenthesis, but received "11"
I've tried to use begin to make a list of expressions in a different function called by the third cond's case, that would re-call the function position, thus making the algorithm recursive again, but no luck since it says that begin isn't a defined function.
I may be overlooking something really easy (mostly due to the introductory classes I've skipped) or I may have taken this problem with an uncorrect mindset, but either way I'm stuck and I appreciate any helpful input.
Just a final question: also the use of else in the last cond case isn't accepted, can anyone explain me why? The fact that DrRacket uses multiple languages is puzzling me quite a lot since lots of documentation online isn't working with my current setup.

Maybe you've been looking at Racket documentation not ISL+ (Intermediate Student With Lambda) documentation so far? See https://docs.racket-lang.org/htdp-langs/intermediate-lam.html for the ISL+ documentation. Pressing f1 on a term from DrRacket takes you to documentation in the context of the language you're using.
((position bin (- k 1) post)
(string-append "0" post))
This is function application. You're trying to apply (as an argument): (string-append "0" post) to a function (position bin (- k 1) post). However, position returns a String.
You can simply pass over the new post to the recursive call. And you can use else in the last clause too. This is the working code:
; String -> String
(define (bin-succ bin)
(position bin (- (string-length bin) 1) ""))
; String Number String -> String
(define (position bin k post)
(cond [(= k -1)
(string-append "1" post)]
[(char=? (string-ref bin k) #\0)
(string-append (substring bin 0 k) "1" post)]
[else
(position bin (- k 1) (string-append "0" post))]))
A cleaner solution would be to not have a counter:
(define (bin-succ bin)
(cond [(string=? bin "1") "10"]
[(string=? (last bin) "0") (string-append (all-but-last bin) "1")]
[else (string-append (bin-succ (all-but-last bin)) "0")]))
(define (last str)
(substring str (sub1 (string-length str)) (string-length str)))
(define (all-but-last str)
(substring str 0 (sub1 (string-length str))))

Related

Unanticipated error when using a cond statement

New to common lisp and having a very rookie problem. My function of one variable is supposed to return the absolute of of the entered variable. It works for when the variable is above or equal to 0 but not below, I suspect this is due to the cond function but i'm not sure.
I have tried the code with brackets and without but cannot see why it is failing. I know this is not the best way of solving this problem but i am just trying to get used to the cond statement at this stage.
(defun abs-x (x)
(cond ((> x 0) x)
((= x 0) 0)
((< x 0) (-x))))
The error message when a variable below 0 is entered is '-X is undefined.
Use
(- x)
; ^
; |
; The space
; is important.
instead of (-x).
That's because - is a valid character in an identifier, so -x is a valid function name. With the space between - and x, though, it calls the function - which takes one or more arguments.
Shorter:
(defun abs-x (x)
(cond ((> x 0) x)
(t (- x))))
Reduced number of checkings using the fact that (- 0) also evaluates to0.
Instead of <= for the last check, use the simpler t - the else in common lisp cond clauses.
With if this would be:
(defun abs-x (x)
(if (> x 0)
x
(- x)))

Recursive Factorial Function in Common-Lisp

Ok, I'm been learning COMMON LISP programming and I'm working on a very simple program to calculate a factorial of a given integer. Simple, right?
Here's the code so far:
(write-line "Please enter a number...")
(setq x (read))
(defun factorial(n)
(if (= n 1)
(setq a 1)
)
(if (> n 1)
(setq a (* n (factorial (- n 1))))
)
(format t "~D! is ~D" n a)
)
(factorial x)
Problem is, when I run this on either CodeChef or Rexter.com, I get a similar error: "NIL is NOT a number."
I've tried using cond instead of an if to no avail.
As a side note, and most bewildering of all, I've seen a lot of places write the code like this:
(defun fact(n)
(if (= n 1)
1
(* n (fact (- n 1)))))
Which doesn't even make sense to me, what with the 1 just floating out there with no parentheses around it. However, with a little tinkering (writing additional lines outside the function) I can get it to execute (equally bewildering!).
But that's not what I want! I'd like the factorial function to print/return the values without having to execute additional code outside it.
What am I doing wrong?
One actually needs to flush the I/O buffers in portable code with FINISH-OUTPUT - otherwise the Lisp may want to read something and the prompt hasn't yet been printed. You better replace SETQ with LET, as SETQ does not introduce a variable, it just sets it.
(defun factorial (n)
(if (= n 1)
1
(* n (factorial (- n 1)))))
(write-line "Please enter a number...")
(finish-output) ; this makes sure the text is printed now
(let ((x (read)))
(format t "~D! is ~D" x (factorial x)))
Before answering your question, I would like to tell you some basic things about Lisp. (Neat fix to your solution at the end)
In Lisp, the output of every function is the "last line executed in the function". Unless you use some syntax manipulation like "return" or "return-from", which is not the Lisp-way.
The (format t "your string") will always return 'NIL as its output. But before returning the output, this function "prints" the string as well.
But the output of format function is 'NIL.
Now, the issue with your code is the output of your function. Again, the output would be the last line which in your case is:
(format t "~D! is ~D" n a)
This will return 'NIL.
To convince yourself, run the following as per your defined function:
(equal (factorial 1) 'nil)
This returns:
1! is 1
T
So it "prints" your string and then outputs T. Hence the output of your function is indeed 'NIL.
So when you input any number greater than 1, the recursive call runs and reaches the end as input 1 and returns 'NIL.
and then tries to execute this:
(setq a (* n (factorial (- n 1))))
Where the second argument to * is 'NIL and hence the error.
A quick fix to your solution is to add the last line as the output:
(write-line "Please enter a number...")
(setq x (read))
(defun factorial(n)
(if (= n 1)
(setq a 1)
)
(if (> n 1)
(setq a (* n (factorial (- n 1))))
)
(format t "~D! is ~D" n a)
a ;; Now this is the last line, so this will work
)
(factorial x)
Neater code (with Lisp-like indentation)
(defun factorial (n)
(if (= n 1)
1
(* n (factorial (- n 1)))))
(write-line "Please enter a number...")
(setq x (read))
(format t "~D! is ~D" x (factorial x))
Common Lisp is designed to be compiled. Therefore if you want global or local variables you need to define them before you set them.
On line 2 you give x a value but have not declared the existence of a variable by that name. You can do so as (defvar x), although the name x is considered unidiomatic. Many implementations will give a warning and automatically create a global variable when you try to set something which hasn’t been defined.
In your factorial function you try to set a. This is a treated either as an error or a global variable. Note that in your recursive call you are changing the value of a, although this wouldn’t actually have too much of an effect of the rest of your function were right. Your function is also not reentrant and there is no reason for this. You can introduce a local variable using let. Alternatively you could add it to your lambda list as (n &aux a). Secondarily your factorial function does not return a useful value as format does not return a useful value. In Common Lisp in an (implicit) progn, the value of the final expression is returned. You could fix this by adding a in the line below your format.
For tracing execution you could do (trace factorial) to have proper tracing information automatically printed. Then you could get rid of your format statement.
Finally it is worth noting that the whole function is quite unidiomatic. Your syntax is not normal. Common Lisp implementations come with a pretty printer. Emacs does too (bound to M-q). One does not normally do lots of reading and setting of global variables (except occasionally at the repl). Lisp isn’t really used for scripts in this style and has much better mechanisms for controlling scope. Secondarily one wouldn’t normally use so much mutating of state in a function like this. Here is a different way of doing factorial:
(defun factorial (n)
(if (< n 2)
1
(* n (factorial (1- n)))))
And tail recursively:
(defun factorial (n &optional (a 1))
(if (< n 2) a (factorial (1- n) (* a n))))
And iteratively (with printing):
(defun factorial (n)
(loop for i from 1 to n
with a = 1
do (setf a (* a i))
(format t “~a! = ~a~%” i a)
finally (return a)))
You can split it up into parts, something like this:
(defun prompt (prompt-str)
(write-line prompt-str *query-io*)
(finish-output)
(read *query-io*))
(defun factorial (n)
(cond ((= n 1) 1)
(t (* n
(factorial (decf n)))))
(defun factorial-driver ()
(let* ((n (prompt "Enter a number: "))
(result (factorial n)))
(format *query-io* "The factorial of ~A is ~A~%" n result)))
And then run the whole thing as (factorial-driver).
Sample interaction:
CL-USER 54 > (factorial-driver)
Enter a number:
4
The factorial of 4 is 24

scheme check-expect output record combined with record-procedures

i am currently programming in scheme and i have written the following record-procedures that records a creature (= kreatur in German) with the character traits strength (= stärke), knowledge (= wissen) and readiness to assume a risk (= risikobereitschaft), i defined two creatures named "ronugor" and "garnolaf" (the names are not my idea, its from a exercise i didn't come up with ;) ) and then i wrote a procedure to mix the character traits of these two creatures (strengh -5%, knowledge unchanged, readiness to assume a risk still 0) to receive a new creature named "ronulaf".
this is my code:
(: stärke (kreatur -> number))
(: wissen (kreatur -> number))
(: risikobereitschaft (kreatur -> number))
(define-record-procedures kreatur
make-kreatur
kreatur?
(stärke
wissen
risikobereitschaft))
; check-property (i kept this out of the posted code to shorten it)
;define the creatures garnolaf and ronugor
(: make-kreatur (number number number -> kreatur))
(define garnolaf
(make-kreatur 100 0 0))
(: make-kreatur (number number number -> kreatur))
(define ronugor
(make-kreatur 0 100 0))
;signaturen
(: garnolaf? (kreatur -> boolean))
(check-expect (garnolaf? garnolaf) #t)
(check-expect (garnolaf? ronugor) #f)
(define garnolaf?
(lambda (x)
(and (= (stärke x) 100)
(= (wissen x) 0)
(= (risikobereitschaft x) 0))))
(: ronugor? (kreatur -> boolean))
(check-expect (ronugor? garnolaf) #f)
(check-expect (ronugor? ronugor) #t)
(define ronugor?
(lambda (x)
(and (= (stärke x) 0)
(= (wissen x) 100)
(= (risikobereitschaft x) 0))))
;mixing of the creatures
(: ronulaf (kreatur kreatur -> kreatur))
;this is where i am missing a check-expect, i suppose
(define ronulaf
(lambda (r g)
(make-kreatur (* 0.95 (stärke g))
(wissen r)
0)))
the question i now have is how i can write a check-expect for the procedure ronulaf. i would write is somehow like this:
(check-expect (ronulaf ronugor garnolaf) #<record:kreatur 95.0 100 0>)
but it doesn't work. does anybody have a better idea for a check-expect?
thanks already!
eva
Notice how your garnolaf? and ronugor? procedures are written? Now write something similar for ronulaf. That's it!
Try this:
(check-expect (ronulaf ronugor garnolaf) (make-kreatur 95 100 0))
Not all objects representations can be feed into read and become that object. #< in the beginning makes it look like an evaluated procedure and it's the same for those.

how to do a count in RACKET

i'm trying to write a code in RACKET , i know how to solve it but i'm having some trouble , i can use your help .
the function will get a list and a specific symbol , and it need to return the number of times that the symbol is shown in the list .
in the test - i'm comparing the result with a number i'm asking and should return true if the number is the same .
i've tried to do it with (if / cond / and even tried acc ) - but there is always something that is missing .
here is my code including the test .
please help me find out how to write it .
the idea of the solution is , the i take the head of the list and i check if it's equal to the symbol i wrote , if it does - n is plus 1 , empty list is equal 0 .
( : counts : (Listof Symbol) -> Integer )
(define (counts a n ) ; a = list of symbols.
(cond [(null? a) 0])
[(eq?(first a) 'x) (= n(+ n 1))]
(counts( (rest a) n)))
;test:
(test (eq? (counts ('a 'b 'x) )1))
There are several problems with your code:
The cond expression is being incorrectly used, and the else case is missing
There are erroneous parentheses, for example at the end of the second line in counts and when you call counts in the fourth line
In the base case of the recursion you must return n, the counter
You must also call the recursion if the symbol was found, in the second case
This part: (= n (+ n 1)) is not doing what you think, it's not changing the value of n, instead is testing for equality between n and (+ n 1) (which will return false, of course)
You're not passing as parameter the symbol being searched, it's hard-coded in the procedure
This is a corrected version of what you intended to write:
(define (counts a x n)
(cond [(null? a) n]
[(eq? (first a) x)
(counts (rest a) x (+ n 1))]
[else
(counts (rest a) x n)]))
Use it like this:
(counts '(a b x c d x e x) 'x 0)
=> 3
I advice you to grab a good book or tutorial, it seems you're struggling with the basic syntax. And learn how to use DrRacket to help with the syntax errors, it's an excellent IDE.

Scheme - do iterative - return value

I trying to write a function which gets an integer number , represented by string , and check if all his chars are digits and return #t \ #f accordingly . Thats the code -
(define (splitString str) (list->vector (string->list str)))
(define myVector 0)
(define flag #t)
(define (checkIfStringLegal str) (
(set! myVector (splitString str))
(do ( (i 0 (+ i 1)) ) ; init
((= i (vector-length myVector)) flag) ; stop condition
(cond ((>= 48 (char->integer (vector-ref myVector i)) ) (set! flag #f))
((<= 57 (char->integer (vector-ref myVector i)) )(set! flag #f))
)
)
)
)
Few explanations -
(list->vector (string->list str)) - convert string the char list .
(vector-ref myVector i) - char from the myVector at place i .
Its run OK , but when I try to use this func , like (checkIfStringLegal "444") I get -
application: not a procedure;
expected a procedure that can be applied to arguments
given: #<void>
arguments...:
#t
Try this:
(define (checkIfStringLegal str)
(andmap char-numeric?
(string->list str)))
This is how the procedure works:
It transforms the string into a list of characters, using string->list
It validates each character in the list to see if it's a number, applying the predicate char-numeric? to each one
If all the validations returned #t, andmap will return #t. If a single validation failed, andmap will return #f immediately
That's a functional-programming solution (and after all, this question is tagged as such), notice that your intended approach looks more like a solution in a C-like programming language - using vectors, explicit looping constructs (do), mutation operations (set!), global mutable definitions ... that's fine and it might eventually work after some tweaking, but it's not the idiomatic way to do things in Scheme, and it's not even remotely a functional-programming solution.
EDIT:
Oh heck, I give up. If you want to write the solution your way, this will work - you had a parenthesis problem, and please take good notice of the proper way to indent and close parenthesis in Scheme, it will make your code more readable for you and for others:
(define (splitString str) (list->vector (string->list str)))
(define myVector 0)
(define flag #t)
(define (checkIfStringLegal str)
(set! myVector (splitString str))
(do ((i 0 (+ i 1)))
((= i (vector-length myVector)) flag)
(cond ((>= 48 (char->integer (vector-ref myVector i)))
(set! flag #f))
((<= 57 (char->integer (vector-ref myVector i)))
(set! flag #f)))))
Even so, the code could be further improved, I'll leave that as an exercise for the reader:
Both conditions can be collapsed into a single condition, using an or
The exit condition should be: end the loop when the end of the vector is reached or the flag is false

Resources