TheSwamp

Code Red => AutoLISP (Vanilla / Visual) => Topic started by: RAIN CODE on June 25, 2012, 03:37:39 AM

Title: how to add list to a set of list ???
Post by: RAIN CODE on June 25, 2012, 03:37:39 AM
Hi, guys.

See if you could find the shortest lisp solution to this harder problem. Okay, previously you all done a great job writing a very short lisp to add value to a list.
But later I found that I have to insert name and level to the list too. I tried using your lisp and modify it but it could not work.

Let say I have top ten value
ranking     score      name         level
1st            10000    Han solo       5
2nd            8000     Luke             3
3rd             5000     Vader           3
...
...
10th          2000     Luke-1          1

And i need to insert new hi score of 6000 with name = Obiwan with level 5

then the result will be at 3rd spot and moving Vader to 4th spot and so on.

Thanks guys

p/s sorry I have not finish writing the game yet. There are still bugs in the program and at the same time I am adding more levels to it.








Title: Re: how to add list to a set of list ???
Post by: gile on June 25, 2012, 04:04:34 AM
Code: [Select]
(defun foo (ele lst)
  (reverse
    (cdr
      (vl-sort
(cons ele lst)
'(lambda (x1 x2) (< (car x1) (car x2)))
      )
    )
  )
)

