How do I generate random in Scheme? Is there a special form or would I have to create a procedure? And if so, how do I do that? (I'm trying to create a procedure called random-choice that inputs two strategies and returns one at random.)
Standard Scheme does not provide a random number generator, and although most Scheme implementations provide one, they tend to differ in their details. If you want to write a portable Scheme program, it's easy to build your own random number generator; here's a method due to Knuth:
(define random
(let ((a 69069) (c 1) (m (expt 2 32)) (seed 19380110))
(lambda new-seed
(if (pair? new-seed)
(set! seed (car new-seed))
(set! seed (modulo (+ (* seed a) c) m)))
(/ seed m))))
Calling (random) returns a random fraction between 0 (inclusive) and 1 (exclusive). The random fractions cycle with period m. Calling (random seed) resets the seed of the random number generator, so that two random sequences starting from the same seed will be identical; dates in the form YYYYMMDD make good seeds (that's Knuth's birthday above). If you want to flip a coin, say: (if (< (random) 1/2) 'heads 'tails).
Sometimes you want a random integer over a range. The randint function shown below returns a random integer on the range lo (inclusive) to hi (exclusive); lo defaults to 0:
(define (randint . args)
(cond ((= (length args) 1)
(floor (* (random) (car args))))
((= (length args) 2)
(+ (car args) (floor (* (random) (- (cadr args) (car args))))))
(else (error 'randint "usage: (randint [lo] hi)"))))
Random numbers such as these are good enough for simple simulations, but beware they are not suitable for cryptographic applications. If you are interested, I have several random number generators, including some suitable for cryptographic applications, at my blog.
The procedure is called, surprisingly enough, random - although the exact syntax might be different depending on the Scheme interpreter in use (read the documentation!), but the general idea is as follows:
(random)
=> 0.9113789707345018
For returning one of two possible values, this will do the trick in Racket:
(define (random-choice a b)
(if (zero? (random 2)) a b))
Notice that the 2 argument passed to random forces it to randomly return one of two possible values: 0 or 1. So if (random 2) evaluates to 0 then a is returned, otherwise b is returned.
(random-choice 4 2)
=> 4
(random-choice 4 2)
=> 2
Since your other question was about implementing a spaceship game in DrRacket, I will assume, that by Scheme you mean one of the teaching languages in DrRacket.
The way to find information on available functions in DrRacket is simple. Write, say, random in the interaction window. Place the cursor on top, and then press F1.
The documentation on the random in htdp-languages is here:
http://docs.racket-lang.org/htdp-langs/beginner.html?q=random#(def.htdp-beginner.((lib._lang/htdp-beginner..rkt)._random))
One way to return a random value:
(list-ref (list "one" "two") (random 2))
Here (random 2) will return 0 or 1.
The list-ref will thus return either the entry
with index 0 or index 1 of the list.
The advantage of using the above approach
is that it is easy to extend to more values
than two.
Related
Let's take the following function to get a pair of numbers:
; (range 1 3) --> '(1 2 3)
(define (range a b)
(if (> a b) nil
(cons a (range (+ 1 a) b))))
; generate pair of two numbers with 1 <= i < j <= N
(define (get-pairs n)
(map (lambda (i)
(map (lambda (j) (list i j))
(range 1 (- i 1))))
(range 1 n)))
(get-pairs 2)
; (() ((2 1)))
(get-pairs 3)
(() ((2 1)) ((3 1) (3 2)))
Why does the above produce '() as the first element of the output? Comparing this with python, I would expect it to just give the three pairs, something like:
>>> for i in range(1,3+1): # +1 because the range is n-1 in python
... for j in range(1,i-1+1):
... print (i,j)
...
(2, 1)
(3, 1)
(3, 2)
I suppose maybe it has to do with when i is 1?
(map (lambda (j) (list 1 j)) '())
; ()
Is that just an identity in Scheme that a map with an empty list is always an empty list?
When i is 1, the inner map is over (range 1 0), which is () by your own definition. Since map takes a procedure and a list (or lists) of values, applies the procedure to each value in the list in turn, and returns a list containing the results, mapping any procedure over a list containing no values will return a list containing no values.
It might help to create a simple definition for map to see how this might work. Note that this definition is not fully featured; it only takes a single list argument:
(define (my-map proc xs)
(if (null? xs)
'()
(cons (proc (car xs))
(my-map proc (cdr xs)))))
Here, when the input list is empty, there are no values to map over, so an empty list is returned. Otherwise the procedure proc is applied to the first value in the input list, and the result is consed onto the result of mapping over the rest of the list.
A couple of observations:
First, the empty list is not represented by nil in either standard Scheme or vanilla Racket, and you should not be using it. In the early days of Scheme nil was allowed as a crutch for programmers coming from other lisps, but this has not been the case for a long time. I don't think that it was ever in any of the RnRS standards, but nil may have survived in some specific implementations until maybe R4RS (1991). SICP was from that era. Today you should use '() to represent empty list literals in Scheme so that your code can run on any Scheme implementation. Racket's #lang sicp allows code directly from the book to be run, but that should not keep you from using the common notation. Note that Common Lisp does use nil as a self-evaluating symbol to represent both the empty list, and boolean false. Seeing this in Scheme just doesn't look right today.
Second, you will probably be led astray more often than to wisdom by thinking in terms of Python when trying to understand Scheme code. In this particular case, map is an iteration construct, but it is not the same thing as a for loop. A for loop is usually used for side-effects, but map is used to transform a list. Scheme has a for-each form which is meant to be used for its side-effects, and in that sense is more like a for loop. The Python version that is posted above is not at all like the Scheme version, though. Instead of returning the results in a list, the results are printed. In the Scheme code, when i is 1, the inner mapping is over (range 1 0) --> (). But, in the Python code, when i is 1, the inner loop is over range(1, 1), so the body of this for loop is not executed and nothing is printed.
Better to think carefully about the Scheme code you want to understand, falling back on basic definitions, than to cobble together a model based on Python that has possibly unconsidered corner cases.
I am working on coming up with a solution for coming with a list of prime numbers using the Sieve of Eratosthenes. So the program is supposed to find prime numbers up to a specific number "n". I believe I have come up with an incomplete solution but not sure how to proceed from here.
;;;This is a helper function
(define sievehelper
(lambda (list)
;;; This is the base condition where we are comparing
;;; that the divisor is less than the square root of n""
(if (> (car list) (sqrt (car (reverse list))))
'()
;;; If the base condition has not be reached, then send it through
;;; this filter function where not-divisible by will go through
;;; the specified list and only output the list which contains
;;; the numbers that are not divisible by (car list)
(filterfunc (not-divisible-by (car list))
list)))
I have tested the other helper function fliterfunc on its own and it works fine.
;;;; This is the main function that calls the above helper function
(define sieve
(lambda (n)
;;; `makelist` is a helper function to generate the list from 2 to n
(sievehelper (makelist n))))
I have tested the makelist helper function separately and it works fine.
My question is with the helper function "sievehelper" in terms of how to iterate through the different elements in the list as the divisor.
Any help is appreciated. Thank you.
One piece of code that leads to getting stuck is (if ( > (car list) (sqrt (car(reverse list)))), which looks a lot like the loop condition you might use in other languages (and the word "iterate" hints at peeking at other languages, as well).
I would recommend that you start over, with a different strategy.
When you work with lists, you usually want to recurse on their structure alone.
Assume that you have the list of all integers, starting with 2.
As a first step, you want to keep the two, and remove all its multiples from the remainder of the list.
Now, the result of that removal will give you a list that starts with the next prime number - i.e. 3 - so you can repeat the procedure with that partial result which will remove all multiples of 3, and repeat again with that partial result, and so on until there is no more list.
(Note that this is far from as efficient as it could be, but is more a "get started with thinking recursively" level of suggestion. Read Will's answer for more.)
Applying some wishful thinking and assuming that there is a procedure remove-multiples-of which does what it sounds like, this could look like this:
(define (my-sieve-helper ls)
(if (null? ls)
'()
(cons (car ls)
(my-sieve-helper (remove-multiples-of (car ls) (cdr ls))))))
So, remove-multiples-of...
This is the same as keeping all the numbers that are not divisible by a number, so let's dream up another function:
(define (remove-multiples-of x ls) (filter (not-divisible-by x) ls))
where (not-divisible-by x) is a procedure that takes a number and returns whether that number is not divisible by x.
(define (not-divisible-by n) (lambda (x) (not (zero? (remainder x n)))))
And now we can add a suitable wrapper.
I did this:
(define (from-to m n)
(if (> m n)
'()
(cons m (from-to (+ m 1) n))))
(define (my-sieve n) (my-sieve-helper (from-to 2 n)))
Test:
> (my-sieve 100)
'(2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71 73 79 83 89 97)
Well, your question presents an interesting case of under-specification that can be advantageous, delaying the actual specification -- not just implementation as usual -- of subroutines used by your piece of code.
Here we have sievehelper which uses the non-implemented non-specified filterfunc and not-divisible-by. Despite their suggestive names these function can do anything, as long as they work, when used together, and make the function using them, sievehelper, also do its work as intended. Delayed specification for the win!
So let's first see what can be intended with the sievehelper as given, what does it do? Assuming the obvious meaning of the two subroutines, it seems to be intended to perform a one-step filtering of its working sequence, culling it from any multiples of its "head" element, the one in its car position.
It would signal the stopping condition by returning (). That stopping condition is a*a > z, for the input list of [a,b,c,...,z].
Otherwise, it does not perform the looping, but just the one step of it. Your sieve doesn't account for that at all, so will need to be changed to continually call this helper, performing step after step as is usual in sieving algorithms, until the square of the first element is bigger than the last element in the working sequence, when it is indeed safe to stop the culling as all the multiples in the sequence will have already been removed from it as multiples of the smaller primes ...... provided that those smaller primes were present in the initial sequence.
So this discovered requirement falls on the third non-implemented subrouting in use, makelist. You do mention that it must create the list of sequential natural numbers from 2 to n, and now we understand why we needed it to do so.
So then, in order to iterate through the different versions of the input list as each divisor is filtered out from it in turn, using your sievehelper definition as given, your sieve function must be changed as e.g.
(define sieve
(lambda (n)
(let ((init (makelist n)))
(let loop ((this init )
(next (sievehelper init)))
(if (null? next)
this
(cons (car this)
(loop next
(sievehelper next))))))))
(The above code incorporates the fix by ad-absurdum from the followup Q&A entry, to the error that this code originally contained).
This code comes from the perspective of working with a pair -- the current sequence, and its next iteration. On each step the next version of the list is found after all the multiples of its head element are removed from it by sievehelper (including the head element itself, the next found prime) -- or the empty list is instead returned to signal the end of processing when all the numbers in the list are known to already be prime, by construction.
Trying it out in Racket:
> (sieve 50)
'(2 3 5 7 11 13 17 19 23 29 31 37 41 43 47)
To run it, further definitions had to be made:
(define filterfunc filter)
(define (not-divisible-by n) ; NB! this critically depends on
(let ((m n)) ; filterfunc working over its
(lambda (x) ; argument list _in order_ NB!
(let ((ret (not (= x m))))
(if (>= x m) (set! m (+ m n)) #f)
ret))))
(define (makelist n)
(range 2 (+ 1 n))) ; in Racket
Defining the not-divisible-by as we did here, enumerating the multiples of each prime internally by iterated additions, makes it be the sieve of Eratosthenes indeed. And stopping early (at the square root of the limit), as in your original code, keeps its time complexity on the sane side, closer to optimal.
write a function in lisp called number(N) that you have to use a nonnegative integer N, and produce the list of all integers from 1 up to and including N.
(defun numbers (N)
(if (<= N 0)
nil
(cons N nil)
(numbers (- N 1)))
I checked some questions, but most of them use loop and range, but this question doesn't allowed me to do this, so I have to use recursion instead:
here is my code, but this code keeps giving me warning:
; caught STYLE-WARNING:
; The variable N is defined but never used.
;
; compilation unit finished
; caught 1 ERROR condition
; caught 1 STYLE-WARNING condition
I think my algorithm is correct ,but because I am new to lisp, I still don't know how to write the function properly. It is grateful if anyone could gave me any help.
IF has generally a common syntax, but there are exceptions
Generally in Lisps like Common Lisp the if operator allows the following syntax:
IF test-form then-form [else-form]
This means that in Lisp usually zero or one else-form are allowed. An example is if in Common Lisp.
In Emacs Lisp multiple else-forms are allowed. Emacs Lisp has the following syntax:
IF test-form then-form else-form*
This means that in Emacs Lisp zero or more else-forms are allowed.
Thus: it's important to mention which language&dialect you are actually using.
Your code
a) Let's assume that you use Common Lisp with its IF syntax.
Your code:
(defun numbers (N)
(if (<= N 0)
nil
(cons N nil)
(numbers (- N 1)))
Your code has the problem, that there are more than one else clauses. You need to write a version which has a single else clause.
b) Let's assume that you use Emacs Lisp with its IF syntax with multiple else forms.
Your code:
(defun numbers (N)
(if (<= N 0)
nil
(cons N nil)
(numbers (- N 1)))
Here the (cons N nil) form is allowed, but has no effect. Its return value is not used and it has no side effect. You could delete it and it would make no difference. Again: you would need how to combine its effect with the form (numbers (- N 1)).
Syntax error: missing closing parenthesis
There is another problem in your code. The s-expressions are not complete -> a closing parenthesis is missing:
(defun numbers (N)
(if (<= N 0)
nil
(cons N nil)
(numbers (- N 1)))
As you can see a closing parenthesis is missing at the end.
Thus your code can not be read by Lisp.
There are two ways one generally can avoid this problem:
count the parentheses and set them accordingly
use the editor to count the parentheses
Most people prefer the latter.
The way to think about this is to think about what the algorithm should be:
To compute the numbers from 1 to n:
if n is less than 1 then there are no numbers, so this is the empty list;
otherwise we want a list which looks like (... n), where ... is all the numbers from 1 to n-1.
Note that we want the numbers in forward order: this is going to be critical.
Doing this is slightly difficult in Lisp because we want the number to be at the end of the list, and access to the ends of lists is hard.
Here is the start of a version which builds the list backwards (so this is not the right answer).
(defun numbers (n)
(if (< n 1)
'() ;the empty list
;; n 1 or more, so build a list which is (n . ...)
(cons n <some function involving n>)))
Well, OK, what function should we call recursively? Do we have a function which returns the list we want? Well, yes: it's numbers, with an argument which is one less than n!
(defun numbers (n)
(if (< n 1)
'()
(cons n (numbers (- n 1)))))
And this function works. But it gets the wrong answer: the list is backwards:
> (numbers 10)
(10 9 8 7 6 5 4 3 2 1)
There are two fixes to this problem: the first is to build the list forwards, using append. This version looks like this (remember append wants to append two lists: it doesn't append an element to the end of a list):
(defun numbers (n)
(if (< n 1)
'()
(append (numbers (- n 1)) (list n))))
This gets the right answer:
> (numbers 10)
(1 2 3 4 5 6 7 8 9 10)
but it's a terrible answer: append has to walk all the way down the list (lists in Lisp are chains of conses: there is no fast access to the end of a list), copying it as it goes, to append the new element. So this has absolutely terrible space & time complexity. Programs written like this are why 'Lisp is slow'.
A better approach is to build the list backwards and then reverse it.
(defun numbers (n)
(reverse (numbers-backwards n)))
(defun numbers-backwards (n)
(if (< n 1)
'()
(cons n (numbers-backwards (- n 1)))))
The problem with this, from the homework perspective, might be that using reverse is not allowed. That's OK, we can write it, recursively. The implementation is slightly fiddly, but this is going to help us below.
(defun reverse-list (l)
;; in real life reverse-list-accumulator would be a local function
(reverse-list-accumulator l '()))
(defun reverse-list-accumulator (l accum)
(if (null l)
accum
(reverse-list-accumulator (rest l) (cons (first l) accum))))
The way this works is that reverse-list calls this auxiliary function with an extra argument. The auxiliary function then checks the list, and if it's not empty it calls itself with the tail of the list and the head of the list consed onto the auxiliary argument. If it is empty, it returns the auxiliary argument. It's a little subtle but you can see that this in fact reverses the list.
So now we can write our function using only recursive functions we wrote:
(defun numbers (n)
(reverse-list (numbers-backwards n)))
But now there should be a moment of inspiration: why are we doing this whole
build-it-backwards-and-reverse-it thing? Why don't we just make numbers do the accumulator trick itself! Well, we can do that:
(defun numbers (n)
(numbers-accumulator n '()))
(defun numbers-accumulator (n accum)
(if (< n 1)
accum
(numbers-accumulator (- n 1) (cons n accum))))
And now we don't need to reverse the list, and for added value our
function is 'tail recursive' and will generally be compiled much more
efficiently.
A real-life version of numbers might look more like this, using a local function:
(defun numbers (n)
(labels ((numbers-accumulator (m accum)
(if (< m 1)
accum
(numbers-accumulator (- m 1) (cons m accum)))))
(numbers-accumulator n '())))
Here is a comparison between the version of numbers using append and the above function, on an argument small enough that the append version does not overflow the stack.
> (time (progn (numbers/append 2000) (values)))
Timing the evaluation of (progn (numbers/append 2000) (values))
User time = 0.024
System time = 0.001
Elapsed time = 0.017
Allocation = 32176304 bytes
97 Page faults
> (time (progn (numbers 2000) (values)))
Timing the evaluation of (progn (numbers 2000) (values))
User time = 0.000
System time = 0.000
Elapsed time = 0.001
Allocation = 32000 bytes
0 Page faults
You can see how terrible the append version is, and how good the other one is: this is a 64-bit Lisp, and conses are two words or 16 bytes: it has allocated precisely 2000 cons cells which is the minimum it could do.
I am trying to programmatically increment a purely alphabetical string in Scheme.
Like this "MA", then "MB" and when it reaches "MZ", it should become "MAA" and so on till "MZZ" and then it should become "MAAA" and so on.The "M" needs to be added as a prefix for the kind of work that I am doing.
I looked at this question: Incrementing alphabets and this is exactly what I want.
However, I have absolutely no idea from where to start. For starters I am not even sure how to handle ASCII in scheme. I am not expecting the whole code, but I would appreciate it if I got a few hints.
Here's my implementation. Note that you need to load SRFI 1, which provides unfold-right:
(define letters "ABCDEFGHIJKLMNOPQRSTUVWXYZ")
(define (number->letters num)
(unfold-right negative?
(lambda (i) (string-ref letters (remainder i 26)))
(lambda (i) (- (quotient i 26) 1))
num))
(define (number->tag num)
(list->string (cons #\M (number->letters num))))
Examples:
> (number->tag 0)
"MA"
> (number->tag 18277)
"MZZZ"
> (number->tag 18278)
"MAAAA"
The OP asked for an explanation of what the code does. So, with the understanding that the OP already understands the algorithm (since they linked to it already), what's basically left is the unfold operation.
Fold and unfold are a bit lengthy to explain and I don't want to derail this post by explaining them, but it's possible to "expand" the unfold into the equivalent loop (using the same variable names as the SRFI 1 reference implementation of unfold-right) to express what's going on:
(define (number->letters num)
(let lp ((seed num) (ans '()))
(if (negative? seed)
ans
(lp (- (quotient seed 26) 1)
(cons (string-ref letters (remainder seed 26)) ans)))))
Basically, it builds a list, from right to left, using (string-ref letters (remainder seed 26)) each iteration (where seed is num in the initial iteration). seed's value is then updated to (- (quotient seed 26) 1) for the next iteration. The list stops when (negative? seed) is true.
You might then ask why one would use an unfold instead of the loop. Basically, in functional programming, when a "concept" can be expressed in higher-level terms (e.g., for-each, map, filter, fold, or unfold), using those terms helps other programmers understand what the code does. It's a bit like "design patterns" (as commonly used in object-oriented programming), within a functional programming context. :-)
I have tried to write a procedure that gets an integer as parameter and returns true if the number is a palindrome and false otherwise and it seems to be that there is a problem with changing a global parameter's value whithin an internal function block.
(define index 0)
(define (palindrome? x)
(if (= (lenght x) 1)
#t
(if (last_equal_first x)
(palindrome? (remove x))
#f)))
(define (lenght x)
(define index **(+ index 1))**
(if (= (modulo x (ten_power index)) x)
index
(lenght x)))
(define (last_equal_first x)
(if (= (modulo x 10) (modulo x (/ (ten_power (lenght x)) 10)))
#t
#f))
I would like to know what can I do about it
thanks!
Well, one problem is that you're redefining index after it's been used, in the length function. define doesn't really do what you want here - you want set!.
However, I think you'll find another bug when you try to call the length function more than once - you never set index to 0 after the first time, so I believe your length function will only work once.
However, this seems like it might be a homework assignment. Would you like clear instructions on fixing these problems, or would you like clues that lead you to understand the algorithm more?
What that (define ...) statement does in lenght is create a new variable called "index" that is more locally scoped than the "index" you defined at the top. That's only the superficial problem---more importantly, it looks like you're trying to write C code using Scheme. In a simple homework assignment like this, you should not need to use global variables, nor should you ever have to change a variable once it's created. Many programmers have trouble shifting how they think when first learning functional programming.
The way you've written lenght is not so much recursion as just a glorified while loop! There is no point to recursion if (lenght x) only calls (lenght x) again. For example, here's how I would write digits to count how many base-10 digits are in a number:
(define digits
(lambda (n)
(letrec ([digit-helper (lambda (n index)
(if (= (modulo n (expt 10 index)) n)
index
(digit-helper n (add1 index))))])
(digit-helper n 0))))
Notice how I never change a variable once it's been created, but only create new variables each time. Since I need to keep track of index, I created helper function digit-helper that takes two arguments to mask the fact that digit only takes one argument.