'Find if the array contain a 2 next to a 2
I am stuck on this problem
Given an array of ints, return True if the array contains a 2 next to a 2 somewhere.
has22([1, 2, 2]) → True
has22([1, 2, 1, 2]) → False
has22([2, 1, 2]) → False
I know the basic idea (there are syntax errors) but I can't implement it. I would also like to know what type of problem this is, eg. graph, search?
def has22(nums):
for x in nums:
if ( (nums[x] = 2) and (nums[x+1] = 2) )
return True
return False
Solution 1:[1]
def has22(nums):
return any(x == y == 2 for x, y in zip(nums, nums[1:]))
>>> has22([1, 2, 2])
True
>>> has22([1, 2, 1, 2])
False
>>> has22([2, 1, 2])
False
In Python 2 use: from itertools import izip
if you want a lazy zip
Solution 2:[2]
Potentially the simplest solution:
def has22(nums):
return (2, 2) in zip(nums, nums[1:])
Suppose nums == [1, 2, 2, 3, 4, 5]
. It then follows that nums[1:] == [2, 2, 3, 4, 5]
. The zip() function, when called as zip(nums, nums[1:])
, zips them into an iterator of the same tuples as below:
nums => [1, 2, 2, 3, 4, 5]
nums[1:] => [2, 2, 3, 4, 5]
zip() => [(1, 2), (2, 2), (2, 3), (3, 4), (4, 5)]
And it should be clear how (2, 2) in [(1, 2), (2, 2), (2, 3), (3, 4), (4, 5)]
is true. This is the same result as (2, 2) in zip(nums, nums[1:])
.
Solution 3:[3]
def has22(nums):
for x in range(len(nums)-1):
if (nums[x] == 2) and (nums[x+1] == 2):
return True
return False
I have just corrected your code. It runs in linear time so don't see any reason to work on it further.
Here is the running code on codebunk. http://codebunk.com/bunk#-Ivk7Xw2blX3cIWavI17
Solution 4:[4]
Use enumerate()
to get both index as well as item, iterating over list only returns it's elements not index.
def has22(lis):
for i,x in enumerate(lis[:-1]):
if x==2 and lis[i+1]==2:
return True
return False
>>> has22([1, 2, 2])
True
>>> has22([1, 2, 1, 2])
False
>>> has22([2, 1, 2])
False
Solution 5:[5]
You can use iter()
:
>>> def has22(lst):
... lst = iter(lst)
... for i in lst:
... try:
... if i == 2 and lst.next() == 2:
... return True
... except StopIteration:
... pass
... return False
...
>>> has22([1, 2, 2])
True
>>> has22([1, 2, 1, 2])
False
>>> has22([2, 1, 2])
False
Solution 6:[6]
def has22(nums):
for i in range(len(nums) - 1):
if nums[i] == 2 and nums[i + 1] == 2:
return True
return False
This was the simplest solution I came up with.
Using a for loop to check if the iterated number, nums[i] == 2
"and" the one very next to it, [i+1] == 2
as well.
(len(nums)-1)
: this line prevents it from going out of the range through the for loop as the i+1
on the final loop will check out of the range.
Solution 7:[7]
def has22(nums):
it = iter(nums)
return any(x == 2 == next(it, None) for x in it)
>>> has22([1, 2, 2])
True
>>> has22([1, 2, 1, 2])
False
>>> has22([2, 1, 2])
False
Solution 8:[8]
def has22(nums):
return '22' in ''.join(map(str, nums))
list [1, 2, 2] -> str '122'
return '22'
in '122'
Solution 9:[9]
I would do this:
def has22(l):
return any(l[i]==2 and l[i+1]==2 for i in xrange(len(l)-1))
This uses a similar idea as the other answers, but works with a generator (as would be preferred in cases like this).
Solution 10:[10]
def has22(lst):
pos = 0
while True:
try:
next = lst.index(2, pos) + 1
except ValueError:
return False
if next == pos + 1:
return True
pos = next
This uses the idea that index()
might be faster due to being implemented not in Python. Didn't measure it, though.
Concerning your questions: Your code suffers from not using range()
at the for
loop init. The way you put it, x
will not be the indexes but the elements of your list. And it also suffers from using =
for comparison (which actually just is assignment). Use ==
for comparison.
This is not a graph problem, it is a simple search issue. There are quite nifty strstr
solutions (besides the straight-forward one) for finding strings in strings (what you actually do).
Solution 11:[11]
def has22(nums):
for i in range(len(nums)-1):
if nums[i:i+2] == [2,2]:
return True
return False
Solution 12:[12]
def has22(nums):
if len(nums)==0:
return False
for i in range(len(nums)-1):
#print nums[i:i+2]
if nums[i:i+2]==[2,2]:
return True
return False
Solution 13:[13]
def has_22(nums):
desired = [2, 2]
if str(desired)[1:-1] in str(nums):
return True
else:
return False
pass
Solution 14:[14]
Just using index
def has22(nums):
return nums[nums.index(2)+1] == 2
Solution 15:[15]
def two_two(nums):
if nums.count(2)==2:
return True
else:
return False
Solution 16:[16]
Try this
>>> ls = [1, 2, 2]
>>> s = str(ls)
>>> '2, 2' in s
>>> True
Solution 17:[17]
The following works for me:
def has22(nums):
for i in range(0,len(nums)-1):
if nums[i:i+2] == [2,2]
return True
return False
this function checks every 2 value chunk of the input to see if it contains [2,2]
Solution 18:[18]
def has22(nums):
for i in range(len(nums)-1):
if nums[i] == 2 and nums[i+1] == 2:
return True
return False
Solution 19:[19]
The function argument can be tuple or list, hence, we should check both via "or".
def has33(int_array):
for i in range(0, len(int_array)):
if int_array[i:i+2] == [3, 3] or int_array[i:i+2] == (3, 3):
return True
return False
# check
print(has33((2, 2, 2, 2, 4, 3, 3)))
# check
print(has33([1, 3, 3]))
Solution 20:[20]
def has22(nums):
numbers = str(nums)
if numbers.count('2, 2') >=1:
return True
else:
return False
Solution 21:[21]
def has22(nums):
for x in range(0, len(nums)-1):
if nums[x] == 2 and nums[x+1] == 2:
return True
return False
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow