Skip to content

Instantly share code, notes, and snippets.

@SQReder
Last active December 10, 2015 17:08
Show Gist options
  • Save SQReder/4465146 to your computer and use it in GitHub Desktop.
Save SQReder/4465146 to your computer and use it in GitHub Desktop.
Попробовал решить еще двумя способами. Кажется, нашел неплохое решение. Хотя и не удовлетворен. Сжирает добрых 400 метров оперативы. Хрень какая-то. Нахрен такие апетиты!
(ns your-application
(:use clojure.math.numeric-tower))
(import java.util.Vector)
;region генератор списка случайных чисел с хвостовой рекурсией
(defn rndgen_recur [l c n]
(if (= c n)
l
(recur (conj l (rand 10)) (inc c) n)))
(defn rndgen [n]
(rndgen_recur () 0 n))
;endregion
; вспомогательная функция
(defn vector-range [v]
(- (reduce max v) (reduce min v)))
; задача - разложить значения в векторе по промежуткам, для последующего отображения в гистограмме
;region влоб через хвостовую рекурсию
(defn slice_recur [in_data quant normal slices]
(if (empty? in_data)
slices ; возвращаем результат
(let [pos (floor (/ (- (first in_data) normal) quant))] ; определяем группу
(let [col (if (= pos (count slices)) (dec pos) pos)] ; проверяем выход индекса за границы
(recur (rest in_data) quant normal (assoc slices col (inc (get slices col)))))))) ; тут собственно рекурсия
; дохера скобок -----^
(defn slice [vector parts]
(let [slices (vec (repeat parts 0))]
(slice_recur vector (/ (vector-range vector) parts) (reduce min vector) slices)))
;endregion
; вторая попытка - пробую сделать полностью на векторе
; производительность ужасная. почему не пойму толком
(defn jSlice [vector parts]
(let [n (count vector) slices (new java.util.Vector (repeat parts 0)) normal (reduce min vector) quant (/ (vector-range vector) parts)]
(println "n:" n " slices:" (vec slices) " normal:" normal " quant:" quant)
(doseq [x vector]
(let [pos (floor (/ (- (nth vector x) normal) quant))]
(let [pos (if (= pos parts) (dec pos) pos)]
(.set slices pos (inc (.get slices pos)))
;(println (vec slices))
)))
slices))
; третий подход - вспомнил про map-reduce
; решение кажется неплохим
(defn mrSlice [vector parts]
(let [vmin (reduce min vector) vmax (reduce max vector)]
(let [slices (new java.util.Vector (repeat parts 0)) normal vmin quant (/ (- vmax vmin) parts)]
(doseq [pos (map #(floor (/ (- %1 normal) quant)) vector)]
(if (= pos parts)
(.set slices (dec pos) (inc (.get slices (dec pos))))
(.set slices pos (inc (.get slices pos)))))
slices)))
; четвертый подход - узнал про атомы
; решение кажется неплохим
(defn atomSlice [vector parts]
(let [vmin (reduce min vector) vmax (reduce max vector)]
(let [slices (atom (vec (repeat parts 0))) normal vmin quant (/ (- vmax vmin) parts)]
(doseq [pos (map #(floor (/ (- %1 normal) quant)) vector)]
(if (= pos parts)
(swap! slices assoc (dec pos) (inc (nth @slices (dec pos))))
(swap! slices assoc pos (inc (nth @slices pos)))))
slices)))
(dotimes [i 10]
(println)(println "i:" i)
(let [v (range 0 2000000) parts 5]
(time (println "sugar " (slice v parts)))
(time (println "map-reduce " (mrSlice v parts)))
(time (println "atom " (atomSlice v parts)))
))
@SQReder
Copy link
Author

SQReder commented Jan 9, 2013

for 2 000 000 items 
sugar  [400000 400000 400000 400000 400000]
"Elapsed time: 3549.00928 msecs"
map-reduce  #<Vector [400000, 400000, 400000, 400000, 400000]>
"Elapsed time: 1724.623753 msecs"

@SQReder
Copy link
Author

SQReder commented Jan 9, 2013

For 20 000 items 
sugar  [4000 4000 4000 4000 4000]
"Elapsed time: 72.062373 msecs"
jslice  #<Vector [4000, 4000, 4000, 4000, 4000]>
"Elapsed time: 4441.144208 msecs"
map-reduce  #<Vector [4000, 4000, 4000, 4000, 4000]>
"Elapsed time: 37.18948 msecs"

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment