Using Racket BSL to abstract two functions and redfine the functions using the new abstraction - racket

I have tried to abstract both functions (good-job and total-length) by creating a new abstraction function called new-num and this is what I have so far but I keep getting errors so I assume I am abstracting incorrectly:
; good-job : [List-of NonNegReal] -> [List-of NonNegReal]
; adds 20% to all supplied costs
(define (good-job lon)
(cond
[(empty? lon) '()]
[(cons? lon)
(cons
(add-thanks (first lon))
(good-job (rest lon)))]))
; add-thanks : NonNegReal -> NonNegReal
; adds 20% to the supplied cost
(define (add-thanks cost)
(* cost 1.2))
; total-length : [List-of String] -> Nat
; returns the total length of all strings in the list
(define (total-length los)
(cond
[(empty? los) 0]
[(cons? los)
(+
(string-length (first los))
(total-length (rest los)))]))
; new-num : [List-of X] X -> X
; abstracts good-job and total-length
; functions
(define (new-num lox cons/+ add-thanks/string-length def)
(cond
[(empty? lox) def]
[(cons? lox)
(cons/+
(add-thanks/string-length (first lox))
(new-num (rest lox) cons/+ add-thanks/string-length def))]))

Related

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

recursive problem using the image module in racket

I have the following error on line 27:
first: expects a non-empty list; given: #<image>
Is it a problem with recursion?
I've been researching but can't find an example where the image package is used recursively.
I can't think of anything, I don't understand why it gives me that error :(
; You must make a program that needs a list of n figures, which you will paint,
; all the color options that the user indicates and separates by a fixed distance that you determine.
; These figures contain a name (they depend on the naming options that you set),
; a measurement or measurements according to what the figure requires and an indicator of whether it is painted full or only the silhouette.
; NOTE: These drawings must be made using the image of the package.
(require 2htdp/image)
(define-struct triangulo_ (color size complete))
(define-struct cuadrado_ (color size complete))
(define-struct circulo_ (color size complete))
(define circulo (make-circulo_ "yellow" 10 "outline"))
(define triangulo (make-triangulo_ "blue" 10 "solid"))
(define cuadrado (make-cuadrado_ "orange" 10 "outline"))
(define lista_figuras (cons circulo (cons triangulo (cons cuadrado empty))))
(define (validar figura ID)
(cond
[(empty? figura) ID]
[(and (circulo_? (first figura)) (positive? (circulo_-size (first figura))) (number? (circulo_-size (first figura))) (string? (circulo_-color (first figura))) (string? (circulo_-complete (first figura)))) (validar (rest figura) #t)]
[(and (cuadrado_? (first figura)) (positive? (cuadrado_-size (first figura))) (number? (cuadrado_-size (first figura))) (string? (cuadrado_-color (first figura))) (string? (cuadrado_-complete (first figura)))) (validar (rest figura) #t)]
[(and (triangulo_? (first figura)) (positive? (triangulo_-size (first figura))) (number? (triangulo_-size (first figura))) (string? (triangulo_-color (first figura))) (string? (triangulo_-complete (first figura)))) (validar (rest figura) #t)]
[else (validar (rest figura) #f)]))
(define (pathway figura)
(cond
[(empty? figura) empty]
[(circulo_? (first figura)) (pathway(circle (circulo_-size (first figura)) (circulo_-complete (first figura)) (circulo_-color (first figura))))]
[(triangulo_? (first figura)) (pathway(triangle (triangulo_-size (first figura)) (triangulo_-complete (first figura)) (triangulo_-color (first figura))))]
[(cuadrado_? (first figura)) (pathway(square (cuadrado_-size (first figura)) (cuadrado_-complete (first figura)) (cuadrado_-color (first figura))))]
[else (pathway (rest figura))]))
(define (main figura)
(cond
[(boolean=? (validar figura 0) #t) (pathway figura)]
[else "Error, solo se permiten: [ circulos, cuadrados y triangulos <equilateros> ]"]))
(main lista_figuras)
It's a type error. In the recursive call to pathway, you're passing in an image but it requires a list which contains triangulo_/cuadrado_/circulo_. Also the right hand side of the cond clauses in validar have multiple expressions, each will be evaluated from left to right but their values wouldn't matter, even if they're false. It's better to combine validation of each field with an and.
First, give a name to the structs you define, let's call it ImageConfig
At a higher level, the problem with the design is that you're mixing up list-processing with the processing of the element in the list. It's better to separate those.
Now separate the processing of [List-of ImageConfig] from ImageConfig for both validar and pathway.
; validar-l : [List-of ImageConfig] -> Boolean
; validar : ImageConfig -> Boolean
; pathway-l : [List-of ImageConfig] -> [List-of Image]
; pathway : ImageConfig -> Image
; main : [List-of ImageConfig] -> [List-of Image]
; You must make a program that needs a list of n figures, which you will paint,
; all the color options that the user indicates and separates by a fixed distance that you determine.
; These figures contain a name (they depend on the naming options that you set),
; a measurement or measurements according to what the figure requires and an indicator of whether it is painted full or only the silhouette.
; NOTE: These drawings must be made using the image of the package.
(require 2htdp/image)
; ImageConfig is one of
(define-struct triangulo_ (color size complete))
(define-struct cuadrado_ (color size complete))
(define-struct circulo_ (color size complete))
(define circulo (make-circulo_ "yellow" 10 "outline"))
(define triangulo (make-triangulo_ "blue" 10 "solid"))
(define cuadrado (make-cuadrado_ "orange" 10 "outline"))
(define lista_figuras (cons circulo (cons triangulo (cons cuadrado empty))))
; [List-of ImageConfig] -> Boolean
(define (validar-l fl)
(cond [(empty? fl) true]
[else (and (validar (first fl)) (validar-l (rest fl)))]))
; ImageConfig -> Boolean
(define (validar f)
(cond
[(circulo_? f) (and (positive? (circulo_-size f)) (number? (circulo_-size f)) (string? (circulo_-color f)))]
[(cuadrado_? f) (and (positive? (cuadrado_-size f)) (number? (cuadrado_-size f)) (string? (cuadrado_-color f)))]
[(triangulo_? f) (and (positive? (triangulo_-size f)) (number? (triangulo_-size f)) (string? (triangulo_-color f)))]))
; ImageConfig -> Image
(define (pathway f)
(cond
[(circulo_? f) (circle (circulo_-size f) (circulo_-complete f) (circulo_-color f))]
[(triangulo_? f) (triangle (triangulo_-size f) (triangulo_-complete f) (triangulo_-color f))]
[(cuadrado_? f) (square (cuadrado_-size f) (cuadrado_-complete f) (cuadrado_-color f))]))
; [List-of ImageConfig] -> [List-of Image]
(define (pathway-l fl)
(cond
[(empty? fl) empty]
[else (cons (pathway (first fl)) (pathway-l (rest fl)))]))
; [List-of ImageConfig] -> [List-of Image]
(define (main fl)
(cond
[(boolean=? (validar-l fl) true) (pathway-l fl)]
[else (error "Error, solo se permiten: [ circulos, cuadrados y triangulos <equilateros> ]")]))
(main lista_figuras)
Result:

Switch uppercase and lowercase of a string

I'm doing a question where it asks me to convert all uppercases in a string to lowercases and lowercases to uppercases, and all other characters remain the same.
Below is my code:
(define (switch-case str)
(list->string
(cons
(cond
[(char-lower-case? (first (string->list str))) (char-upcase (first
(string->list str)))]
[(char-upper-case? (first (string->list str))) (char-downcase (first
(string->list str)))]
[else (first (string->list str))])
(switch-case (rest (string->list str))))))
The error message for str "ABC" is:
string->list: expects a string, given (cons #\B (cons #\C empty))
Can somebody tell me what has gone wrong with my code? Thx
The recursive call is on the wrong type. You pass [List-of Character] to switch-case, but it expects String.
; String -> String
(define (switch-case str)
(list->string
(cons
(swapcase nestr)
(switch-case
(rest (string->list str)) ; the type of this expression is [List-of Character]
))))
Follow this template:
; [List-of Character] -> [List-of Character]
(define (switch-case-charlist cl)
(cond [(empty? cl) ...]
[else (... (first cl) ... (switch-case-charlist (rest cl)))]))
; Character -> Character
(define (swap-case-character c)
...)
; String -> String
(define (swap-case-string s)
(list->string (... (string->list s))))

Racket List Questio

Does anyone know how to return a number of specific elements in a list?
Example: given
(list 'a 'a 'a 'a 'a 'b 'b 'b)
Returns the numbers of 'a: 5
numbers of 'b: 3
You count them. You make a procedure that takes a list and what you want to search for and you iterate that list while keeping a count and when you reach the end you return that value.
A skeleton for a simple recursive solution:
(define (count-element element lst)
(define (helper lst count)
(cond ((empty? lst) count)
((equal? element <first element>) <recurse whith cdr and increasing count>)
(else <recurse with cdr>)))
(helper lst 0))
Or you can use foldl
(define (count-element element lst)
(foldl (lambda (e count)
(if <e is the same as element>
<return 1 more than count>
<return count>))
0
lst))
There are probably 10 more ways I could do it, but the first is the most educational and the second the most common way I would do it.
Some tests:
(define test '(a a a a a b b b))
(count-element 'b '()) ; ==> 0
(count-element 'e test) ; ==> 0
(count-element 'a test) ; ==> 5
(count-element 'b test) ; ==> 3
I somewhat managed to find the answer, so here's the function definition:
(define (number-of s L)
(cond
[(empty? L) 0]
[else (cond [(eq? s (first L)) (+ 1 (number-of s (rest L)))]
[else (number-of s (rest L))])]))

Defining a function that accepts a List of Lists in racket

My assignment is to count how many lists I have with length 3 in my list (List of List).
I thought I built everything correctly, but when I want to send the first list to my recursive function it fails because my list has the type Any, and I can't find a way to make it a list of lists.
#lang pl
(: count-3lists : (Listof Any) -> Number)
(define (count-3lists l)
(cond
[(null? l) 0]
[else (+ (count-3lists-helper (first l)) (count-3lists (rest l)))]))
(: count-3lists-helper : (Listof Any) -> Number)
(define (count-3lists-helper l)
(cond [(= (length l) 3) 1]
[else 0]))
(: length : (Listof Any) -> Number)
(define (length l)
(cond
[(null? l) 0]
[else (add1 (length (rest l)))]))
The error I get is:
. Type Checker: Polymorphic function `first' could not be applied to
arguments:
Types: (Pairof a (Listof b)) -> (a : ((! False # (car) (0 0)) | (False # (car) (0 0))) : (car (0 0)))
(Listof a) -> a
Arguments: (Pairof Any (Listof Any))
Expected result: (Listof Any)
in: (first l)
It seems like you want your count-3lists function to take a list of lists as its input. Right now you have (Listof Any).
What you want is express something like (Listof List), but the inner list has to be a list of something, so you can write that as (Listof (Listof Any)).
Then the first part of your code becomes this:
(: count-3lists : (Listof (Listof Any)) -> Number)
(define (count-3lists l)
(cond
[(null? l) 0]
[else (+ (count-3lists-helper (first l)) (count-3lists (rest l)))]))
After that, the rest of your code works. It turns out that your length function was fine. (So you should probably rename your question.)