我已经尝试了这么多晚,我终于放弃了自己。看起来像一个非常简单的问题,但我想我并不完全理解Clojure以及我应该(我部分地将这归因于我对命令式语言的几乎唯一体验)。问题来自hackerrank.com
问题在于:
Problem Statement
Given a list repeat each element of the list n times. The input and output
portions will be handled automatically by the grader.
Input Format
First line has integer S where S is the number of times you need to repeat
elements. After this there are X lines, each containing an integer. These are the
X elements of the array.
Output Format
Repeat each element of the original list S times. So you have to return
list/vector/array of S*X integers. The relative positions of the values should be
same as the original list provided as input.
Constraints
0<=X<=10
1<=S<=100
所以,给定:
2
1
2
3
输出:
1
1
2
2
3
3
我试过了:
(fn list-replicate [num list]
(println (reduce
(fn [element seq] (dotimes [n num] (conj seq element)))
[]
list))
)
但这只是给了我一个例外。我已经尝试了很多其他的解决方案,这可能不是我最好的解决方案之一,但这是我能在这里发布一些最快的方法。
答案 0 :(得分:3)
(defn list-replicate [num list]
(mapcat (partial repeat num) list))
(doseq [x (list-replicate 2 [1 2 3])]
(println x))
;; output:
1
1
2
2
3
3
答案 1 :(得分:3)
之前的答案很简短且有效,但它非常“压缩”,对新人来说并不容易学习。我会以更简单,更明显的方式做到这一点。
首先,查看repeat
函数:
user=> (doc repeat)
-------------------------
clojure.core/repeat
([x] [n x])
Returns a lazy (infinite!, or length n if supplied) sequence of xs.
user=> (repeat 3 5)
(5 5 5)
所以我们看到如何容易地重复N次。
如果我们对列表的每个元素运行(重复n ...)怎么办?
(def N 2)
(def xvals [1 2 3] )
(for [curr-x xvals]
(repeat N curr-x))
;=> ((1 1) (2 2) (3 3))
所以我们越来越近了,但我们有一个输出列表。怎么修?最简单的方法是使用flatten
函数:
(flatten
(for [curr-x xvals]
(repeat N curr-x)))
;=> (1 1 2 2 3 3)
请注意,repeat
和for
都是惰性函数,除非我真的需要它,否则我宁愿避免使用它们。此外,我通常更喜欢将我的线性集合存储在具体的矢量中,而不是通用的“seq”类型。出于这些原因,我还包括一个额外的步骤,将结果强制为最终产品的单个(eagar)载体:
(defn list-replicate [num-rep orig-list]
(into []
(flatten
(for [curr-elem xvals]
(repeat N curr-elem)))))
(list-replicate N xvals)
;=> [1 1 2 2 3 3]
答案 2 :(得分:1)
我建议建立在Alan的解决方案上,而不是使用concat扁平化,因为如果您输入了类似[[1 2] [3 4]]的信息,它将保留数据的结构。
((fn [coll] (apply concat (for [x coll] (repeat 2 x)))) [[1 2] [3 4]])
output: => ([1 2] [1 2] [3 4] [3 4])
与展平不同,它会执行以下操作
((fn [coll] (flatten (for [x coll] (repeat 2 x)))) [[1 2] [3 4]])
output: => (1 2 1 2 3 4 3 4)
对于简单列表,例如'(1 2 3),其工作原理相同:
((fn [coll] (apply concat (for [x coll] (repeat 2 x)))) '(1 2 3))
output => (1 1 2 2 3 3)
答案 3 :(得分:0)
(reduce #(count (map println (repeat %1 %2))) num list)