loop numbers down and up and not using recursion in python - python

I have a small problem with my code. I can't seem to figure out how to do this. I can get it to work with two for loops. But in the exercise it says that i only can use one loop to get the result.
The code is supposed to execute this:
bounce2(4):
4
3
2
1
0
1
2
3
4
What I have come up with:
def bounce2(n):
for x in range(n,-1,-1):
print(x)
Which prints out 4,3,2,1,0
But now i dont know what to do..
I have tried different if statements such as:
def bounce2(n):
for x in range(n,-1,-1):
print(x)
if n == 0:
x = x + 1
print(x)
But they only print one integer because they are out of the loop.
Same thing goes if i try to make the if-statement inside the loop, then it prints out something like 433221100. I dont know how to get the numbers to switch places. The print statement should also be an integer and not a string. So i can't use replaced.
Really need help to figure out the logic. All help is appreciated.

So, a little bit of my thought process before showing you the code. Clearly there are nine lines, or more generally n * 2 + 1 lines. Because we need to count down to 0 and back up. That's how many times you need to call print.
Now, if you add line numbers to the expected output and think of it as a table describing a function f(i, n) where i is the line number, and n is the starting and ending value. what is f? Can you write down the formula? e.g.
i f(i, 4)
0 4
1 3
2 2
3 1
4 0
5 1
6 2
7 3
8 4
We can write down the basic structure of the code, we still don't know what f look like but assume we have it:
for i in range(2*n+1):
print f(i)
And, what is f? Now you need to be a little creative and maybe experiment a bit. What I did was to try basic arithmetic combinations of i and n to match f(i, n), and I quickly noticed that n - i works until we reach the second half of the output, which only differs by a - sign.
i f(i, 4) n - i
0 4 4
1 3 3
2 2 2
3 1 1
4 0 0
5 1 -1
6 2 -2
7 3 -3
8 4 -4
Soooo, take the absolute value of n - i or i - n, whatever.
def f(i, n):
return abs(n-i)

Here is what I believe to be a pretty elegant solution:
def bounce(n):
for x in range(-n, n+1):
print(abs(x))
Our loop goes from the negative of n to the positive of n, printing the absolute value.

Since you need to count n times downwards, and another n times upwards, and 1 comes from counting 0, instead of actually counting downwards and then upwards in two separate loops, we can use one loop to count upwards 2 * n + 1 times, which effectively is like counting towards n and then bouncing off n, so we can simply calculate the "distance" to n instead, which is the absolute value of n - x:
def bounce2(n):
for x in range(2 * n + 1):
print(abs(n - x))
so that bounce2(4) would output:
4
3
2
1
0
1
2
3
4

a very simple solution will be:
for i in range(n, -(n+1), -1):
print(abs(i))
this like mirroring numbers around some point.
in your case that point is zero and to have identical mirroring use abs

Try the below, have a list l with a element of str(n) iterate trough the range of n times 2, then check x is bigger than n+2 if it is add 1 to n, otherwise subtract 1 from n, both cases append to l, then at the end, do str.join to join '\n' (newline) with l:
def bounce2(n):
l=[str(n)]
for x in range(n*2):
if x>n+2:
n+=1
l.append(str(n))
else:
n-=1
l.append(str(n))
return '\n'.join(l)
print(bounce2(4))
Output:
4
3
2
1
0
1
2
3
4

Related

Start loop from certain number to n number in python

How to start a loop from certain number to n numbers in python.
Example: starting loop from 2 but ending based on n numbers
If I start a loop from 2 but wish to go through next 5 numbers how to achieve that?
2
3
4
5
6
7
Range will do that for you
start = 2
length = 6
for i in range(start, start + length):
print(i)
Or you could leave range alone and add your offset onto the number inside the loop
for i in range(0, length):
print(i+start)
Which would be less common but depending on the scenario this might be more readable.

Moves to make all the elements in a array equal in Python

I came across a problem in which the input is as follows:
5
1 1 1 1 6
And the expected output is 4
Basically what we are trying to do is print the minimum number of moves it will require to make all the 5 values equal to each other. One move means reducing a location and incrementing another location. If it is not possible to make them all equal, we print -1.
I tried the below approach:
def solution(N, W):
counter=0
W.sort()
k=W[int(N/2)]
for i in range(0,N):
counter=counter+abs(W[i]-k)
if N%2==0:
tempC=0
k=W[int(N/2)-1]
for i in range(0,N):
tempC=tempC+abs(A[i]-k)
counter=min(counter,tempC)
return counter
and am getting 5 as the answer. Kindly share what your function to achieve this would be.
Lets see how logic works with your input.
5 1 1 1 1 6
1. If 1 2 1 3 3 this case possible then finally it show look like this 2 2 2 2 2. What are the things we get from this result Sum(INITAL_LIST) is equal to SUM(FINAL_LIST), this is 1st condition, if this hold pattern is possible.
2. Among all index-value some of them is going to leave some value some will take. Decrement of one-index and Increment of another-index is taken as one step, so we will consider only decrement case. Those who are leaving and finally become equal to 2. So total-step is equal to some of decremented index value.
Here I use vectorization properties of numpy for easy operation.
CODE :
import numpy as np
def solution(N, W):
if sum(W)%N !=0:
return -1
eq = sum(W)//N
step = np.array(W)-eq
step_sum = np.sum(step[step>0])
return step_sum
if __name__ == '__main__':
var_, list_ = input().split(maxsplit=1)
print(solution(int(var_), list(int(i) for i in list_.split())))
WITHOUT NUMPY :
Update :
step = np.array(W)-eq
step_sum = np.sum(step[step>0])
To :
step = [i-eq for i in W]
step_sum = sum(i for i in step if i>0)
OUTPUT :
5 1 1 1 1 6
4

