I am trying to solve the problem in the title, and I'm getting an IndexError.
def count_zeros(number:int) -> int:
number = str(number)
i = 0
j = -1
while number[j] == '0'
i += 1
j += -1
return i
This code spits out the IndexError only when the number is 0. I cannot figure out why.
>>>count_zeros(0)
IndexError Traceback (most recent call last)
<ipython-input-45-688099e7700c> in <module>
----> 1 end_zeros(0)
<ipython-input-43-181de92af60c> in end_zeros(number)
4 i = 0
5
----> 6 while number[j] == '0':
7 i += 1
8 j -= 1
IndexError: string index out of range
I would use the modulus here and count the number of zeroes on the right:
def count_zeros(number:int) -> int:
if number == 0:
return 1
else:
count = 0
while True:
if number % 10 != 0 or number == 0:
break
count = count + 1
number = number / 10
return count
This approach is straightforward, and will almost certainly outperform casting the input integer to a string and then checking for trailing zeroes.
As an alternative approach to iteration, using regular expressions proves to be a simple approach.
Since your code converts the number to a string already, it doesn't hurt to pass the string directly to re.search to find the trailing zeros for you effortlessly.
Here is a working example, along with some test cases:
import re
def count_zeros(number: int) -> int:
count = re.search(r'0+$', str(number))
return len(count[0]) if count else 0
print(count_zeros(1))
print(count_zeros(123))
print(count_zeros(0))
print(count_zeros(10))
print(count_zeros(12300))
print(count_zeros(123000))
Output:
0
0
1
1
2
3
How many zeros does a number have at the end
def count_zeros(num: int) -> int:
return len(str(num)) - len(str(num).rstrip('0'))
print(count_zeros(0)) #1
print(count_zeros(1)) #0
print(count_zeros(10)) #1
print(count_zeros(245)) #0
print(count_zeros(101)) #0
print(count_zeros(100100)) #2
For this problem, honestly, the simplest solution is likely going to be to handle the case where number==0 separately, by putting something like this at the top.
if number ==0:
return 1
Your loop with an iterator and a count works, but I would prefer to cast to a list so I don't have to keep track of two variables...assuming performance is not a huge concern here.
So something like:
def count_zeros(number:int) -> int:
if number==0:
return 1
number_list = list(str(number))
is_zero = True
zero_count = 0
while is_zero:
if int(number_list.pop())==0:
zero_count += 1
else:
is_zero = False
return zero_count
def end_zeros(a: int) -> int:
count = 0
list = [int(x) for x in str(a)]
list.reverse()
list.append(1)
for x in list:
if x == 0:
count += 1
else:
return count
Write a function that takes an array/list of numbers and returns a number.
See the examples and try to guess the pattern:
even_odd([1,2,6,1,6,3,1,9,6]) => 393
even_odd([1,2,3]) => 5
even_odd([0,2,3]) => 3
even_odd([1,0,3]) => 3
even_odd([3,2]) => 6
def even_odd(arr):
count = 0
index = 0
length = len(arr)
while index < length:
for num in range(len(arr)):
if arr[index] % 2 != 0:
count += arr[index]
index += 1
else:
count *= arr[index]
index += 1
return count
So basically the pattern is multiply the first 2 numbers and add the third and I set it to where for each index value if it it was the first number I would add it to the count to keep track and then multiply it with the second number and then add the third. I passed 3/4 sample cases except for one which was the first one ---> even_odd([1,2,6,1,6,3,1,9,6]) => 393. I am just wondering what is the flaw with my logic and does anyone have a better way to solve this that is efficient and clean.
Your question is a challenge on Codewars (https://www.codewars.com/kata/559e708e72d342b0c900007b), so maybe you should use this platform to discuss solutions with other competitiors, instead of Stackoverflow.
The main point of this challange is to investigate the calculated pattern and not the code itself.
If you know the required pattern, the code is easy (Spoiler!):
def even_odd(arr):
num = 0
for i, e in enumerate(arr):
if (i % 2) == 0:
num += e
else:
num *= e
return num
This produces the desired results:
from operator import add, mul
def even_odd(nums):
acc = nums[0] # accumulator
ops = [mul, add]
i = 0
for num in nums[1:]:
acc = ops[i](acc, num)
i = 1 - i # alternates between the two operators
return acc
I am trying to add all even Fibonacci numbers up to 4000000. I have successfully outputted all Fibonacci numbers up to 4000000, but adding all the even ones is becoming a problem for me. So far this is what I tried:
fibonacci = [1, 2]
i = 0
while fibonacci[-1] < 4000000:
fib = fibonacci[-1] + fibonacci[-2]
fibonacci.append(fib)
i += 1
del fibonacci[-1]
result = 0
for x in fibonacci:
if fibonacci[x] % 2 == 0:
result += fibonacci[x]
print(result)
It outputs an error:
IndexError: list index out of range
In the lines:
for x in fibonacci:
if fibonacci[x] % 2 == 0:
result += fibonacci[x]
x is actually the Fibonacci number itself, not an index, and is guaranteed to be outside of the bounds of the fibonacci list. If the code was for x in range(len(fibonacci)):, this would yield the indexes as x.
Change it to:
for x in fibonacci:
if x % 2 == 0:
result += x
or better yet, use a list comprehension:
result = sum(x for x in fibonacci if x % 2 == 0)
print(result)
Furthermore, instead of building an entire list, you could accumulate the sum on the spot as you generate the Fibonacci numbers, which is much more memory-efficient:
def even_fib_sum(n):
total = 0
a = 0
b = 1
while a < n:
if a % 2 == 0:
total += a
a, b = a + b, a
return total
if __name__ == "__main__":
print(even_fib_sum(55))
Or, even better, you can use a generator and drop even, since fib is more generally reusable:
def fib(n):
a = 0
b = 1
while a < n:
yield a
a, b = a + b, a
if __name__ == "__main__":
print(sum(x for x in fib(4000000) if x % 2 == 0))
Note that the Fibonacci series usually begins with 0, 1, 1, 2, 3, 5... rather than 1, 2, 3, 5... but you can adjust this as necessary, along with whether you want to iterate inclusive of n or not.
A small compilation of previous answers
fibonacci = [0, 1]
while fibonacci[-1] + fibonacci[-2] < 4000000:
fibonacci.append(fibonacci[-1] + fibonacci[-2])
print(sum(x for x in fibonacci if x % 2 == 0))
That's how I wrote as a beginner.
#By considering the terms in the Fibonacci sequence whose values do
#not exceed four million,
#find the sum of the even-valued terms.
cache = {}
def fib(n):
if n < 3:
return 1
elif n in cache:
return cache[n]
else:
value = fib(n - 1) + fib(n - 2)
cache[n] = value
return value
tot = 0
for n in range(1, 34):
if fib(n) % 2 == 0:
tot += fib(n)
print(n, ':', fib(n))
print(tot)
It says I have invalid syntax at Sum += 1. If my code is incorrect what is a better way to go about counting how many even numbers are in a list?
def countEvens(listOfInts):
'''
- Returns an integer value representing the number of even numbers that
exist in listOfInts.
- Return 0 if listOfInts is not a list type or if no even number exists
in listOfInts.
- Note: elements in listOfInts can contain any data type.
'''
Sum = 0
for x in listOfInts:
if x % 2 == 0:
return Sum += 1
if type(listOfInts) != list:
return 0
In Python you cannot return assignments. And Sum += 1 is an assignment, it assigns Sum + 1 to Sum.
In fact the return isn't just a SyntaxError it's also wrong (in a logical sense), so just remove it:
Sum = 0
for x in listOfInts:
if x % 2 == 0:
Sum += 1
return Sum
Alternatively you can use sum with a generator:
return sum(1 for value in listOfInts if value % 2 == 0)
The syntax error comes from this line, as you say
return Sum += 1
That's because (Sum += 1) is not a valid value to return from a function. It's a separate statement
Keeping your code as close as possible, try this
Sum += 1
return Sum
or, more simply
return Sum+1
As for a more pythonic approach
def countEvens(listOfInts):
return sum( x % 2 == 0 for x in listOfInts )
does the entire thing
I would like to know if my implementation is efficient.
I have tried to find the simplest and low complex solution to that problem using python.
def count_gap(x):
"""
Perform Find the longest sequence of zeros between ones "gap" in binary representation of an integer
Parameters
----------
x : int
input integer value
Returns
----------
max_gap : int
the maximum gap length
"""
try:
# Convert int to binary
b = "{0:b}".format(x)
# Iterate from right to lift
# Start detecting gaps after fist "one"
for i,j in enumerate(b[::-1]):
if int(j) == 1:
max_gap = max([len(i) for i in b[::-1][i:].split('1') if i])
break
except ValueError:
print("Oops! no gap found")
max_gap = 0
return max_gap
let me know your opinion.
I do realize that brevity does not mean readability nor efficiency.
However, ability to spell out solution in spoken language and implement it in Python in no time constitutes efficient use of my time.
For binary gap: hey, lets convert int into binary, strip trailing zeros, split at '1' to list, then find longest element in list and get this element lenght.
def binary_gap(N):
return len(max(format(N, 'b').strip('0').split('1')))
Your implementation converts the integer to a base two string then visits each character in the string. Instead, you could just visit each bit in the integer using << and &. Doing so will avoid visiting each bit twice (first to convert it to a string, then to check if if it's a "1" or not in the resulting string). It will also avoid allocating memory for the string and then for each substring you inspect.
You can inspect each bit of the integer by visiting 1 << 0, 1 << 1, ..., 1 << (x.bit_length).
For example:
def max_gap(x):
max_gap_length = 0
current_gap_length = 0
for i in range(x.bit_length()):
if x & (1 << i):
# Set, any gap is over.
if current_gap_length > max_gap_length:
max_gap_length = current_gap_length
current_gap_length = 0
else:
# Not set, the gap widens.
current_gap_length += 1
# Gap might end at the end.
if current_gap_length > max_gap_length:
max_gap_length = current_gap_length
return max_gap_length
def max_gap(N):
xs = bin(N)[2:].strip('0').split('1')
return max([len(x) for x in xs])
Explanation:
Both leading and trailing zeros are redundant with binary gap finding
as they are not bounded by two 1's (left and right respectively)
So step 1 striping zeros left and right
Then splitting by 1's yields all sequences of 0'z
Solution: The maximum length of 0's sub-strings
As suggested in the comments, itertools.groupby is efficient in grouping elements of an iterable like a string. You could approach it like this:
from itertools import groupby
def count_gap(x):
b = "{0:b}".format(x)
return max(len(list(v)) for k, v in groupby(b.strip("0")) if k == "0")
number = 123456
print(count_gap(number))
First we strip all zeroes from the ends, because a gap has to have on both ends a one. Then itertools.groupby groups ones and zeros and we extract the key (i.e. "0" or "1") together with a group (i.e. if we convert it into a list, it looks like "0000" or "11"). Next we collect the length for every group v, if k is zero. And from this we determine the largest number, i.e. the longest gap of zeroes amidst the ones.
I think the accepted answer dose not work when the input number is 32 (100000). Here is my solution:
def solution(N):
res = 0
st = -1
for i in range(N.bit_length()):
if N & (1 << i):
if st != -1:
res = max(res, i - st - 1)
st = i
return res
def solution(N):
# write your code in Python 3.6
count = 0
gap_list=[]
bin_var = format(N,"b")
for bit in bin_var:
if (bit =="1"):
gap_list.append(count)
count =0
else:
count +=1
return max(gap_list)
Here is my solution:
def solution(N):
num = binary = format(N, "06b")
char = str(num)
find=False
result, conteur=0, 0
for c in char:
if c=='1' and not find:
find = True
if find and c=='0':
conteur+=1
if c=='1':
if result<conteur:
result=conteur
conteur=0
return result
this also works:
def binary_gap(n):
max_gap = 0
current_gap = 0
# Skip the tailing zero(s)
while n > 0 and n % 2 == 0:
n //= 2
while n > 0:
remainder = n % 2
if remainder == 0:
# Inside a gap
current_gap += 1
else:
# Gap ends
if current_gap != 0:
max_gap = max(current_gap, max_gap)
current_gap = 0
n //= 2
return max_gap
Old question, but I would solve it using generators.
from itertools import dropwhile
# a generator that returns binary
# representation of the input
def getBinary(N):
while N:
yield N%2
N //= 2
def longestGap(N):
longestGap = 0
currentGap = 0
# we want to discard the initial 0's in the binary
# representation of the input
for i in dropwhile(lambda x: not x, getBinary(N)):
if i:
# a new gap is found. Compare to the maximum
longestGap = max(currentGap, longestGap)
currentGap = 0
else:
# extend the previous gap or start a new one
currentGap+=1
return longestGap
Can be done using strip() and split() function :
Steps:
Convert to binary (Remove first two characters )
Convert int to string
Remove the trailing and starting 0 and 1 respectively
Split with 1 from the string to find the subsequences of strings
Find the length of the longest substring
Second strip('1') is not mandatory but it will decrease the cases to be checked and will improve the time complexity
Worst case T
def solution(N):
return len(max(bin(N)[2:].strip('0').strip('1').split('1')))
Solution using bit shift operator (100%). Basically the complexity is O(N).
def solution(N):
# write your code in Python 3.6
meet_one = False
count = 0
keep = []
while N:
if meet_one and N & 1 == 0:
count+=1
if N & 1:
meet_one = True
keep.append(count)
count = 0
N >>=1
return max(keep)
def solution(N):
# write your code in Python 3.6
iterable_N = "{0:b}".format(N)
max_gap = 0
gap_positions = []
for index, item in enumerate(iterable_N):
if item == "1":
if len(gap_positions) > 0:
if (index - gap_positions[-1]) > max_gap:
max_gap = index - gap_positions[-1]
gap_positions.append(index)
max_gap -= 1
return max_gap if max_gap >= 0 else 0
this also works:
def solution(N):
bin_num = str(bin(N)[2:])
list1 = bin_num.split('1')
max_gap =0
if bin_num.endswith('0'):
len1 = len(list1) - 1
else:
len1 = len(list1)
if len1 != 0:
for i in range(len1):
if max_gap < len(list1[i]):
max_gap = len(list1[i])
return max_gap
def solution(number):
bits = [int(digit) for digit in bin(number)[2:]]
occurences = [i for i, bit in enumerate(bits) if(bit==1)]
res = [occurences[counter+1]-a-1 for counter, a in enumerate(occurences) if(counter+1 < len(occurences))]
if(not res):
print("Gap: 0")
else:
print("Gap: ", max(res))
number = 1042
solution(number)
This works
def solution(number):
# convert number to binary then strip trailing zeroes
binary = ("{0:b}".format(number)).strip("0")
longest_gap = 0
current_gap = 0
for c in binary:
if c is "0":
current_gap = current_gap + 1
else:
current_gap = 0
if current_gap > longest_gap:
longest_gap = current_gap
return longest_gap
def max_gap(N):
bin = '{0:b}'.format(N)
binary_gap = []
bin_list = [bin[i:i+1] for i in range(0, len(bin), 1)]
for i in range(len(bin_list)):
if (bin_list[i] == '1'):
# print(i)
# print(bin_list[i])
# print(binary_gap)
gap = []
for j in range(len(bin_list[i+1:])):
# print(j)
# print(bin_list[j])
if(bin_list[i+j+1]=='1'):
binary_gap.append(j)
# print(j)
# print(bin_list[j])
# print(binary_gap)
break
elif(bin_list[i+j+1]=='0'):
# print(i+j+1)
# print(bin_list[j])
# print(binary_gap)
continue
else:
# print(i+j+1)
# print(bin_list[i+j])
# print(binary_gap)
break
else:
# print(i)
# print(bin_list[i])
# print(binary_gap)
binary_gap.append(0)
return max(binary_gap)
pass
def find(s, ch):
return [i for i, ltr in enumerate(s) if ltr == ch]
def solution(N):
get_bin = lambda x: format(x, 'b')
binary_num = get_bin(N)
print(binary_num)
binary_str = str(binary_num)
list_1s = find(binary_str,'1')
diffmax = 0
for i in range(len(list_1s)-1):
if len(list_1s)<1:
diffmax = 0
break
else:
diff = list_1s[i+1] - list_1s[i] - 1
if diff > diffmax:
diffmax = diff
return diffmax
pass
def solution(N: int) -> int:
binary = bin(N)[2:]
longest_gap = 0
gap = 0
for char in binary:
if char == '0':
gap += 1
else:
if gap > longest_gap:
longest_gap = gap
gap = 0
return longest_gap
Here's a solution using iterators and generators that will handle edge cases such as the binary gap for the number 32 (100000) being 0 and the binary gap for 0 being 0. It doesn't create a list, instead relying on iterating and processing elements of the bit string one step at a time for a memory efficient solution.
def solution(N):
def counter(n):
count = 0
preceeding_one = False
for x in reversed(bin(n).lstrip('0b')):
x = int(x)
if x == 1:
count = 0
preceeding_one = True
yield count
if preceeding_one and x == 0:
count += 1
yield count
yield count
return(max(counter(N)))
Here is one more that seems to be easy to understand.
def count_gap(x):
binary_str = list(bin(x)[2:].strip('0'))
max_gap = 0
n = len(binary_str)
pivot_point = 0
for i in range(pivot_point, n):
zeros = 0
for j in range(i + 1, n):
if binary_str[j] == '0':
zeros += 1
else:
pivot_point = j
break
max_gap = max(max_gap, zeros)
return max_gap
This is really old, I know. But here's mine:
def solution(N):
gap_list = [len(gap) for gap in bin(N)[2:].strip("0").split("1") if gap != ""]
return max(gap_list) if gap_list else 0
Here is another efficient solution. Hope it may helps you. You just need to pass any number in function and it will return longest Binary gap.
def LongestBinaryGap(num):
n = int(num/2)
bin_arr = []
for i in range(0,n):
if i == 0:
n1 = int(num/2)
bin_arr.append(num%2)
else:
bin_arr.append(n1%2)
n1 = int(n1/2)
if n1 == 0:
break
print(bin_arr)
result = ""
count = 0
count_arr = []
for i in bin_arr:
if result == "found":
if i == 0:
count += 1
else:
if count > 0:
count_arr.append(count)
count = 0
if i == 1:
result = 'found'
else:
pass
if len(count_arr) == 0:
return 0
else:
return max(count_arr)
print(LongestBinaryGap(1130)) # Here you can pass any number.
My code in python 3.6 scores 100
Get the binary Number .. Get the positions of 1
get the abs differennce between 1.. sort it
S = bin(num).replace("0b", "")
res = [int(x) for x in str(S)]
print(res)
if res.count(1) < 2 or res.count(0) < 1:
print("its has no binary gap")
else:
positionof1 = [i for i,x in enumerate(res) if x==1]
print(positionof1)
differnce = [abs(j-i) for i,j in zip(positionof1, positionof1[1:])]
differnce[:] = [differnce - 1 for differnce in differnce]
differnce.sort()
print(differnce[-1])
def solution(N):
return len(max(bin(N).strip('0').split('1')[1:]))
def solution(N):
maksimum = 0
zeros_list = str(N).split('1')
if zeros_list[-1] != "" :
zeros_list.pop()
for item in zeros_list :
if len(item) > maksimum :
maksimum = len(item)
return(maksimum)
def solution(N):
# Convert the number to bin
br = bin(N).split('b')[1]
sunya=[]
groupvalues=[]
for i in br:
count = i
if int(count) == 1:
groupvalues.append(len(sunya))
sunya=[]
if int(count) == 0:
sunya.append('count')
return max(groupvalues)
def solution(N):
bin_num = str(bin(N)[2:])
bin_num = bin_num.rstrip('0')
bin_num = bin_num.lstrip('0')
list1 = bin_num.split('1')
max_gap = 0
for i in range(len(list1)):
if len(list1[i]) > max_gap:
max_gap = len(list1[i])
return (max_gap)