Skip to main content
added 2 characters in body
Source Link
Tobias
  • 33.7k
  • 1
  • 38
  • 78

Generate a complete (inverserassoc-) map assigning time-stamps to nodes at first. Afterwards sort and then locate time-stamp in the sorted list. From there you can go forward and backward.

(defvar goto-node-timestamp-tolerance 1e-5
  "Tolerance for testing equality of timestamps.")

(defun goto-node (list time-stamp n)
  "Go to the desired node commencing from an existing TIME-STAMP in LIST.
If N is positive, then go forwards in time by that number of N time-stamps.
If N is negative, then backwards in time by that number of N time-stamps.
If node does not exist, return nil; otherwise, return node and corresponding time-stamp."
  (let* ((full-list (apply #'append
                           (loop for node-stamps in list
                                 collect (mapcar (lambda (stamp) (list (car node-stamps) stamp)) (cadr node-stamps)))))
         (full-list (cl-sort full-list (lambda (node-stamp1 node-stamp2) (< (caadr node-stamp1) (caadr node-stamp2)))))
         (current-pos (cl-position-if (lambda (node-stamp) (< (abs (- (caadr node-stamp) time-stamp)) goto-node-timestamp-tolerance)) full-list)))
    (assert current-pos nil "Timestamp not found in list!")
    (nth (max (min (+ current-pos n) (1- (length full-list))) 0) full-list)))

(setq l '(([node1] ((5.6) (3.7) (11.7) (8.2)))
  ([node2] ((4.4) (9.9) (6.1 . t)))
  ([node3] ((7.5) (2.3) (1.5)))
  ([node4] ((10.3)))))

(goto-node l 6.1 -1) ; => '([node3] (5.6))

(goto-node l 6.1 -4) ; => '([node3] (2.3))

(goto-node l 6.1 1) ; => '([node3] (7.5))

(goto-node l 6.1 4) ; => '([node4] (10.3))

Generate a complete (inverse) map assigning time-stamps to nodes at first. Afterwards sort and then locate time-stamp in the sorted list. From there you can go forward and backward.

(defvar goto-node-timestamp-tolerance 1e-5
  "Tolerance for testing equality of timestamps.")

(defun goto-node (list time-stamp n)
  "Go to the desired node commencing from an existing TIME-STAMP in LIST.
If N is positive, then go forwards in time by that number of N time-stamps.
If N is negative, then backwards in time by that number of N time-stamps.
If node does not exist, return nil; otherwise, return node and corresponding time-stamp."
  (let* ((full-list (apply #'append
                           (loop for node-stamps in list
                                 collect (mapcar (lambda (stamp) (list (car node-stamps) stamp)) (cadr node-stamps)))))
         (full-list (cl-sort full-list (lambda (node-stamp1 node-stamp2) (< (caadr node-stamp1) (caadr node-stamp2)))))
         (current-pos (cl-position-if (lambda (node-stamp) (< (abs (- (caadr node-stamp) time-stamp)) goto-node-timestamp-tolerance)) full-list)))
    (assert current-pos nil "Timestamp not found in list!")
    (nth (max (min (+ current-pos n) (1- (length full-list))) 0) full-list)))

(setq l '(([node1] ((5.6) (3.7) (11.7) (8.2)))
  ([node2] ((4.4) (9.9) (6.1 . t)))
  ([node3] ((7.5) (2.3) (1.5)))
  ([node4] ((10.3)))))

(goto-node l 6.1 -1) ; => '([node3] (5.6))

(goto-node l 6.1 -4) ; => '([node3] (2.3))

(goto-node l 6.1 1) ; => '([node3] (7.5))

(goto-node l 6.1 4) ; => '([node4] (10.3))

Generate a complete (rassoc-) map assigning time-stamps to nodes at first. Afterwards sort and then locate time-stamp in the sorted list. From there you can go forward and backward.

(defvar goto-node-timestamp-tolerance 1e-5
  "Tolerance for testing equality of timestamps.")

(defun goto-node (list time-stamp n)
  "Go to the desired node commencing from an existing TIME-STAMP in LIST.
If N is positive, then go forwards in time by that number of N time-stamps.
If N is negative, then backwards in time by that number of N time-stamps.
If node does not exist, return nil; otherwise, return node and corresponding time-stamp."
  (let* ((full-list (apply #'append
                           (loop for node-stamps in list
                                 collect (mapcar (lambda (stamp) (list (car node-stamps) stamp)) (cadr node-stamps)))))
         (full-list (cl-sort full-list (lambda (node-stamp1 node-stamp2) (< (caadr node-stamp1) (caadr node-stamp2)))))
         (current-pos (cl-position-if (lambda (node-stamp) (< (abs (- (caadr node-stamp) time-stamp)) goto-node-timestamp-tolerance)) full-list)))
    (assert current-pos nil "Timestamp not found in list!")
    (nth (max (min (+ current-pos n) (1- (length full-list))) 0) full-list)))

(setq l '(([node1] ((5.6) (3.7) (11.7) (8.2)))
  ([node2] ((4.4) (9.9) (6.1 . t)))
  ([node3] ((7.5) (2.3) (1.5)))
  ([node4] ((10.3)))))

(goto-node l 6.1 -1) ; => '([node3] (5.6))

(goto-node l 6.1 -4) ; => '([node3] (2.3))

(goto-node l 6.1 1) ; => '([node3] (7.5))

(goto-node l 6.1 4) ; => '([node4] (10.3))
Source Link
Tobias
  • 33.7k
  • 1
  • 38
  • 78

Generate a complete (inverse) map assigning time-stamps to nodes at first. Afterwards sort and then locate time-stamp in the sorted list. From there you can go forward and backward.

(defvar goto-node-timestamp-tolerance 1e-5
  "Tolerance for testing equality of timestamps.")

(defun goto-node (list time-stamp n)
  "Go to the desired node commencing from an existing TIME-STAMP in LIST.
If N is positive, then go forwards in time by that number of N time-stamps.
If N is negative, then backwards in time by that number of N time-stamps.
If node does not exist, return nil; otherwise, return node and corresponding time-stamp."
  (let* ((full-list (apply #'append
                           (loop for node-stamps in list
                                 collect (mapcar (lambda (stamp) (list (car node-stamps) stamp)) (cadr node-stamps)))))
         (full-list (cl-sort full-list (lambda (node-stamp1 node-stamp2) (< (caadr node-stamp1) (caadr node-stamp2)))))
         (current-pos (cl-position-if (lambda (node-stamp) (< (abs (- (caadr node-stamp) time-stamp)) goto-node-timestamp-tolerance)) full-list)))
    (assert current-pos nil "Timestamp not found in list!")
    (nth (max (min (+ current-pos n) (1- (length full-list))) 0) full-list)))

(setq l '(([node1] ((5.6) (3.7) (11.7) (8.2)))
  ([node2] ((4.4) (9.9) (6.1 . t)))
  ([node3] ((7.5) (2.3) (1.5)))
  ([node4] ((10.3)))))

(goto-node l 6.1 -1) ; => '([node3] (5.6))

(goto-node l 6.1 -4) ; => '([node3] (2.3))

(goto-node l 6.1 1) ; => '([node3] (7.5))

(goto-node l 6.1 4) ; => '([node4] (10.3))