use accumulative recursion to find longest win in drracket - racket

Assume (list 'win 'loss 'win 'win 'win 'loss 'win 'win) and produce the longest win which is 3. using accumulative recursion. what i did is as follows:
(define (fun list)
(local
[(define (helper los accu1 accu2)
(cond
[(empty? los) (length accu2)]
[else
(cond
[(equal? (first los) 'loss)
(helper (rest los) 0 accu2)]
[else
(helper (rest los) 0 (cons (first los) accu2))])]))]
(helper list empty empty)))
the problem is i don't know what to do when i got a loss in the list,my function only calculates all the win instead of the longest win.someone help please :).

This is probably what you intended:
(define (fun lst)
(define (helper lst current longest)
(cond
[(empty? lst) (max current longest)]
[(equal? (first lst) 'win) (helper (rest lst) (add1 current) longest)]
[else (helper (rest lst) 0 (max current longest))]))
(helper lst 0 0))
then
> (fun (list 'win 'loss 'win 'win 'win 'loss 'win 'win))
3
The point is that you need 2 variables; one for the number of current consecutive 'win symbols, and one for the previously highest consecutive number. There's no need to create intermediate lists, counters are sufficient.

Related

Create Python's collections.counter() method in Beginner Racket

The goal is to create a function that accepts a list of symbols and produces a list of key value pairs that count how many times each symbol in list appears. eg:
(counter (list 't 't 'c 'a)) -> (list (list 't 2) (list 'c 1) (list 'a 1))
The function must be completed with recursion
I've only gotten as far as to create a list of key value pairs that treat duplicates as standalone values:
(define val 0)
(define (counter los)
(cond
[(empty? los) empty]
[else (cons (list (first los) (add1 val))
(counter (rest los)))]))
(counter (list 't 't 'c 'a)) -> (list (list 't) (list 't) (list 'c 1) (list 'a 1))
It has been a very long time since I used BSL but I believe these operations are all present. There may be a cleaner way of doing this but I will leave it up to you to check the documentation and simplify it if possible
(define (counter los) (counter-helper los empty))
(define (counter-helper los lists)
(cond
[(empty? los) lists]
[else (if (list? (assq (first los) lists))
(counter-helper
(rest los)
(cons (list (first los) (add1 (second (assq (first los) lists))))
(remove (assq (first los) lists) lists)))
(counter-helper (rest los) (cons (list (first los) 1) lists)))]))
the if statement checks if there is already an entry in our list of lists for that key, it returns the pair if yes, false otherwise.
If the result is false we just append a new pair with value 1 and recur.
If it already exists, we construct a new pair from the previous one, with the same key, but the value incremented and append this new pair to our list of lists - the previous pair removed

Reducing list (dr racket)

I am a beginner in Dr Racket and now I am looking for a solution to reduce nested lists.
For example:
+ 0 (list 1 2 (list 3 (list 4 5) 6) 7 (list (list 8)) empty 9))
should produce 45.
My current function only works for normal lists, but as soon as there is a list in the list, it doesn´t work anymore.
(define (reduce fun neutral lst)
(cond
((empty? lst) neutral)
(else
(fun (car lst)
(reduce fun neutral (rest lst))))))
You must consider the case where (car lst) is also a list. In that case, you will need to reduce (car lst) too, before applying fun.
(define (reduce fun neutral lst)
(cond
[(empty? lst)
neutral]
[(list? (car lst))
(fun (reduce fun neutral (car lst))
(reduce fun neutral (rest lst)))]
[else
(fun (car lst)
(reduce fun neutral (rest lst)))]))

Don't know how to solve this error [Racket]: "car: contract violation expected: pair? given: '()"

I'm trying to get a list with the average of the following n elements. I'm reading a csv file that has 7 columns im just using the 6th one that has number values in order to get the average.
This is the code
;Function that returns a list containing the values of the desired column
(define (get-column col)
(let loop
([file (cdr(all-rows csv-path read-csv))]
[result empty])
(if (empty? file)
result
(loop (cdr file)
(cond
[(equal? col 1) (append result (list (caar file)))]
[(equal? col 2) (append result (list (string->number(cadar file))))]
[(equal? col 3) (append result (list (string->number(caddar file))))]
[(equal? col 4) (append result (list (string->number(car (cdddar file)))))]
[(equal? col 5) (append result (list (string->number(cadr (cdddar file)))))]
[(equal? col 6) (append result (list (string->number(caddr (cdddar file)))))]
[(equal? col 7) (append result (list (string->number(car (cdddr (cdddar file))))))]
)))))
(define (suma-SMA col n)
(let loop
([n n]
[res 0]
[col col])
(if (zero? n)
res
(loop (sub1 n) (+ res (car col)) (cdr col)))))
(define (get-SMA days)
(let loop
([col (get-column 6)]
[result empty])
(if (empty? col)
result
(loop (cdr col)(append result (list (suma-SMA col days)))))))
Here's a function that does what you asked for in the comments, e.g. given (1 2 3 4) it produces ((1+2)/2 (2+3)/2 (3+4)/2).
(define (sum list)
(cond
((null? list)
'()) ;; error?
((null? (cdr list))
'())
(else
(cons (/ (+ (car list) (cadr list)) 2) (sum (cdr list))))))
I'm still a bit confused because even the combination of get-SMA and suma-SMA does nothing like this. It's completely unclear what the days variable is doing, as you can see I didn't need it in my code above.
So I may have misunderstood what you are trying to do, but the function above does what you actually asked for so hopefully it will be helpful.
Here is the answer that I found useful for my problem.
(define (sum list n)
(cond
((null? list)
'()) ;; error?
((null? (cdr list))
'())
(else
(cons (suma-SMA list n) (sum (cdr list) n)))))

How can I just use high order functions to rewrite these (use Dr.Racket)

This is my homework but we are only allowed to use filter, map, foldr, sort, build-list, and lambda instead of the explicit recursion
How can I rewrite these use those high order functions above to not let the function call itself.
What I have now are these:
(define (worthless loc name)
(cond
[(empty? loc) loc]
[(equal? name (coin-name (first loc))) (cons (make-coin (coin-name (first loc)) 0) (worthless (rest loc) name))]
[else (cons (first loc) (worthless (rest loc) name))]))
(define (working-group locations group-tz)
(cond
[(empty? locations) empty]
[(and (equal? (utc-hours group-tz) (utc-hours (location-timezone (first locations)))) (equal? (utc-sign group-tz) (utc-sign (location-timezone (first locations)))))
(cons (location-city (first locations)) (working-group (rest locations) group-tz))]
[(and (equal? (add1 (utc-hours group-tz)) (utc-hours (location-timezone (first locations))))
(equal? (utc-sign group-tz) (utc-sign (location-timezone (first locations))))
(equal? (utc-mins group-tz) (utc-mins (location-timezone (first locations)))))
(cons (location-city (first locations)) (working-group (rest locations) group-tz))]
[(and (equal? (sub1 (utc-hours group-tz)) (utc-hours (location-timezone (first locations))))
(equal? (utc-sign group-tz) (utc-sign (location-timezone (first locations))))
(equal? (utc-mins group-tz) (utc-mins (location-timezone (first locations)))))
(cons (location-city (first locations)) (working-group (rest locations) group-tz))]
[else (working-group (rest locations) group-tz)])) ```
Yes. worthless can be rewritten with map. Imagine we have this function that adds 3 to each element in a list:
(define (add3 lst)
(if (null? lst)
'()
(cons (+ (car lst) 3)
(add3 (cdr lst)))))
Map for one list looks like this:
(define (map f lst)
(if (null? lst)
'()
(cons (f (car lst))
(map f (cdr lst))))
Looking at these you can see that an add3 with map only needs to focus on adding 3. Basically you need to pass a function with one argument that adds 3 to that argument:
(define (add3-wm lst)
(map (lambda (v) (+ v 3)) lst))
Now foldr for one list looks like this:
(define (foldr f init lst)
(if (null? lst)
init
(f (car lst)
(foldr f init (cdr lst)))))
Here you see that cons isn't done so rewriting add3 using foldr takes a combiner and it needs to add 3 to the first argument and combine the two arguments where the second argument is the result fo the same process with the later elements.
(define (add3-fr lst)
(define (combiner v acc)
(cons (+ v 3) acc))
(foldr combiner '() lst))
In reality using foldr here is overkill, but it would be interesting if you sometimes needed to skip an element like working-group does. In that case the combiner just returns the second argument. You can make filter with foldr:
(define (filter f lst)
(foldr (lambda (v acc)
(if (f v)
(cons v acc)
acc))
'()
lst))
Good luck

Racket - Find lists that has the same element in a 2D list

Can someone please show me how to do this problem/give me a template? I'm not allowed to use map or lambda or any other advanced built-in functions, only list
First extract the country associated with the input string:
(define (get-country l s)
(cond [(empty? (rest l)) (second (second (first l)))]
[else (if (equal? s (first (first l)))
(second (second (first l)))
(get-country (rest l) s))]))
Then extract all strings that have that country associated with it:
(define (get-countries l s)
(cond [(empty? l) '()]
[else (if (equal? s (second (second (first l))))
(cons (first (first l)) (get-countries (rest l) s))
(get-countries (rest l) s))]))
Then put them together:
(define (same-country l s)
(get-countries l (get-country l s)))
When we evaluate we get a result different from (list "YUL" "YVR" "YWG" "YYZ"):
> (same-country alist "YUL")
(list "YYZ" "YWG" "YUL" "YVR")
So we check if the result is a permutation of the desired list. First we make is-permutation:
(define (is-permutation l1 l2)
(and (not (and (cons? l1) (empty? l2)))
(not (and (empty? l1) (cons? l2)))
(or (and (empty? l1) (empty? l2))
(and (is-member (first l1) l2)
(is-permutation (rest l1)
(remove-one (first l1) l2))))))
(define (is-member e l)
(and (not (empty? l))
(or (equal? (first l) e)
(is-member e (rest l)))))
(define (remove-one e nel)
(cond [(empty? (rest nel)) '()]
[else (if (equal? (first nel) e)
(rest nel)
(cons (first nel) (remove-one e (rest nel))))]))
Then we can test:
> (is-permutation (same-country alist "YUL")
(list "YUL" "YVR" "YWG" "YYZ"))
#true