2011-07-06 4 views
5

x 벡터의 벡터로 저장된 x, y 포인트 목록이 있습니다. 경계를 찾고 싶습니다. 이 주어진 예를 들어x, y 포인트 목록의 경계를 얻으십시오.

:

[[0 0] [20 30] [-50 -70] [200 300]] 

결과는 다음과 같습니다

{:x -50, :y -70, :x2 200, :y2 300} 

가 여기에 지금까지 무슨이다. 그것은 원하는 결과를 주지만, 장황하고 나에게 매우 냉담한 것처럼 보이지는 않습니다.

(defn get-stroke-bounds [vector-of-points] 
    (reduce (fn [m [x y]] 
     {:x (min (:x m Integer/MAX_VALUE) x) 
     :y (min (:y m Integer/MAX_VALUE) y) 
     :x2 (max (:x2 m Integer/MIN_VALUE) x) 
     :y2 (max (:y2 m Integer/MIN_VALUE) y)}) 
     {} 
     (vector-of-points))) 

개선 방법에 대한 아이디어가 있으십니까? 감사!

답변

3

이미 입력 점에 벡터를 사용하고 있다면 반환 값을 동일한 형식으로 지정해야합니다. 이를 염두에두고이 도구는 훌륭한 관용적 솔루션이라고 생각합니다.

(defn bounds 
    [points] 
    (let [xs (sort (map first points)) 
     ys (sort (map second points))] 
    (list [(first xs) (first ys)] 
      [(last xs) (last ys)]))) 
+0

'first'와'second'를 목록에 매핑하여 어떤 것을 얻을 수 있습니다! 당연하지! 감사! – jhickner

4

당신의 해결책은 이미 꽤 좋습니다! 그것은 상당히 관용적이며 알고리즘 적으로 최적 인 점의 수에서 O (n)입니다 (실제로는 정렬을 수행하는 방법보다 낫습니다).

하지만, 여기에 내가 솔루션을 생각하지 않는다

(defn get-stroke-bounds [stroke] 
    (zipmap 
     [:x :y :x2 :y2] 
     (map 
     (fn [[getter reducer]] 
      (reduce 
      reducer 
      (map getter stroke))) 
     [ 
      [first min] 
      [second min] 
      [first max] 
      [second max]]))) 
+0

확실히 흥미 롭습니다. 그것이 작동하는 방법을 따라 잠시 나 걸렸어. 아주 멋지다! – jhickner

1

:-) 고차 기능의 큰 팬이기 때문에 주로 생성 .... 당신이 흥미있을 거라고 그것을하는 다른 방법 clojure-ey도 아니다. 그러나 코드가 적 으면 정렬 된 집합을 시도 할 수 있습니다.

(let [v [[0 0] [20 30] [-50 -70] [200 300]] 
     v-sorted (apply sorted-set v)] 
    [(first v-sorted) (last v-sorted)]) 

업데이트 : 나는 위의 코드가 정확하지 않습니다 죄송합니다. separetely x와 y를 정렬하여 최대 또는 최소 점이 아닌 바운드를 찾는 것이 필요합니다. 세트가 선호되지 않는 한 John의 solution이 좋습니다.

관련 문제