random integer in scheme - random

In my OO World, I have an instance of "weapon" class called "max-damage". I asked to create a random number for a variable called "damage".
It says: The amount of "damage" suffered should be a random integer no more than the "max-damage", and at least 1.
I need some help to create that random integer, thanks!
PS: I can't ask more questions, in order to ask this question, I have changed the previous one, sorry..

You got the syntax of filter wrong, it's necessary that you pass a procedure as the first argument. Concretely, the procedure is a predicate (meaning: it evaluates to a boolean value), and the output list will only keep the elements in the original list that evaluate to #t when passed to the procedure. This is what I mean:
(define (remove-divisible lst value)
(filter (lambda (x) (not (zero? (remainder x value))))
lst))
If using a lambda bothers you, it's always possible to define a helper procedure, like this:
(define (remove-divisible lst value)
(define (not-divisible? x)
(not (zero? (remainder x value))))
(filter not-divisible? lst))

Related

How do I apply ormap to a single variable? - Scheme

Working on this project for hours now and I can't figure it out.
I have a list of numbers and I need it to produce true if any of those numbers matches a separate number without using recursion.
(compare-numbers (list 1 2 3) 2) => true
What I know I have to do is use ormap on a local function, but I can't figure out how to make the function.
What I wrote is
(define (comp? num)
(equal? num num-lst)) ;Where num-lst is the list of accepted numbers
But I know I can't use this as ormap needs two lists to work.
Can anyone throw me a hint at solving this?
Thanks.
ormap doesn't need two lists. It just needs a procedure that compares a list element to the given number, which you can create with lambda.
(define (compare-numbers lst num)
(ormap (lambda (n) (equal? n num))
lst))

Racket count occurrences using `map`

Write a Racket function count-occurrences that consumes two lists of symbols and produces a list of
natural numbers measuring how many times items in the first list occur in the second list. For example:
(count-occurrences (list 'a 'b 'a 'q) (list 'r 'a 'b 'e 'b 'g))
=> (list 1 2 1 0)
I've been struggling with this question - how do I use map to do it, since for this question it's specified we can't use recursion.
My original idea was to do the following:
(define (count-occurrences los1 los2)
(map
(length (filter (lambda (x) (symbol=? x (first los1))) los2))
los1))
but using length here can only get us the number 'a occurred, instead of going into recursion. and for abstract functions there can only be one argument for the inside function, so I'm totally lost.
If ... x ... is an open formula, i.e. an expression which references an unbound variable x, wrapping it in a lambda form makes it a function in x, like so:
(lambda (x) ... x ... )
where x becomes bound by that lambda form; a parameter to this so called lambda function, which is to say, an anonymous function introduced by a lambda form.
So, the solution for your troubles is quite simple: recognize that
(length
(filter (lambda (x)
(symbol=? x (first los1)))
los2))
should actually be
(length
(filter (lambda (x)
(symbol=? x y))
los2))
where y refers to each of the elements of los1 in turn, not just the first one; and that it is then an open formula in y – that is to say, y is unbound, free, there. So we must capture it, and make it bound, by ... yes, enclosing this expression in a lambda form, thereby making it a function in y! Like so:
(lambda (y)
(length
(filter (lambda (x)
(symbol=? x y))
los2)))
And this is what gets mapped over los1.
With this simple tweak, your code becomes a correct, working function definition.
Does this fit your requirements and restrictions?
(define (count-occurrences lst1 lst2)
(map (lambda (e1)
(count (lambda (e2) (eq? e1 e2))
lst2))
lst1))
A good way to keep track of keys and values is with a hash-table. While it is possible to write count-occurrences using map and passing a lambda, being explicit may make it easier to see what is going on.
;;; list list -> list
;;;
(define (count-occurrences keys values)
;; Create data structure
(define ht (make-hash))
;; Initialize data structure with keys
;; Set the value of each key to zero
;; Since we have not started counting
(for ([k keys])
(hash-set! ht k 0))
;; Iterate over values and
;; Increment hash table if
;; When value is a key
(for ([v values])
(if (hash-has-key? ht v)
(hash-set! ht v (+ (hash-ref ht v) 1))
null))
;; Iterate over keys and
;; Create list of values
(for/list ([k keys])
(hash-ref ht k)))
Since recursion is prohibited, explicitly looping may make for more maintainable/readable code than an implicit loop. Besides, the variations of for are worth knowing. Hash tables have the advantage that duplicate keys read the same value and there is no need to track the same key twice.
One of the engineering advantages of using for rather than map is that it is easier to reason about the running time. The running time for this code is 2m + n where m is keys and n is values. Solutions using map will typically be m * n. There's nothing inherently wrong with that. But it is worth recognizing.

Scheme,level intermediate student, find min without recursion

