Python recursive sequence related code - python

I am trying to make a code that produces numbers according to the following formula...
T[n] = 1 + T[n-1] * 2
numList = []
numLisst.append (1)
#Begins with a term 1.
def numSequence ():
while True:
for i in range (1,12):
#Temporally set numbers from 1 to 12
numList[i] == 1+(numList[i-1]*2)
break
print (numList)
numSequence()
First of all, this brings an error, list index out of index
I'd like to see this code produce the fibonacci sequences, for example,,
1, 3, 7, 15, 31, 63, 127 , ....
I hope if I use this recursive program, I would be able to find out specific order of the numbers in an array,
e.g. If I'd like to find out 3rd number in the array, should be whether 7 or 15 (It would depend how I would set it)

The recursive implementation of your formula would be the following, assuming your base case was T(1) = 1
def T(n):
if n == 1:
return 1
else:
return 1 + T(n-1)*2
Some examples
>>> [T(i) for i in range(1,10)]
[1, 3, 7, 15, 31, 63, 127, 255, 511]
>>> T(15)
32767

One way to solve this probem (not most Pythonic implementation, though...)
# T[n] = 1 + T[n-1] * 2
def nextFibonachi(n,i):
n = 1 + n*2
print(str(i)+": "+str(n))
return n,i
fibArr = []
for i in range(0,100):
if i == 0:
n = 0
n,i = nextFibonachi(n, i)
fibArr.append(n)
print(fibArr)
m = 10
print("\n"+str(m)+": "+str(fibArr[m]))

Related

How to recursively find the sequence in a list with the highest difference?

Given this grid:
grid = [[10,23,16,25,12],
[19,11,8,1,4],
[3,6,9,7,20],
[18,24,4,17,5],
[7,3,4,6,1]]
The sequence with the greatest difference between the sum of its odd rows and the sum of its even rows is the sequence of row 1 to row 3. This is because (10 + 23 + 16 + 25 + 12) - (19 + 11 + 8 + 1 + 4) + (3 + 6 + 9 + 7 + 20) = 88 which is the maximum difference out of all sequences like this.
The sequence should have an even row and an odd row so it must have at least 2 rows. The maximum number of rows depends on the size of the grid.
The problem is I need it to work on an O(log n) time complexity. My idea is to use recursion to divide the grid into 2 and solve it from there. However, it doesn't work as I wanted to.
This is my whole code:
import math
class Sequence:
def __init__(self,grids):
self.grids = grids
self.calculate_max_difference()
def calculate_max_difference(self):
# Get the odd and even rows using list slicing
odd_rows = self.grids[::2]
even_rows = self.grids[1::2]
odd_sum = 0
even_sum = 0
for odd_lst in odd_rows:
odd_sum += sum(odd_lst)
for even_lst in even_rows:
even_sum += sum(even_lst)
self.diff = odd_sum - even_sum
def consecutive_seq(start,end,max,grids):
middle = math.ceil((start+end)/2)
sequence = []
for row in range(end-start):
sequence.append(grids[start+row])
seq_ins = Sequence(sequence)
if (end-start) <= 3 and (end-start) > 1:
return seq_ins.grids
upper_seq = consecutive_seq(start,middle,seq_ins.diff,seq_ins.grids)
lower_seq = consecutive_seq(middle+1,end,seq_ins.diff,seq_ins.grids)
greater_seq = upper_seq
if upper_seq.diff < lower_seq.diff:
greater_seq = lower_seq
if greater_seq.diff < max:
return seq_ins.grids
# Sample Input
grid = [[10,23,16,25,12],
[19,11,8,1,4],
[3,6,9,7,20],
[18,24,4,17,5],
[7,3,4,6,1]]
n = len(grid)
max_seq = consecutive_seq(0,n-1,0,grid)
print(max_seq)
How should I go about this?
Firstly you don't really need a 2d array for this. You can sum up all the rows and only store the sums in a 1D array. So for example
grid = [[10,23,16,25,12],
[19,11,8,1,4],
[3,6,9,7,20],
[18,24,4,17,5],
[7,3,4,6,1]]
turns in to
sums = [sum(row) for row in grid] # sums = [86, 43, 45, 68, 21]
Once you have the sums you have to simply invert the signs for odd indices
[86, 43, 45, 68, 21] becomes => [86, -43, 45, -68, 21]
Once you have the data in this format, you can use the algorithm for Finding the largest sum in a contiguous subarray which has a time complexity of O(n). You might have to make a few small tweaks to that to include at least 2 numbers.
Also if you care only about the difference, you will have to run the algorithm again but this time multiply the even indices by -1.
I really don't think you can solve this in O(log n) time.

