Why I am getting a one less count always - python

I am solving a problem in Codeforce and this was my previous submission
#!/usr/local/bin/python
limit = 10**18
string = raw_input()
year1, year2 = string.split()
year1 = int(year1)
year2 = int(year2)
x = 1
count = 0
a = []
while True:
k = 2**x - 1
if k > limit:
break
else:
for i in xrange(len(bin(k)[2:])):
if year1 <= k - (1 << i) <= year2 and len(bin(k - (1 << i))[2:].split('0')) == 2:
count += 1
x += 1
print count
It worked for all the given values but it gave one less count value for the range 1 to 1000000000000000000. It was hard to debug and hence I put a hacked up code before the last print like this
if year2 - year1 + 1 == limit:
count += 1
and it worked for that value but again gave one less value value for another range, 1 to 935829385028502935.
No wonder that the logic-less hack didn't work but I want to know that why it gave one less count value previously ?

You need to increase limit by another order of magnitude:
limit = 10**19
Otherwise you'd miss 864691128455135231, obtained from 1152921504606846975 - (1 << 58).
(Observe that 1152921504606846975 > 10**18.)

I tried to simplify code (it works now, Accepted):
limit = 10**19 # this change is important because otherwise you will loose 1 solution
# k > limit and exists such i that k - (1 << i) < limit
string = raw_input()
year1, year2 = string.split()
year1 = int(year1)
year2 = int(year2)
x = 1
count = 0
a = []
while True:
k = 2**x - 1
if k > limit:
break
for i in xrange(x - 1): # k has exactly x bits. So we have only x-1 chances to set zero bit
if year1 <= k - (1 << i) <= year2:
count += 1
x += 1
print count
Submission: http://codeforces.com/contest/611/submission/15230069

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)

Counting Consecutive 1s in a Binary Number

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

Finding even numbers with while as

I'm doing this assignment:
Write a program that prints all even numbers less than the input
number using the while loop.
The input format:
The maximum number N that varies from 1 to 200.
The output format:
All even numbers less than N in ascending order. Each number must be
on a separate line.
N = int(input())
i = 0
while 200 >= N >= 1:
i += 1
if i % 2 == 0 and N > i:
print(i)
and its output like:
10 # this is my input
2
4
6
8
but there is an error about time exceed.
The simple code would be:
import math
N = int(input(""))
print("1. " + str(N))
num = 1
while num < math.ceil(N/2):
print (str(num) + ". " + str(num * 2))
num += 1
The problem is that the while loop never stops
while 200 >= N >= 1 In this case because you never change the value of N the condition will always be true. Maybe you can do something more like this:
N = int(input())
if N > 0 and N <= 200:
i = 0
while i < N:
i += 2
print(i)
else
print("The input can only be a number from 1 to 200")

Is there a way to make this code more "Neat"?

