我正在尝试解决CodeWars上的以下Ruby难题:
编写一个名为
merge_every
的函数,该函数接受3个参数:2个数组 和一个数字,指示要插入第二个项目的数量 将项目排列到第一个。第三个参数是可选的,应该 默认为4
。请考虑一下,因为您有一系列正常事件和 特色事件,并且您想将两者合并以产生一个数组 具有特色的事件每3个项目就会显示一次。
event_ids = [1, 2, 3, 4, 5, 6, 7] featured_event_ids = [10, 11] merge_every(event_ids, featured_event_ids, 3) # => [1, 2, 3, 10, 4, 5, 6, 11, 7]
如果第一个数组应在第二个数组之前完成,则其余 第二个被丢弃。而如果第二个在第一个之前用完, 应该保留第一个数组的整体。应该计数为0 或更少,则不应插入任何项目,并且如果目标数组为空, 比应返回一个空数组。
更多示例
numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] letters = ['a', 'b', 'c', 'd'] merge_every(numbers, letters) # => [1, 2, 3, 4, 'a', 5, 6, 7, 8, 'b', 9, 10] merge_every(letters, numbers) # => ['a', 'b', 'c', 'd'] merge_every(letters, numbers, 2) # => ['a', 'b', 1, 'c', 'd']
我的解决方法是:
def merge_every(target, source, count=4)
count == 0 ? number_of_source_in_target = 0 : number_of_source_in_target = target.count / count
insertion_number = count
source_number = 0
if insertion_number == 0 || source.count == 0 || number_of_source_in_target <= 1
target
elsif target.count % insertion_number == 0
number_of_source_in_target -= 1
while source_number < number_of_source_in_target && source_number < source.count do
modulo_0_return = target.insert(insertion_number, source[source_number])
insertion_number += (count + 1)
source_number += 1
end
modulo_0_return
else
while source_number < number_of_source_in_target && source_number < source.count do
modulo_numbers_return = target.insert(insertion_number, source[source_number])
insertion_number += (count + 1)
source_number += 1
end
modulo_numbers_return
end
end
numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
letters = ['a', 'b', 'c', 'd']
print merge_every(numbers, letters, 3)
当我在计算机上运行代码时,我得到了正确的答案,但是在CodeWars网站上,他们的检查器给出了不同的输出。区别在于:
merge_every(numbers, letters, 3)
# My Terminal: [1, 2, 3, 'a', 4, 5, 6, 'b', 7, 8, 9, 'c', 10]
# CodeWars "checker": [1, 2, 3, "a", 4, "a", 5, "b", 6, 7, 8, "c", "b", 9, 10]
merge_every(numbers, letters, 1)
# My Terminal: [1, 'a', 2, 'b', 3, 'c', 4, 'd', 5, 6, 7, 8, 9, 10]
# CodeWars "checker": [1, "a", 2, "b", 3, "c", "a", "d", 4, "a", 5, "b", 6, 7, 8, "c", "b", 9, 10]
我不知道为什么。谁能帮我找出这种差异?
答案 0 :(得分:0)
我不确定代码大战在做什么,但可能是它多次运行您的方法。您的代码要做的一件事是使数组target
发生突变,因此,如果您这样做了。
numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
letters = ['a', 'b', 'c', 'd']
merge_every(numbers, letters, 3)
=> [1, 2, 3, 'a', 4, 5, 6, 'b', 7, 8, 9, 'c', 10]
但是,如果您选中numbers
,就会发现它们已更改...
p numbers
=> [1, 2, 3, 'a', 4, 5, 6, 'b', 7, 8, 9, 'c', 10]
因此,您的数字数组将发生更改,并且每次使用相同的输入对象运行merge_every
时,您都会得到不同的结果(并再次更改numbers
数组)
您可以尝试确保在数组的副本(副本)上而不是数组本身上运行代码...看上去相同但对象不同的数组。这样,当代码更改target
时,原始输入arry不变。
def merge_every(target, source, count=4)
target = target.dup
...
答案 1 :(得分:0)
这是使用内置功能Enumerable#each_slice
的选项,也许您也可以在codewar中进行测试以查看是否存在某些问题:
n = 3
event_ids.each_slice(n).zip(featured_event_ids).flatten.compact
#=> [1, 2, 3, "a", 4, 5, 6, "b", 7]
检查其工作方式可能会提供提示。
需要添加一个条件来避免此结果,例如使用n=6
:
#=> [1, 2, 3, 4, 5, 6, "a", 7, "b"]
答案 2 :(得分:0)
如果您的代码通过了测试,但未通过CodeWar的测试,则最可能的解释是您的测试不正确,或者更有可能是不完整的。
这是一种类似于Ruby的插入方式。
def insert_em(arr, insertions, after_every = 4)
return arr if after_every <= 0
enum_arr = arr.to_enum
isize = insertions.size
arr.size.times.with_object([]) do |i,a|
a << enum_arr.next
a << insertions[i/after_every] if
i <= after_every*isize && ((i+1) % after_every).zero?
end
end
arr = (1..10).to_a
insert_em(arr, [:a, :b, :c], -1)
#=> [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
insert_em(arr, [:a, :b, :c], 0)
#=> [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
insert_em(arr, [:a, :b, :c], 1)
#=> [1, :a, 2, :b, 3, :c, 4, 5, 6, 7, 8, 9, 10]
insert_em(arr, [:a, :b, :c], 2)
#=> [1, 2, :a, 3, 4, :b, 5, 6, :c, 7, 8, 9, 10]
insert_em(arr, [:a, :b, :c], 4)
#=> [1, 2, 3, 4, :a, 5, 6, 7, 8, :b, 9, 10]
insert_em(arr, [:a, :b, :c], 5)
#=> [1, 2, 3, 4, 5, :a, 6, 7, 8, 9, 10, :b]
insert_em(arr, [:a, :b, :c], 11)
#=> [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
insert_em(arr, [])
#=> [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
insert_em([], [:a, :b, :c])
#=> []
insert_em([], [])
#=> []