Counting Consecutive 1s in a Binary Number - python

This is a HackerRank Day 10 Code Problem (30 Days of Code Challenge)
I have figured out most of the part but I am stuck at the part where you have to count the number of consecutive 1s in a binary representation.
The code works just fine for consecutive 1s in the beginning or in the middle of the whole series,
But for consecutive 1s at the end I can't figure out what to do
cons = 0
def bin_no():
global rem, cons
#Input
n = int(input("Enter Number : "))
rem=[]
#Checking If The Number Is Valid Or Not.
if n < 0:
print("Please Enter A Valid Number : ")
bin_no()
elif n == 0:
print('0000')
#While Loop for Conversion
while n >=1 :
rem.append(n%2)
n = n//2
rem.reverse()
print("Binary Representation ",*rem, sep = '')
#Finding Maximum Consecutive 1s.
maxcon = 0
for x in rem:
if x == 1:
cons += 1
elif x != 1 and cons > maxcon:
maxcon = cons
cons = 0
print(maxcon)
bin_no()
You can see the Maximum Consecutive 1s code block near the end of the code.
I know the error is caused due to the ending of the list doesn't contain any element that is
not equal to 1
Thus the ending elif code block is ignored.

You need to setup a condition to check the maximality after the loop itself incase as you mentioned the maximum-consecutive-1s are towards the end:
#Finding Maximum Consecutive 1s.
maxcon, cons = 0, 0
for x in rem:
if x == 1:
cons += 1
elif x != 1 and cons > maxcon:
maxcon = cons
cons = 0
maxcon = max(maxcon, cons)
^^This should fix it
EDIT
Btw, I come up with a more elegant solution which doesnt require converting the number into its binary format:
N = int(14)
cons, maxcon = 0, 0
while N > 0:
if N & 1:
cons += 1
else:
maxcon = max(cons, maxcon)
cons = 0
N >>= 1
maxcon = max(cons, maxcon)
print(maxcon)
3

Serial Lazer's edit is definitely the way to go, but I just wanted to correct their first answer.
def consec_ones_a(rem):
count, largest = 0, 0
for x in rem:
if x == 1:
count += 1
else:
if count > largest:
largest = count
count = 0
return max(largest, count)
def consec_ones_b(rem):
maxcon, cons = 0, 0
for x in rem:
if x == 1:
cons += 1
elif x != 1 and cons > maxcon:
maxcon = cons
cons = 0
return max(maxcon, cons)
# 4 consecutive 1s
binary = [1,1,1,0,1,0,1,1,1,1]
print(consec_ones_a(binary))
print(consec_ones_b(binary))
outputs
4
5

Related

Finding number with specified collatz sequence length

