Last active
December 10, 2015 17:08
-
-
Save SQReder/4465146 to your computer and use it in GitHub Desktop.
Попробовал решить еще двумя способами. Кажется, нашел неплохое решение. Хотя и не удовлетворен.
Сжирает добрых 400 метров оперативы. Хрень какая-то.
Нахрен такие апетиты!
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(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))) | |
)) |
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