检查连续数字
Check for consecutive numbers
我有一个整数数组 m
。我正在寻找一种方法来检查 m
的元素是否连续。有没有办法测试连续数字?
我想出了这段代码,旨在在数组长度为四时工作:
m.count == 4 && (m.max-m.min) == 3
对于 [1,1,1,4]
或 [0,0,0,3]
.
returns true
不正确
你可以试试这个:
a == (a.min..a.max).to_a && a.count == 4
这仅在数组递增时有效。 [3, 4, 5, 6]
会通过,但 [4, 3, 5, 6]
不会。
Enumerable 有一个非常方便的方法,称为 each_cons
,其工作方式如下:
[1,2,3,4].each_cons(2).to_a # => [ [1, 2], [2, 3], [3, 4] ]
也就是说,它产生每组连续的 n 个元素。在我们的例子中 n 是 2.
当然,顾名思义,它 returns 是一个 Enumerator,因此我们可以将它与其他 Enumerable 方法链接起来,例如 all?
:
def four_consecutive?(arr)
return false unless arr.size == 4
arr.each_cons(2).all? {|a, b| b == a + 1 }
end
four_consecutive?([2,3,4,5]) # => true
four_consecutive?([2,2,2,5]) # => false
four_consecutive?([1,2,3,4,5]) # => false
这个方法比其他方法有优势,因为all?
一旦块returns为假就会短路,它只会测试数字直到找到不满足的一对条件 (b == a + 1
)。当然,只有四个元素并没有什么区别——除非你在性能很重要的情况下调用这个方法数千次。
答案基于 Sum of consecutive integers
的数学问题
Sum = n∗(n+1)/2
代码:
def check_sum_match?(arr)
m = arr.min - 1
n = arr.max
sum1 = arr.inject{|sum, x| sum = sum + x}
sum2 = (n*(n+1) - m*(m+1))/2
sum1 == sum2
end
arr = [5,6,7,8]
if arr.count == 4 && check_sum_match?(arr)
puts 'Yes condition matches'
else
puts 'Invalid Array'
end
# valid arrays are
# [4,6,5,7], [4,5,6,7], etc
暂定解释:
如果a
是数组,n
是要求的大小:
def size_and_consecutive?(a, n)
a == (a.first..(a.first+n-1)).to_a
end
size_and_consecutive? [3,4,5,6], 4
#=> true
size_and_consecutive? [4,3,5,6], 4
#=> false
size_and_consecutive? [3,4,5], 4
#=> false
我能想出的一个紧凑的解决方案如下:
def consec(arr)
is_of_proper_length = (arr.size == 4)
if(is_of_proper_length)
are_consec = true
arr.each_cons(2) {|x,y| are_consec = false unless ((y - x) == 1)}
end
is_of_proper_length && are_consec
end
输出:
consec([1,2,3,4])
=> true
2.2.0 :051 > consec([0,0,0,0])
=> false
2.2.0 :052 > consec([4,6,5,7])
=> true
2.2.0 :053 > consec([4,5,6,7])
=> true
2.2.0 :054 > consec([5,6,7,8])
=> true
2.2.0 :055 > consec([2,2,2,5])
=> false
2.2.0 :056 > consec([2,3,4,5])
=> true
2.2.0 :057 > consec([1,2,3,4,5])
=> false
我有一个整数数组 m
。我正在寻找一种方法来检查 m
的元素是否连续。有没有办法测试连续数字?
我想出了这段代码,旨在在数组长度为四时工作:
m.count == 4 && (m.max-m.min) == 3
对于 [1,1,1,4]
或 [0,0,0,3]
.
true
不正确
你可以试试这个:
a == (a.min..a.max).to_a && a.count == 4
这仅在数组递增时有效。 [3, 4, 5, 6]
会通过,但 [4, 3, 5, 6]
不会。
Enumerable 有一个非常方便的方法,称为 each_cons
,其工作方式如下:
[1,2,3,4].each_cons(2).to_a # => [ [1, 2], [2, 3], [3, 4] ]
也就是说,它产生每组连续的 n 个元素。在我们的例子中 n 是 2.
当然,顾名思义,它 returns 是一个 Enumerator,因此我们可以将它与其他 Enumerable 方法链接起来,例如 all?
:
def four_consecutive?(arr)
return false unless arr.size == 4
arr.each_cons(2).all? {|a, b| b == a + 1 }
end
four_consecutive?([2,3,4,5]) # => true
four_consecutive?([2,2,2,5]) # => false
four_consecutive?([1,2,3,4,5]) # => false
这个方法比其他方法有优势,因为all?
一旦块returns为假就会短路,它只会测试数字直到找到不满足的一对条件 (b == a + 1
)。当然,只有四个元素并没有什么区别——除非你在性能很重要的情况下调用这个方法数千次。
答案基于 Sum of consecutive integers
Sum = n∗(n+1)/2
代码:
def check_sum_match?(arr)
m = arr.min - 1
n = arr.max
sum1 = arr.inject{|sum, x| sum = sum + x}
sum2 = (n*(n+1) - m*(m+1))/2
sum1 == sum2
end
arr = [5,6,7,8]
if arr.count == 4 && check_sum_match?(arr)
puts 'Yes condition matches'
else
puts 'Invalid Array'
end
# valid arrays are
# [4,6,5,7], [4,5,6,7], etc
暂定解释:
如果a
是数组,n
是要求的大小:
def size_and_consecutive?(a, n)
a == (a.first..(a.first+n-1)).to_a
end
size_and_consecutive? [3,4,5,6], 4
#=> true
size_and_consecutive? [4,3,5,6], 4
#=> false
size_and_consecutive? [3,4,5], 4
#=> false
我能想出的一个紧凑的解决方案如下:
def consec(arr)
is_of_proper_length = (arr.size == 4)
if(is_of_proper_length)
are_consec = true
arr.each_cons(2) {|x,y| are_consec = false unless ((y - x) == 1)}
end
is_of_proper_length && are_consec
end
输出:
consec([1,2,3,4])
=> true
2.2.0 :051 > consec([0,0,0,0])
=> false
2.2.0 :052 > consec([4,6,5,7])
=> true
2.2.0 :053 > consec([4,5,6,7])
=> true
2.2.0 :054 > consec([5,6,7,8])
=> true
2.2.0 :055 > consec([2,2,2,5])
=> false
2.2.0 :056 > consec([2,3,4,5])
=> true
2.2.0 :057 > consec([1,2,3,4,5])
=> false