Find the largest palindrome made from the product of two 3-digit numbers using numpy

I got stuck on this question when I tried solving it using the numpy package. My idea was that I would multiply and keep a list of all the calculations I did of the 3 digit numbers ranging from 100 to 999, then check through the list to see which ones are a palindrome and save them. Finally, I would order the list and get the largest palindrome. Code below shows what I tried to do.
import numpy as np
def void():
list1 = np.array(range(100,999))
list2 = np.array(range(100,999))
k = []
for i,j in zip(list1,list2):
k.append(np.multiply(list1,list2))
b = []
for x in range(0,len(k)):
if(reverseNum(k[x])==k[x]):
b.append(k[x])
print(b)
print(b[-1])
def reverseNum(num):
rev = 0
while(num>0):
rem = num % 10
rev = (rev*10) +rem
num = num // 10
return rev
void()
However, when I try to check if the numbers in the list are a palindrome, I get the following bug:
Traceback (most recent call last):
File "main.py", line 40, in <module>
void()
File "main.py", line 22, in void
if(reverseNum(k[x]),k[x]):
File "main.py", line 31, in reverseNum
while(num>0):
ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()
Does this mean that it is not possible to use numpy as a method to solve this problem? If it is, where am I going wrong?
EDIT:
What I have tried so far (since it was asked):
Based on the error messages, I tried using np.equal as well as np.greater instead of checking if(reverseNum(k[x])==k[x]) and num>0 but it gives the same error.
Your issue stems from the your line including the zip. My code below isn't pretty, but attempts to follow your approach loosely.
import numpy as np
def void():
list1 = np.array(range(100,1000)) # you want to include '999'
list2 = np.array(range(100,1000))
k = []
for i,j in zip(list1,list2):
k.append(np.multiply(list1,j))
b = []
for r, row in enumerate(k):
for c, cell in enumerate(row):
if reverseNum(cell)==cell:
b.append(cell)
print(b)
print(max(b))
def reverseNum(num):
rev = 0
while(num>0):
rem = num % 10
rev = (rev*10) +rem
num = num // 10
return rev
void()
A NumPy way assuming the result has six digits (it can't have more, as 9992 is 998001):
import numpy as np
v = np.arange(100, 1000) # the range of three-digit numbers
a = np.outer(v, v) # all the products
print(a[(a // 100000 == a % 10) & # first digit == sixth digit
(a // 10000 % 10 == a // 10 % 10) &
(a // 1000 % 10 == a // 100 % 10)].max())
Prints 906609.
Double checking with pure Python:
>>> max(x*y
for x in range(100, 1000)
for y in range(100, 1000)
if str(x*y) == str(x*y)[::-1])
906609
Why does it have to use numpy?
# test if palindrome based on str
def is_palindrome(number: int):
converted_to_string = str(number)
return converted_to_string == converted_to_string[::-1]
# product of two three-digit numbers
you_right = []
values = []
for x in range(999, 99, -1):
for y in range(999, 99, -1):
product = x*y
if is_palindrome(product):
values.append((x, y))
you_right.append(product)
winner = you_right.index(max(you_right))
print(values[winner])
# output
(993, 913)
Another real NumPy solution, using your way to reverse the numbers (fixing it mostly by using .any() as suggested in the error message, which you stubbornly refused to try).
v = np.arange(100, 1000)
a = np.outer(v, v)
num = a.copy()
rev = num * 0
while (m := num > 0).any():
rev[m] = rev[m] * 10 + num[m] % 10
num[m] //= 10
print(a[rev == a].max())
Without the mask m you get the same result (906609), but it's safer with it. Otherwise products with five digits aren't reversed correctly, like 101*102=10302 becomes 203010 instead of 20301.

Average length of sequence with consecutive values >100 (Python)

I am trying to identify the length of consecutive sequences within an array that are >100. I have found the longest sequence using the following code but need to alter to also find the average length.
def getLongestSeq(a, n):
maxIdx = 0
maxLen = 0
currLen = 0
currIdx = 0
for k in range(n):
if a[k] >100:
currLen +=1
# New sequence, store
# beginning index.
if currLen == 1:
currIdx = k
else:
if currLen > maxLen:
maxLen = currLen
maxIdx = currIdx
currLen = 0
if maxLen > 0:
print('Index : ',maxIdx,',Length : ',maxLen,)
else:
print("No positive sequence detected.")
# Driver code
arrQ160=resultsQ1['60s']
n=len(arrQ160)
getLongestSeq(arrQ160, n)
arrQ260=resultsQ2['60s']
n=len(arrQ260)
getLongestSeq(arrQ260, n)
arrQ360=resultsQ3['60s']
n=len(arrQ360)
getLongestSeq(arrQ360, n)
arrQ460=resultsQ4['60s']
n=len(arrQ460)
getLongestSeq(arrQ460, n)
output
Index : 12837 ,Length : 1879
Index : 6179 ,Length : 3474
Index : 1164 ,Length : 1236
Index : 2862 ,Length : 617
This should work:
def get_100_lengths( arr ) :
s = ''.join( ['0' if i < 100 else '1' for i in arr] )
parts = s.split('0')
return [len(p) for p in parts if len(p) > 0]
After that you may calculate an average or do whatever you like.
The result:
>>> get_100_lengths( [120,120,120,90,90,120,90,120,120] )
[3, 1, 2]
that might be a little tricky. You want to use one variable to keep track of sum of length, one variable to keep track of how many times a sequence occurred.
We can determine if a sequence terminated when current number<100 and previous number is greater than 100
def getLongestSeq(array):
total_length = total_ct = 0
last_is_greater = False
for number in array:
if number > 100:
total_length += 1
last_is_greater = True
elif number<100 and last_is_greater:
total_ct += 1
last_is_greater = False
return round(total_length / total_ct)
Did not test this code, please comment if there is any issue
You want to find all the sequences, take their lengths, and get the average. Each of those steps are relatively straightforward.
items = [1, 101, 1, 101, 101, 1, 101, 101, 101, 1]
Finding sequences: use groupby.
from itertools import groupby
groups = groupby(items, lambda x: x > 100) # (False, [1]), (True, [101]), ...
Find lengths (careful, iterable of iterables not a list):
lens = [len(g) for k, g in groups if k] # [1, 2, 3]
Find average (assumes at least one):
avg = float(sum(lens)) / len(lens) # 2.0

Adjust values in a list by normalizing_zybook

1.7 LAB: Adjust values in a list by normalising
When analysing data sets, such as data for human heights or for human weights, a common step is to adjust the data. This can be done by normalising to values between 0 and 1, or throwing away outliers.
Write a program that first gets a list of integers from input. The input begins with an integer indicating the number of integers that follow. Then, adjust each integer in the list by subtracting the smallest value from all the integers.
Ex: If the input is:
5
30
50
10
70
65
the output is:
20
40
0
60
55
The 5 indicates that there are five integers in the list, namely 30, 50, 10, 70, and 65. The smallest value in the list is 10, so the program subtracts 10 from all integers in the list.
Anyone can solve this question in python?
This is my code.
arr1 = []
input = int()
for i in range(0,input):
e = int(intput())
arr1.append(e)
k = min(arr1)
for i in range(0,val):
arr1[i] = arr1[i] - k
for i in range(0,val):
print(arr1[i])
Here is the error.
Traceback (most recent call last):
File "main.py", line 8, in <module>
arr1.append(e)
NameError: name 'e' is not defined
You could use list comprehension:
input = [5,30,50,10,70,65]
input = input[1:]
output = [i - min(input) for i in input]
print(output)
[20, 40, 0, 60, 55]
This is the way I solved it
list = []
values = int(input())
for n in range(values):
number = float(input())
list.append(number)
largest = max(list)
for number in list:
number = number / largest
print(f'{number:.2f}')
def get_minimum_int(nums):
low = min(nums)
return low
if __name__ == '__main__':
num = int(input())
nums = []
while num != -1:
nums.append(num)
num = int(input())
l = get_minimum_int(nums)
for n in nums:
print(n - l)
idk if your question ever got answered but I also had the same type of task.
Mine was:
"For this program, adjust the values by dividing all values by the largest value. The input begins with an integer indicating the number of floating-point values that follow.
Output each floating-point value with two digits after the decimal point, which can be achieved as follows:
print('{:.2f}'.format(your_value))
Ex: If the input is:
5
30.0
50.0
10.0
100.0
65.0
the output is:
0.30
0.50
0.10
1.00
0.65
The 5 indicates that there are five floating-point values in the list, namely 30.0, 50.0, 10.0, 100.0, and 65.0. 100.0 is the largest value in the list, so each value is divided by 100.0."
So this is how I solved mine:
x = int(input())
dislist = []
i = 1
while i <= x:
y = float(input())
dislist.append(y)
i += 1
q = max(dislist)
for item in dislist:
item = item / q
print('{:.2f}'.format(item))
Tell me what you think :)
A few problems I can see with your code.
input = int()`
input in the name of a function that gets an input string from the user. int() simply returns 0. You are assigning the value 0 to a variable named input, making the input function no longer accessible.
for i in range(0,input):
e = int(intput())
Because input is 0, this is an empty range. The loop never runs. Which is good because it would have no idea what intput is.
Because the loop never runs, e is never defined, which is why you get the error you do.
Another style note: arr1 is a list so using a name that suggests it's an array is misleading.
You likely wanted something like the following tweaked version of your code.
n = int(input())
vals = []
for _ in range(0, n):
e = int(input())
vals.append(e)
k = min(vals)
for i in range(0, n):
arr1[i] = -= k
for i in range(0, n):
print(arr1[i])
Gathering the input numbers could be simplified using a list comprehension.
vals = [int(input()) for _ in range(0, n)]
This may be helpful for your lab:
user_int = []
while True:
user_input = int(input())
user_int.append(int(user_input))
if len(user_int) > (int(user_int[0])):
break
user_int.pop(0)
vals = min(user_int)
for user_vals in user_int:
my_vals = user_vals - vals
print(my_vals)

Credit card validation - returning values that aren't hard coded

How do I compute the answer so that the answer is not a hard-coded solution? Like if I wanted to put in another credit card number how can I return the result of that new credit card? Also how can I create one x list rather then the way I have it now with the values split up by 2?
Also here is the original question for reference:
Credit card numbers are validated using Luhn’s formula 3. Implement a program that takes a credit card numbers as a multidimensional array (you may assume it consists of exactly of 16 columns), and returns a list with values Valid if it is a valid card number, and Invalid otherwise.
One way to perform the validity test is as follows:
1. From the rightmost digit, which is the check digit, moving left, double the value of every second digit; if the product of this doubling operation is greater than 9 (e.g., 8 2 = 16), then sum the digits of the products (e.g.,16: 1 + 6 = 7, 18: 1 + 8 = 9).
2. Take the sum of all the digits.
3. If the total is divisible by 10, then the number is valid according to the Luhn formula; else it is not valid.
Note: You can maniplulate card numbers either as strings (using indexing and slicing to extract digits, etc) or as integers (using integer division and remainder to manipulate digits).
My script:
import numpy as py
x = [[7,1],[6,3],[4,5],[6,2],[7,8],[3,4],[6,8],[3,9]] #credit card numbers
x2 = np.array(x)
evryothernum = x2[:,1] #returns every other number / every seconds digit
evryothernum2 = np.multiply(evryothernum,2)
sumdigits = []
def card_validate(x):
evryothernum = x2[:,1] #valid
evryothernum2 = np.multiply(evryothernum,2) #multiplys evryothernum by 2
b=np.sort(evryothernum2, axis = None) #sorts the evryothernum2 array in order
b2 = np.array(b)
b3 = b2[4:8] #shows the highest values aka greater than 9
b3
b3 = [1,7,7,9]
newb3 = np.sum(b3)
newx2 = np.sum(x2[:,0])
total = np.sum(newb3+newx2)
if ( (total % 10) == 0 ):
print "Valid"
else:
print "Invalid"
return card_validate()
Is there an easier way then to do this without Numpy?
The following can be used to implement the logic without using numpy
a=[[4,0,1,2,8,8,8,8,8,8,8,8,1,8,8,1],[4,0,1,2,8,8,8,8,8,8,8,8,1,8,8,2]] #array of credit card numbers
def validate(creditcard_numbers,tmp):
even_index=-1
for j in range(0,16):
sum_val=0
if even_index%2 ==0: #index calculation for even indices
val=creditcard_numbers[even_index]*2
if val>9: # add the digits if the value got after multiplying by 2 is two digit number
while val !=0:
rem=val%10
val=val/10
sum_val=sum_val+rem
tmp[even_index]=sum_val #append the temporary list with the new values which is got by adding the digits if the result of multiplying by 2 is a 2 digit number
else:
tmp[even_index]=val
else:
tmp[even_index]=creditcard_numbers[even_index]
even_index=even_index-1
total=0
for i in tmp:
total=total+i
if total%10 == 0:
return "valid"
else:
return "invalid"
for creditcard_numbers in a:
print creditcard_numbers
tmp=[0]*len(creditcard_numbers) #temporary list with zeros's
result=validate(creditcard_numbers,tmp)
print result
**OUTPUT :
[4, 0, 1, 2, 8, 8, 8, 8, 8, 8, 8, 8, 1, 8, 8, 1]
valid
[4, 0, 1, 2, 8, 8, 8, 8, 8, 8, 8, 8, 1, 8, 8, 2]
invalid
**
Here's a couple of ways. The first is a straight port to Python of the pseudo-code on the "Luhn algorithm" Wikipedia page (link). The second uses a lookup table to with the pre-computed doubled value of every other digit:
def checkLuhn(purportedCC):
sm = 0
nDigits = len(purportedCC)
parity = nDigits % 2
for i in range(nDigits):
digit = int(purportedCC[i])
if i % 2 == parity:
digit = digit * 2
if digit > 9:
digit = digit - 9
sm = sm + digit
return (sm % 10) == 0
def check(s):
lookup = [0,2,4,6,8,1,3,5,7,9]
digits = [int(c) for c in reversed(s)] # count odd/even from the right
odd = digits[::2]
even = digits[1::2]
total = sum(odd) + sum(lookup[c] for c in even)
return total % 10 == 0
cards = '1111222233334444','1111222233334445','01111222233334444'
for card in cards:
print(card,check(card))
print(card,checkLuhn(card))
Output (note if done correctly leading zeros don't affect the validation):
1111222233334444 True
1111222233334444 True
1111222233334445 False
1111222233334445 False
01111222233334444 True
01111222233334444 True

Categories

Resources