permutations with restrictions on python

I want to create all possible sequence of numbers with 10 digits by using numbers 0 to 9 . Each digit should be used only once like:
5 2 8 7 3 0 6 1 9 4 and 5 0 6 2 7 8 3 1 9 4.
So there are P(10,10) = 3 628 800 possible combinations out there. However there are three rules about the ordering of elements:
2 > 8 > 3 > 9 > 4 (rule 1) and 5 > 9 > 4 (rule 2) and 2 > 8 > 1 (rule 3). Here > sign means left operand should be on a higher significance digit (meaning closer to the left). Unspecified numbers in the rules which are 0 6 7 could be used anywhere on the combination.
So I have this idea of having a list of all possible combinations and then applying rules one by one and discard the sequences that do not follow. However, after some thoughts, found out that I can further assess the precise position for some digits, lets say 2. Looking at 2,8,3,9,4 (rule 1), there should be at least 4 elements on the rightside of 2--> (8,3,9,4). This makes 2 could be assigned to digits D(1,2,3,4,5,6) (1 is MSB and 10 is LSB). Further investigating 2,8,1 (rule 3) 1 should also be on the right side of 2 that makes 2 could be assigned to D(1,2,3,4,5). There are no further simplifications I figured out, and that's it I guess.
So what kind of approach might work here? I don't know even if the brute-force approach I suggest is feasible yet have to check it but I'm looking for a neater pythonic way to implement this.
P.S. An idea is that we can split rules like
(2>8),(2>3),(2>9),(2>4)
(8>3),(8>9),(8>4)
(3>9),(3>4)
(9>4) for rule 1. But it still looks like a brute-force to me.
Easy, you can use itertools.permutations(), and as it generates tuples, we check to see each tuple meets the rules:
from itertools import permutations
for t in permutations(range(10), 10):
if t.index(2) < t.index(8) < t.index(3) < t.index(9) < t.index(4) and t.index(5) < t.index(9) < t.index(4) and t.index(2) < t.index(8) < t.index(1):
print(t)
For the brute force method & for rule1 and rule2, you can do this:
import itertools
allpermutations = list(itertools.permutations([x for x in range(10)]))
def rule1(seq):
return seq.index(2) < seq.index(8) and seq.index(8) < seq.index(3) and seq.index(3) < seq.index(9) and seq.index(9) < seq.index(4)
def rule2(seq):
return seq.index(5) < seq.index(9) and seq.index(9) < seq.index(4)
result = [eachsequence for eachsequence in allpermutations if rule1(eachsequence) and rule2(eachsequence)]
(Similarly for rule3.)
For itertools usage, see this, for the .index() method, this.

range countdown to zero

I am taking a beginner Python class and the instructor has asked us to countdown to zero without using recursion. I am trying to use a for loop and range to do so, but he says we must include the zero.
I searched on the internet and on this website extensively but cannot find the answer to my question. Is there a way I can get range to count down and include the zero at the end when it prints?
Edit:
def countDown2(start):
#Add your code here!
for i in range(start, 0, -1):
print(i)
The range() function in Python has 3 parameters: range([start], stop[, step]). If you want to count down instead of up, you can set the step to a negative number:
for i in range(5, -1, -1):
print(i)
Output:
5
4
3
2
1
0
As another option to #chrisz's answer, Python has a built-in reversed() function which produces an iterator in the reversed order.
start_inclusive = 4
for i in reversed(range(start_inclusive + 1)):
print(i)
outputs
4
3
2
1
0
This can be sometimes easier to read, and for a well-written iterator (e.g. built-in range function), the performance should be the same.
In the below code n_range doesn't need to be told to count up or down, it can just tell if the numbers ascend or descend through the power of math. A positive value divided by it's negative equivalent will output a -1 otherwise it outputs a 1.
def n_range(start, stop):
return range(start, stop, int(abs(stop-start)/(stop-start)))
An input of 5, -1 will output
5
4
3
2
1
0

Need explanation of how function works printing digits in reverse

I cheated after giving up of how to figure out how to print digits backwards making a function for it but I still do not quite understand how it works. For instance why does it print the digits backwards and not in order?
def print_digits(n):
"""
>>> print_digits(13789)
9 8 7 3 1
>>> print_digits(39874613)
3 1 6 4 7 8 9 3
>>> print_digits(213141)
1 4 1 3 1 2
"""
while n > 0:
print n % 10
n = n / 10
I would appreciate a line by line explanation starting with the while loop. I've tried tracing it in my head and on paper but just can't grasp the code in the function.
In the first line in the loop the '%' operator devides the number given by 10 and returns the rest only, means the fraction of the division (25 : 10 = 2.5, so it returns the 5 only!).
The line 'n/10' then does exactly the other way around and stores part left of the comma into the variable itself, as the '/' operator returns only the left part of the comma.
In short you can say:
n%10 returns only the rest of the divison
n/10 "throws" the rest of the division away
the code repeats
% operator returns the remainder of division. (20%3=2,24%5=4).
When you divide a number by 10 remainder is always the last digit.
For example 123/10=12 & remainder is 3. So 123%10=3.
Inside the while loop while n is greater than 0 the last digit of n is printed.
And because of the line n=n/10, n becomes n/10. Here integer division has used so finally value of n will become 0 and then the loop will stop.( if n is initially 123 value of n will change as 123,12,1,0 and then loop will stop.)

Categories