Author Topic: [challenge] Flip list of coordinates  (Read 680 times)

0 Members and 1 Guest are viewing this topic.

dexus

  • Newt
  • Posts: 75
[challenge] Flip list of coordinates
« on: April 15, 2022, 05:07:45 AM »
Hi there, I thought it would be fun to do another challenge.
Came across this in a project and I thought this would fit.

The input is a "list of x coordinates" for a couple of line segments with a specific length.
Now the output should be the coordinates of those same line segments in reverse order.
Here is an example:

Code - Auto/Visual Lisp: [Select]
  1. Command: (flip '(9 36 54 90 162))
  2. => '(72 108 126 153 162)

In this example the length of the lines are 9 27 18 36 and 72.
The image below will hopefully make it more clear.

Good luck  :lol:

gile

  • Water Moccasin
  • Posts: 2392
  • Marseille, France
Re: [challenge] Flip list of coordinates
« Reply #1 on: April 15, 2022, 05:29:54 AM »
Hi,
Code - Auto/Visual Lisp: [Select]
  1. (defun flip (l)
  2.   (mapcar '(lambda (x) (- (last l) x))
  3.           (cdr (reverse (cons 0 l)))
  4.   )
  5. )
Speaking English as a French Frog

gile

  • Water Moccasin
  • Posts: 2392
  • Marseille, France
Re: [challenge] Flip list of coordinates
« Reply #2 on: April 15, 2022, 05:33:10 AM »
A little optimization.
Code - Auto/Visual Lisp: [Select]
  1. (defun flip (l / f)
  2.   (defun f (x) (- (last l) x))
  3.   (mapcar 'f (cdr (reverse (cons 0 l))))
  4. )
Speaking English as a French Frog

kirby

  • Newt
  • Posts: 110
Re: [challenge] Flip list of coordinates
« Reply #3 on: April 18, 2022, 09:04:10 AM »
My attempt.  Uses separate function to cumulate or unaccumulate the a list of numbers.

Code - Auto/Visual Lisp: [Select]
  1. (defun C:TestFlip2 ( / TestList Ans)
  2. ; Test routine for 'flip-kirby2'
  3.  
  4. (setq TestList (list 9 36 54 90 162))
  5. (prompt "\n  Input = ")(princ TestList)(princ)
  6.  
  7. (setq Ans (flip-kirby2 TestList))
  8. (prompt " => ")(princ Ans)(princ)
  9. )
  10.  
  11.  
  12.  
  13. (defun flip-kirby2 (MyList / List1 List2)
  14. ; Flip a list of numbers representing cumulative lengths
  15. ; Input:
  16. ;       MyList - (list) list of cumulative lengths (assume integers)
  17. ; Returns:
  18. ;       flipped list, beginning cumulative list from other end of list
  19. ;       e.g. (flip '(9 36 54 90 162))  => '(72 108 126 153 162)
  20. ; Uses custom functions:
  21. ;       listcumulate
  22.  
  23. (setq List1 (listcumulate mylist 0))                    ; unaccumulate list to get individual lengths
  24. (setq List2 (listcumulate (reverse list1) 1))           ; cumulate lengths in reverse order
  25. List2
  26. )
  27.  
  28.  
  29. (defun ListCumulate (MyList MyCode / LastVal OutList MyItem NewVal)
  30. ; Cumulate or un-cumulate (?) a list
  31. ; Input:
  32. ;       MyList - (list) list of cumulative lengths (assume integers)
  33. ;       MyCode - (integer) code 0 = unaccumulate
  34. ;                               1 = cumulate
  35. ; Returns:
  36. ;       cumulated or uncumulated list, depending upon MyCode
  37. ;       e.g. Code 0 Input '(9 36 54 90 162) => '(9 27 18 36 72)
  38. ;       e.g. Code 1 Input '(9 27 18 36 72)  => '(9 36 54 90 162)
  39.  
  40. (setq LastVal 0)
  41. (setq OutList nil)
  42.  
  43. (setq CNT 0)
  44. (repeat (length MyList)
  45.         (setq MyItem (nth CNT MyList))
  46.         (cond
  47.                 ((eq MyCode 0) (setq NewVal (- MyItem LastVal) LastVal MyItem)) ; unaccumluate
  48.                 ((eq MyCode 1) (setq NewVal (+ MyItem LastVal) LastVal NewVal)) ; cumulate     
  49.         )
  50.        
  51.         (setq OutList (cons NewVal OutList))
  52.  
  53.         (setq CNT (1+ CNT))
  54. ) ; close repeat       
  55. (setq OutList (reverse OutList))
  56. OutList
  57. )
  58.  

Command: TESTFLIP2
  Input = (9 36 54 90 162) => (72 108 126 153 162)

dexus

  • Newt
  • Posts: 75
Re: [challenge] Flip list of coordinates
« Reply #4 on: April 20, 2022, 06:47:36 AM »
Before asking this question I didn't realize subtracting each value from the total length would give you the flipped list.
Amazing work gile!

Here was my version before that realization.
Code - Auto/Visual Lisp: [Select]
  1. (defun flip (lst / rm tmp)
  2.   (setq rm 0)
  3.   (while lst ; break down
  4.     (setq tmp (cons (- (car lst) rm) tmp)
  5.           rm (car lst)
  6.           lst (cdr lst))
  7.   )
  8.   ; Here tmp holds the unaccumulated list
  9.   (setq rm 0)
  10.   (while tmp ; rebuild
  11.     (setq rm (+ (car tmp) rm)
  12.           lst (cons rm lst)
  13.           tmp (cdr tmp))
  14.   )
  15.   (reverse lst)
  16. )

bruno_vdh

  • Newt
  • Posts: 82
Re: [challenge] Flip list of coordinates
« Reply #5 on: May 02, 2022, 06:03:37 AM »
Hello, for simplicity
Code - Auto/Visual Lisp: [Select]
  1. (defun flip (l / e r)
  2.   (setq e (last l)
  3.         r (list e)
  4.   )
  5.   (cdr (foreach x l
  6.          (setq r (cons (- e x) r))
  7.        )
  8.   )
  9. )

dexus

  • Newt
  • Posts: 75
Re: [challenge] Flip list of coordinates
« Reply #6 on: May 03, 2022, 06:32:57 AM »
Hello, for simplicity
Code - Auto/Visual Lisp: [Select]
  1. (defun flip (l / e r)
  2.   (setq e (last l)
  3.         r (list e)
  4.   )
  5.   (cdr (foreach x l
  6.          (setq r (cons (- e x) r))
  7.        )
  8.   )
  9. )
Nice, and you didn't even need reverse unlike everyone else.

I have to say these challenges help a lot with getting better at coding, I didn't realize foreach returned a variable until now.  :oops:

bruno_vdh

  • Newt
  • Posts: 82
Re: [challenge] Flip list of coordinates
« Reply #7 on: May 03, 2022, 10:56:40 AM »
I have to say these challenges help a lot with getting better at coding, I didn't realize foreach returned a variable until now.  :oops:
In Lisp all functions return an expression, even the princ function (which returns a blank) :wink: