I am competing in an online competition and the scenario is like this : I coded with my basic knowledge of clojure and got 11 out of 20 testcases and others being timed out and one being runtime error..
I started optimizing my code and read https://groups.google.com/forum/#!searchin/clojure/performance/clojure/SxT2MaOsip8/xoMkDVHeOqMJ and other google articles for performance.. but after that i just managed to solve only one more problem and i am stuck at 12 solved.. ( the time for each case is 8 seconds max) The last 12th was completed in 7.05 secs :) .. just on the border huh... :) The problem is about that of Solving calculataor expressions like "2+3/2/2/(2+8)" mod 10^8+7 gives answer 10^8+3.. Nevertheless it is the concern but optimizing code is :) This is current condition of my code : (ns fpcontest.expression) (def Term) (def Factor) (def ToMod (int (+ 1000000000 7))) ;; (int ToMod) (def toPrint false) (defn myprintln [& args] ;; (if toPrint ;; (apply println args)) ) (defn EulerDivNonMemo [^long x ^long p] (let [ToMod (+ p 2)] (loop [num (long 1) toPow p numDouble x] (if (= 0 toPow) ;;(do (myprintln " EulerDiv : " num " for " x p)) num (let [numDouble2 (rem (* numDouble numDouble) ToMod) halfToPow (bit-shift-right toPow 1)] (if (odd? toPow) (recur (rem (* num numDouble) ToMod) halfToPow numDouble2) (recur num halfToPow numDouble2)) )))) ) (def EulerDiv (memoize EulerDivNonMemo) ) ;; (EulerDiv 2 2) ;; (defn TestEulerDiv [] ;; (and ;; (= 2 (mod (* 4 (EulerDiv 2 (- 3 2))) 3)) ;; (= 1 (mod (* 2 (EulerDiv 2 (- 3 2))) 3)) ;; (= 1 (int (mod (* 2 (EulerDiv 2 (- ToMod 2))) ToMod)))) ;; ) ;; (= true (TestEulerDiv)) (defn Expression [lst] (let [term (Term lst) ;; p (myprintln term " term for exp " lst) sizeTerm (count term) evaluateExpr (fn [opr lst] (let [expr (Expression (drop 2 lst)) ;; p (myprintln expr " expr for Expr " lst " and " opr) intLst (first lst)] (cons (rem (opr intLst (first expr)) ToMod) (drop 1 expr))))] (if (> sizeTerm 2) (if (= (second term) "+") (evaluateExpr + term) (if (= (second term) "-") (evaluateExpr - term) term) ) ;; first of term is the answer term ) )) (defn Term [lst] (let [factor (Factor lst) ;; p (myprintln factor " factor for term " lst) sizeFactor (count factor) evaluateExpr (fn [opr lst] (let [expr (Term (drop 2 lst)) ;;p (myprintln expr " term for expr " lst " and " opr) intLst (first lst)] (cons (rem (opr intLst (first expr)) ToMod) (drop 1 expr) )))] (if (> sizeFactor 2) (if (= (second factor) "*") (evaluateExpr * factor) (if (= (second factor) "/") (let [expr (Term (drop 2 factor)) fExpr (first expr)] (cons (rem (* (first factor) (EulerDiv fExpr (- ToMod 2))) ToMod) (drop 1 expr)) ) ;;(evaluateExpr / factor) factor) ) factor ) )) (defn Factor [lst] (let [fFactor (first lst) ;;p (myprintln " Factor has : " lst) ] (if (= fFactor "+") (cons (int (Integer. (second lst))) (rest lst)) (if (= fFactor "-") (cons (- (int (Integer. (second lst)))) (rest (rest lst))) (if (= fFactor "(") ;; remove the '(' and ')' (let [expr (Expression (rest lst))] (cons (first expr) (drop 2 expr)) ) ;; (if (= (count lst) 1)) (cons (int (Integer. (first lst))) (rest lst)) ;;(myprintln "I do not know where i am... " lst) ) )) ) (defn split-with-delim [d s] (clojure.string/split s (re-pattern (str "(?=" d ")|(?<=" d ")")))) (defn make-calulator-list [s] (->> s (split-with-delim #"[\/\+\-\*\(\) ]") (filter #(not (or (= "" %) (= " " %)))) doall )) (defn StartRun [FuncToCall inputParse outputParse] (let [lines (line-seq (java.io.BufferedReader. *in*))] (outputParse (FuncToCall (inputParse (first lines))))) ) and this is how i am testing my code ................................ ****************** Test ******************************** (defn RunTests [] (and (= 1717 (int (first (Expression (make-calulator-list " 22 * 79 - 21"))))) (= 12 (int (first (Expression (make-calulator-list " 4/2/2 + 8"))))) (= 4 (int (first (Expression (make-calulator-list "4/-2/2 + 8"))))) (= 999998605 (int (mod (first (Expression (make-calulator-list "55+3-45*33-25"))) ToMod))) (= 999999987 (int (mod (first (Expression (make-calulator-list "4/-2/(2+8)"))) ToMod))) (= 22 (int (first (Expression (make-calulator-list "(22)*+1/-1+(1)"))))) (= 22 (int (first (Expression (make-calulator-list "11*(2/2)*2"))))) (= 11 (int (first (Expression (make-calulator-list "22*2/2*2"))))) (= '("4" "/" "-" "2" "/" "2" "+" "8") (make-calulator-list "4/-2/2 + 8")) (= '("4" "/" "-" "2" "/" "(" "2" "+" "8" ")") (make-calulator-list " 4/-2/(2 + 8)")) ) ) (RunTests) (Expression '("3" "+" "2")) (conj '("3") 1) (cons 2333 '(2 3 4)) (cons 2 (drop 1 '())) (drop 1 '()) (str (int 1.0)) (cons "1" '(1 "3")) (cons "1" nil) (int (Integer. "1")) (int (mod (first (Expression (make-calulator-list "4/-2/(2+8)"))) ToMod)) (mod (first (Expression (make-calulator-list "4/2"))) ToMod) (defn diffTime [func & args] (let [start (.getTime (java.util.Date.)) res (apply func args) end (.getTime (java.util.Date.))] (- end start))) (defn somuchtime= [times] (let [start (java.util.Date.) ] (loop [iTime 0] (if (= iTime times) start (recur (inc iTime)))))) (defn GenerateCalculatorTests [nums] (loop [num 0 sb (StringBuilder.)] (if (= num nums) (str "1" (.toString sb)) (->> sb ((fn [sb] (let [r (rand-int 500)] (do (if (< r 100) (.append sb "+") (if (< r 200) (.append sb "-") (if (< r 300) (.append sb "*") (if (< r 497) (.append sb "/") (.append sb (str "*(" (GenerateCalculatorTests 4) ")+")))))) (.append sb (rand-int 1000000000)) sb)))) (recur (inc num)) )) ) ) (GenerateCalculatorTests 50) (defn Execute [num] (let [str (GenerateCalculatorTests num)] (do (println str " = " ) (Expression (make-calulator-list (GenerateCalculatorTests num)))))) (diffTime Execute 2074) I find that the last problem which is giving runtime error is may be StackOverflow as i get it in with (diffTime Execute 3000) ;; where 3000 tries to get a calculator expression of 3000 or more ints.. see GenerateCalculatorTests.. with diffTime i also found that using rem is faster than using mod.. -- You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups "Clojure" group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.