Given an array of scores sorted in increasing order, return true if the array contains 3 adjacent scores that differ from each other by at most 2, such as with {3, 4, 5} or {3, 5, 5}. Examples
scoresClump([3, 4, 5]) → true
scoresClump([3, 4, 6]) → false
scoresClump([1, 3, 5, 5]) → true
A solution below here seems to work but Translating it into Python looks tricky.
function scoresClump(scores) {
for (let i = 0; i < scores.length - 1; i ) {
if (scores[i 2] - scores[i] <= 2) {
return true;
}
}
return false;
}
I have tried this in Python and it keeps going out of range or giving the wrong output.
arr=[1,3, 5, 5]
i=0
while i<(len(arr)-1):
if (arr[i 2]-arr[i])<=2 and (arr[i 1]-arr[i])<=2:
print("True")
i=i 1
else:
print("False")
break
CodePudding user response:
You're iterating until i < len(arr)-1, but you're reaching for arr[i 2], which is out of range.
In Python you usually do not need to use an index variable. As you've seen they're a source of errors, and Python offers cleaner syntax without using them. For instance:
# unpythonic
for i in range(len(scores)):
print(scores[i])
# pythonic
for score in scores:
print(score)
zip combines two (or more) things you can iterate over.
scores[2:] means "the scores list, but discarding the first two values".
scores = [1, 2, 3, 4, 5, 6]
for a, b in zip(scores, scores[2:]):
print(a, b)
# 1 3
# 2 4
# 3 6
# zip then ends because it reached the end of scores[2:]
So, you can use zip and list slicing to compare the list with itself without index variables:
def scores_clump(scores):
for a, b in zip(scores, scores[2:]):
if b - a <= 2:
return True
return False
scores_clump([1, 3, 4, 5])
# 4 - 1 is not <= 2
# 5 - 3 is <= 2, return True
scores_clump([1, 3, 6, 7, 9])
# 6 - 1 is not <= 2
# 7 - 3 is not <= 2
# 9 - 6 is not <= 2
# reached end of loop with no match, return False
scores_clump([3, 3, 7, 7, 9])
# 7 - 3 is not <= 2
# 7 - 3 is not <= 2
# 9 - 7 is <= 2, return True
Taking a leaf from Max's answer, you can reduce it further using any:
def scores_clump(scores):
return any(b - a <= 2 for a, b in zip(scores, scores[2:]))
CodePudding user response:
You can use this following function -
def scoresClump(nums):
for x in range(2, len(nums)):
if nums[x] - nums[x-2] <= 2:
return True
return False
if you want a one-liner using any() -
def scoresClump(nums):
return any(nums[x] - nums[x-2] <= 2 for x in range(2, len(nums)))
>>> scoresClump([3, 4, 5])
True
>>> scoresClump([3, 4, 6])
False
>>> scoresClump([3, 4, 5, 5])
True
>>> scoresClump([3, 4])
False
>>> scoresClump([3])
False
>>> scoresClump([3, 3, 7, 7, 9])
True
CodePudding user response:
Your if statement will reach arr[:-1] and then try and check two elements ahead of that, which don't exist, therefore going out of range. Rather than a while loop I would try something like this:
for x in range(0, len(arr)-2)
CodePudding user response:
This is basically a "sliding window" problem where window size=3 and we keep iterating over the array until we find a window where difference between adjacent elements is less than or equal to 2.
Here we can simply check if difference between last and first element of the window is <=2 or not because we are given a sorted array.
def scoresClump(array):
for i in range(2,len(array)):
if array[i]-array[i-2]<=2:
return True
return False
print(scoresClump([1, 3, 5, 5]))