I need to make a program that finds a number with specified collatz sequence length. However, there is always a problem that the program is too slow. For example my current best score that i could get was number with collatz sequence length of 1200 (I need to be able to get number with collatz sequence length of 1800).
I tried a lot of diffrent methods, but the best one so far was trying to recreate collatz number tree.Here is an example from wiki. As I said before i need to be able to get a number with collatz sequence length of 1800 but I cant get more than 1200.
That's my current solution (I know it's complicated but other methods I tried so far were able to get collatz sequence length up to 500 only):
A = int(input())
limit = 1000000000000000000
def runCollaz(ciag):
steps = 0
while ciag != 1:
if (ciag % 2 == 0):
ciag /= 2
else:
ciag *= 3
ciag += 1
steps+=1
return steps
def makeChainLess(number):
if (number % 2 == 0):
return number / 2
else:
return ((number * 3) + 1)
collatzTree = [[1, 1]]
finallAns = "None"
def getAns(collatzTree, what):
awnser = "None"
if (collatzTree[0][0] < limit and collatzTree[0][1] == A):
awnser = collatzTree[0][0]
while (len(collatzTree) > 250):
currentHigh = collatzTree[0][0]
highIndex = 0
index = 0
for x in collatzTree:
if (x[0] > currentHigh):
currentHigh = x[0]
highIndex = index
index += 1
collatzTree.pop(highIndex)
if (collatzTree[0][0] > 4):
if (collatzTree[0][0] - 1) % 3 == 0:
if (collatzTree[0][0] - 1) % 2 != 0:
collatzTree += [[(collatzTree[0][0] - 1) / 3, int(collatzTree[0][1]) + 1]]
collatzTree += [[collatzTree[0][0] * 2, int(collatzTree[0][1]) + 1]]
collatzTree.pop(0)
else:
collatzTree += [[collatzTree[0][0] * 2, int(collatzTree[0][1]) + 1]]
collatzTree.pop(0)
else:
collatzTree += [[collatzTree[0][0] * 2, int(collatzTree[0][1]) + 1]]
collatzTree.pop(0)
if (what == "C"):
return collatzTree
else:
return awnser
while finallAns == "None":
finallAns = getAns(collatzTree, "A")
collatzTree = getAns(collatzTree, "C")
print(int(finallAns))
If anyone could help i would really appricate it.
Here is a simple code that takes only a few minutes to run for 10 million. It just needs more computing power, which is kind of the story on Collatz.
'''
This code finds numbers that have the specified Collatz sequence length
(by brute force)
'''
import time
start = time.time() #start code timer
n = 1 #set low end of range
for number in range (10000000, n-1, -1): #work down from max range
num = number
trial = 0
while number > 1: #set up looping until 1 is reached
if number % 2 == 0: #set up normal Collatz sequence comp.
number = number // 2
else:
number = (number * 3) + 1
trial = trial+1 #update counter for each loop
if number == 1 and trial == 500 or trial == 600: #set target numbers
#print all numbers where specified target occured:
print("Number with sequence "
"length of {0}: {1}".format(trial, num))
if number == n:
print("end of range") #tells user that code has ended
end = time.time()
print("elapsed time: ",end - start)

Count how many times can a number be divided by 2

