-1

I need to create a function in Racket, but I found the examples a little confusing. I need to create a function that removes the elements similar to each other from the list. You can pass a function that determines the similarity or not (this function is optional). By default, elements are removed if they are equal, using the eq? function. You can takes on that the similarity function is always symmetric.

Danilobol
  • 33
  • 4
  • 12
  • 2
    I'd call this `keep-unique`. Don't name functions after what is **not** in their output. (At least try; there are times when it does make sense.) – Kaz Jun 08 '21 at 00:56
  • presumably you received an error message together with that bug. what was it? – Will Ness Jun 08 '21 at 08:08
  • Since you did not include your function in the question, nobody can guess what the problem could be. – molbdnilo Jun 08 '21 at 09:19

2 Answers2

0

As long as the count of an element is more than 1, I use remove* to remove their occurrences. The good thing is that both functions have a proc parameter to use as predicates. Also, I use the helper takes the same input list twice but use them differently: l1 is used to recur on, and l2 is used as the accumulator.

(define (remove-similars l f)
  (define (remove-lsts l1 l2 f)
    (cond [(empty? l1) l2]
          [else (if (> (count (lambda (e) (f e (first l1))) l2) 1)
                    (remove-lsts (rest l1) (remove* (list (first l1)) l2 f) f)
                    (remove-lsts (rest l1) l2 f))]))
  (remove-lsts l l f))
Atharva Shukla
  • 2,098
  • 8
  • 21
0

Here's an approach to doing this:

  • start with an empty list of elements we're collecting, and an empty list of duplicates
  • look at the list we're trying to filter:
    • if it is empty, return the reverse of the list we're collecting
    • if it is not empty:
      • check whether the first element is similar to any of the duplicates we've already seen: if it is, just iterate on the rest of the list
      • if it's not, then check whether it is similar to any element of the rest of the list: if it is then it's a duplicate, so iterate on the rest of the list, adding the first element to the list of duplicates;
      • if it's not either of those it must be unique, so iterate on the rest of the list adding the first element to the list of elements being collected.

Depending on how much of Racket you are allowed to use, it's worth knowing that (member element l similar?) will check whether element is in l using similar? as the predicate. If you aren't allowed to use that then you can write it fairly easily.

Also to define a function which takes an optional argument with a default value you can say

(define (find-similar list (test? similar))
  ...)

That will make test? be the test function and its default value will be similar's value.