Square of Sums in racket/scheme - math

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

Related

Why is my code getting stuck in a recursive call when a negative argument gets passed through?

I'm trying to implement a recursive procedure in Scheme that takes the square of the number without using multiplication by using the formula n^2=1+3+5+...+(n+n-1). The if(< n 0) statement is in case a negative number is the argument. I know I could easily just use abs but I wanted to try coding it without abs.
When (Square1 2) is called it returns the correct value, but when I called (Square1 -2) it gets stuck in the recursive call.
I think I managed to narrow it down to the Square1(+ n -1) being the cause of the problem, but I am not sure why this is causing a problem. I tried programming this using the same logic in Java and it seems that my logic is correct. This is my first functional language so there is probably something I am not understanding.
(define Square1
(lambda (n)
(if (= n 0)
0)
(if (< n 0)
(Square1 (* -1 n)))
(if (= n 1)
1
(+ (+ (+ n n) -1) (Square1 (+ n -1))))))
The problem is that the procedure gets stuck in the the second if, never reaching the base case because of the way your conditions are structured. We should split the problem in two parts: one procedure for checking the cases when n <= 0 and the other for performing the loop in the general case.
Be aware that in a Scheme procedure, only the result of the last expression gets returned - the other expressions are executed for sure, but their results ignored. In the case of an if expression, structure it so it always has an "else" part. Having said that, this should work:
(define (aux n)
(if (= n 1)
1
(+ (+ (+ n n) -1)
(aux (+ n -1)))))
(define (square1 n)
(if (= n 0)
0
(if (> n 0)
(aux n)
(aux (- n)))))
The above solution is correct, but not that idiomatic. We can do better!
The aux procedure should be internal to the main procedure, because it won't be used anywhere else
Instead of nesting ifs, it's nicer to use cond
We could use existing procedures for common task, like zero?, positive?, sub1
For efficiency, we should use tail recursion whenever possible
This is how a more idiomatic answer might look, it works the same as the first one:
(define (square1 n)
(define (aux n acc)
(if (= n 1)
acc
(aux (sub1 n) (+ acc (sub1 (+ n n))))))
(cond ((zero? n) 0)
((positive? n) (aux n 1))
(else (aux (- n) 1))))
Either way, it works as expected:
(square1 -4)
=> 16
(square1 -3)
=> 9
(square1 -2)
=> 4
(square1 -1)
=> 1
(square1 0)
=> 0
(square1 1)
=> 1
(square1 2)
=> 4
(square1 3)
=> 9
(square1 4)
=> 16

Digits of a number in Racket are in random order