The user inserts multiple values and the program determines how many positive values, negative values, zero values, even values, odd values, and the min, max, average, and total of those values. The code works, however it's quite messy.
negative=0
zero=0
positive=0
even=0
odd=0
max=0
min=0
a=int(input('Number of values:'))
b=int(input('First value:'))
if b==0:
zero=1
if b<0:
negative=1
if b>0:
positive=1
if b%2==0:
even=1
else:
odd=1
if b>max:
max=b
total=b
for x in range(a-1):
b=int(input('Next value:'))
total+=b
if b==0:
zero+=1
if b==0:
zero+=1
if b<0:
negative+=1
if b>0:
positive+=1
if b%2==0:
even+=1
else:
odd+=1
if b>max:
max=b
if b<max:
min=b
print('Negative values:',negative)
print('Zero values:',zero)
print('Positive values:',positive)
print('Even values:',even)
print('Odd values:',odd)
print('Total:',total)
print('Minimum:',min)
print('Maximum:',max)
print('Average:',total/a)
There's two parts of the script essentially doing the same thing, except that you're asking the user "First Value" instead of "Next value". So I would just merge them together in a loop and determine what msg to use.
There's also a lack of white space everywhere which makes it harder to read. Check out Python's PEP 8 guide to standard conventions.
You can also use more descriptive variable names so it's more readable at a glance.
Also be careful naming your variables min and max. Those are already built-in methods in Python that you're overriding.
negative = 0
zero = 0
positive = 0
even = 0
odd = 0
maxVal = 0
minVal = 0
total = 0
count = int(input('Number of values:'))
for i in range(count):
if i == 0:
msg = 'First value:'
else:
msg = 'Next value:'
val = int(input(msg))
total += val
if val == 0:
zero += 1
if val < 0:
negative += 1
if val > 0:
positive += 1
if val % 2 == 0:
even += 1
else:
odd += 1
if val > maxVal:
maxVal = b
if val <= minVal <= val and val < maxVal:
minVal = val
print('Negative values:', negative)
print('Zero values:', zero)
print('Positive values:', positive)
print('Even values:', even)
print('Odd values:', odd)
print('Total:', total)
print('Minimum:', minVal)
print('Maximum:', maxVal)
print('Average:', total / count)
I made a rendition of your code that in my mind is neater, this way you aren't just storing values you have a Counter that remembers all the values put in and the number of times they were used. Also fixed your whitespace and times_to_run is more descriptive than a and value is more descriptive than b. I also just used the iteration number you're on as the n'th number being input
from collections import Counter
total = 0
all_numbers = Counter()
times_to_run = int(input('Number of values: '))
for x in range(times_to_run):
value = int(input(f'Value {x + 1}: '))
total += value
all_numbers[value] += 1
negative = sum(all_numbers[n] for n in all_numbers if n < 0)
zero = all_numbers[0]
positive = sum(all_numbers[n] for n in all_numbers if n > 0)
even = sum(all_numbers[n] for n in all_numbers if abs(n) % 2)
odd = sum(all_numbers[n] for n in all_numbers if not abs(n) % 2)
max = max(all_numbers)
min = min(all_numbers)
print()
print('Negative values:',negative)
print('Zero values:',zero)
print('Positive values:',positive)
print('Even values:',even)
print('Odd values:',odd)
print('Total:',total)
print('Minimum:',min)
print('Maximum:',max)
print('Average:',total / times_to_run)
To test:
Number of values: 10
Value 1: -1
Value 2: -1
Value 3: 5
Value 4: 2
Value 5: 0
Value 6: 3
Value 7: 55
Value 8: 8
Value 9: 10
Value 10 :4
Negative values: 2
Zero values: 1
Positive values: 7
Even values: 5
Odd values: 5
Total: 85
Minimum: -1
Maximum: 55
Average: 8.5

Working with recursion but not with for loop

I have written a code using recursion, but later realized that the depth is too high and does not work for higher level input values. It works completely fine without any issue.
def checkCount(first_window, index=0,reference_list=None):
reference_list = []
count = 0
while index<=len(first_window)-2:
if first_window[index] < first_window[index+1]:
index += 1
count += 1
else: break
if count != 0:
reference_list.append(int((count*(count+1))/2))
count = 0
while index <= len(first_window)-2:
if first_window[index] > first_window[index+1]:
index += 1
count += 1
else: break
if count != 0:
reference_list.append(-int((count*(count+1))/2))
if index > len(first_window)-2: return reference_list
elif first_window[index] == first_window[index+1] and index<len(first_window)-2: index += 1
reference_list = reference_list + checkCount(first_window, index, reference_list)
return reference_list
import random
import time
start = time.clock()
input_array = list(map(int,"188930 194123 201345 154243 154243".split(" ")))
input_array = random.sample(range(1,100),10)
def main():
N = len(input_array)
K = 8
if K == 1: return None
print("Input array: ",input_array)
print("First Window",input_array[:K])
print("Real Output", checkCount(input_array[:K]))
if __name__ == "__main__":main()
Now no matter how I try without recursion, it ends with an infinite loop. I have tried different ways but no progress.
One way I have tried is taking out the recursion statement and returning the referencelist + index:
def checkCount(..):
....
....
return referencelist,index
while index <= K-2:
print("While",index)
reference_list, index = checkCount(new_input, index=0, reference_list=[])
referencelist += reference_list
The application is similar to the here. But we have to deal with tons of data where recursion cannot help. Assume that the input array is greater than 100,000. I am really struck here, I do not understand what logic am I missing. Any help will be grateful.
The first_window variable is only read, and the index variable is only incremented. There is no need for recursion, a simple loop can work.
def check_count(first_window):
reference_list = []
index = 0
while index < len(first_window) - 2:
count = 0
while index <= len(first_window) - 2:
if first_window[index] < first_window[index + 1]:
index += 1
count += 1
else:
break
if count != 0:
reference_list.append(int((count * (count + 1)) / 2))
count = 0
while index <= len(first_window) - 2:
if first_window[index] > first_window[index + 1]:
index += 1
count += 1
else:
break
if count != 0:
reference_list.append(-int((count * (count + 1)) / 2))
if index < len(first_window) - 2 and first_window[index] == first_window[index + 1]:
index += 1
return reference_list
Of course, this algorithm can be optimised, for instance, we can avoid repetitions like: len(first_window) - 2.

Categories