I am given a real number which is between 0 and 1. This is my niceness-factor. This factor is a kind of probability. I mean if it is 0.2, it means that something will be happen with the probability of 1/5.
I tried to use
random
procedure for this. Here is my code piece:
(if (eq? 'c (tit-for-tat my-history other-history))
'c
(if (= (random (/ 1 niceness-factor)) 0) 'c 'd))
However the "random" procedure wants me to give an exact integer number. How can I solve this problem? Is there any procedure similar to random?
Thanks in advance...
Just convert your niceness-factor to an integer-like value (something comparable to the result of random). For example:
(if (eq? 'c (tit-for-tat my-history other-history))
'c
(if (> (random 100) (* 100 niceness-factor))
'c
'd)))
One approach to solving this, would be to use (random 1). Now if the result <= niceness-factor then do "something" else do "nothing".
Rationale:
There is 20% probability of obtaining a number <=0.2 in a range of (0,1) inclusive.
In the modules racket and racket/base (random k) generates an integer from 0 to k-1 inclusive. (k must be between 1 and 4294967087 inclusive) (random gives an inexact number between 0 and 1 exclusive. reference guide: random provided by racket and racket/base
Assuming you are using the racket, and not one of the other languages racket supports, from where you started adding a call to exact-round would be closest to what you started with:
(if (eq? 'c (tit-for-tat my-history other-history))
'c
(if (= (random (exact-round (/ 1 niceness-factor))) 0) 'c 'd))
But I find the following to be simpler:
(if (eq? 'c (tit-for-tat my-history other-history))
'c
(if (<= (random) niceness-factor) 'c 'd))
Related
I try to create a procedure that converts a binary number in a list to a string. Sample output: (binary->string '(1 1 0 1 0 0)) should give "110100".
(define reduce
(lambda (op base x) ;passing by name
(if (null? x)
base
(op (car x) (reduce op base (cdr x))))))
And here is my code:
(define (binary->string lst)
(reduce (number->string lst list->string )))
I know it is wrong but it is the best I came out with so far. Please help me to make it work properly.
Before I will show you solution, here is some advice: when you write Racket code, you should check correct number of arguments and their type.
In this case, you know that reduce needs (op base x), that are three arguments, but when you use some unknown function, like number->string, there is Racket documentation and after short search, you fill find number->string entry:
(number->string z [radix]) → string?
z : number?
radix : (or/c 2 8 10 16) = 10
Returns a string that is the printed form of z (see Printing Numbers) in the base specified by radix. If z is inexact, radix must be 10, otherwise the exn:fail:contract exception is raised.
Examples:
(number->string 3.0)
"3.0"
(number->string 255 8)
"377"
As you can see, you can call this function with one or two arguments, but in both cases, they have to be number. But with this call (number->string lst list->string ), you are passing list and procedure- so I can already tell that your code will end with error. And when you try to call your function in REPL, exactly this happens:
> (binary->string '(1 0 0 1))
. . number->string: contract violation
expected: number?
given: '(1 0 0 1)
argument position: 1st
other arguments...:
After you carefully check what did you write, you should be able to predict what will happen, before you even run your code.
Here is solution:
(define (binary->string lst)
(reduce string-append "" (map number->string lst)))
You will use map to create string from each number in list, then you join these strings with your reduce and string-append.
I am new to Racket, and I am trying to write a recursive function that takes a number n and returns the sum of the squares of the first n integers. For example, (this-function 3) returns 14 because 14 is 9 + 4 + 1 + 0.
I tried creating two separate functions, one that squares each number and returns a list of the squared numbers, and a second that sums up the list. The function the squares each number is:
(define (squared my-list)
(cond [(empty? my-list) empty]
[(zero? my-list) 0]
[else (cons (expt my-list 2)
(cons (squared (sub1 my-list)) empty))]))
which if I run (squared 3) returns (cons 9 (cons (cons 4 (cons (cons 1 (cons 0 empty)) empty)) empty)).
When I run the second function (the sum function):
(define (sum numbers)
(cond
[(empty? numbers) 0]
[else (+ (first numbers) (sum (rest numbers)))]))
and run (sum (squared 3)) I get an error message because (squared 3) returns an extra "cons" in the list.
How can I fix this?
Your logic in squared is a little bit off. I'll explain the issues clause-by-clause.
[(empty? my-list) empty]
This doesn't make any sense since my-list will never even be a list. In fact, my-list is poorly named. The parameter squared takes is a number, not a list. This clause can be completely removed.
[(zero? my-list) 0]
This is what the actual terminating case should be, but it shouldn't return 0. Remember, squared has to return a list, not a number. This case should return empty.
[else (cons (expt my-list 2)
(cons (squared (sub1 my-list)) empty))]))
Finally, this clause is far too complicated. You have the right idea—to cons the new number onto the rest of the list—but you're cons'ing too many times. Remember, the result of (squared (sub1 my-list)) is itself a list, and the second argument of cons is the rest of the list. You don't need the extra cons—you can just eliminate it completely.
Combining these changes, you get this, which does what you want:
(define (squared my-list)
(if (zero? my-list) empty
(cons (expt my-list 2)
(squared (sub1 my-list)))))
(I also replaced cond with if since cond is no longer necessary.)
That said, this code is not very Racket-y. You had a good idea to break up your function into two functions—in functional programming, functions should really only ever do one thing—but you can break this up further! Specifically, you can leverage Racket's built-in higher-order functions to make this type of thing extremely easy.
You can replace your entire squared function by appropriately combining map and range. For example, the following creates a list of the squares from 0–3.
(map (curryr expt 2) (range 4))
(You need to call (range 4) because the list generated by range goes from 0 to n-1.)
Next, you can easily sum a list using apply. To sum the above list, you'd do something like this:
(apply + (map (curryr expt 2) (range 4)))
That gives you the appropriate result of 14. Obviously, you could encapsulate this in its own function for clarity, but it's a lot clearer what the above code is doing once you learn Racket's functional constructs.
(However, I'm not sure if you're allowed to use those, since your question looks a lot like homework. Just noted for future reference and completeness.)
The most straightforward solution is to use the closed form:
(define (sum-of-squares n)
(* 1/6 n (+ n 1) (+ n n 1)))
Credit: WolframAlpha
one function for providing a list of squares and one function for summing up the list is not necessary.
This will do the trick, and is recursive as required.
(define (my-sq n)
(cond [(zero? n) 0]
[else
(+ (* n n) (my-sq (- n 1)))]))
(my-sq 3) -> 14
Many Project Euler problems require manipulating integers and their digits, both in base10 and base2. While I have no problem with converting integers in lists of digits, or converting base10 into base2 (or lists of their digits), I often find that performance is poor when doing such conversions repeatedly.
Here's an example:
First, here are my typical conversions:
#lang racket
(define (10->bin num)
(define (10->bin-help num count)
(define sq
(expt 2 count))
(cond
[(zero? count) (list num)]
[else (cons (quotient num sq) (10->bin-help (remainder num sq) (sub1 count)))]
)
)
(member 1 (10->bin-help num 19)))
(define (integer->lon int)
(cond
[(zero? int) empty]
[else (append (integer->lon (quotient int 10)) (list (remainder int 10)))]
)
)
Next, I need a function to test whether a list of digits is a palindrome
(define (is-palindrome? lon)
(equal? lon (reverse lon)))
Finally, I need to sum all base10 integers below some max that are palindromes in base2 and base10. Here's the accumulator-style function:
(define (sum-them max)
(define (sum-acc count acc)
(define base10
(integer->lon count))
(define base2
(10->bin count))
(cond
[(= count max) acc]
[(and
(is-palindrome? base10)
(is-palindrome? base2))
(sum-acc (add1 count) (+ acc count))]
[else (sum-acc (add1 count) acc)]))
(sum-acc 1 0))
And the regular recursive version:
(define (sum-them* max)
(define base10
(integer->lon max))
(define base2
(10->bin max))
(cond
[(zero? max) 0]
[(and
(is-palindrome? base10)
(is-palindrome? base2))
(+ (sum-them* (sub1 max)) max)]
[else (sum-them* (sub1 max))]
)
)
When I apply either of these two last functions to 1000000, I takes well over 10 seconds to complete. The recursive version seems a bit quicker than the accumulator version, but the difference is negligible.
Is there any way I can improve this code, or do I just have to accept that this is the style of number-crunching for which Racket isn't particularly suited?
So far, I have considered the possibility of replacing integer->lon by a similar integer->vector as I expect vector-append to be faster than append, but then I'm stuck with the need to apply reverse later on.
Making your existing code more efficient
Have you considered getting the list of bits using any of Racket's bitwise operations? E.g.,
(define (bits n)
(let loop ((n n) (acc '()))
(if (= 0 n)
acc
(loop (arithmetic-shift n -1) (cons (bitwise-and n 1) acc)))))
> (map bits '(1 3 4 5 7 9 10))
'((1) (1 1) (1 0 0) (1 0 1) (1 1 1) (1 0 0 1) (1 0 1 0))
It'd be interesting to see whether that speeds anything up. I expect it would help a bit, since your 10->bin procedure currently makes a call to expt, quotient, and remainder, whereas bit shifting, depending on the representations used by the compiler, would probably be more efficient.
Your integer->lon is also using a lot more memory than it needs to, since the append is copying most of the result at each step. This is kind of interesting, because you were already using the more memory efficient approach in bin->10. Something like this is more efficient:
(define (digits n)
(let loop ((n n) (acc '()))
(if (zero? n)
acc
(loop (quotient n 10) (cons (remainder n 10) acc)))))
> (map digits '(1238 2391 3729))
'((1 2 3 8) (2 3 9 1) (3 7 2 9))
More efficient approaches
All that said, perhaps you should consider the approach that you're using. It appears that right now, you're iterating through the numbers 1…MAX, checking whether each one is a palindrome, and if it is, adding it to the sum. That means you're doing something with MAX numbers, all in all. Rather than checking for palindromic numbers, why not just generate them directly in one base and then check whether they're a palindrome in the other. I.e., instead of of checking 1…MAX, check:
1
11
101, and 111
1001, and 1111
10001, 10101, 11011, and 11111,
and so on, up until the numbers are too big.
This list is all the binary palindromes, and only some of those will be decimal palindromes. If you can generate the binary palindromes using bit-twiddling techniques (so you're actually working with the integers), it's easy to write those to a string, and checking whether a string is a palindrome is probably much faster than checking whether a list is a palindrome.
Are you running these timings in DrRacket by any chance? The IDE slows down things quite a bit, especially if you happen to have debugging and/or profiling turned on, so I'd recommend doing these tests from the command line.
Also, you can usually improve the brute-force approach. For example, you can say here that we only have to consider odd numbers, because even numbers are never a palindrome when expressed as binaries (a trailing 0, but the way you represent them there's never a heading 0). This divides the execution time by 2 regardless of the algorithm.
Your code runs on my laptop in 2.4 seconds. I wrote an alternative version using strings and build-in functions that runs in 0.53 seconds (including Racket startup; execution time in Racket is 0.23 seconds):
#!/usr/bin/racket
#lang racket
(define (is-palindrome? lon)
(let ((lst (string->list lon)))
(equal? lst (reverse lst))))
(define (sum-them max)
(for/sum ((i (in-range 1 max 2))
#:when (and (is-palindrome? (number->string i))
(is-palindrome? (number->string i 2))))
i))
(time (sum-them 1000000))
yields
pu#pumbair: ~/Projects/L-Racket time ./speed3.rkt
cpu time: 233 real time: 233 gc time: 32
872187
real 0m0.533s
user 0m0.472s
sys 0m0.060s
and I'm pretty sure that people with more experience in Racket profiling will come up with faster solutions.
So I could give you the following tips:
Think about how you may improve the brute force approach
Get to know your language better. Some constructs are faster than others for no apparent reason
see http://docs.racket-lang.org/guide/performance.html and http://jeapostrophe.github.io/2013-08-19-reverse-post.html
use parallelism when applicable
Get used to the Racket profiler
N.B. Your 10->bin function returns #f for the value 0, I guess it should return '(0).
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.
While translating some Fortran to Scheme/Racket I have come across the
function:
; EPSILON(X) The least positive number that added
; to 1 returns a number that is greater than 1
How do I find the number in Scheme?
#lang racket/base
;; http://en.wikipedia.org/wiki/Machine_epsilon
;; approximates the machine epsilon
(require racket/flonum)
(define (compute-machine-epsilon)
(let loop ([n 1.0])
(define next-n (fl/ n 2.0))
(if (fl= 1.0 (fl+ 1.0 next-n))
n
(loop next-n))))
Assuming you're using IEEE-754 floating-point (which may not be the case in Scheme, I don't know), then the machine epsilon is well known: for double-precision arithmetic, it's 1.11e-16.
For other platforms or floating-point implementations, Wikipedia shows the formula to compute it as (in Haskell):
main = print . last . map (subtract 1) . takeWhile (/= 1) . map (+ 1) . iterate (/2) $ 1
This is not a new answer -- it just bothers me that Danny's code makes it look like it's hard to do this kind of thing... it could be simplified to
(let loop ([n 1.0])
(if (= 1 (+ 1 (/ n 2)))
n
(loop (/ n 2))))
The existing answers are needlessly complicated, and might lead to non-portable code.
The correct answer is, as documented in Racket's math/flonum package is to use the epsilon.0 value, which will be correct for the current machine, and which won't require you to compute it by hand:
(require math/flonum)
epsilon.0