I need to make a recursive procedure that finds how many 6's are in a number. For example, 606 has two 6's. I started it.
(define num
(lambda (n)
(cond
((< n 0) (num (- n)))
((= n 0) 0)
((> n 6)
I do not want to convert anything. Is there a way of dividing it by 10, then if the decimal is .6 add one?
1) For integer division in scheme, use the quotient function, as in (quotient 9 2) gives 4.
2) For integer modulus in scheme, use the remainder function, as in (remainder 9 2) gives 1.
Scheme is based on recursion, as you stated. To solve a recursive problem, you have to state the solution in terms of a smaller instances of the problem:
"The number of 6 digits in a number N is ... "
and for ... you state the solution in terms of the solution of part of N.
The easiest part of N to recur on is N/10, which is all but the last digit of N. Then, to solve this recursively, you should assume that you know the answer to (num (quotient N 10)). Call that value X. How does knowing N and X tell you how many digits is in N?
If the last digit of N is 6, then the solution is X+1. Otherwise, the solution is X. How can you tell if the last digit is 6? Use the remainder function.
(define (num N)
; check cases
(cond
; case 1) negative condition
((< N 0) (num (- N)))
; case 2) zero condition, the terminal case
((= N 0) 0)
; case 3) recursive case with a 6 as the last digit
((= (remainder N 10) 6) (+ X 1))
; case 4) recursive case without a 6 as the last digit
(#t X)
))
Now you just have to substitute the recursive assumption in for X, so for example case 3 becomes
; case 3
((= (remainder N 10) 6) (+ (num (quotient N 10)) 1))
Change X for case 4 as well and you'll get the solution.
Almost as good, let me introduce you to modulo. It takes in two numbers, and returns the remainder of the first divided by the second. Taking the (modulo n 10) will return the last digit of n. The general Scheme (ba-duh-duh-chiiing) for what you want is
(define num-6s
(lambda (n)
(cond
((< n 10)
; Base Case, if n = 6, then 1 else 0
((= (modulo n 10) 6)
; The last digit of n is 6
(else
; The last digit of n isn't 6
))))
Now as another helpful hint, (floor (/ n 10)) drops the last digit of a number. This is how you should get the next number to recurse upon.
Related
I am writing the square of sums in racket/scheme recursively. The code sums the numbers right, but it doesn't square it right. I don't know what I am doing wrong. If I pass 10, it should be 3025.
(define (squareOfSums n)
(if (= n 0)
0
(expt (+ n (squareOfSums (- n 1))) 2)))
You should do the squaring only once, at the end of the recursion. Currently, your code squares at every iteration. One way to solve this problem would be to separate the sum part into a helper procedure, and square the result of calling it. Like this:
(define (squareOfSums n)
(define (sum n)
(if (= n 0)
0
(+ n (sum (- n 1)))))
(sqr (sum n)))
Also, did you know that there's a formula to add all natural numbers up to n? This is a nicer solution, with no recursion needed:
(define (squareOfSums n)
(sqr (/ (* n (+ n 1)) 2)))
Either way, it works as expected:
(squareOfSums 10)
=> 3025
Here's a version which I think is idiomatic but which I hope no-one who knows any maths would write:
(define (square-of-sums n)
(let loop ([m n] [sum 0])
(if (> m 0)
(loop (- m 1) (+ sum m))
(* sum sum))))
Here's the version someone who knows some maths would write:
(define (square-of-sums n)
(expt (/ (* n (+ n 1)) 2) 2))
I wish people would not ask homework questions with well-known closed-form solutions: it's actively encouraging people to program badly.
If you start out with your function by writing out some examples, it will be easier to visualize how your function will work.
Here are three examples:
(check-expect (SquareOfSums 0) 0)
(check-expect (SquareOfSums 2) (sqr (+ 2 1))) ;9
(check-expect (SquareOfSums 10) (sqr (+ 10 9 8 7 6 5 4 3 2 1))) ;3025
As we can see clearly, there are two operators we are using, which should indicate that we need to use some sort of helper function to help us out.
We can start with out main function squareOfSums:
(define (squareOfSums n)
(sqr (sum n)))
Now, we have to create the helper function.
The amount of times that you use the addition operator depends on the number that you use. Because of this reason, we're going to have to use natural recursion.
The use of natural recursion requires some sort of base case in order for the function to 'end' somewhere. In this case, this is the value 0.
Now that we have identified the base case, we can create our helper function with little issue:
(define (sum n)
(if (= 0 n)
0
(+ n (sum (sub1 n)))))
The following function was given to me on a review sheet:
(define mystery(lambda(m n)
(cond
((= m 0) n)
((= n 0) m)
(#t (+ 2(mystery(- m 1)(- n 1))))
)))
The first two conditions are simple, it's just the recursive otherwise that's confusing me. It just seems to me that the recursion will continue until they both equal zero, which certainly doesn't return the sum. Can someone provide an explanation?
First, let's format the code a bit better to see what's happening:
(define (mystery m n)
(cond ((= m 0) n)
((= n 0) m)
(else (+ 2 (mystery (- m 1) (- n 1))))))
Now, remember that a cond executes only the action corresponding to the first condition that is true (from top to bottom), the others are ignored. If none of the conditions is true, then the else part is executed. The important thing to remember is that only one action is executed.
In particular, your mystery procedure will stop when either m or n becomes zero, not when both become zero. When one of the two reaches zero, the recursion starts to unwind, returning the sum. You can see this when tracing the execution - for example, in Racket:
(require racket/trace)
(trace mystery)
(mystery 3 2)
>(mystery 3 2)
> (mystery 2 1)
> >(mystery 1 0)
< <1
< 3
<5
Just to elaborate on Óscar López's answer (I can't format this in a comment): I find that it's often useful to write these sorts of little recursive maths functions down as if they were maths:
Let m and n be natural numbers, then
n + m = n if m = 0;
n + m = m if n = 0;
n + m = n - 1 + m - 1 + 2;
there are no other cases.
I feel the best way is not to nest but to precompute. Looking at the base case we test with either zero:
(mystery 0 2) ; ==> 2
(nystery 3 0) ; ==> 3
Thus every time at least one argument is zero it returns the other argument. Lets try with a non zero value and remember the second you see a value we have already done before you just switch it with its result:
(mystery 1 3) ; ==
(+ 2 (mystery 0 2)) ; == (we switch known value)
(+ 2 2)
; ==> 4
(mystery 4 1) ; == (we substitute with the expression)
(+ 2 (mystery 3 0)) ; == (we switch known value)
(+ 2 3)
; ==> 5
Since we know the base case always returns the other value we don't need to precalculate it. Here is a go that does that:
(mystery 3 9) ; == (we substitute with the expression)
(+ 2 (mystery 2 8) ; == (we substitute with the expression)
(+ 2 (+ 2 (mystery 1 7))) ; == (we substitute with the expression)
(+ 2 (+ 2 (+ 2 (mystery 0 6))) ; == (we substitute with the expression, n, which is 6)
(+ 2 (+ 2 (+ 2 6))) ; == (we substitute (+ 2 6))
(+ 2 (+ 2 8)) ; == (we substitute (+ 2 8))
(+ 2 10) ; == (we substitute (+ 2 10)
; ==> 12
We can generalize what will happen. The lowest of n and m will decide when the recursion ends. At each step it will add 2 and recurse. Thus it is a fancy way of making:
(define (double-min n m)
(let ((vmin (min n m))
(vmax (max n m)))
(+ (* 2 vmin) (- vmax vmin))))
Which again is a fancy way of adding the two numbers since if n > m, then 2*m+(n-m) = m+m+(n-m) = m+n
(define mystery(lambda(m n)
(cond
((= m 0) n)
((= n 0) m)
(#t (+ 2 (mystery (- m 1) (- n 1))))
)))
First and second conditions are obvious.
Explanation of how the third statement is working:
1 each is taken out of m and n and kept as 2 outside this function.
This is continued till either m is 0 or n is 0.
The first 2 cases are obvious, the sum of 2 numbers where one of the numbers is 0, is equal to the other number.
In the last case, after checking the arguments for 0, we know for sure that both of them are non-0. Assuming that mystery returns the sum of its 2 arguments, then
(+ 2 (mystery (- arg1 1) (- arg2 1)))
will return a sum that is equal to (mystery arg1 arg2) and will eventually halt when one of the arguments is 0, returning the desired result.
Assuming that mystery returns the sum of its 2 arguments is key here and is called the recursive leap of faith. (Google it)
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.
ive been given a task in Scheme (Dr Racket) to reverse to order of a given digit. The solution should be recursive, and this is what i got this far..
The truth is, im not quite sure if the given algorithm even works because i get:
" application: not a procedure;
expected a procedure that can be applied to arguments"
error every time i run it..
Any thoughts or help on the issue?
(define reverse-digits
(lambda (n) (if (> n 9)
(+ (* 10 (modulo n 10)) (reverse-digits (quotient n 10)))
(n))))
(reverse-digits 1234)
This is a HW assignment so I won't give you code.
Your problem is that multiplying (modulo n 10) by 10 doesn't get you to the position you need to be in. Consider (reverse-digits 123):
(reverse-digits 123)
(+ 30 (reverse-digits 12))
(+ 30 (+ 20 (reverse-digits 1)))
(+ 30 (+ 20 1))
51
What you want is to multiply it by a different power of 10 every time depending on the length of the number. You could either make a function that calculates the length of the number (possibly by repeatedly dividing the number by 10 and keeping track of how many times it did that) or passing along the length of the number (possibly by creating another function that takes the number n as an argument and calculates the length, then passes it along to your function which will then subtract 1 from length every recursive call.
What you would then get is something like this:
(reverse-digits 123)
(+ 300 (reverse-digits 12))
(+ 300 (+ 20 (reverse-digits 1)))
(+ 300 (+ 20 1))
321
The error you're getting is because in your else-case, you do (n). As n is not a procedure, you get an error. You just want n instead.
Are you bound to using specific procedures ? If not, there's an alternative to using modulo and adding numbers. It's about using list procedures such as
number->string
take
list->string
and so on.
This is my solution, it is not very efficient!
(define
invert-number-aux (λ (n res)
(if (empty? n) res
(invert-number-aux
(take n (-(length n) 1)) ;new n
(append res (list (last n))) ;new res
)
)))
(define
invert-number (λ (n)
(string->number (list->string (invert-number-aux (string->list(number->string n)) '())))
))
It will be helpful to use smaller helper functions.
Here is one way to split the task in smaller parts:
; number->digits : natural -> list-of-digits
(define (number->digits n)
...)
; digits->number : list-of-digits -> natural
(define (number->digits n)
...)
With these helpers you can write:
(define (reverse-number x)
(digits->number
(reverse
(number->digits x))))
Also - if you want to the error " application: not a procedure; expected a procedure that can be applied to arguments" replace (n) with n.
If you run your program in DrRacket, the application (n) ought to be colored red. The problem is that (42) means evaluate 42 and then call the result as if is a function. Since 42 is a number, you get the error.
Its important to understand that fixnums don't have just one representation and what the different digits are of a number might change with the base of its representation. Here is my take on it.
(define (number->digits number (base 10))
(let loop ((n number) (acc '()))
(if (zero? n)
acc
(let-values (((res rem) (quotient/remainder n base)))
(loop res (cons rem acc))))))
(define (list->number lst (base 10))
(foldl (lambda (x acc)
(+ (* acc base) x))
0
lst))
(define (reverse-digits number (base 10))
(list->number (reverse (number->digits number base))
base))
(number->string (reverse-digits #b100111 #b10) #b10) ; ==> "111001" (or 39 => 57 in base 10)
(number->string (reverse-digits #xebabefac #x10) #x10) ; ==> "cafebabe" (or 3953913772 => 3405691582 in base 10)
(number->string (reverse-digits 1234)) ; ==> 4321
This is what I did until now it tells me that it is not of type list.
(defun number_list(n)
(setf x
(if (zerop (truncate n 10))
(list n)
(append (number_list (truncate n 10)) (list (mod n 10)))))
(length x))
When I remove the (length x) I can see that the result is a list however.
Would appreciate any help.
Your solution uses a global variable x, which is generally a bad idea, especially in recursive functions. Then, you create a list in order to count the number of digits. This is not really necessary.
Using a list
If you want to work with a list, I suggest you split the problem in 2 parts:
1. convert a number to a list
Your function works well for this if you remove setf x:
(defun number_list(n)
(if (zerop (truncate n 10))
(list n)
(append (number_list (truncate n 10)) (list (mod n 10)))))
2. count the number of digits
(defun numdigits (n)
(length (number_list n))).
Alternative
But I would suggest a simple recursive definition such as:
(defun numdigits (n)
(if (< -10 n 10)
1
(1+ (numdigits (truncate n 10)))))
If you want to get the decimal digits and then count the length, assuming that numbers are 0 or greater integers.
(defun number-list (n)
(if (< n 10)
(list n)
(cons (mod n 10)
(number-list (truncate n 10)))))
CL-USER 44 > (length (number-list 123456789))
9
But it is preferable to directly count the digits. See the other answers.