Author Topic: [challenge] A27 : delete-if / delete-if-not  (Read 1581 times)

0 Members and 1 Guest are viewing this topic.

JohnK

  • Administrator
  • Seagull
  • Posts: 10158
[challenge] A27 : delete-if / delete-if-not
« on: February 23, 2022, 08:00:39 AM »
Derive a function that accepts a function and deletes a member from a list if a member is...

(delete-if oddp '(1 2 3 4 5 6 7 8))
> (2 4 6 8)
AND/OR
(delete-if evenp '(1 2 3 4 5 6 7 8))
> (1 3 5 7)


Derive a function that accepts a function and deletes a member from a list if a member is NOT...

(delete-if-not oddp '(1 2 3 4 5 6 7 8))
> (1 3 5 7)
AND/OR
(delete-if-not evenp '(1 2 3 4 5 6 7 8))
...

TheSwamp.org (serving the CAD community since 2003)

Donate to TheSwamp.org

Lee Mac

  • Seagull
  • Posts: 12711
  • London, England
Re: [challenge] A27 : delete-if / delete-if-not
« Reply #1 on: February 23, 2022, 08:03:22 AM »
Quick one -
Code - Auto/Visual Lisp: [Select]
  1. (defun deleteif ( f l )
  2.     (cond
  3.         (   (not l) l)
  4.         (   (apply f (list (car l))) (deleteif f (cdr l)))
  5.         (   (cons (car l) (deleteif f (cdr l))))
  6.     )
  7. )
Code - Auto/Visual Lisp: [Select]
  1. _$ (deleteif '(lambda ( x ) (zerop (rem x 2))) '(0 1 2 3 4 5 6 7 8))
  2. (1 3 5 7)

Lee Mac

  • Seagull
  • Posts: 12711
  • London, England
Re: [challenge] A27 : delete-if / delete-if-not
« Reply #2 on: February 23, 2022, 08:04:42 AM »
Or, an iterative solution:
Code - Auto/Visual Lisp: [Select]
  1. (defun deleteif ( f l )
  2.     (apply 'append (mapcar '(lambda ( x ) (if (not (apply f (list x))) (list x))) l))
  3. )

Or:
Code - Auto/Visual Lisp: [Select]
  1. (defun deleteif ( f l )
  2.     (apply 'append
  3.         (mapcar '(lambda ( a b ) (if (not a) b))
  4.             (mapcar f l)
  5.             (mapcar 'list l)
  6.         )
  7.     )
  8. )

Or imperatively rather than functionally:
Code - Auto/Visual Lisp: [Select]
  1. (defun deleteif ( f l / r )
  2.     (foreach x l (or (apply f (list x)) (setq r (cons x r))))
  3.     (reverse r)
  4. )
« Last Edit: February 23, 2022, 08:11:15 AM by Lee Mac »

gile

  • Water Moccasin
  • Posts: 2400
  • Marseille, France
Re: [challenge] A27 : delete-if / delete-if-not
« Reply #3 on: February 23, 2022, 08:26:45 AM »
Hi,
To avoid calling apply (or eval) at each loop, it would be more efficient to set f to (eval f) before the loops and simply call (f item) at each loop.
Code - Auto/Visual Lisp: [Select]
  1. (defun deleteif (f l / loop)
  2.   (defun loop (f l)
  3.     (cond
  4.       ((not l) l)
  5.       ((f (car l)) (deleteif f (cdr l)))
  6.       ((cons (car l) (deleteif f (cdr l))))
  7.     )
  8.   )
  9.   (loop (eval f) l)
  10. )
« Last Edit: February 23, 2022, 08:49:30 AM by gile »
Speaking English as a French Frog

JohnK

  • Administrator
  • Seagull
  • Posts: 10158
Re: [challenge] A27 : delete-if / delete-if-not
« Reply #4 on: February 23, 2022, 08:33:20 AM »
Mine:
Code - Auto/Visual Lisp: [Select]
  1. (defun oddp (int)
  2.   (eq 1 (logand int 1)))
  3.  
  4. (defun evenp (int)
  5.   (eq 0 (logand int 1)))
  6.  
  7. (defun delete-if (proc lst)
  8.   (apply
  9.     'append
  10.     (mapcar
  11.       '(lambda (x)
  12.          (if (not (eval (list proc x))) (list x)))
  13.       lst)) )
  14.  
  15. (defun delete-if-not (proc lst)
  16.   (apply
  17.     'append
  18.     (mapcar
  19.       '(lambda (x)
  20.          (if (eval (list proc x)) (list x)))
  21.       lst)) )
  22.  
  23. ; (delete-if 'oddp '(1 2 3 4 5 6 7 8))
  24. ; (delete-if 'evenp '(1 2 3 4 5 6 7 8))
  25. ; (delete-if-not 'oddp '(1 2 3 4 5 6 7 8))
  26. ; (delete-if-not 'evenp '(1 2 3 4 5 6 7 8))
  27.  

Code: [Select]
Command: (delete-if 'oddp '(1 2 3 4 5 6 7 8))
(2 4 6 8)

Command: (delete-if 'evenp '(1 2 3 4 5 6 7 8))
(1 3 5 7)

Command: (delete-if-not 'oddp '(1 2 3 4 5 6 7 8))
(1 3 5 7)

Command: (delete-if-not 'evenp '(1 2 3 4 5 6 7 8))
(2 4 6 8)

Command: (setq lst '(0 1 2 3 4 5 6 7 8 9))
(0 1 2 3 4 5 6 7 8 9)

Command: (mapcar '(lambda (f) (delete-if f lst)) '(oddp evenp))
((0 2 4 6 8) (1 3 5 7 9))


(defun oddp (int)
  (eq 1 (logand int 1)))
(defun evenp (int)
  (eq 0 (logand int 1)))

(defun delete-if (proc lst)
  (apply
    'append
    (mapcar
      '(lambda (x)
         (if (not (proc x)) (list x)))
      lst)) )

(defun delete-if-not (proc lst)
  (apply
    'append
    (mapcar
      '(lambda (x)
         (if (proc x) (list x)))
      lst)) )

(delete-if oddp '(1 2 3 4 5 6 7 8))
(delete-if evenp '(1 2 3 4 5 6 7 8))
(delete-if-not oddp '(1 2 3 4 5 6 7 8))
(delete-if-not evenp '(1 2 3 4 5 6 7 8))



EDIT: Corrected code to allow for quoted function arguments.
« Last Edit: February 23, 2022, 09:01:20 AM by JohnK »
TheSwamp.org (serving the CAD community since 2003)

Donate to TheSwamp.org

gile

  • Water Moccasin
  • Posts: 2400
  • Marseille, France
Re: [challenge] A27 : delete-if / delete-if-not
« Reply #5 on: February 23, 2022, 08:46:40 AM »
@JohnK
To be consistent with other AutoLISP higher order functions, the function passed as argument should be quoted.

Code - Auto/Visual Lisp: [Select]
  1. (setq lst '(0 1 2 3 4 5 6 7 8 9)
  2. (mapcar '(lambda (f) (delete-if f lst)) '(oddp evenp))
Speaking English as a French Frog

JohnK

  • Administrator
  • Seagull
  • Posts: 10158
Re: [challenge] A27 : delete-if / delete-if-not
« Reply #6 on: February 23, 2022, 09:03:43 AM »
gile, you are a cruel man! :)

We are like children to you aren't we?
@JohnK
To be consistent with other AutoLISP higher order functions, the function passed as argument should be quoted.

Code - Auto/Visual Lisp: [Select]
  1. (setq lst '(0 1 2 3 4 5 6 7 8 9)
  2. (mapcar '(lambda (f) (delete-if f lst)) '(oddp evenp))
TheSwamp.org (serving the CAD community since 2003)

Donate to TheSwamp.org

gile

  • Water Moccasin
  • Posts: 2400
  • Marseille, France
Re: [challenge] A27 : delete-if / delete-if-not
« Reply #7 on: February 23, 2022, 09:11:01 AM »
gile, you are a cruel man! :)

We are like children to you aren't we?
@JohnK
To be consistent with other AutoLISP higher order functions, the function passed as argument should be quoted.
Not at all. Look at Lee's replies he handled this using apply. We just have already played with building higher order functions some times ago.
Speaking English as a French Frog

bruno_vdh

  • Newt
  • Posts: 82
Re: [challenge] A27 : delete-if / delete-if-not
« Reply #8 on: February 23, 2022, 09:52:34 AM »
Hi,
To avoid calling apply (or eval) at each loop, it would be more efficient to set f to (eval f) before the loops and simply call (f item) at each loop.
Code - Auto/Visual Lisp: [Select]
  1. (defun deleteif (f l / loop)
  2.   (defun loop (f l)
  3.     (cond
  4.       ((not l) l)
  5.       ((f (car l)) (deleteif f (cdr l)))
  6.       ((cons (car l) (deleteif f (cdr l))))
  7.     )
  8.   )
  9.   (loop (eval f) l)
  10. )

Hello (gile),
Small write error, because it is on this condition alone..  :wink:
(not getting out of the loop)
Code - Auto/Visual Lisp: [Select]
  1. (defun deleteif (f l / loop)
  2.   (defun loop (f l)
  3.     (cond
  4.       ((not l) l)
  5.       ((f (car l)) (loop f (cdr l)))
  6.       ((cons (car l) (loop f (cdr l))))
  7.     )
  8.   )
  9.   (loop (eval f) l)
  10. )
  11.  
Small precision, because few people here know that in terms of lisp I owe you a lot, if that's not all...
« Last Edit: February 23, 2022, 10:18:06 AM by bruno_vdh »

kirby

  • Newt
  • Posts: 111
Re: [challenge] A27 : delete-if / delete-if-not
« Reply #9 on: February 23, 2022, 10:16:47 AM »
one more...

Code - Auto/Visual Lisp: [Select]
  1. (defun C:Test-A27 ( / MyFuncList MyTestList MySwitchList CNT MyFunc MySwitch Ans)
  2.  
  3. ; Test input
  4. (setq MyFuncList (list oddp evenp oddp evenp))
  5. (setq MyTestList (list 0 1 2 3 4 5 6 7 8))
  6. (setq MySwitchList (list 0 0 1 1))
  7.  
  8. (prompt "\nTest List = ")(princ MyTestList)(princ)
  9.  
  10. (setq CNT 0)
  11. (repeat (length MyFuncList)
  12.         (setq MyFunc (nth CNT MyFuncList))
  13.         (setq MySwitch (nth CNT MySwitchList))
  14.        
  15.         (setq Ans (delete-if-kirby MyFunc MyTestList MySwitch))
  16.        
  17.         (prompt "\n  Func = ")(princ MyFunc)
  18.         (prompt "  Invert? = ")(princ MySwitch)
  19.         (prompt "  Ans = ")(princ Ans)
  20.         (princ)
  21.        
  22.         (setq CNT (1+ CNT))
  23. ) ; close repeat
  24.  
  25. )
  26.  
  27. (defun delete-if-kirby (MyFunc MyList MySwitch / OutList CNT MyItem)
  28. ; [challenge] A27 : delete-if / delete-if-not
  29. ; function that accepts a function and deletes a member from a list if a member is ...  / or if a member is NOT...
  30. ; Input:
  31. ;       MyFunc - (name of autolisp function) function must be appropriate for operations on list items (e.g. can't test if a string is an even number)
  32. ;       MyList - (list) a list or numbers or strings
  33. ;       MySwitch - (integer) code to control function behaviour
  34. ;                       0 = use function to test for item deletion
  35. ;                       1 = inverse function (NOT)
  36. ; Returns:
  37. ;       modified list
  38.  
  39. (setq OutList nil)
  40.  
  41. (if MyList
  42.   (progn
  43.         (setq CNT 0)
  44.         (repeat (length MyList)
  45.                 (setq MyItem (nth CNT MyList))
  46.                
  47.                 (cond
  48.                         ((eq MySwitch 0)                ; delete if function is true
  49.                           (progn
  50.                                 (if (not (MyFunc MyItem))
  51.                                         (setq OutList (cons MyItem OutList))
  52.                                 )      
  53.                           )
  54.                         )
  55.                         ((eq MySwitch 1)                ; Inverse case: delete if function is NOT true
  56.                           (progn
  57.                                 (if (MyFunc MyItem)
  58.                                         (setq OutList (cons MyItem OutList))
  59.                                 )                      
  60.                           )
  61.                         )
  62.                 ) ; close cond
  63.                
  64.                 (setq CNT (1+ CNT))
  65.         ) ; close repeat
  66.        
  67.         (setq OutList (reverse OutList))
  68.   )    
  69. )
  70.  
  71. OutList
  72. )
  73.  
  74. ; Test predicate functions
  75. (defun Evenp (MyVal / )
  76. ; Return T is value is Even
  77.         (if (equal (rem MyVal 2.0) 0.0 1e-8)
  78.                 T
  79.         )      
  80. )
  81.  
  82. (defun Oddp (MyVal / )
  83. ; Return T if value is Odd
  84.         (if (equal (rem MyVal 2.0) 1.0 1e-8)
  85.                 T
  86.         )      
  87. )
  88.  
  89. (defun Positivep (MyVal / )
  90. ; Return T if value is positive
  91.         (if (not (minusp MyVal))
  92.                 T
  93.         )      
  94. )
  95.  
  96.  

JohnK

  • Administrator
  • Seagull
  • Posts: 10158
Re: [challenge] A27 : delete-if / delete-if-not
« Reply #10 on: February 23, 2022, 10:49:09 AM »
Many of us owe gile a lot for many programming languages.
TheSwamp.org (serving the CAD community since 2003)

Donate to TheSwamp.org

gile

  • Water Moccasin
  • Posts: 2400
  • Marseille, France
Re: [challenge] A27 : delete-if / delete-if-not
« Reply #11 on: February 23, 2022, 11:07:52 AM »
Hello (gile),
Small write error, because it is on this condition alone..  :wink:
(not getting out of the loop)
Code - Auto/Visual Lisp: [Select]
  1. (defun deleteif (f l / loop)
  2.   (defun loop (f l)
  3.     (cond
  4.       ((not l) l)
  5.       ((f (car l)) (loop f (cdr l)))
  6.       ((cons (car l) (loop f (cdr l))))
  7.     )
  8.   )
  9.   (loop (eval f) l)
  10. )
  11.  
Small precision, because few people here know that in terms of lisp I owe you a lot, if that's not all...

Oops!!!... I to quickly pasted Lee's code...

We all owe to each other due to the sharing here, at TheSwamp, and elsewhere.
Speaking English as a French Frog

pBe

  • Bull Frog
  • Posts: 401
Re: [challenge] A27 : delete-if / delete-if-not
« Reply #12 on: February 23, 2022, 01:36:14 PM »
Still not sure if i followed the rules. very difficult to not to look at the other's posts.
Let me know if this is acceptable or i'm totally off
 
Code - Auto/Visual Lisp: [Select]
  1. (defun delete-if:Pbe (pr l)
  2.   ((lambda (ls)
  3.      (foreach itm l
  4.        (if (eval (list pr itm))
  5.          (setq ls (cons itm ls))
  6.        )
  7.      )
  8.      (reverse ls)
  9.    )
  10.     nil
  11.   )
  12. )

I kept the same logic as my blundered post :)
All the good ones are taken.
Code - Auto/Visual Lisp: [Select]
  1. (defun _even (n / o)
  2.     (while (null
  3.              (cond
  4.                ((setq o (= n 1)))
  5.                ((zerop n))
  6.              )
  7.            )
  8.       (setq n (- n 2))
  9.     )
  10.     o
  11.   )
  12.  
  13. (defun _odd  (n / e)
  14.     (while (null
  15.              (cond
  16.                ((setq e (zerop n)))
  17.                ((= n 1))
  18.              )
  19.            )
  20.       (setq n (- n 2))
  21.     )
  22.     e
  23.   )
« Last Edit: February 24, 2022, 02:15:33 AM by pBe »

JohnK

  • Administrator
  • Seagull
  • Posts: 10158
Re: [challenge] A27 : delete-if / delete-if-not
« Reply #13 on: February 23, 2022, 02:15:08 PM »
@pBe
Nice but your function does not remove items from a list based on a condition (-i.e. a function). Your function will just remove the odd items from a list.
TheSwamp.org (serving the CAD community since 2003)

Donate to TheSwamp.org

pBe

  • Bull Frog
  • Posts: 401
Re: [challenge] A27 : delete-if / delete-if-not
« Reply #14 on: February 23, 2022, 07:35:26 PM »
@pBe
Nice but your function does not remove items from a list based on a condition (-i.e. a function). Your function will just remove the odd items from a list.

:D Sorry about that, I honestly did not read through the entire discussion, i'll repost later today.