clojure performance on badly performing code -
i have completed this problem on hackerrank , solution passes test cases not fast enough 4 out of 11 test cases.
my solution looks this:
(ns scratch.core (require [clojure.string :as str :only (split-lines join split)])) (defn ascii [char] (int (.charat (str char) 0))) (defn process [text] (let [parts (split-at (int (math/floor (/ (count text) 2))) text) left (first parts) right (if (> (count (last parts)) (count (first parts))) (rest (last parts)) (last parts))] (reduce (fn [acc i] (let [a (ascii (nth left i)) b (ascii (nth (reverse right) i))] (if (> b) (+ acc (- b)) (+ acc (- b a)))) ) 0 (range (count left))))) (defn print-result [[x & xs]] (prn x) (if (seq xs) (recur xs))) (let [input (slurp "/users/paulcowan/downloads/input10.txt") inputs (str/split-lines input) length (read-string (first inputs)) texts (rest inputs)] (time (print-result (map process texts))))
can give me advice should @ make faster?
would using recursion instead of reduce faster or maybe line expensive:
right (if (> (count (last parts)) (count (first parts))) (rest (last parts)) (last parts))
because getting count twice.
you redundantly calling reverse on every iteration of reduce:
user=> (let [c [1 2 3] noisey-reverse #(doto (reverse %) println)] (reduce (fn [acc e] (conj acc (noisey-reverse c) e)) [] [:a :b :c])) (3 2 1) (3 2 1) (3 2 1) [(3 2 1) :a (3 2 1) :b (3 2 1) :c]
the reversed value calculated inside containing let, , need calculated once.
also, due way parts
defined, doing linear time lookups each call nth
. better put parts in vector , indexed lookup. in fact wouldn't need reversed parts, , arithmetic based on count of vector find item up.
Comments
Post a Comment