How can I write a function using abstract list functions (foldr, map, and filter) without recursion that consumes a list of numbers (list a1 a2 a3 ...) and produces a new list removing the minimum number from the original list?
The recursion code is:
(define (find-min lst)
(cond
[(empty? (rest lst)) (first lst)]
[else
(local [(define min-rest (find-min (rest lst)))]
(cond
[(< (first lst) min-rest) (first lst)]
[else min-rest]))]))
A fold applies a 2-argument function against a given value and the car of a list uses the result against the successive cars or the cdrs or the list. this is what we want.
Whereas map returns a new list by doing something with each element of a list.
And filter returns a smaller or equal list based on some predicate.
Now just to formulate a function that can choose the lessor of two arguments
(define (the-lessor x y)
(if (< x y)
x
y))
From there implementation is straightforward.
(define (min L) (fold the-lessor (car L) (cdr L)))
Since this looks like a homework question, I'm not going to provide all the code, but hopefully push you in the right direction.
From the HTDP book, we see that "The Intermediate Student language adds local bindings and higher-order functions." The trick here is probably going to using "local bindings".
Some assumptions:
(remove-min-from-list '()) => not allowed: input list must be non-empty
(remove-min-from-list '(1)) => '()
(remove-min-from-list '(1 2 3 1 2 3)) => '(2 3 2 3) ; all instances of 1 were removed
Somehow, we need to find the minimum value of the list. Call this function min-of-list. What are its inputs and outputs? It's input is a list of numbers and its output is a number. Of the abstract list functions, which ones allow us to turn a list of numbers into a number? (And not another list.) This looks like foldl/foldr to me.
(define (min-of-list lst)
(foldr some-function some-base lst))
Since you already showed that you could write min-of-list recursively, let's move on. See #WorBlux's answer for hints there.
How would we use this in our next function remove-min-from-list? What are the inputs and outputs of remove-min-from-list? It takes a list of numbers and returns a list of numbers. Okay, that looks like map or filter. However, the input list is potentially shorter than that output list, so filter and not map.
(define (remove-min-from-list lst)
....
(filter some-predicate list))
What does some-predicate look like? It needs to return #f for the minimum value of the list.
Let's pull this all together and use local to write one function:
(define (remove-min-from-list lst)
(local [(define min-value ...)
(define (should-stay-in-list? number) ...min-value ...)]
(filter should-stay-in-list? lst)))
The key here, is that the definition for should-stay-in-list? can refer to min-value because min-value came before it in the local definitions block and that the filter later on can use should-stay-in-list? because it is in the body of the local.
(define (comparator n) (local [(define (compare v) (not (equal? v n)))] compare))
(define (without-min list) (filter (comparator (foldr min (foldr max 0 list) list)) list))

Using Scheme to find the least element in a list

(define min
(lambda (l m c)
(cond ((null? l) (print m))
(else ((c (car l))
if((< c m) (m c))
min((cdr l) m c))))))
I want to use the tail-recursive method to do it,but it doesn't work. I'm very very new in Scheme, hope you can help me. Thank you!
This looks like homework, I'll give you some pointers so you can solve it by yourself. Fill-in the blanks:
(define (mymin lst minval)
(cond ((null? lst) ; If the list is empty
???) ; return the minimum value.
((< ??? minval) ; If current element < minimum value
(mymin ??? ???)) ; advance recursion, current element is new minimum.
(else ; If current element >= minimum value
(mymin ??? ???)))) ; advance recursion, keep the same minimum.
In the above code, we're implementing a two-parameter tail-recursive procedure called mymin (don't use the name min, that's a built-in procedure.) The first parameter is the list to traverse; the second parameter stores the minimum value found so far, and when the recursion ends, it will hold the answer.
Call it like this, noticing that for the first call we need to pass in the second argument a number so big that all the other numbers are smaller:
(mymin '(1 2 3 4 0 5) +inf.0)
> 0
Oscar's version will work but I have some stylistic quibbles (this is not a dig at Oscar, who is keeping it simple to make the solution plainer). If you get it working along those lines, see if you can make a couple of changes.
No spurious parameters
You have 3 parameters and Oscar has two but this is a list that takes one input - a list. Give the wrong extra seed parameters and you'll fail. One way to fix this is to recur inside the main function. It could look something like this
(define (mymin lst)
(let ((minval ???))
(define (findmin lst testval)
(cond
(????)
(????)
(????))
(findmin lst minval)))
Do you see how that works? You could initialise minval to inf.0, as Oscar did, or to a special non-numerical value (there are a couple of good choices, one better than the other).
If you're really smart, though, you'll see that there's no need to pass two values each time. You can pass one simple object to each recursion, with no need for an inner function or any initialisation - why initialise anything with infinite values when you have all the data you need at the start?
Here's a clue to how it would look (it starts much like Oscar's version):
(define (mymin lst)
(cond
((null? lst) ???)
((?????) (car lst))
(else (mymin (??????????????????????? lst)))))
There are a few things going on in that last line of ???s ;)
But only try for these improvements once you have a working version, unless you can't get it working any other way. Get it working, then improve - you learn twice ;)
Some things to think about, along the way...
What do you return if there's only one element in the list?
What's the simplest way to test if there's only one element in the list?
What's the most logical thing to return if the list is empty?

Bounded variables and scope

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.

Resources