Reputation: 385
Here's a problem I'm trying to solve:
Write a function
lucky_sevens?(numbers)
, which takes in an array of integers and returnstrue
if any three consecutive elements sum to7
.lucky_sevens?([2,1,5,1,0]) == true # 1 + 5 + 1 == 7 lucky_sevens?([0,-2,1,8]) == true # -2 + 1 + 8 == 7 lucky_sevens?([7,7,7,7]) == false lucky_sevens?([3,4,3,4]) == false
Make sure your code correctly checks for edge cases (i.e. the first and last elements of the array).
def lucky_sevens?(numbers)
i = 0
while i < numbers.length - 2
if numbers[i] + numbers[i + 1] + numbers[i + 2] == 7
puts true
return true
end
i+=1
end
puts false
return false
end
While my code does seem to work (I did some test cases), I know it can be improved. There's no reason to have both puts
and return
statements. I'm also wondering if there are general improvements to the syntax itself that can make it much more readable.
Upvotes: 2
Views: 273
Reputation: 110725
You could do it like this:
def consecutive_sum?(arr, n, tot)
return false if arr.size < n
t = arr[0,n].reduce(:+)
return true if t == tot
(arr.size-n).times.any? { |i| (t+=(arr[i+n]-arr[i]))==tot }
end
consecutive_sum?([2,1,5,1,0], 3, 7) #=> true
consecutive_sum?([2,1,5,2,1], 3, 7) #=> false
3 numbers are summed to obtain t
, then there are at most 2 adjustments to t
that each involve an addition and a subtraction, so there are at most 7 additions/subtractions. By contrast, @sawa's solution using each_cons(3)
requires at most 3 summations of 3 numbers, for a total of nine additions. Regardless, I would expect each_cons
to be be faster, and it certainly reads better.
I presented this answer merely to suggest an efficient way of summing runs for larger values of n
. You did not ask for this, but you or some readers may find it useful in other situations. Suppose, for example:
consecutive_sum?([1,4,2,5,6,2,7,1,5,2,8,4,3,1,7,6,3,1],6,21) #=> true
6 numbers are summed to obtain t
, then there are at most 12 adjustments to t
, each involving an addition and a subtraction, a total of 30 additions/subtractions. each_cons(6)
, however, requires 13 sums of 6 numbers each, or 78 additions.
Upvotes: 0
Reputation: 168199
If you are using an index outside of a block, you can often improve it. Here is an orthodox way.
def lucky_sevens?(numbers)
numbers.each_cons(3).any?{|x, y, z| x + y + z == 7}
end
Upvotes: 3