recursion, Python, countup, countdown - python

I am supposed to write a recursive function counting(5) that prints 5 4 3 2 1 0 1 2 3 4 5.
I have made two functions down below that do half part each but I need them to be put together.
def countdown(n):
if n == 0:
print 0
else:
print n,
countdown(n-1)
def countup(n):
if n >= 1:
countup(n - 1)
print n,

I suppose the trick is to understand the recursion point does not end execution:
def count_down_up(n):
if not n:
print n # prints 0 and terminates recursion
return
print n # print down 5, 4, 3, 2, 1
count_down_up(n-1) # recursion point
print n # prints up 1, 2, 3, 4, 5
You can see each step print n, <RECURSION>, n, which unfolds to:
5, <count_up_down 4>, 5
5, 4, <count_up_down 3>, 4, 5
# ...
5 ,4, 3, 2, 1, <count_up_down 0>, 1, 2, 3, 4, 5 # recursion stops ...
5, 4, 3, 2, 1, 0, 1, 2, 3, 4, 5

#Reut_Sharabani solution is fine but I think this is simpler to read :
def countdown(N,n):
if abs(n) > N:
return
else:
print(abs(n))
countdown(N,n-1)
Call like this :
countdown(5,5)

One way to do it is by keeping track of 2 lists during the recursion and then stiching them together at return at the end.
def countdown_up(n, i=0, down=[], up=[] ):
if n >i:
return countdown_up(n-1, i, down+[n], [n]+up)
else:
# stich the 2 lists together with the low point [i]
return down+[i]+up
# by default it counts down to 0.
>>>countdown_up(5)
[5, 4, 3, 2, 1, 0, 1, 2, 3, 4, 5]
# you can run with any arbitrary high and low numbers.
>>>countdown_up(10, 3)
[10, 9, 8, 7, 6, 5, 4, 3, 4, 5, 6, 7, 8, 9, 10]
To have the function print instead of return list we just need to change 1 line.
def countdown_up(n, i=0, down=[], up=[] ):
if n >i:
return countdown_up(n-1, i, down+[n], [n]+up)
else:
print(" ".join("%s "%x for x in down+[i]+up))
>>>countdown_up(5)
5 4 3 2 1 0 1 2 3 4 5
>>>countdown_up(10,3)
10 9 8 7 6 5 4 3 4 5 6 7 8 9 10

Related

Maze algorithm python

Turn the four rings so that the sums of each four of the numbers that are located along the same radius are the same. Find what they are equal to?
problem image
We can do it by Brute Force method but it will be dummy cause too many combinations.
I had thoughts about DFS method but cant imagine how to consume it here truly.
I dont need code for this problem, perhaps you can share your thoughts on this issue.
input data
1-st ring: 3 9 6 4 3 7 5 2 4 8 3 6
2-nd ring: 8 4 7 5 8 2 9 5 5 8 4 6
3-rd ring: 6 5 8 1 6 6 7 1 3 7 1 9
4-th ring: 9 2 4 6 8 4 3 8 5 2 3 7
Have done this problem without using any theoretical algorithm using python.
Just simple Brute Force method like walking through my rings starting from 2-nd one**
def find_radius(*args):
arr = []
for i in range(0, len(args[0])):
sum_radius = args[0][i] + args[1][i] + args[2][i] + args[3][i]
arr.append(sum_radius)
return list(dict.fromkeys(arr))
def move_ring(arr):
first_element = arr[0]
arr.remove(first_element)
arr.append(first_element)
return arr
def print_all_rings(*args):
print(args[0])
print(args[1])
print(args[2])
print(args[3])
if __name__ == '__main__':
# first example
ring_1 = [3, 9, 6, 4, 3, 7, 5, 2, 4, 8, 3, 6]
ring_2 = [8, 4, 7, 5, 8, 2, 9, 5, 5, 8, 4, 6]
ring_3 = [6, 5, 8, 1, 6, 6, 7, 1, 3, 7, 1, 9]
ring_4 = [9, 2, 4, 6, 8, 4, 3, 8, 5, 2, 3, 7]
# second example
# ring_1 = [4, 2]
# ring_2 = [6, 8]
# ring_3 = [9, 8]
# ring_4 = [5, 8]
first_round = 0
second_round = 0
while True:
if first_round == len(ring_1):
first_round = 0
move_ring(ring_3)
second_round += 1
if second_round == len(ring_1):
second_round = 0
move_ring(ring_4)
if len(find_radius(ring_1, ring_2, ring_3, ring_4)) == 1:
print("200 OK! All subsums in column are the same")
break
else:
print("404 Error!")
move_ring(ring_2)
first_round += 1
print(find_radius(ring_1, ring_2, ring_3, ring_4))
print_all_rings(ring_1, ring_2, ring_3, ring_4)
Not sure if this is what you mean by brute force, but I don't think you can avoid trying all combinations (which is exactly what a tree search does as well).
Note though that since only relative displacements matter, it is enough to search on displacements of 3 rings. You can do so using backtracking (which exactly corresponds to a tree search).

How to resample an array by duplicating/skipping every N item?

