Function that will return the biggest number of consecutive 0's - recursion

For a homework problem, in python we are asked to define in a recursive way a function that will return the biggest number of consecutive 0's in binary for any the number n. We need to use "&" and ">>".
For example, the function should return 2 for n = 44 because its binary representation is 101100.
I do not know where to go from here. Any help would be appreciated!

def max_consecutive_zero_iterative(n):
res = 0
streak = 0
while n > 0:
if n & 1:
streak = 0
else:
streak += 1
n = n >> 1
res = max(res, streak)
return res
def max_consecutive_zero_recursive(n):
if n == 0: # end of recursion
return 0
value = max_consecutive_zero_recursive(n >> 1) # call to recursive
current_streak = value & 0xff # current streak is stored in the lowest 8 bits
longest_streak = value >> 8 # longest streak is stored in the upper bits
if n & 1: # if we have a bit set
return max(longest_streak, current_streak) << 8 # we just return the max value between current_streak and longest_streak, stored in upper bits
# else if the bit is not set
current_streak += 1 # we increase our current streak by 1
# and return the max between the longest_streak and current_streak in the upper bits...
return max(longest_streak, current_streak) << 8 | current_streak
# ... but this time we keep information (we don't reset) about the current_streak stored in the lowest 8 bits.
def main():
print(max_consecutive_zero_recursive(0b1000101111000110000000100110) >> 8)
if __name__ == "__main__":
main()

Related

Thinkscript: Recursive Counter

I'd like to create a scan in thinkorswim where it returns stocks that have closed higher then when it opened for 4 days or more out of the last 5 days.
This is the current code I have, but I don't know if it is correct or how to limit it to only the last 5 days:
def count = if (close > open) then 1 else 0;
rec counter = counter[1] + count;
plot scan =
counter >= 5;
Here are some alternatives:
Did you want the last 4 or 5 days consecutively to close higher? If so, this option will check for that:
# set aggregation because you want the last 5 days,
# not the last 5 bars regardless of time set
def closeVal = close(period=AggregationPeriod.DAY);
def openVal = open(period=AggregationPeriod.DAY);
# define the condition you want met (it'll check for this on every bar)
def countCondition = closeVal > openVal;
# sum the last 4 bars (days in this case, due to aggregation setting)
# note: the indexes are pointing to the current bar, 1 bar prior, 2 bars prior, and 3 bars prior
# also, each `true` condition will equal 1; `false` is 0
def sumLast4 = countCondition + countCondition[1] + countCondition[2] + countCondition[3];
# ensure last 4 all closed higher than they opened
def last4Condition = (sumLast4 == 4);
# if the last 4 days met the condition, then add in the 5th day prior;
# else, just use the sum of those last 4
def total = if last4Condition then sumLast4 + countCondition[5] else sumLast4;
# plot the final desired condition:
# at least the last 4 days closed higher than their open
plot scan = total >= 4;
If the days closing higher don't need to be consecutive:
# set aggregation because you want the last 5 days, not the last 5 bars
def closeVal = close(period=AggregationPeriod.DAY);
def openVal = open(period=AggregationPeriod.DAY);
# define the condition you want met (it'll check for this on every bar)
def countCondition = closeVal > openVal;
# sum the last 5 bars (days in this case, due to aggregation setting)
# note: each `true` condition will equal 1; `false` is 0
def sumLast5 = countCondition + countCondition[1] + countCondition[2] + countCondition[3] + countCondition[4];
# plot the final desired match
plot scan = sumLast5 > 3;
Using fold, ThinkScript's equivalent of a for loop. This one finds 4 out of the last 5, but not necessarily consecutive:
# set the length - using `input` means you can edit in the scan settings
input length = 5;
# set aggregation because you want the last 5 days, not the last 5 bars
def closeVal = close(period=AggregationPeriod.DAY);
def openVal = open(period=AggregationPeriod.DAY);
# declare a `counter` variable, but we'll set its value in the `if` statement
def counter;
# ensure all data is available by checking to see if the 5th bar back is a number
if !isNaN(closeVal[length - 1]){
# we have a number, so let's fold...
# `with count = 0` initializes a variable called `count` to 0
# for i = 0 to length... (i will go 0 thru 4; it ends when it sees 5)
# if closeVal[i] (the closeVal i bars back) is less than openVal[i]
# then `count = count + 1` else `count` just remains the same as it last was
# when the loop is done, put the `count` value into the `counter` variable
counter = fold i = 0 to length with count = 0 do if getValue(closeVal, i) > getValue(openVal, i) then count + 1 else count;
}
else {
# if the 5th bar back wasn't a number, we can't calculate
# so, simply set the counter to indicate it's Not a Number
counter = Double.NaN;
}
plot scan = counter > 3;
*edited to clarify that a true value equals 1, while a false value equals 0
easy way:
#comment: declare five Booleans for each of five days
def candle1 = close[5] > open[5];
def candle2 = close[4] > open[4];
def candle3 = close[3] > open[3];
def candle4 = close[2] > open[2];
def candle5 = close[1] > open[1];
#
#comment: add up all the green candles(value == 1) and red candles(value == 0)
def sumofgreencandles = candle1 + candle2 + candle3+ candle4 + candle5;
#
#comment: return one if 4 or five candles are green, zero if 3 or fewer are green-
plot fouroffivegreen= if sumofgreencandles > 3 then low else double.nan;
#
#comment: add an arrow to graph where condition exists:
fouroffivegreen.setpaintingstrategy(paintingstrategy.arrow_UP);
fouroffivegreen.setdefaultcolor(color.cyan);
This will place a cyan colored arrow under any bar or point where at least the last four of five periods closed higher than open. I know it looks clunky, but if you use a fold statement, it is much slower and will delay the rendering of your charts.

