Проверить, равна ли сумма двух разных чисел в массиве переменному числу?
в 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