我不确定这里最好的词是什么。通过“金字塔化”,我的意思是:
[1,2,3,4].pyramidize # => [1,1,1,1,2,2,2,3,3,4]
["a","b","c","d"].pyramidize # => ["a","a","a","a","b","b","b","c","c","d"]
为了直观地表示,可以将其视为:
[ 1,1,1,1,
2,2,2,
3,3,
4 ]
有没有办法做到最大化优雅?最像红宝石的方式?
我遇到了“需要”在我的一个项目中这样做。在考虑之后,我放弃了,决定以丑陋的方式解决问题。我想知道是否有一个很好的方法来做到这一点。到目前为止,为了直接进行,我最终为每个索引创建了一个单独的数组,并将每个数组拉伸到适当的长度并将它们组合在一起。但我不知道该怎么做,所以它看起来很漂亮;我的解决方案非常难看。
添加了代码高尔夫标签,因为一行中的任何解决方案都可能会成为我的一天,但不一定如此。
如果你的解决方案使第一个索引成为金字塔的“基础”或最后一个索引,那真的无关紧要,因为我可以在运行之前反转数组。
答案 0 :(得分:3)
irb(main):001:0> [2,1,3,5].flat_map.with_index{|i,j|[i]*(j+1)}
=> [2, 1, 1, 3, 3, 3, 5, 5, 5, 5]
irb(main):002:0> [1,2,3,4].flat_map{|i|[i]*i}
=> [1, 2, 2, 3, 3, 3, 4, 4, 4, 4]
答案 1 :(得分:3)
在Ruby 1.9中需要新的迭代器功能。
class Array
def pyramidize
reverse.map.with_index do |object, index|
[object] * (index + 1)
end.flatten.reverse
end
end
[1,2,3,4].pyramidize
=> [1, 1, 1, 1, 2, 2, 2, 3, 3, 4]
["a","b","c","d"].pyramidize
=> ["a", "a", "a", "a", "b", "b", "b", "c", "c", "d"]
答案 2 :(得分:0)
我不确定是否要使用列表或索引的值来确定列表应该重复多少,但是python中的一个简单解决方案可能很容易转移到ruby:
>>> import operator
>>> input = range(6)
>>> reduce(operator.add, [[i]*idx for idx, i in enumerate(input)])
[1, 2, 2, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 5]
<强>更新强>
哦,反转计数:
>>> import operator
>>> input = range(1, 6)
>>> reduce(operator.add, [[i]*(max(input) - idx) for idx, i in enumerate(input)])
[1, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 4, 4, 5]
当然,你在一个例子中颠倒了这个列表:
>>> import operator
>>> input = range(1, 6)
>>> reduce(operator.add, [[i]*(max(input) - idx) for idx, i in enumerate(input)])[::-1]
[ 5,
4, 4,
3, 3, 3,
2, 2, 2, 2,
1, 1, 1, 1, 1]
答案 3 :(得分:0)
FWIW,这是一种糟糕的做法:
>>> A = [1, 2, 3, 4]
>>> [ A[int((sqrt(8*k+1)-1) / 2)] for k in range(len(A)*(len(A)+1) / 2) ]
[1, 2, 2, 3, 3, 3, 4, 4, 4, 4]
不可否认,使用sqrt非常难看。
答案 4 :(得分:-1)
这是另一种在Python中执行此操作的方法
>>> A=[1,2,3,4]
>>> [y for i,x in enumerate(A) for y in [x]*(len(A)-i)]
[1, 1, 1, 1, 2, 2, 2, 3, 3, 4]
但是不要创建所有这些临时列表
>>> from itertools import repeat
>>> [y for i,x in enumerate(A) for y in repeat(x, len(A)-i)]
[1, 1, 1, 1, 2, 2, 2, 3, 3, 4]