Проверить, равна ли сумма двух разных чисел в массиве переменному числу?

в Ruby я хотел бы взять массив чисел, выбрать 2 разных числа, добавить эти 2 числа вместе и увидеть погоду там, равную переменной x.y-переменная x. Вот код, который я использовал

def arrayIsEqual? (numArray, x)
  return true if numArray.sample + numArray.sample == x
  return false if numArray.empty? || numArray.count == 1
end
numArray = [4,2,7,5]
x = 11

arrayIsEqual (numArray, n) должен возвратить true, так как 4 + 7 = n (11)

как мне заставить это работать?

Я не хочу, чтобы это были 2 случайных числа, просто любые 2 разных числа, которые складываются в n

5 ответов


похоже, вы пытаетесь увидеть, если есть любой два числа в массиве, которые складываются до указанного значения x. Однако ваш код просто выбирает два числа наугад и проверяет, складываются ли эти числа.

у Руби есть Array#combination метод, который генерирует все комбинации заданной длины:

def contains_pair_for_sum?(arr, n)
  !!arr.uniq.combination(2).detect { |a, b| a + b == n }
end

дополнительная информация:

  • во-первых, мы назвали его в соответствии с соглашениями Ruby: каждое слово separated_by_underscores. The ? в конце означает, что метод является методом предикатов и возвращает значение true или false.

  • внутри метода, происходит несколько вещей. Давайте посмотрим на эту строчку, кусочек за кусочком.

    • arr: мы берем массив, который был передан.

    • <...>.uniq: мы только смотрим на уникальные элементы (потому что OP хочет выбрать два разных числа.)

    • <...>.combination(2): мы запрашиваем все комбинации из массива длины 2. Если массив был [4, 5, 6], мы получили бы [[4, 5], [4, 6], [5, 6]].

    • <...>.detect { |a, b| a + b == n }: мы ищем первую комбинацию, которая складывается в n. Если мы его нашли, то это результат того метода. В противном случае, мы получим nil.

    • !!<...>: наконец, мы берем результат, который мы получили от detect и отрицайте это дважды. Первое отрицание порождает Логическое значение (true если значение, которое мы получили, было nil или false если это что-то еще); второе отрицание производит логическое значение, идентичное значению истинности первого отрицания. Это идиома Ruby, чтобы заставить результат быть либо true или false.

давайте посмотрим его в действии:

array = [4, 5, 9, 7, 8]

contains_pair_for_sum?(array, 11)
# => true (because [4, 7] sums to 11)

contains_pair_for_sum?(array, 17)
# => true (because [9, 8] sums to 17)

contains_pair_for_sum?(array, 100)
# => false (no pair matched)

Я понимаю, что ваш вопрос "есть любой пара чисел в моем массиве равна x", в этом случае это сделает то, что вам нужно:

def has_pair_equal?(num_array, x)
  (0..num_array.length-1).any? do |i| 
    num_array[i+1..-1].any? { |n| n + num_array[i] == x }
  end
end

проверяет все суммы пар чисел в массиве, и чеки, если их сумма x. sample случайно выбирает элемент из массива, что означает, что ваш код делает "return true иногда если в моем массиве есть пара чисел, равная x"


def array_is_equal? (num_array, x) 
  equality = 0
  num_array.each do |a|
    equality += 1 if a == x
    return true if equality == 2
  end
  return false
end

используйте строчные и подчеркивания для переменных в Ruby. Конвенция отличается здесь от некоторых других языков.


один лайнер

x=[4,2,7,5]; x.each_with_index.any? {|y,i| x.each_with_index.any? {|z,j| unless i==j; z+y==11; end } }

и как функция

def pair_sum_match?(arr, x)
    arr.each_with_index.any? do |y,i|
        arr.each_with_index.any? do |z,j|
            unless i==j
                z+y==x
            end
        end
    end
end

Обновлено: добавлен each_with_index, чтобы избежать самостоятельного включения в проверки. Теперь это намного дольше: -/


просто повторите его один раз и используйте целевой номер, чтобы увидеть, соответствует ли он. В 100 раз быстрее, чем большинство ответов здесь

numbers = ( -10..10 ).to_a
numbers.unshift( numbers.first + -1 ) # if you do -20 or 20
numbers.push( numbers.last + 1 )
target    = 5
searched  = { }
matches   = { }
numbers.each do |number|
  if searched[ target - number + 1 ] == true
    matches[ "#{ number }_plus_#{ target - number }" ] = target
  end
  searched[ number + 1 ] = true
end
ap matches