初学者';s clojure试图破解Kerrank问题超时
我正在hackerrank上尝试以下问题: 但不幸的是,我下面的clojure代码在许多测试用例上都超时了,我不知道是什么让它如此低效。请宽大点。我总共只有两个小时的clojure经验初学者';s clojure试图破解Kerrank问题超时,clojure,Clojure,我正在hackerrank上尝试以下问题: 但不幸的是,我下面的clojure代码在许多测试用例上都超时了,我不知道是什么让它如此低效。请宽大点。我总共只有两个小时的clojure经验 (require '[clojure.string :as str]) ; Complete the countingValleys function below. (defn countingValleys [n s] (do (def running 0) (defn count
(require '[clojure.string :as str])
; Complete the countingValleys function below.
(defn countingValleys [n s]
(do
(def running 0)
(defn counter [elem]
(do
(cond
(= elem "D") (def running (+ running 1))
(= elem "U")(def running (- running 1))
)
running
)
)
(def valley-num 0)
(defn valley-count [a b]
(do
(if (and (= a "U") (= b 0))
(def valley-num (+ valley-num 1)))
)
)
(def heights (for [elem s] (counter elem)))
(doseq [[i j] (map vector s heights)]
(valley-count i j))
valley-num
)
)
(def fptr (get (System/getenv) "OUTPUT_PATH"))
(def n (Integer/parseInt (clojure.string/trim (read-line))))
(def s (read-line))
(def result (countingValleys n (str/split s #"")))
(spit fptr (str result "\n") :append true)
同样逻辑的简单python实现,耗时5分钟并通过了所有测试用例:
def countingValleys(n, s):
list = []
for i in range(len(s)):
d = 0
if s[i] == "D":
d = 1
elif s[i] == "U":
d = -1
if len(list) == 0:
list.append(d)
else:
list.append(list[-1] + d)
num = 0
for i in range(len(s)):
if s[i] == "U" and list[i] == 0:
num += 1
return num
所以我想出来了。效率低下的原因是:
(doseq [[i j] (map vector s heights)]
(valley-count i j))
可替换为:
(doall (map valley-count s heights))
然后所有的测试都通过了 所以我想出来了。效率低下的原因是:
(doseq [[i j] (map vector s heights)]
(valley-count i j))
可替换为:
(doall (map valley-count s heights))
然后所有的测试都通过了 代码的缓慢是它的最小问题。你应该使用的工具是
- 纯函数
- 序列库
- 在速度方面,还有传感器的前景李>
(defn countingValleys [n s]
(let [counter {\D 1, \U -1}
heights (reductions + (map counter s))
s-heights (map vector s heights)
valley-num (count (filter #{[\U 0]} s-heights))]
valley-num))
。。。或者,使用->
线程宏
(defn countingValleys [_ s]
(->> s
(map {\D 1, \U -1})
(reductions +)
(map vector s)
(filter #{[\U 0]})
(count)))
这些比你的更清晰、更快
看起来你和HackerRank实际上在使用ClojureScript。使用
“U”
作为字符串元素在Clojure中不起作用:必须使用字符\U
代码的缓慢是它的最小问题。你应该使用的工具是
Those of us who are JavaScript(Node JS) developers, my solution here works perfectly
// Complete the countingValleys function below.
function countingValleys(n, s) {
const min = 2;
const max = 1000000;
let valleys = 0;
let isInValley;
s = (typeof s === 'string') ? s.split('') : s;
if (s.length >= min && s.length <= max &&
n === parseInt(n, 0) &&
n >= min &&
n <= max &&
n === s.length) {
s.map(steps => ((steps === "U") ? 1 : -1))
.reduce((prev, next) => {
if (prev < 0 && !isInValley) {
isInValley = true;
}
if ((prev + next) === 0 && isInValley) {
valleys++;
isInValley = false;
}
return prev + next;
});
}
return valleys;
}
- 纯函数
- 序列库
- 在速度方面,还有传感器的前景李>
(defn countingValleys [n s]
(let [counter {\D 1, \U -1}
heights (reductions + (map counter s))
s-heights (map vector s heights)
valley-num (count (filter #{[\U 0]} s-heights))]
valley-num))
。。。或者,使用->
线程宏
(defn countingValleys [_ s]
(->> s
(map {\D 1, \U -1})
(reductions +)
(map vector s)
(filter #{[\U 0]})
(count)))
这些比你的更清晰、更快
看起来你和HackerRank实际上在使用ClojureScript。使用
“U”
作为字符串元素在Clojure中不起作用:必须使用字符\U
我们这些JavaScript(Node-JS)开发人员,我的解决方案非常有效
Those of us who are JavaScript(Node JS) developers, my solution here works perfectly
// Complete the countingValleys function below.
function countingValleys(n, s) {
const min = 2;
const max = 1000000;
let valleys = 0;
let isInValley;
s = (typeof s === 'string') ? s.split('') : s;
if (s.length >= min && s.length <= max &&
n === parseInt(n, 0) &&
n >= min &&
n <= max &&
n === s.length) {
s.map(steps => ((steps === "U") ? 1 : -1))
.reduce((prev, next) => {
if (prev < 0 && !isInValley) {
isInValley = true;
}
if ((prev + next) === 0 && isInValley) {
valleys++;
isInValley = false;
}
return prev + next;
});
}
return valleys;
}
//完成下面的CountingValley功能。
函数计数(n,s){
常数min=2;
const max=1000000;
设谷=0;
让伊森瓦利;
s=(typeof s=='string')?s.split(“”):s;
如果(s.length>=min&&s.length=min&&
n((步数==“U”)?1:-1))
.减少((上一个,下一个)=>{
如果(上一个<0&!isInValley){
isInValley=真;
}
如果((上一个+下一个)==0&&isInValley){
图形++;
isInValley=假;
}
返回上一个+下一个;
});
}
返回谷;
}
对于我们这些JavaScript(Node JS)开发人员,我的解决方案非常有效
//完成下面的CountingValley功能。
函数计数(n,s){
常数min=2;
const max=1000000;
设谷=0;
让伊森瓦利;
s=(typeof s=='string')?s.split(“”):s;
如果(s.length>=min&&s.length=min&&
n((步数==“U”)?1:-1))
.减少((上一个,下一个)=>{
如果(上一个<0&!isInValley){
isInValley=真;
}
如果((上一个+下一个)==0&&isInValley){
图形++;
isInValley=假;
}
返回上一个+下一个;
});
}
返回谷;
}
到目前为止,您尝试了什么?你认为是什么造成了这段时间的缓慢?我不确定。我基本上在python中实现了相同的逻辑,并且通过了所有测试。也许我正在做一些非常具体的Clojure的低效工作。您应该遵循Clojure教程来理解函数式编程的基础知识,这将帮助您编写更多的惯用(以及更高性能)代码。特别是,请使用而不是def
和defn
。这个问题属于您迄今为止尝试过的内容?你认为是什么造成了这段时间的缓慢?我不确定。我基本上在python中实现了相同的逻辑,并且通过了所有测试。也许我正在做一些非常具体的Clojure的低效工作。您应该遵循Clojure教程来理解函数式编程的基础知识,这将帮助您编写更多的惯用(以及更高性能)代码。特别是,使用而不是def
和defn
。这个问题属于当OP向Clojure寻求帮助时给出JavaScript解决方案似乎没有多大帮助。当OP向Clojure寻求帮助时给出JavaScript解决方案似乎没有多大帮助。