I am confused on how to achieve the following:
Say I have an array of size X (e.g: 3000 items). I want to create a function that will stretch that array to size Y (e.g: 4000) by duplicating every N item.
Along with another function to do the opposite, remove every N items to make the array size 2000 for example.
I guess this is more of a math problem than a programming problem, and as you can tell maths aren't my strong point. Here's what I have so far:
def upsample(originalArray, targetSize):
newArray = []
j = 0
for i in range (0, len(originalArray)):
newArray.append(originalArray[i])
# calculate at what interval items need to be duplicated
# this is what I'm having trouble with
if j == interval:
newArray.append(originalArray[i])
j = 0
j+=1
return newArray
Here is an example of what I'm trying to do:
# stretch array from 10 to 12 items
originalArray = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
upsample(originalArray, 11)
# output: [0, 1, 2, 3, 4, 4, 5, 6, 7, 8, 9, 9]
Any help will be much appreciated
Create a floating point linspace and map it back to integer to use it as indices for your original Array. (Since you wanted [0, 1, 2, 3, 4, 4, 5, 6, 7, 8, 9, 9] instead of [0, 0, 1, 2, 3, 4, 4, 5, 6, 7, 8, 9] you need to do this flipping stuff in the if condition).
The code avoids loops for performance.
import numpy as np
def upsample(originalArray, targetSize):
x = np.linspace(0, originalArray.size, num=targetSize, endpoint=False)
if targetSize > originalArray.size:
x = -np.flip(x, axis=0) + originalArray.size
x[-1] = originalArray.size - 1
x = originalArray[x.astype(int)]
return x
upsample(originalArray, 21) gives [0 0 1 1 2 2 3 3 4 4 5 5 6 6 7 7 8 8 9 9 9]
upsample(originalArray, 23) gives [0 0 1 1 2 2 3 3 3 4 4 5 5 6 6 6 7 7 8 8 9 9 9]
upsample(originalArray, 5) gives [0 2 4 6 8]
etc.
To downsample your array:
N =2 #downsampling by 2
new = originalArray[0:N:]
To upsample (a being originaArray):
new = [item for t in [[a[i]]*2 if i%N==0 else [a[i],] for i in range(0,len(a))] for item in t]
or more explicitly:
res = list()
i=0
while(i<len(originalArray)):
res.append(originalArray[i])
if i%N==0:
continue
i +=1

Get top K values in pandas series include recurring values

I have a code snippet in python. It gets top K=5 values but don't increment the value of K if the value has already occurred.
For example upon giving [1, 3, 3, 5, 5, 6, 1, 4, 8, 9, 34, 66, 124] and K = 5, it should return
[1, 3, 3, 5, 5, 6, 1, 4]
Here if a value is repeating then it should not increment the value of K. Here is the Python code. But how can I do it in pandas Series?.
def get_top_K_uniques(K, nums):
ret = []
presense = defaultdict(bool)
counter = 0
for each in nums:
if not presense[each]:
presense[each] = True
counter+=1
ret.append(each)
if counter == K:
return ret
Thanks in advance.
Using Series.unique() and Series.isin()
nums = pd.Series([1, 3, 3, 5, 5, 6, 1, 4, 8, 9, 34, 66, 124])
uniq = nums.unique()[:5]
nums[nums.isin(uniq)]
Output
0 1
1 3
2 3
3 5
4 5
5 6
6 1
7 4
Using category
s[s.astype('category').cat.codes<4]
Out[153]:
0 1
1 3
2 3
3 5
4 5
6 1
7 4
dtype: int64

how do i do round-robin in python 3

i have to do a rotation of a list. I get a sorted list and i have to get minimum of pairs and maximum of tree numbers in a permutation of this sorted list as an answear. It has to have different numbers sorted from lowest to highest. For example:
MyList=[1, 1, 1, 2, 2, 2, 3, 3, 3, 3]
and the output must be:
1 2 3
1 2 3
1 3
2 3
and for :
MyList=[1, 1, 1, 1, 1, 2, 3, 4, 5, 6]
and the output must be:
1 2
1 3
1 4
1 5
1 6
I saw i can do it with a method called round-robin but i don't know how.
Thank you for your help!
from itertools import cycle
A = [[1,2,3],[4,5,6],[7]]
B = [[8],[9,10,11],[12,13]]
for p in A:
max1 = len(p) if max1 <len(p) else max1
for p in B:
max1 = len(p) if max1 <len(p) else max1
i = len(A)
j = 0
C = []
list_num = cycle(k for k in range(i))
for x in list_num:
j += 1
if j == i*3:
break
if A[x]:
C.append(A[x].pop(0))
if B[x]:
C.append(B[x].pop(0))
Output:
[1, 8, 4, 9, 7, 12, 2, 5, 10, 13, 3, 6, 11]

Android pattern plotting in Python

I need to make make an android pattern or just a pattern in a 3x3 matrix. The pattern is [8, 7, 6, 5, 4, 3, 2, 0, 1] and I need to plot it in a 3x3 matrix. The first entry in the pattern is the beginning point and it connects to the second in the row. The result needs to be the following:
8, 9, 7
6, 5, 4
3, 2, 1
pattern = [8, 7, 6, 5, 4, 3, 2, 0, 1]
matrix = [0,0,0,0,0,0,0,0,0]
lst = ([matrix[i:i + 3] for i in range(0, len(matrix), 3)])
for i in lst:
print(i)
for char in pattern:
matrix[char]=char
Do you mean something like this:
def print_pattern(pattern, cols=3):
for ii, pp in enumerate(pattern):
if ii % cols == 0:
print("")
print(pp),
Then you can call this function as
pattern = [8, 7, 6, 5, 4, 3, 2, 0, 1]
print_pattern(pattern)
This results in the following output:
8 7 6
5 4 3
2 0 1
If you want to print the pattern in the opposite order you can pass a reversed list of your pattern, e.g.:
print_pattern(reversed(pattern))
Gives the following output:
1 0 2
3 4 5
6 7 8
This functions accepts an integer n and an iterable. It makes a list of tuples of width n from that iterable
def mat(n, it):
return list(zip(*[iter(it)]*n))

Categories

Resources