(setq topFive '((10000 "a" 5) (8000 "b" 3) (5000 "c" 3) (2000 "d" 2) (500 "e" 2)))
(foo '(6000 "z" 5) topFive)
returns:
((10000 "a" 5) (8000 "b" 3) (6000 "z" 5) (5000 "c" 3) (2000 "d" 2))
Title: Re: how to add list to a set of list ???
Post by: irneb on June 25, 2012, 04:11:21 AM
Ah ... gile you were quicker:
Code - Auto/Visual Lisp: [Select]
  1. (defun InsertScores  (lst item /)
  2.   (reverse (cdr (vl-sort (cons item lst) '(lambda (a b) (< (car a) (car b)))))))
  3.  
Example:
Code: [Select]
(setq ScoresList '((10000 "Han solo" 5) (8000 "Luke" 3) (5000 "Vader" 3) (5000 "Luke" 2) (4000 "Vader" 2) (2000 "Luke-1" 1)))
_$ (InsertScores ScoresList '(6000 "Obiwan" 5))
((10000 "Han solo" 5) (8000 "Luke" 3) (6000 "Obiwan" 5) (5000 "Luke" 2) (5000 "Vader" 3) (4000 "Vader" 2))
Same code though ... it does seem to be the shortest version (though not necessarily the "quickest"  ;) ).
Title: Re: how to add list to a set of list ???
Post by: Lee Mac on June 25, 2012, 05:54:15 AM
Using Evgeniy's method from here (http://www.theswamp.org/index.php?topic=42050.msg471902#msg471902).

Code - Auto/Visual Lisp: [Select]
  1. (defun insertitem ( item lst / l )
  2.     (mapcar '(lambda ( a b ) (nth a l))
  3.         (vl-sort-i (setq l (cons item lst)) '(lambda ( a b ) (> (car a) (car b))))
  4.         lst
  5.     )
  6. )
Title: Re: how to add list to a set of list ???
Post by: kruuger on June 25, 2012, 06:47:13 AM
Code - Auto/Visual Lisp: [Select]
  1. (defun cd:LST_SortList (Lst Pos Order)
  2.   (vl-Sort Lst
  3.     (function
  4.       (lambda (%1 %2)
  5.         ( (if (zerop Order) < >)
  6.           (nth Pos %1)
  7.           (nth Pos %2)
  8.         )
  9.       )
  10.     )
  11.   )
  12. )
Code - Auto/Visual Lisp: [Select]
  1. (cd:LST_SortList (list '(10000 "Han solo" 5) '(8000 "Luke" 3) '(5000 "Vader" 3)) 2 1)
sort by column and order
k.
Title: Re: how to add list to a set of list ???
Post by: Stefan on June 25, 2012, 06:59:32 AM
In this case, vl-sort does not eliminate duplicates.
Code: [Select]
Code removed ... See Gile and irneb
Code: [Select]
_$ (score1 '((10 "Mara" 2) (8 "Peter" 3) (8 "Peter" 3) (8 "Peter" 3) (1 "Lola" 8)) '(8 "Arthur" 4))
((10 "Mara" 2) (8 "Arthur" 4) (8 "Peter" 3) (8 "Peter" 3) (8 "Peter" 3))
@Rain Code
What happens when a new score is equal to another in the list? It will goes in front or after the existing one?
What about level? Does it make a difference in the sorted list?
Title: Re: how to add list to a set of list ???
Post by: irneb on June 25, 2012, 07:19:52 AM
Here's another one where reverse does not seem to be a bad idea:
Code: [Select]
Benchmarking .... done for 8192 iterations. Sorted from fastest.
Statement                                Increment  Time(ms) Normalize  Relative
--------------------------------------------------------------------------------
(FOO ITEM SCORESLIST)                         8192      1171      1171      1.12
(INSERTSCORES ITEM SCORESLIST)                8192      1201      1201      1.09
(IB:INSERTITEM ITEM SCORESLIST)               8192      1218      1218      1.08
(INSERTITEM ITEM SCORESLIST)                  8192      1311      1311      1.00
--------------------------------------------------------------------------------
_$ (QuickBench (mapcar '(lambda (f) (list f 'item 'ScoresList)) '(InsertScores foo insertitem IB:InsertItem)))
Benchmarking .... done for 8192 iterations. Sorted from fastest.
Statement                                Increment  Time(ms) Normalize  Relative
--------------------------------------------------------------------------------
(FOO ITEM SCORESLIST)                         8192      1155      1155      1.17
(INSERTSCORES ITEM SCORESLIST)                8192      1201      1201      1.13
(IB:INSERTITEM ITEM SCORESLIST)               8192      1232      1232      1.10
(INSERTITEM ITEM SCORESLIST)                  8192      1356      1356      1.00
--------------------------------------------------------------------------------
gile and my 1st one is actually the exact same code, so the differences are due to the benchmarking. But no matter how many times I perform this, the idea of using mapcar instead of reverse never wins out.
Title: Re: how to add list to a set of list ???
Post by: irneb on June 25, 2012, 07:24:20 AM
Sorry, should've added my mod to Lee's mod  :lmao:
Code - Auto/Visual Lisp: [Select]
  1. (defun IB:InsertItem (item lst /)
  2.   (mapcar '(lambda (a b) a)
  3.           (vl-sort (cons item lst) '(lambda (a b) (> (car a) (car b))))
  4.           lst))
Title: Re: how to add list to a set of list ???
Post by: irneb on June 25, 2012, 07:28:11 AM
What about level? Does it make a difference in the sorted list?
I'm guessing it would if the scores are the same, then a lower level would outrank a higher one. In which case the comparison function could become:
Code - Auto/Visual Lisp: [Select]
  1. (lambda (a b) (or (> (car a) (car b)) (and (= (car a) (car b)) (< (caddr a) (caddr b))))
Title: Re: how to add list to a set of list ???
Post by: ribarm on June 25, 2012, 08:28:05 AM
@Rain Code
What happens when a new score is equal to another in the list? It will goes in front or after the existing one?
What about level? Does it make a difference in the sorted list?

When designing highscores list, equal scores shouldn't be removed... I use this instead of (vl-sort) :
Code - Auto/Visual Lisp: [Select]
  1. ;;; vl-sort function except it doesn't remove duplicate elements ;;;
  2.  
  3. (defun _vl-sort ( lst func / lstn )
  4.   (foreach itm (vl-sort-i lst func)
  5.     (setq lstn (cons (nth itm lst) lstn))
  6.   )
  7.   (reverse lstn)
  8. )
  9.  

M.R.
Title: Re: how to add list to a set of list ???
Post by: irneb on June 25, 2012, 08:49:21 AM
Just curious: When does vl-sort omit duplicates? From my tests it doesn't do so:
Code - Auto/Visual Lisp: [Select]
  1. (defun InsertScores  (item lst /)
  2.   (reverse (cdr (vl-sort (cons item lst) '(lambda (a b) (< (car a) (car b)))))))
  3.  
  4. _$ (InsertScores '(8 "Arthur" 4) '((10 "Mara" 2) (8 "Peter" 3) (8 "Peter" 3) (8 "Peter" 3) (1 "Lola" 8)))
  5. ((10 "Mara" 2) (8 "Peter" 3) (8 "Peter" 3) (8 "Peter" 3) (8 "Arthur" 4))

Am I missing something? That test is done on 64bit ACad Vanilla 2012, is there a difference with other versions or clones?
Title: Re: how to add list to a set of list ???
Post by: ribarm on June 25, 2012, 09:07:38 AM
Quote
Command: (vl-sort '(1 2 3 3 5 7 7 7 9 0 0 0) '(lambda (a b) (< a b)))
(0 1 2 3 5 7 9)

M.R.
Title: Re: how to add list to a set of list ???
Post by: kruuger on June 25, 2012, 09:25:06 AM
Just curious: When does vl-sort omit duplicates? From my tests it doesn't do so:
Code - Auto/Visual Lisp: [Select]
  1. (defun InsertScores  (item lst /)
  2.   (reverse (cdr (vl-sort (cons item lst) '(lambda (a b) (< (car a) (car b)))))))
  3.  
  4. _$ (InsertScores '(8 "Arthur" 4) '((10 "Mara" 2) (8 "Peter" 3) (8 "Peter" 3) (8 "Peter" 3) (1 "Lola" 8)))
  5. ((10 "Mara" 2) (8 "Peter" 3) (8 "Peter" 3) (8 "Peter" 3) (8 "Arthur" 4))

Am I missing something? That test is done on 64bit ACad Vanilla 2012, is there a difference with other versions or clones?
omit only when list is (list 0 1 2 3 4) but ok when list is list of dotted pairs (list (1 . "a") (2 . "b"))
k.
Title: Re: how to add list to a set of list ???
Post by: ribarm on June 25, 2012, 10:45:30 AM
If elements are defined as lists or dotted pairs inside list, that's true, vl-sort doesn't remove duplicates, but if list consists of symbols or variables that are to be evaluated during sorting, then duplicates are removed...

Quote
Command: (vl-sort (list (list 0 1) (list 1 1) (list 1 1) (list 2 1)) '(lambda
(a b) (< (car a) (car b))))
((0 1) (1 1) (1 1) (2 1))

Command: (setq p1 (getpoint))
(60.3202 23.1086 0.0)

Command: (setq p2 (getpoint))
(76.2727 30.3611 0.0)

Command: (setq p3 (getpoint))
(90.5159 25.5261 0.0)

Command: (vl-sort (list p1 p2 p2 p1 p1 p3 p3 p3) '(lambda (a b) (< (car a) (car
b))))
((60.3202 23.1086 0.0) (76.2727 30.3611 0.0) (90.5159 25.5261 0.0))

Command: (setq p1 (list 0 1))
(0 1)

Command: (setq p2 (list 1 1))
(1 1)

Command: (setq p3 (list 2 1))
(2 1)

Command: (vl-sort (list p1 p2 p2 p1 p1 p3 p3 p3) '(lambda (a b) (< (car a) (car
b))))
((0 1) (1 1) (2 1))

M.R.
Title: Re: how to add list to a set of list ???
Post by: RAIN CODE on June 26, 2012, 01:58:06 AM

Thank you guys. You all write good lisp. I wish I could write as good as you.

With the internet, I get to see the best in the world (from Russia, USA and France etc..) at work.

thanks again  ^-^