2017-04-19 7 views
0

ユーザには、AB(コレクション)の2つの入力と数字のXが与えられ、出力を作成する必要があります。出力はAの最初の値から開始し、次にから5までX単位をとり、ABの両方が使い果たされるまで続けます。 1 < X < sizeof(B)とすることができます。ただし、AまたはBのいずれかが不足している場合は、ショートコレクションの先頭にループバックし、もう一方がなくなるまで続行する必要があります。ループバックは、両方のコレクションが終了するまで続きます。2つのRubyコレクションを結合するには?

とは何ですか? Rubyでこれを行う方法はありますか?私はコードが半分壊れていて、これを行う良い方法を見つけることができないようです。いいえ、それは宿題の問題ではありません。私には奇妙な趣味がある。ここで

は、私がしたい行動のいくつかのサンプルテストです:ここで

# SomeModule.copy(A, B, X) 
SomeModule.copy(%w(a1 a2 a3), %w(b1 b2 b3),  1) == %w(a1 b1 a2 b2 a3 b3)) 
SomeModule.copy(%w(a1),   %w(b1),    1) == %w(a1 b1)) 
SomeModule.copy(%w(a1),   %w(b1 b2 b3),  1) == %w(a1 b1 a1 b2 a1 b3)) 
SomeModule.copy(%w(a1 a2),  %w(b1 b2 b3 b4 b5), 2) == %w(a1 b1 b2 a2 b3 b4 a1 b5 b1)) 
SomeModule.copy(%w(a1 a2),  %w(b1 b2 b3 b4 b5), 2) == %w(a1 b1 b2 a2 b3 b4 a1 b5 b1)) 
SomeModule.copy(%w(a1 a2 a3 a4), %w(b1 b2 b3 b4 b5), 3) == %w(a1 b1 b2 b3 a2 b4 b5 b1 a3 b2 b3 b4 a4 b5 b1 b2)) 
+4

あなたはRubyで試した方法は何ですか?半分壊れた、まったく期待していないコードでも、あなたのソリューションに努力を注ぎ込んだ印であり、人々の手助けを促します。 – tadman

+0

希望する結果を含む簡単な例が参考になります。 –

+0

@CarySwoveland私は、入力と希望出力のサンプルテストを含んでいました。 –

答えて

1

は、アイデアは、それらの両方が彼らの最大のインデックスに達するまで、すべての配列を反復処理することで、何か、次のとおりです。

def custom_combine(a,b,x) 
    max_index_a = a.count - 1 
    max_index_b = b.count - 1 
    a_run_out = false 
    b_run_out = false 

    output = [] 

    a.cycle.each_with_index do |elem_a, index_a| 
    output << elem_a 
    # base on a index get x elements from b 
    x.times do |i| 
     index_b = ((index_a * x) + i) % (max_index_b + 1) 
     output << b[index_b] 
     b_run_out = true if index_b == max_index_b 
    end 
    a_run_out = true if index_a == max_index_a 
    break if a_run_out && b_run_out 
    end 

    output 
end 

a = %w(a1 a2 a3 a4) 
b = %w(b1 b2 b3 b4 b5) 
x = 3 

custom_combine(a,b,x) 
# => ["a1", "b1", "b2", "b3", "a2", "b4", "b5", "b1", "a3", "b2", "b3", "b4", "a4", "b5", "b1", "b2"] 
+0

ありがとう!私は列挙型を読んでいたので、私は「サイクル」をスキップしたか、それが何をしたのかを正確に理解することはできませんでした。それはそれを行う良い方法です。 –

+0

私が最終的に思いついたのは、あなたがここに持っているものとかなりよく似ていて、コレクショントラッキングロジックがクラスに引き出されています。 –

1

Enumerableがあり一度にN個のアイテムを列挙可能なオブジェクトに対して反復させるメソッドですeach_sliceです。それを使用して、あなたはこのような何かを行うことができます。

ここ
a1 = [1, 2, 3, 4, 5, 6] 
a2 = [10, 11, 12, 20, 21, 22, 30, 31, 32, 40, 41, 42, 50, 51, 52, 60] 

a1.each_slice(1).zip(a2.each_slice(3)).flatten 

# => [1, 10, 11, 12, 2, 20, 21, 22, 3, 30, 31, 32, 4, 40, 41, 42, 5, 50, 51, 52, 6, 60] 
0

ようやく4.30amで私の脳から飛び出したものです:

class InfiniteArray 
    private 
    attr_reader :collection 
    attr_accessor :index, :wrapped_count 
    public 

    def initialize(collection) 
    @collection = collection 
    reset 
    end 

    def next 
    value = collection[index] 
    if index < collection.length - 1 
     self.index = index + 1 
    else 
     self.index = 0 
     self.wrapped_count = wrapped_count + 1 
    end 
    value 
    end 

    def wrapped? 
    wrapped_count > 0 
    end 

    def reset 
    @index = 0 
    @wrapped_count = 0 
    end 
end 

class IntervalCopier 
    private 
    attr_reader :source_collection, :destination_collection, :interval 
    public 

    def initialize(source_collection, destination_collection, interval) 
    @source_collection = InfiniteArray.new(source_collection) 
    @destination_collection = InfiniteArray.new(destination_collection) 
    @interval = interval 
    end 

    def copy 
    final = [] 
    until source_collection.wrapped? && destination_collection.wrapped? do 
     final << source_collection.next 
     interval.times { final << destination_collection.next } 
    end 
    [source_collection, destination_collection].each(&:reset) 
    final 
    end 
end 
0
def copy(array1, array2, slice_length) 
    iterations = [array1.length, 
       (array2.length.to_f/slice_length.to_f).round 
       ].max 

    result = [] 
    enum1 = array1.cycle 
    enum2 = array2.cycle 

    iterations.times do 
    result << enum1.next 
    slice_length.times { result << enum2.next } 
    end 

    result 
end 

require 'minitest/autorun' 

class TestCopy < Minitest::Test 
    def test_copy 
    assert_equal(%w(a1 b1 a2 b2 a3 b3),        copy(%w(a1 a2 a3), %w(b1 b2 b3),  1)) 
    assert_equal(%w(a1 b1),           copy(%w(a1),   %w(b1),    1)) 
    assert_equal(%w(a1 b1 a1 b2 a1 b3),        copy(%w(a1),   %w(b1 b2 b3),  1)) 
    assert_equal(%w(a1 b1 b2 a2 b3 b4 a1 b5 b1),      copy(%w(a1 a2),  %w(b1 b2 b3 b4 b5), 2)) 
    assert_equal(%w(a1 b1 b2 a2 b3 b4 a1 b5 b1),      copy(%w(a1 a2),  %w(b1 b2 b3 b4 b5), 2)) 
    assert_equal(%w(a1 b1 b2 b3 a2 b4 b5 b1 a3 b2 b3 b4 a4 b5 b1 b2), copy(%w(a1 a2 a3 a4), %w(b1 b2 b3 b4 b5), 3)) 
    end 
end 
関連する問題