how to take apart numbers into integer & fractional part in scheme? - scheme

I want a function number->second-pair that accepts a number and returns a pair of integer representing its integer part & fractional part multipled with 1000000.
i.e.:
(number->second-pair 1)
; returns (1 . 0)
; 1 sec -> (1 sec + 0 usec)
(number->second-pair 5.1234)
; returns (5 . 123400)
; 5.1234 sec -> (5 sec + 123400 usec)
It might be easy for you to find a solution, but I've searched many docs and sadly can't find the way to convert numbers to integers. Can someone help me out?
BTW:
Actually I want a preciser alarm(this one) by making use of setitimer, so I want exact integers passed as arguments.

I may be a bit rusty with scheme but I think something like this would work for you,
(define (number->second-pair n)
(cons (inexact->exact (floor n))
(inexact->exact (floor (* 1000000 (- n (floor n)))))))
(number->second-pair 5.1234) returns (5 . 123400)
(number->second-pair 1) returns (1 . 0)

Related

Are there any default arguments for procedures if they have only one?

Could someone explain the following expression
> (+)
0
> (+ 1)
1
> (- 1)
-1
> (/ 1)
1
> (/ 2)
1/2
> (/ 3)
1/3
If there is a default argument of 1, why does (+ 1) return 1 while (/ 2) return 1/2 ?
Shouldn't (+ 1) return 2 ?
For + and * the implicit default first argument is the identity element for the mathematical operations they represent, which are the addition and multiplication operations over various number fields. For + this is 0 which is the identity element for the group of addition over numbers; for * this is 1 which is the identity element for multiplication over numbers.
So
(+) is (+ 0) is 0;
(+ 1) is (+ 0 1) is 1;
(*) is (* 1) is 1;
(* 2) is (* 1 2) is 2.
For - and / the implicit default arguments are the appropriate identities of the operations that these are the inverses of as well, although these functions require at least one argument, and their behaviour with more than one argument is not quite as simple.
So
(-) is an error (I don't see why it should not be 0);
(- 1) is (- 0 1) is -1;
(- 1 2) is not (- 0 1 2);
(/) is an error (I don't see why it should not be 1);
(/ 2) is (/ 1 2) is 1/2;
(/ 3 2) is not (/ 1 3 2).
To be really precise, in the Scheme context, the default arguments are the exact numbers representing the identities I think.
Note that these default arguments are just chosen for mathematical convenience: this is not something inherent in the design of the language. I could define a language where (+) was "foo", although it would probably not be a very useful language.
If there are default argument 1, why (+ 1) return 1 ...
Look carefully. For +, the "default argument" is actually 0 (and not 1 as you claim):
> (+)
0
This is exactly what the documentation says about +:
... If no arguments are provided, the result is 0.
Then when you add 1 to 0, you get 1:
> (+ 1)
1
(Note: If you want to add 1 to a number, use add1. e.g. (add1 1) -> 2)
For a variadic procedure (i.e. a procedure that can take a variable number of arguments), the "default argument" depends on how the procedure was implemented. For example, if you define a variadic procedure using (define (f . arglist) ...), the implicit default argument depends on how the body of the procedure makes use of arglist.
You should understand the reduce and fold operations. + and - can be expressed as reductions, but in reductions you explicitly see the value for empty set of operands.

Implementing a math formula in Scheme (DrRacket)

Let me start off by saying that I am a complete novice when it comes to Scheme/Racket. I am trying to implement the following formula:
αi = (3/h)((ai+1 – ai) – (ai – ai-1))
Here is how I've defined my function:
(define alpha_values (lambda (y_values h n) (...))
What I would like it to do is to run the function with a list of y_values along with some constant h and a number n, then compute and return a list of α values. n will go from 1 to n-1, so the first and last element of the list are not going to be iterated upon.
For example, if the list of y_values is '(2 4 6 8) and h is 1 and n is 3 then there should be two α values returned: one for i=1 (y=4), and one for i=2 (y=6), like so: 3*((6-4)-(4-2)) = 0 and 3*((8-6)-(6-4)) = 0 returns '(0 0) for α.
Truthfully, I'm lost as to how to even begin to implement this. I thought about using map but I don't know if it's possible to skip the first and last element while doing so. I've tried doing so recursively using car and cdr but I ran into the issue of "losing" an element in the list needed for the calculation when recursively calling the function again without the first element. I would appreciate some insight as to how to approach the implementation of this formula – not an answer, just an idea as to how to get the ball rolling.
Whenever you are unsure about how to approach a particular problem, consider breaking it down to smaller tasks that are easier to manage, think about, and implement.
For example, going backwards from the end result, you want to produce a list of alphas, whereby each alpha is created from h and an interval {a_i-1, a_i, a_i+1} using the noted formula.
So one small function you can create would be the function, lets call it compute-alpha, that takes an interval and h as arguments, then produces an alpha using the formula. Ie:
(define (compute-alpha interval h)
...)
The body of this function will simply be the formula, and it will behave as follows:
> (compute-alpha '(2 4 6) 1)
0
> (compute-alpha '(4 6 8) 1)
0
But then you realize that you don't have the intervals (eg. '(2 4 6), '(4 6 8) etc) in order to use compute-alpha. So next step is to define another small function, lets call it build-intervals, that takes y-values and n as arguments, and produces a list of intervals. Ie:
(define (build-intervals y-values n)
...)
and behaves as follows:
> (build-intervals '(2 4 6 8) 3)
'((2 4 6) (4 6 8))
> (build-intervals '(1 2 3 4 5 6 7) 4)
'((1 2 3) (2 3 4) (3 4 5))
Now, all that is left is applying compute-alpha on every interval produced by build-intervals. And this is where map shines:
(define (alpha-values y-values h n)
(map (lambda (interval)
(compute-alpha interval h))
(build-intervals y-values n)))
Then you can have:
> (alpha-values '(2 4 6 8) 1 3)
'(0 0)
Once you implement build-intervals and compute-alpha, you might notice ways of combining them to reduce alpha-values to a single function that iterates y-values only once before producing the list of alphas.

Iterative tree calculation in scheme

I'm trying to implement a function defined as such:
f(n) = n if n < 4
f(n) = f(n - 1) + 2f(n - 2) + 3f(n - 3) + 4f(n - 4) if n >= 4
The iterative way to do this would be to start at the bottom until I hit n, so if n = 6:
f(4) = (3) + 2(2) + 3(1) + 4(0) | 10
f(5) = f(4) + 2(3) + 3(2) + 4(1) | 10 + 16 = 26
f(6) = f(5) + 2f(4) + 3(3) + 4(2) | 26 + 2(10) + 17 = 63
Implementation attempt:
; m1...m4 | The results of the previous calculations (eg. f(n-1), f(n-2), etc.)
; result | The result thus far
; counter | The current iteration of the loop--starts at 4 and ends at n
(define (fourf-iter n)
(cond [(< n 4) n]
[else
(define (helper m1 m2 m3 m4 result counter)
(cond [(= counter n) result]
[(helper result m1 m2 m3 (+ result m1 (* 2 m2) (* 3 m3) (* 4 m4)) (+ counter 1))]))
(helper 3 2 1 0 10 4)]))
Several problems:
The returned result is one iteration less than what it's supposed to be, because the actual calculations don't take place until the recursive call
Instead of using the defined algorithm to calculate f(4), I'm just putting it right in there that f(4) = 10
Ideally I want to start result at 0 and counter at 3 so that the calculations are applied to m1 through m4 (and so that f(4) will actually be calculated out instead of being preset), but then 0 gets used for m1 in the next iteration when it should be the result of f(4) instead (10)
tl;dr either the result calculation is delayed, or the result itself is delayed. How can I write this properly?
I think the appropriately "Scheme-ish" way to write a function that's defined recursively like that is to use memoization. If a function f is memoized, then when you call f(4) first it looks up 4 in a key-value table and if it finds it, returns the stored value. Otherwise, it simply calculates normally and then stores whatever it calculates in the table. Therefore, f will never evaluate the same computation twice. This is similar to the pattern of making an array of size n and filling in values starting from 0, building up a solution for n. That method is called dynamic programming, and memoization and dynamic programming are really different ways of looking at the same optimization strategy - avoiding computing the same thing twice. Here's a simple Racket function memo that takes a function and returns a memoized version of it:
(define (memo f)
(let ([table (make-hash)])
(lambda args
(hash-ref! table
args
(thunk (apply f args))))))
Now, we can write your function f recursively without having to worry about the performance problems of ever calculating the same result twice, thus going from an exponential time algorithm down to a linear one while keeping the implementation straightforward:
(define f
(memo
(lambda (n)
(if (< n 4)
n
(+ (f (- n 1))
(* 2 (f (- n 2)))
(* 3 (f (- n 3)))
(* 4 (f (- n 4))))))))
Note that as long as the function f exists, it will keep in memory a table containing the result of every time it's ever been called.
If you want a properly tail-recursive solution, your best approach is probably to use the named let construct. If you do (let name ([id val] ...) body ...) then calling (name val ...) anywhere in body ... will jump back to the beginning of the let with the new values val ... for the bindings. An example:
(define (display-n string n)
(let loop ([i 0])
(when (< i n)
(display string)
(loop (add1 i)))))
Using this makes a tail-recursive solution for your problem much less wordy than defining a helper function and calling it:
(define (f n)
(if (< n 4)
n
(let loop ([a 3] [b 2] [c 1] [d 0] [i 4])
(if (<= i n)
(loop (fn+1 a b c d) a b c (add1 i))
a))))
(define (fn+1 a b c d)
(+ a (* 2 b) (* 3 c) (* 4 d)))
This version of the function keeps track of four values for f, then uses them to compute the next value and ditches the oldest value. This builds up a solution while only keeping four values in memory, and it doesn't keep a huge table stored between calls. The fn+1 helper function is for combining the four previous results of the function into the next result, it's just there for readability. This might be a function to use if you want to optimize for memory usage. Using the memoized version has two advantages however:
The memoized version is much easier to understand, the recursive logic is preserved.
The memoized version stores results between calls, so if you call f(10) and then f(4), the second call will only be a table lookup in constant time because calling f(10) stored all the results for calling f with n from 0 to 10.

How to count number of digits?

(CountDigits n) takes a positive integer n, and returns the number of digits it contains. e.g.,
(CountDigits 1) → 1
(CountDigits 10) → 2
(CountDigits 100) → 3
(CountDigits 1000) → 4
(CountDigits 65536) → 5
I think I'm supposed to use the remainder of the number and something else but other then that im really lost. what i tried first was dividing the number by 10 then seeing if the number was less then 1. if it was then it has 1 digit. if it doesnt then divide by 100 and so on and so forth. but im not really sure how to extend that to any number so i scrapped that idea
(define (num-digits number digit)
(if (= number digit 0)
1
Stumbled across this and had to provide the log-based answer:
(define (length n)
(+ 1 (floor (/ (log n) (log 10))))
)
Edit for clarity: This is an O(1) solution that doesn't use recursion. For example, given
(define (fact n)
(cond
[(= n 1) 1]
[else (* n (fact (- n 1)))]
)
)
(define (length n)
(+ 1 (floor (/ (log n) (log 10))))
)
Running (time (length (fact 10000))) produces
cpu time: 78 real time: 79 gc time: 47
35660.0
Indicating that 10000! produces an answer consisting of 35660 digits.
After some discussion in the comments, we figured out how to take a number n with x digits and to get a number with x-1 digits: divide by 10 (using integer division, i.e., we ignore the remainder). We can check whether a number only has one digit by checking whether it's less than 10. Now we just need a way to express the total number of digits in a number as a (recursive) function. There are two cases:
(base case) a number n less than 10 has 1 digit. So CountDigits(n) = 1.
(recursive case) a number n greater than 10 has CountDigits(n) = 1+CountDigits(n/10).
Now it's just a matter of coding this up. This sounds like homework, so I don't want to give everything away. You'll still need to figure out how to write the condition "n < 10" in Scheme, as well as "n/10" (just the quotient part), but the general structure is:
(define (CountDigits n) ; 1
(if [n is less than 10] ; 2
1 ; 3
(+ 1 (CountDigits [n divided by 10])))) ; 4
An explanation of those lines, one at a time:
(define (CountDigits n) begins the definition of a function called CountDigits that's called like (CountDigits n).
In Racket, if is used to evaluate one expression, called the test, or the condition, and then to evaluate and return the value of one of the two remaining expressions. (if test X Y) evaluates test, and if test produces true, then X is evaluated and the result is returned, but otherwise Y is evaluated and the result is returned.
1 is the value that you want to return when n is less than 10 (the base case above).
1+CountDigits(n/10) is the value that you want to return otherwise, and in Racket (and Scheme, and Lisp in general) it's written as (+ 1 (CountDigits [n divided by 10])).
It will be a good idea to familiarize with the style of the Racket documentation, so I will point you to the appropriate chapter: 3.2.2 Generic Numerics. The functions you'll need should be in there, and the documentation should provide enough examples for you to figure out how to write the missing bits.
I know this is old but for future reference to anyone who finds this personally I'd write it like this:
(define (count-digits n acc)
(if (< n 10)
(+ acc 1)
(count-digits (/ n 10) (+ acc 1))))
The difference being that this one is tail-recursive and will essentially be equivalent to an iterative function(and internally Racket's iterative forms actually exploit this fact.)
Using trace illustrates the difference:
(count-digits-taylor 5000000)
>(count-digits-taylor 5000000)
> (count-digits-taylor 500000)
> >(count-digits-taylor 50000)
> > (count-digits-taylor 5000)
> > >(count-digits-taylor 500)
> > > (count-digits-taylor 50)
> > > >(count-digits-taylor 5)
< < < <1
< < < 2
< < <3
< < 4
< <5
< 6
<7
7
(count-digits 5000000 0)
>(count-digits 5000000 0)
>(count-digits 500000 1)
>(count-digits 50000 2)
>(count-digits 5000 3)
>(count-digits 500 4)
>(count-digits 50 5)
>(count-digits 5 6)
<7
7
For this exercise this doesn't matter much, but it's a good style to learn. And of course since the original post asks for a function called CountDigits which only takes one argument (n) you'd just add:
(define (CountDigits n)
(count-digits n 0))

decomposing a list of points in drRacket

I have a list of points with the form :
((1.10) (2.980) (3.567) (4.0)...(1000.87 ))
And, to be able to use them in the function plot, I would like to extract the two sublist with the x and the y separated. So I want to have that :
x : (1 2 3 4 ... 1000)
and
y : (10 980 567 0 ... 87)
For the first one I just use (define x ( build-list 1000 (lambda (x) (+ x 1 )))
But for the second one I don't find any function to help me :(
I guess i could make a procedure with a loop that use car and cdr but I am a newbee in racket and I can't do a simple loop (I really miss the simple for and while of the other language)
So does anyone know a already made fonction that could solve my problem?
It looks like your list is made up of decimals, rather than dotted pairs, as I think you want. So it should have spaces between the numbers and the dots. However, that's a minor issue.
For your main question, the simplest thing is probably to map "car" and "cdr" onto your list separately:
(define list-of-points '((1 . 10) (2 . 980) (3 . 567) (4 . 0) ... (1000 . 87)))
(define x (map car list-of-points))
(define y (map cdr list-of-points))
Check out the documentation on map for more information.

Resources