gsc Posted May 20, 2021 Posted May 20, 2021 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? Quote
ten0s Posted May 20, 2021 Posted May 20, 2021 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) Quote
Roy_043 Posted May 20, 2021 Posted May 20, 2021 (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 May 21, 2021 by Roy_043 Quote
gsc Posted May 21, 2021 Author Posted May 21, 2021 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! Quote
gsc Posted May 21, 2021 Author Posted May 21, 2021 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? 2 Quote
Lee Mac Posted May 24, 2021 Posted May 24, 2021 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 Quote
Recommended Posts
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.