Expressing Natural Number by sum of Triangular numbers

Triangular numbers are numbers which is number of things when things can be arranged in triangular shape.
For Example, 1, 3, 6, 10, 15... are triangular numbers.
o o o o o o o o o o is shape of n=4 triangular number
what I have to do is A natural number N is given and I have to print
N expressed by sum of triangular numbers.
if N = 4
output should be
1 1 1 1
1 3
3 1
else if N = 6
output should be
1 1 1 1 1 1
1 1 1 3
1 1 3 1
1 3 1 1
3 1 1 1
3 3
6
I have searched few hours and couldn't find answers...
please help.
(I am not sure this might help, but I found that
If i say T(k) is Triangular number when n is k, then
T(k) = T(k-1) + T(k-3) + T(k-6) + .... + T(k-p) while (k-p) > 0
and p is triangular number )
Here's Code for k=-1(Read comments below)
#include <iostream>
#include <vector>
using namespace std;
long TriangleNumber(int index);
void PrintTriangles(int index);
vector<long> triangleNumList(450); //(450 power raised by 2 is about 200,000)
vector<long> storage(100001);
int main() {
int n, p;
for (int i = 0; i < 450; i++) {
triangleNumList[i] = i * (i + 1) / 2;
}
cin >> n >> p;
cout << TriangleNumber(n);
if (p == 1) {
//PrintTriangles();
}
return 0;
}
long TriangleNumber(int index) {
int iter = 1, out = 0;
if (index == 1 || index == 0) {
return 1;
}
else {
if (storage[index] != 0) {
return storage[index];
}
else {
while (triangleNumList[iter] <= index) {
storage[index] = ( storage[index] + TriangleNumber(index - triangleNumList[iter]) ) % 1000000;
iter++;
}
}
}
return storage[index];
}
void PrintTriangles(int index) {
// What Algorithm?
}
Here is some recursive Python 3.6 code that prints the sums of triangular numbers that total the inputted target. I prioritized simplicity of code in this version. You may want to add error-checking on the input value, counting the sums, storing the lists rather than just printing them, and wrapping the entire routine into a function. Setting up the list of triangular numbers could also be done in fewer lines of code.
Your code saved time but worsened memory usage by "memoizing" the triangular numbers (storing and reusing them rather than always calculating them when needed). You could do the same to the sum lists, if you like. It is also possible to make this more in the dynamic programming style: find the sum lists for n=1 then for n=2 etc. I'll leave all that to you.
""" Given a positive integer n, print all the ways n can be expressed as
the sum of triangular numbers.
"""
def print_sums_of_triangular_numbers(prefix, target):
"""Print sums totalling to target, each after printing the prefix."""
if target == 0:
print(*prefix)
return
for tri in triangle_num_list:
if tri > target:
return
print_sums_of_triangular_numbers(prefix + [tri], target - tri)
n = int(input('Value of n ? '))
# Set up list of triangular numbers not greater than n
triangle_num_list = []
index = 1
tri_sum = 1
while tri_sum <= n:
triangle_num_list.append(tri_sum)
index += 1
tri_sum += index
# Print the sums totalling to n
print_sums_of_triangular_numbers([], n)
Here are the printouts of two runs of this code:
Value of n ? 4
1 1 1 1
1 3
3 1
Value of n ? 6
1 1 1 1 1 1
1 1 1 3
1 1 3 1
1 3 1 1
3 1 1 1
3 3
6

Python: a type error

