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

0 Members and 1 Guest are viewing this topic.

#### JohnK

• Administrator
• Seagull
• Posts: 10140
##### [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 )
> (2 4 6
AND/OR
(delete-if evenp '(1 2 3 4 5 6 7 )
> (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 )
> (1 3 5 7)
AND/OR
(delete-if-not evenp '(1 2 3 4 5 6 7 )
...

TheSwamp.org (serving the CAD community since 2003)

Donate to TheSwamp.org

#### Lee Mac

• Seagull
• Posts: 12696
• 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: 12696
• 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.         (mapcar '(lambda ( a b ) (if (not a) b))
3.             (mapcar f l)
4.             (mapcar 'list l)
5.         )
6.     )
7. )

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: 2392
• 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: 10140
##### 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.       '(lambda (x)
9.          (if (not (eval (list proc x))) (list x)))
10.       lst)) )
11.
12. (defun delete-if-not (proc lst)
13.       '(lambda (x)
14.          (if (eval (list proc x)) (list x)))
15.       lst)) )
16.
17. ; (delete-if 'oddp '(1 2 3 4 5 6 7 8))
18. ; (delete-if 'evenp '(1 2 3 4 5 6 7 8))
19. ; (delete-if-not 'oddp '(1 2 3 4 5 6 7 8))
20. ; (delete-if-not 'evenp '(1 2 3 4 5 6 7 8))
21.

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 )
(delete-if evenp '(1 2 3 4 5 6 7 )
(delete-if-not oddp '(1 2 3 4 5 6 7 )
(delete-if-not evenp '(1 2 3 4 5 6 7 )

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: 2392
• 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: 10140
##### 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: 2392
• 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..
(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: 110
##### 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.         (setq CNT 0)
43.         (repeat (length MyList)
44.                 (setq MyItem (nth CNT MyList))
45.
46.                 (cond
47.                         ((eq MySwitch 0)                ; delete if function is true
48.                                 (if (not (MyFunc MyItem))
49.                                         (setq OutList (cons MyItem OutList))
50.                                 )
51.                           )
52.                         )
53.                         ((eq MySwitch 1)                ; Inverse case: delete if function is NOT true
54.                                 (if (MyFunc MyItem)
55.                                         (setq OutList (cons MyItem OutList))
56.                                 )
57.                           )
58.                         )
59.                 ) ; close cond
60.
61.                 (setq CNT (1+ CNT))
62.         ) ; close repeat
63.
64.         (setq OutList (reverse OutList))
65.   )
66. )
67.
68. OutList
69. )
70.
71. ; Test predicate functions
72. (defun Evenp (MyVal / )
73. ; Return T is value is Even
74.         (if (equal (rem MyVal 2.0) 0.0 1e-8)
75.                 T
76.         )
77. )
78.
79. (defun Oddp (MyVal / )
80. ; Return T if value is Odd
81.         (if (equal (rem MyVal 2.0) 1.0 1e-8)
82.                 T
83.         )
84. )
85.
86. (defun Positivep (MyVal / )
87. ; Return T if value is positive
88.         (if (not (minusp MyVal))
89.                 T
90.         )
91. )
92.
93.

#### JohnK

• Administrator
• Seagull
• Posts: 10140
##### 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: 2392
• 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..
(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.              (cond
3.                ((setq o (= n 1)))
4.                ((zerop n))
5.              )
6.            )
7.       (setq n (- n 2))
8.     )
9.     o
10.   )
11.
12. (defun _odd  (n / e)
13.              (cond
14.                ((setq e (zerop n)))
15.                ((= n 1))
16.              )
17.            )
18.       (setq n (- n 2))
19.     )
20.     e
21.   )
« Last Edit: February 24, 2022, 02:15:33 AM by pBe »

#### JohnK

• Administrator
• Seagull
• Posts: 10140
##### 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.

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

#### JohnK

• Administrator
• Seagull
• Posts: 10140
##### Re: [challenge] A27 : delete-if / delete-if-not
« Reply #15 on: February 24, 2022, 03:13:12 PM »
@pBe
I just noticed your latest edit now. Your latest edit code looks good (looks to meet the specifications).
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 #16 on: February 24, 2022, 08:39:54 PM »
@pBe
I just noticed your latest edit now. Your latest edit code looks good (looks to meet the specifications).

Thank you for that @JohnK, it did not make the cut but at least it meets the specifications
I will read it thoroughly next time.

#### dexus

• Newt
• Posts: 75
##### Re: [challenge] A27 : delete-if / delete-if-not
« Reply #17 on: March 24, 2022, 03:54:01 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. )
Wait, shouldn't be the loop function that does the recursion instead of the deleteif? This way it still does an eval every loop.

If you create a new function anyway, you don't even have to pass it along as a variable.
Just create the variable in the parent function and use that, I'm not sure if that is more efficient though.
Code - Auto/Visual Lisp: [Select]
1. (defun deleteif (f l / loop)
2.   (setq f (eval f))
3.   (defun loop (l)
4.     (cond
5.       ((not l) l)
6.       ((f (car l)) (loop (cdr l)))
7.       ((cons (car l) (loop (cdr l))))
8.     )
9.   )
10.   (loop l)
11. )