Jump to content

Recommended Posts

Posted

Hi,

I want to remove elements from a list which exists of only x-coordinates in ascending order with the following condition:

 

The difference between 2 consecutive elements in the list must be equal or greater than a specified value.

Compare the first and second element, If false, remove the second element and compare the first element with the third element,

keep removing the next elements of the list as long as the difference is smaller then the specified value

If true go to the next value comparison

a simple example:


specified value = 5
Input List: (1 4 9 11 12 15 20)


4-1 < 5, so 4 must be removed

9-1=>5, so 9 stays

11-9 < 5, so 11 must be removed

12-9 <5, so 12 must be removed

15-9=>5, so 15 stays

20-15=>5, so 20 stays

Resulting List: (1 9 15 20)

Somebody an idea how to do this in LISP?

 

Posted

Hi,

 

(defun shrink (threshold lst / shrink-acc)
  (defun shrink-acc (fst lst acc / snd rest)
    (setq snd (car lst)
          rest (cdr lst))
    (cond ((null lst)
           acc)
          ((>= (- snd fst) threshold)
           (shrink-acc snd rest (cons snd acc)))
          (t
           (shrink-acc fst rest acc))))
  (if (not (null lst))
      (progn
        (setq fst (car lst)
              rest (cdr lst))
        (reverse
         (shrink-acc fst rest (list fst))))))

 

> (shrink 5 '())
nil
> (shrink 5 '(1))
(1)
> (shrink 5 '(1 4))
(1)
> (shrink 5 '(1 5))
(1)
> (shrink 5 '(1 6))
(1 6)
> (shrink 5 '(1 4 9 11 12 15 20))
(1 9 15 20)

 

Posted (edited)
; (test '(1 4 9 11 12 15 20) 5)
(defun test (inLst minDis / outLst)
  (setq outLst (list (car inLst)))
  (while (setq inLst (cdr inLst))
    (if (<= minDis (- (car inLst) (car outLst)))
      (setq outLst (cons (car inLst) outLst))
    )
  )
  (reverse outLst)
)

EDIT: Localized outLst.

Edited by Roy_043
Posted
13 hours ago, Roy_043 said:

; (test '(1 4 9 11 12 15 20) 5)
(defun test (inLst minDis)
  (setq outLst (list (car inLst)))
  (while (setq inLst (cdr inLst))
    (if (<= minDis (- (car inLst) (car outLst)))
      (setq outlst (cons (car inLst) outLst))
    )
  )
  (reverse outLst)
)

 

 

Wow thanx, this works like a charm!

Posted
13 hours ago, mhupp said:

Just wondering what you would use this for @gsc

 

This is for an Offshore Windfarm project. We have to bury an export cable, which transports the electricity from the offshore High Voltage station to the shore.
But this is in the North Sea, which has a lot of sand waves, which are moving sand dunes under water.
There are burial depth requirements for the export cable, but the moving sand waves (approx. 4m height difference) may cause that the cable is exposed after a couple of years because sand dunes are moving with the current.
To prevent that the buried cable gets exposed, the client provides not only a bathymetry of the seabed, but also a non-mobile reference level which is a bathymetry of the part of the seabed that doesn' t move. The burial requirement of the cable is based on this non-mobile reference level (NMRL), which is much deeper than the existing seabed bathymetry.

We bury the cable with a Trencher. This trencher is moving over cable (which is first layed on the seabed) and buries the cable (depending on the soil type) with either a big knife or waterjet. The problem is that this trencher has a maximum reach. If the Trench is burying at the top of a sand wave it may not reach the required burial depth.
Therefor we first need to pre-sweep ( scrape away with a dredger) the top of all sand waves where the trencher can't reach the burial depth.
We try to minimize the pre-sweeping depth to keep it as cheap as possible. There are along the 60km cable route a lot of sand waves...and there are often >2 export cables to bury.
So we need to calculate the volume of pre-sweeped sand.

Now here my routine steps in.
We create in a CAD drawing 2 vertical profiles: 1 of the latest Seabed bathymetry and 1 of the Non-mobile reference level.
The X-coord = the KP of the route and the Y-coord = the depth of the seabed or Non-mobile reference level (NMRL).
We shift the NMRL line vertically upwards in such a way that at that level the cable trencher can achieve the burial depth requirement.
Now the NMRL profile is intersecting the Seabed profile at the sand wave locations. These intersections are the start and end KP's to Pre-weep.
However if the distance between a range of intersections (start and end KP's) is to small we remove the inner intersections.
 

The main routine is used to create a list of KP ranges we use in DTM software to create polygons along the route to calculate the pre-sweep volume
The Subroutine, removes the KP's where the distance between 2 intersections is smaller than e.g. 5m
The 5m input is based on the size of the suction head of the dredger which pre-sweeps the sand waves.
If a range of intersections is smaller than e.g 5m, then this location can be omitted because the head is larger than the area to be pre-sweeped

Capice? 😉
 

  • Like 2
Posted

Another recursive variation (so likely to be slow):

(defun f ( l m )
    (if (cadr l)
        (if (< (cadr l) (+ (car l) m))
            (f (cons (car l) (cddr l)) m)
            (cons (car l) (f (cdr l) m))
        )
        l
    )
)

 

Interesting application @gsc 👍

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...