I decided to write a function that given a number will return a list containing the digits in that number, my attempt is:
(define (rev-digits n)
(if (= n 0)
'()
(cons (modulo n 10) (digits (quotient n 10)))))
(define (digits n)
(reverse (rev-digits n)))
The fact is, I need the digits to be in proper order, but the function returns, for example:
> (digits 1234567890)
'(9 7 5 3 1 2 4 6 8 0)
In seemingly random order... can you help me getting a more ordinated output?
rev-digits needs to call itself, not digits.
(define (rev-digits n)
(if (= n 0)
'()
(cons (modulo n 10) (rev-digits (quotient n 10)))))
(define (digits n)
(reverse (rev-digits n)))
should work.
It's worth noting that your "random" output was not in fact random; rather the digits were "bouncing" back and forth from the start to the end of the list. Which makes sense, because you were effectively switching back and forth between a "normal" and reversed version of your digits function.
The answer given by #JayKominek is spot-on and fixes the error in your code. To complement it, here's an alternative implementation:
(define (rev-digits n)
(let loop ((n n) (acc '()))
(if (< n 10)
(cons n acc)
(loop (quotient n 10) (cons (modulo n 10) acc)))))
The advantages of the above code are:
It's tail recursive and hence more efficient
It correctly handles the edge case when n is zero (your code returns an empty list)
It doesn't require a helper procedure, thanks to the use of a named let
It builds the list in the correct order, there's no need to reverse it at the end
A simple solution:
#lang racket
(define (digits n)
(for/list ([c (number->string n)])
(- (char->integer c) (char->integer #\0))))

Reverse the order of a given integer - Scheme

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

Can't seem to get this function to work in scheme

Here is what I have done so far:
(define sumOdd
(lambda(n)
(cond((> n 0)1)
((odd? n) (* (sumOdd n (-(* 2 n) 1)
output would look something like this:
(sumOdd 1) ==> 1
(sumOdd 4) ==> 1 + 3 + 5 + 7 ==> 16
(sumOdd 5) ==> 1 + 3 + 5 + 7 + 9 ==> 25
This is what I am trying to get it to do: find the sum of the first N odd positive integers
I can not think of a way to only add the odd numbers.
To elaborate further on the sum-odds problem, you might solve it in terms of more abstract procedures that in combination accumulates the desired answer. This isn't necessarily the easiest solution, but it is interesting and captures some more general patterns that are common when processing list structures:
; the list of integers from n to m
(define (make-numbers n m)
(if (= n m) (list n) ; the sequence m..m is (m)
(cons n ; accumulate n to
(make-numbers (+ n 1) m)))) ; the sequence n+1..m
; the list of items satisfying predicate
(define (filter pred lst)
(if (null? lst) '() ; nothing filtered is nothing
(if (pred (car lst)) ; (car lst) is satisfactory
(cons (car lst) ; accumulate item (car lst)
(filter pred (cdr lst))) ; to the filtering of rest
(filter pred (cdr lst))))) ; skip item (car lst)
; the result of combining list items with procedure
(define (build-value proc base lst)
(if (null? lst) base ; building nothing is the base
(proc (car lst) ; apply procedure to (car lst)
(build-value proc base (cdr lst))))) ; and to the building of rest
; the sum of n first odds
(define (sum-odds n)
(if (negative? n) #f ; negatives aren't defined
(build-value + ; build values with +
0 ; build with 0 in base case
(filter odd? ; filter out even numbers
(make-numbers 1 n))))) ; make numbers 1..n
Hope this answer was interesting and not too confusing.
Let's think about a couple of cases:
1) What should (sumOdd 5) return? Well, it should return 5 + 3 + 1 = 9.
2) What should (sumOdd 6) return? Well, that also returns 5 + 3 + 1 = 9.
Now, we can write this algorithm a lot of ways, but here's one way I've decided to think about it:
We're going to write a recursive function, starting at n, and counting down. If n is odd, we want to add n to our running total, and then count down by 2. Why am I counting down by 2? Because if n is odd, n - 2 is also odd. Otherwise, if n is even, I do not want to add anything. I want to make sure that I keep recursing, however, so that I get to an odd number. How do I get to the next odd number, counting down from an even number? I subtract 1. And I do this, counting down until n is <= 0. I do not want to add anything to my running total then, so I return 0. Here is what that algorithm looks like:
(define sumOdd
(lambda (n)
(cond ((<= n 0) 0)
((odd? n) (+ n (sumOdd (- n 2))))
(else (sumOdd (- n 1))))))
If it helps you, here is a more explicit example of a slightly different algorithm:
(define sumOdd
(lambda (n)
(cond ((<= n 0) 0)
((odd? n) (+ n (sumOdd (- n 1))))
((even? n) (+ 0 (sumOdd (- n 1))))))) ; note that (even? n) can be replaced by `else' (if its not odd, it is even), and that (+ 0 ..) can also be left out
EDIT:
I see that the problem has changed just a bit. To sum the first N positive odd integers, there are a couple of options.
First option: Math!
(define sumOdd (lambda (n) (* n n)))
Second option: Recursion. There are lots of ways to accomplish this. You could generate a list of 2*n and use the procedures above, for example.
You need to have 2 variables, one which keep counter of how many odd numbers are still to be added and another to hold the current odd number which gets increment by 2 after being used in addition:
(define (sum-odd n)
(define (proc current start)
(if (= current 0)
0
(+ start (proc (- current 1) (+ start 2)) )))
(proc n 1))
Here is a nice tail recursive implementation:
(define (sumOdd n)
(let summing ((total 0) (count 0) (next 1))
(cond ((= count n) total)
((odd? next) (summing (+ total next)
(+ count 1)
(+ next 1)))
(else (summing total count (+ next 1))))))
Even shorter tail-recursive version:
(define (sumOdd n)
(let loop ((sum 0) (n n) (val 1))
(if (= n 0)
sum
(loop (+ sum val) (- n 1) (+ val 2)))))

How to improve this piece of code?

My solution to exercise 1.11 of SICP is:
(define (f n)
(if (< n 3)
n
(+ (f (- n 1)) (* 2 (f (- n 2))) (* 3 (f (- n 3))))
))
As expected, a evaluation such as (f 100) takes a long time. I was wondering if there was a way to improve this code (without foregoing the recursion), and/or take advantage of multi-core box. I am using 'mit-scheme'.
The exercise tells you to write two functions, one that computes f "by means of a recursive process", and another that computes f "by means of an iterative process". You did the recursive one. Since this function is very similar to the fib function given in the examples of the section you linked to, you should be able to figure this out by looking at the recursive and iterative examples of the fib function:
; Recursive
(define (fib n)
(cond ((= n 0) 0)
((= n 1) 1)
(else (+ (fib (- n 1))
(fib (- n 2))))))
; Iterative
(define (fib n)
(fib-iter 1 0 n))
(define (fib-iter a b count)
(if (= count 0)
b
(fib-iter (+ a b) a (- count 1))))
In this case you would define an f-iter function which would take a, b, and c arguments as well as a count argument.
Here is the f-iter function. Notice the similarity to fib-iter:
(define (f-iter a b c count)
(if (= count 0)
c
(f-iter (+ a (* 2 b) (* 3 c)) a b (- count 1))))
And through a little trial and error, I found that a, b, and c should be initialized to 2, 1, and 0 respectively, which also follows the pattern of the fib function initializing a and b to 1 and 0. So f looks like this:
(define (f n)
(f-iter 2 1 0 n))
Note: f-iter is still a recursive function but because of the way Scheme works, it runs as an iterative process and runs in O(n) time and O(1) space, unlike your code which is not only a recursive function but a recursive process. I believe this is what the author of Exercise 1.1 was looking for.
I'm not sure how best to code it in Scheme, but a common technique to improve speed on something like this would be to use memoization. In a nutshell, the idea is to cache the result of f(p) (possibly for every p seen, or possibly the last n values) so that next time you call f(p), the saved result is returned, rather than being recalculated. In general, the cache would be a map from a tuple (representing the input arguments) to the return type.
Well, if you ask me, think like a mathematician. I can't read scheme, but if you're coding a Fibonacci function, instead of defining it recursively, solve the recurrence and define it with a closed form. For the Fibonacci sequence, the closed form can be found here for example. That'll be MUCH faster.
edit: oops, didn't see that you said forgoing getting rid of the recursion. In that case, your options are much more limited.
See this article for a good tutorial on developing a fast Fibonacci function with functional programming. It uses Common LISP, which is slightly different from Scheme in some aspects, but you should be able to get by with it. Your implementation is equivalent to the bogo-fig function near the top of the file.
To put it another way:
To get tail recursion, the recursive call has to be the very last thing the procedure does.
Your recursive calls are embedded within the * and + expressions, so they are not tail calls (since the * and + are evaluated after the recursive call.)
Jeremy Ruten's version of f-iter is tail-recursive rather than iterative (i.e. it looks like a recursive procedure but is as efficient as the iterative equivalent.)
However you can make the iteration explicit:
(define (f n)
(let iter
((a 2) (b 1) (c 0) (count n))
(if (<= count 0)
c
(iter (+ a (* 2 b) (* 3 c)) a b (- count 1)))))
or
(define (f n)
(do
((a 2 (+ a (* 2 b) (* 3 c)))
(b 1 a)
(c 0 b)
(count n (- count 1)))
((<= count 0) c)))
That particular exercise can be solved by using tail recursion - instead of waiting for each recursive call to return (as is the case in the straightforward solution you present), you can accumulate the answer in a parameter, in such a way that the recursion behaves exactly the same as an iteration in terms of the space it consumes. For instance:
(define (f n)
(define (iter a b c count)
(if (zero? count)
c
(iter (+ a (* 2 b) (* 3 c))
a
b
(- count 1))))
(if (< n 3)
n
(iter 2 1 0 n)))

Resources