So here is my situation. Ive been trying to make a advanced calculator in python 3.4, one where you can just type something like this. '1 + 1', and it would then give you the answer of '2'. Now i will explain how my calculator is supposed to work. So you start by entering a maths equation, then it counts the words you entered based on the spaces. It does this so it knows how long some future loops need to be. Then it splits up everything that you entered. It splits it up into str's and int's but its all still in the same variable and it's all still in order. The thing i'm having trouble with is when it is meant to actually do the calculations.
here is all of my code-
# This is the part were they enter the maths equation
print("-------------------------")
print("Enter the maths equation")
user_input = input("Equation: ")
# This is were it counts all of the words
data_count = user_input.split(" ")
count = data_count.__len__()
# Here is were is splits it into str's and int's
n1 = 0
data = []
if n1 <= count:
for x in user_input.split():
try:
data.append(int(x))
except ValueError:
data.append(x)
n1 += 1
# And this is were it actually calculates everything
number1 = 0
number2 = 0
n1 = 0
x = 0
answer = 0
while n1 <= count:
#The code below checks if it is a number
if data[n1] < 0 or data[n1] > 0:
if x == 0:
number1 = data[n1]
elif x == 1:
number2 = data[n1]
elif data[n1] is "+":
if x == 0:
answer += number1
elif x == 1:
answer += number2
n1 += 1
x += 1
if x > 1:
x = 0
print("Answer =", answer)
but during the calculation it messes up and gives me and error
error-
if data[n1] < 0 or data[n1] > 0:
TypeError: unorderable types: str() < int()
can anyone see what i am doing wrong here?
Thanks
When you are comparing a string and an integer, this problem comes.
Python doesn't guess, it throws an error.
To fix this, simply call int() to convert your string to an integer:
int(input(...))
So, corrected statement should be:
if int(data[n1]) < 0 or int(data[n1]) > 0:

Python Programming While Loop

Hi I'm new to python and programming in general. I am trying write a program that uses a while loop to add integers from 1 to the number entered. the program also has to give an error statement if the user enters a 0 or negative number. So far the integers add up and the error statement works but the program is not looping, it only asks the user to input a number one time. Please help. This is my source code so far. Thanks
x = int(input("Enter a positive number not including zero:" ))
total = 0
n = 1
while n <= x:
total = total + n
n = n + 1
# prints the total of integers up to number entered
print("Sum of integers from 1 to number entered= ",total)
if x <= 0 or x == -x:
print ("invalid entry")
Try this code...
op='y'
while op=='y':
x = int(input("Enter a positive number not including zero:" ))
total = 0
n = 1
if x > 0:
while n <= x:
total = total + n
n = n + 1
# prints the total of integers up to number entered
print("Sum of integers from 1 to number entered= ",total)
else:
print ("invalid entry")
op = raw_input("Are you want to continue this operation (y/n):" )
Put your whole code this way
done = False
while not done:
//your entire code here except the last 2 lines
if x > 0:
done = True

Conversion of Double to value digits and exponent

For ex.
double size = 10.35;
i should get
value = 1035;
exponent = -2;
so when i re calculate i will get 10.35.
i.e 1035 * 10^-2 = 10.35;
Please help me.
Thanks in advance
In general this is not possible since the fractional part of a double is stored in powers-of-2, and might or might not match powers-of-10.
For example: When looking at powers-of-2 vs powers-of-3: Just like 1/2 == 2^-1 == 5 * 10^-1 has a match, 1/3 == 3^-1 == ?? does not have a match.
However, you can approximate it.
It would have an answer if you would ask for powers-of-2. In that case you can just look at the double representation (see IEEE-754 here) and extract the right bits.
Very simplistically (in C#):
double size = 10.36;
int power = 0;
while (size != (int)size)
{
size *= 10.0;
power--;
}
Console.WriteLine("{0} * 10 to the {1}", size, power);
Though I'm sure with a bit more thought a more elegant solution can be found.
This doesn't go the other way where you've got a large number (103600 say) and want to get the smallest value to some power (1036 * 10^2).
I had to do something very similar. Here's a solution in Python (it hasn't been tested very well):
def normalize(value, fdigits=2):
"""
Convert a string representing a numerical value to value-digit/exponent form.
Round the fractional portion to the given number of digits.
value the value (string)
fdigits the number of digits to which to round the fractional
portion
"""
# if empty string, return error
if not value:
return None
# split value by decimal
v = value.split('.')
# if too many decimals, return error
if len(v) > 2:
return None
# add empty string for fractional portion if missing
elif len(v) == 1:
v.append('')
# assign whole and fractional portions
(w, f) = v
# pad fractional portion up to number of significant digits if necessary
if len(f) < fdigits:
f += ('0' * (fdigits - len(f)))
# if the number of digits in the fractional portion exceeds the
# number of digits allowed by fdigits
elif len(f) > fdigits:
# convert both portions to integers; use '0' for whole portion if missing
(wi, fi) = (int(w or '0'), int(f[:fdigits]))
# round up if first insignificant digit is gteq 5
if int(f[fdigits]) >= 5:
fi += 1
# roll whole value up if fractional portion rounds to a whole
if len(str(fi)) > fdigits:
wi += 1
fi = 0
# replace the whole and fractional strings
(w, f) = (str(wi), ("%0" + str(fdigits) + "d") % fi)
# derive value digits and exponent
n = w.lstrip() + f
l = len(n)
x = -fdigits
n = n.rstrip('0')
x += (l - len(n))
# return value digits and exponent
return (int(n), x)

Resources