n = int(input())
counter = 0
while n > 0:
if (n // 2) > 1:
counter = counter +1
print (counter)
Hi,
I am a python learner and I am having problems with this homework I was given.
Read a natural number from the input.
Find out how many times in a row this number can be divided by two
(e.g. 80 -> 40 -> 20 -> 10 -> 5, the answer is 4 times)
And I should use while loop to do it.
Any Ideas, because I really don't have any idea how to do it.
This is my best try
You are not changing n. I would write it like this:
while (n % 2) == 0:
n //= 2
counter += 1
Try this, we take the value from "n" and check whether it is divisible by two or not. If it is divisible by two, we increment the counter and then divide that number by 2. If not, it will print the output.
n = int(input("Input your number: "))
counter = 0
while n % 2 != 1:
counter = counter + 1
n = n/2
print(counter)
Your while loop condition is wrong.
While the number is evenly divisible by 2, divide it by 2 and increment counter
num = int(input('Enter a number: '))
counter = 0
while num % 2 == 0 and num != 0:
num = num / 2
counter = counter + 1
print(counter)
The code above will not work as intended. The intended functionality is to take an input natural number and find out how many times in a row the number can be divided by 2. However, the code will only divide the number by 2 once.
To fix this, you can change the code to the following:
n = int(input())
counter = 0
while n > 0:
if (n % 2) == 0:
counter = counter +1
n = n // 2
print (counter)
You need to test whether a number is divisible by 2. You can do this in one of two ways...
x % 2 == 0 # will be True if it's divisible by 2
x & 1 == 0 # will be True if it's divisible by 2
So, you need a loop where you test for divisibility by 2, if True divide your original value by 2 (changing its value) and increment a counter
N = int(input())
counter = 0
if N != 0:
while N % 2 == 0:
counter += 1
N //= 2
print(counter)
Or, if you prefer more esoteric programming, then how about this:
N = int(input())
b = bin(N)
print(0 if (o := b.rfind('1')) < 0 else b[o:].count('0'))

Why does the list index not reset after I remove a block?

The question reads as follows:
Every maximal block of k consecutive digits with k>1 scores 10**(k-2) points for that block. A block of two digits thus scores one point, three digits score ten points, four digits score a hundred points, and so on. However, a special rule is in effect saying that whenever a block of digits lies at the lowest end of the number, that block scores double the points it would score in any other position. This function should compute the meaningfulness score of the given positive integer n as the sum of its individual block scores.
def duplicate_digit_bonus(n):
num = str(n)
if len(num) == 1:
return 0
digit = num[0]
new_len, old_len, score = len(num), len(num), 0
while new_len != 0:
block_len = 0
for i in range(len(num)):
if num[i] != digit:
digit = num[i]
new_len = old_len - block_len
old_len = new_len
num = num[block_len:]
if block_len >= 2:
score = score + 10**(block_len - 2)
else:
block_len += 1
return score
While I haven't addressed the duplicate points at the end, how do I make sure the index resets when i read through the new_block. It continues from the previous loop.
Honestly I don't get the idea of your algorithm.
Maybe you can get some value from this approach:
def f (n):
scores = []
length = 1
for i in range (1, len(n)):
if n[i-1] < n[i]:
length += 1
else:
scores.append (length)
length = 1
scores.append (length)
return sum([10 ** (k - 2) for k in scores if k >= 2])
print ( f ([1,2,3,4,1,2]) )
Result:
101

How to not count negative input

is there a way to keep the counter going without counting the negatives and only to stop when the input is zero?
count = 0
total = 0
n = input()
while n != '0':
count = count + 1
total = total + int(n) ** 2
n = input()
print(total)
Here is an example of execution result.
Input: -1 10 8 4 2 0
Output: 184
Since you want only number to enter the loop you can use isnumeric() built in function to check that.
You need if() : break here.
num = input()
...
while(isnumeric(num)):
...
if(num == "0"):
break;
The response you wait for is:
ignore negative number
count positive numbers
stop when input is 0
count = 0
total = 0
n = int(input())
while (n != 0):
count += 1
if (n > 0):
total = total + n**2
num = int(input())
print(total)
Your code was already OK except that you did not cast the number n into int and you did not test n to take away negative values.
Execution:
When you enter -1 10 8 4 2 0, it should show 184
You can parse your Input to an integer (number) and check if it's larger than zero:
count = 0
total = 0
num = int(input())
while number != 0:
if number < 0:
continue
count += 1
total = total + num**2
num = int(input())
print(total)
The difference between pass, continue, break and return are:
pass = ignore me an just go on, usefull when you create a function that has no purpose yet
continue = ignore everything else in the loop and start a new loop
break = break the loop
return = end of a function - a return statement can be used to give an output to a function but also as a way to break out of the function like the break statement does in loops.

Logical error in max and min implementation?

I know there is a min max syntax but I just wanted to do it myself using if but the code i wrote keep returning 0 0 where is my mistake at?
The program is supposed to print out larges and least number from a space separated numbers input
user = input(" :) ")
user = user.split(' ')
lt = 0
gt = 0
gtn = 0
ltn = 0
for i in user:
for j in range(0, len(user)):
if int(i) < int(user[j]):
lt += 1
elif int(i) > int(user[j]):
gt += 1
else:
pass
if lt == len(user):
ltn = i
elif gt == len(user):
gtn = i
print(gtn, ltn)
You don't need a nested for, neither so many if conditions. All you have to do is initialize min to a very large value and max to a very small value then iterate once.
nums = map(int, input(" :) ").split())
min_n = float('inf')
max_n = -float('inf')
for n in nums:
if n < min_n:
min_n = n
if n > max_n:
max_n = n
print(min_n)
print(max_n)
Sample output:
:) 3 4 5 6 2 11 2 3 4 99 1 -1
-1
99

Categories