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

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

Related

define: expected only one expression for the function body, but found 1 extra part ceasercipher function

I am currently writing a drracket function for rscipher-3 that consumes a non-empty string s consisting of only alphabet uppercase letters and produces a new string (i.e., ciphertext) with the "right shift of 3" rule applied on s. Here is my function but I keep getting the "define: expected only one expression for the function body, but found 1 extra part" error.
(define (rscipher-3 s)
(define (helper s)
(cond [(empty? s) '()]
[(= (first s) "X") (cons "A" (helper (rest s)))]
[(= (first s) "Y") (cons "B" (helper (rest s)))]
[(= (first s) "Z") (cons "C" (helper (rest s)))]
[else (cons (integer->char (+ (char->integer (first s)) 3))
(helper (rest s)))]))
(list->string (helper (string->list s))))
Where did I go wrong?
Some DrRacket dialects/ teaching languages (Beginning Student, Intermediate Student and so on) don't allow definitions with multiple expressions.
Your rscipher-3 has two expressions:
First one:
(define (helper s)
(cond [(empty? s) '()]
[(= (first s) "X") (cons "A" (helper (rest s)))]
[(= (first s) "Y") (cons "B" (helper (rest s)))]
[(= (first s) "Z") (cons "C" (helper (rest s)))]
[else (cons (integer->char (+ (char->integer (first s)) 3))
(helper (rest s)))]))
Second one:
(list->string (helper (string->list s)))
You have to change your language- or, if you have to use it, move the definition of the helper function outside rscipher-3 definition. Also, you don't need these three branches (as noted in the comments, they also don't work, because you should compare with character, not with string):
[(= (first s) "X") (cons "A" (helper (rest s)))]
[(= (first s) "Y") (cons "B" (helper (rest s)))]
[(= (first s) "Z") (cons "C" (helper (rest s)))]
When you remove them, you can simplify your cond to if:
(define (helper s)
(if (empty? s) '()
(cons (integer->char (+ (char->integer (first s)) 3))
(helper (rest s)))))
(define (rscipher-3 s)
(list->string (helper (string->list s))))
Example:
> (rscipher-3 "FOOBAR")
"IRREDU"
If your DrRacket language supports map, you can also do:
(define (rscipher-3 s)
(list->string
(map (lambda (c) (integer->char (+ (char->integer c) 3)))
(string->list s))))

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

Difficulty writing LISP Recursive Function for Merge Sort

Hi so I have question that I am having some difficulty solving see below
Use the function SPLIT-LIST and MERGE-LISTS to define a recursive
Lisp function MSORT such that if L is a list of real numbers then (MSORT L) is a list consisting of the elements of L in ascending order. In the definition of MSORT you may call SPLIT-LIST,
MSORT itself, MERGE-LISTS, CAR, CDR, CADR and ENDP, but you should not call any
other function. Be sure to use LET or LET*, so that MSORT only calls SPLIT-LIST once.
So far I was able to write the SPLIT-LIST and MERGE-LISTS functions correctly but for M-SORT I am having difficulty writing the function. See below all three definitions so far. Any help on how to write the MSORT function correctly by following the guidelines in the question would be appreciated.
(defun SPLIT-LIST (L)
(if (endp L)
'(nil nil)
(let ((X (split-list (cdr L))))
(list (cons (car L)(cadr X)) (car X) ))))
(defun MERGE-LISTS (L1 L2)
(cond
((and(endp L1 )(endp L2)) nil )
((endp L1) (cons (CAR L2) (MERGE-LISTS nil (CDR L2))))
((endp L2) (cons (CAR L1) (MERGE-LISTS (CDR L1) NIL)))
((< (CAR L1) (CAR L2)) (cons (CAR L1) (MERGE-LISTS (CDR L1) L2 )))
((>= (CAR L1) (CAR L2)) (cons (CAR L2) (MERGE-LISTS L1 (CDR L2)) ))))
(defun MSORT (L)
(cond ((endp L ) nil)
( (equal (Length L) 1) L)
(T
(let* (
(S (SPLIT-LIST L ))
(L1 (CAR S))
(L2 (CADR S))
(X (MSORT (cdr L1)))
(Y (MSORT (cdr L2)))
)
(MERGE-LISTS
(if (and (numberp (car L1)) (numberp (car X))(<= (car L1 ) (car X)))
(list (car L1) (car X))
(list (car X) (car L1) )
)
(Cons (car L2) Y))
)))
)
You're overcomplicating it. You don't need to sort the CDRs of the sub-lists returned by SPLIT-LIST, just sort the whole lists, and merge them.
(defun MSORT (L)
(cond ((endp L) nil)
((endp (cdr L)) L)
(t
(let* ((S (SPLIT-LIST L ))
(L1 (car S))
(L2 (cadr S))
(X (MSORT L1))
(Y (MSORT L2)))
(MERGE-LISTS X Y)))))

Replacing sublists with their last element

(defun rep(list)
(format t"~a~%" list)
(cond
((null list) nil)
((atom (car list)) (cons (car list) (rep (cdr list))))
((listp (car list)) (cons (car (reverse (car list))) (cdr list)))
(t (rep list))
)
)
Write a function to replace each sublist of a list with its last element.
A sublist is an element from the first level, which is a list.
Example:
(a (b c) (d (e (f)))) ==> (a c (e (f))) ==> (a c (f)) ==> (a c f)
(a (b c) (d ((e) f))) ==> (a c ((e) f)) ==> (a c f)
I have the above problem to solve. Got it till one point but I'm stuck.
Apparently it doesn't go to the next elements in the list and I don't know why. Any ideas?
I would break it down like this:
(defun last-element (lst)
(if (listp lst)
(last-element (car (last lst)))
lst))
(defun rep (lst)
(when lst
(cons (last-element (car lst)) (rep (cdr lst)))))
then
(rep '(a (b c) (d (e (f)))))
=> '(A C F)
Did it without using map functions
(defun rep(list)
(cond
((null list) nil)
((listp (car list)) (rep (cons (car (reverse (car list))) (rep (cdr list)))))
(t (cons (car list) (rep (cdr list))))
)
)

Generate Permutations of a List

I'm writing a function that takes a list and returns a list of permutations of the argument.
I know how to do it by using a function that removes an element and then recursively use that function to generate all permutations. I now have a problem where I want to use the following function:
(define (insert-everywhere item lst)
(define (helper item L1 L2)
(if (null? L2) (cons (append L1 (cons item '())) '())
(cons (append L1 (cons item L2))
(helper item (append L1 (cons (car L2) '())) (cdr L2)))))
(helper item '() lst))
This function will insert the item into every possible location of the list, like the following:
(insert-everywhere 1 '(a b))
will get:
'((1 a b) (a 1 b) (a b 1))
How would I use this function to get all permutations of a list?
I now have:
(define (permutations lst)
(if (null? lst)
'()
(insert-helper (car lst) (permutations (cdr lst)))))
(define (insert-helper item lst)
(cond ((null? lst) '())
(else (append (insert-everywhere item (car lst))
(insert-helper item (cdr lst))))))
but doing (permutations '(1 2 3)) just returns the empty list '().
First, construct a family of related examples:
(permutations '()) = ???
(permutations '(z)) = ???
(permutations '(y z)) = ???
(permutations '(x y z)) = ???
Figure out how each answer is related to the one before it. That is, how can you calculate each answer given the previous answer (for the tail of the list) and the new element at the head of the list?
Here is a function, that generates all permutations of numbers with size 'size' , that it consisted of the elements in the list 'items'
(define (generate-permutations items size)
(if (zero? size)
'(())
(for/list ([tail (in-list (generate-permutations items (- size 1)))]
#:when #t
[i (in-list items)]
#:unless (member i tail))
(cons i tail))))