Moves to make all the elements in a array equal in Python - 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

Related

How do I modify this Fibonacci Sequence Problem?

I am trying to figure out how I can modify the code below to help solve the question given. However, instead of only being able to take 1 or 2 steps at a time, I want to make it so I can also take 3 steps.
You have a ladder of N steps (rungs). You can go up the ladder by taking either 1 step or two steps at a time, in any combination. How many different routes are there (combinations of 1 steps or 2 steps) to make it up the ladder?
Here is some code that I'm trying to modify:
def countP(n):
if (n == 1 or n == 2):
return n
return countP(n-1) + countP(n-2)
I've already tried this so far and I am not getting the correct answer:
def countP(n):
if (n == 1 or n == 2 or n == 3):
return n
return countP(n-1) + countP(n-2) + countP(n-3)
Any help of guidance would be of great help! Thanks
Your base case in the recursion for n = 3 is wrong.
For n = 3, the correct answer should be 4, but you are returning 3.
I suggest you to simplify the base case by using the following observations:
Utmost base case is when n <= 1 i.e when we have only one stair or no stair, hence the only way to climb is taking a step of 1 unit or 0 unit. Hence, number of ways is countP(0) = 1 and countP(1) = 1.
What happens when n > 1 ? Well, we have three options to take for first step - we can take m units (1 unit, 2 units or 3 units step) as first step provided m <= n.
If we can take 1 unit step as first step, we can reduce the sub-problem from countP(n) to countP(n-1).
If we can take 2 units step as first step, we can reduce the sub-problem from countP(n) to countP(n-2).
If we can take 3 units step as first step, we can reduce the sub-problem from countP(n) to countP(n-3).
So, our final count will be : countP(n - m) for all m <= n
Code will be as follows:
def countP(n):
if (n == 0 or n == 1):
return 1
count = 0
for m in [1, 2, 3]:
if m <= n:
count += countP(n - m)
return count
The line return n is correct for the first problem but not the second. Keep in mind that the result is supposed to be the number of possible routes you can take.
If you can take either one or two steps at a time, then when you have one rung left, there is only one thing to do: take one step. If you have two rungs left, you have two options: either take two steps, or take one step (one rung), then another (the second rung). So, somewhat by coindicence, for this version of the problem the number of routes in the base case happens to equal the number of rungs left.
If you can take either one, two or three steps at a time, then the number of routes when you have three rungs remaining is not three; there are more than three options. You will have to count how many options there are, and return that in the case where n == 3.

How do I count how many times I've divided in a recursion?

I'm currently taking a course in Computer Science, I got an assignment to use either Python or pseudocode to ask the user to enter a digit, then divide it by 2, and then count how many divisions it takes to reach 1 (and add 1 more as it reaches 1). I've never coded before but I came up with this; but it only returns a 1 no matter what I input.
def divTime (t):
if d <= 1:
return t + 1
else:
return t + 1, divTime(d / 2)
d = input("Enter a number:")
t = 0
print (divTime)(t)
You can add 1 to the recursive call with the input number floor-divided by 2, until the input number becomes 1, at which point return 1:
def divTime(d):
if d == 1:
return 1
return 1 + divTime(d // 2)
so that:
print(divTime(1))
print(divTime(3))
print(divTime(9))
outputs:
1
2
4
This works:
def div_time(d, t=0):
if d < 1:
return t
else:
return div_time(d/2, t+1)
d = input("Enter a number:")
print(f"t = {div_time(int(d))}")
It always returns 1 because you're always passing it 0.
It looks like you're "thinking in loops" – you don't need a separate counter variable.
How many times does it take to divide:
k smaller than 2? None.
k greater than or equal to 2? One more than it takes to divide k // 2.
That is,
def divTime(x):
if x < 2:
return 0
return 1 + divTime(x // 2)
or
def divTime(x):
return 0 if x < 2 else 1 + divTime(x //2)
Instead of providing a straight forward answer, I'll break the problem out into a few steps for students:
Ignore the input and edge cases for now, let's focus on writing a function that solves the problem at hand, then we may come back to providing an input to this function.
Problem statement confusion - You will often divide an odd number with a remainder, skipping the exact number 1 due to remainders. There is ambiguity with your problem from dealing with remainders - we will reword the problem statement:
Write a function that returns the number of times it takes to divide an input integer to become less than or equal to 1.
The next part is identifying the type of algorithm that can solve this type of problem. Since we want to run the function an unknown amount of times using the same function, this seems to be a perfect use case of recursion.
Say I provide 10 as an input. We then want to say 10/2=5 (count 1), 5/2=2.5 (count 2), 2.5/2=1.25 (count 3), 1.25/2=0.625 (count 4), return [4] counts.
Now we know we need a counter (x = x+1), recursion, and a return/print statement.
class solution:
''' this class will print the number of times it takes to divide an integer by 2 to become less than or equal to 1 '''
def __init__(self):
#this global counter will help us keep track of how many times we divide by two. we can use it in functions inside of this class.
self.counter=0
def counter_2(self, input_integer):
#if the input number is less than or equal to 1 (our goal), then we finish by printing the counter.
if input_integer<=1:
print(self.counter, input_integer)
#if the input is greater than 1, we need to keep dividing by 2.
else:
input_integer=input_integer/2
#we divided by two, so make our counter increase by +1.
self.counter=self.counter+1
#use recursion to call our function again, using our current inputer_integer that we just divided by 2 and reassigned the value.
self.counter_2(input_integer)
s=solution()
s.counter_2(10)

loop numbers down and up and not using recursion in 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

Compress long vector consists of 0 and 1

Say I got a vector of size [1 x 300], in which each element consists of 0 or 1. I might need to store a bunch of these iteratively during the run time. How do I effectively represent it so that I can effeciently store them (python)?
I guess there are two ways to do it. The first method is to do something like a bitmap (do they even have this in python)?
The second approach
I was thinking maybe is to store the 1's position.
eg. [0, 1, 1, 1]. I will store them as [1,2,3].
Any ideas?
An alternative often used in raster filled shapes processing (where you typically have large uniform areas) is to store your data as spans, i.e. store just the length of each run of 0s or 1s (essentially, it's RLE with the item of each run implicit in the position). You can choose arbitrarily that the first value (and so, all even values) represents a run of 0s, while the second (and so, all odd values) a run of 1s. So, something like
0 0 0 0 0 1 1 0 0 0 1 1 1 1
becomes
5 2 3 4
Appending to such a structure is trivial:
def append(l, value):
cur = (len(l) + 1) % 2
if value == cur:
l[-1] += 1
else:
l.append(1)

Getting the number of digits of nonnegative integers (Python) [duplicate]

This question already has answers here:
How to find length of digits in an integer?
(31 answers)
Closed 6 years ago.
The question asks:
<< BACKGROUND STORY:
Suppose we’re designing a point-of-sale and order-tracking system for a new burger
joint. It is a small joint and it only sells 4 options for combos: Classic Single
Combo (hamburger with one patty), Classic Double With Cheese Combo (2 patties),
and Classic Triple with Cheese Combo (3 patties), Avant-Garde Quadruple with
Guacamole Combo (4 patties). We shall encode these combos as 1, 2, 3, and 4
respectively. Each meal can be biggie sized to acquire a larger box of fries and
drink. A biggie sized combo is represented by 5, 6, 7, and 8 respectively, for the
combos 1, 2, 3, and 4 respectively. >>
Write an iterative function called order_size which takes an order and returns the number of combos in the order. For example, order_size(237) -> 3.
Whereby I should have
order_size(0) = 0
order_size(6) = 1
order_size(51) = 2
order_size(682) = 3
My code is:
def order_size(order):
# Fill in your code here
if order > 0:
size = 0
while order > 0:
size += 1
order = order // 10
return size
else:
return 0
But I don't get the order // 10 portion. I'm guessing it's wrong but I can't think of any stuff to substitute that.
No need for iterative function, you can measure the length of the number by "turning" it into a string:
num = 127
order = len(str(num))
print(order) # prints 3
But if you really want to do it iteratively:
def order(num):
res = 0
while num > 0:
num = int(num / 10)
res += 1
return res
print(order(127)) # prints 3
How about this:
from math import log
def order_size(order):
if order <= 0: return 0
return int(log(order, 10) + 1)
Some samples (left column order, right column order size):
0 0
5 1
10 2
15 2
20 2
100 3
893 3
10232 5
There are a couple errors in your suggested answer.
The else statement and both return statements should be indented a level less.
Your tester questions indicate you are supposed to count the digits for nonnegative integers, not just positive ones (i.e. you algorithm must work on 0).
Here is my suggested alternative based on yours and the criteria of the task.
def order_size(order):
# Fill in your code here
if order >= 0:
size = 0
while order > 0:
size += 1
order = order // 10
return size
else:
return 0
Notice that
By using an inclusive inequality in the if condition, I am allowing 0 to enter the while loop, as I would any other nonnegative single digit number.
By pushing the first return statement back, it executes after the while loop. Thus after the order is counted in the variable size, it is returned.
By pushing the else: back, it executes in the even the if condition is not met (i.e. when the numbers passed to order_size(n) is negative).
By pushing the second return back, it is syntactically correct, and contained in the else block, as it should be.
Now that's taken care of, let me address this:
But I don't get the order // 10 portion.
As of Python 3, the // is a floor division (a.k.a integer division) binary operation.
It effectively performs a standard division, then rounds down (towards negative infinity) to the nearest integer.
Here are some examples to help you out. Pay attention to the last one especially.
10 // 2 # Returns 5 since 10/2 = 5, rounded down is 5
2 // 2 # Returns 1 since 2/2 = 1, rounded down is 1
11 // 2 # Returns 5 since 11/2 = 5.5, rounded down is 5
4 // 10 # Returns 0 since 4/10 = 0.4, rounded down is 0
(-4) // 10 # Returns -1 since (-4)/10 = -0.4, rounded down is -1
For nonnegative numerator n, n // d can be seen as the number of times d fits into n whole.
So for a number like n = 1042, n // 10 would give you how many whole times 10 fits into 1042.
This is 104 (since 1042/10 = 104.2, and rounded down we have 104).
Notice how we've effectively knocked off a digit?
Let's have a look at your while loop.
while order > 0:
size += 1
order = order // 10
Every time a digit is "knocked off" order, the size counter is incremented, thus counting how many digits you can knock off before you hit your terminating step.
Termination occurs when you knock of the final (single) digit. For example, say you reduced order to 1 (from 1042), then 1 // 10 returns 0.
So once all the digits are "knocked off" and counted, your order will have a value of 0. The while loop will then terminate, and your size counter will be returned.
Hope this helps!
Disclaimer: Perhaps this isn't what you want to hear, but many Universities consider copying code from the Internet and passing it off as your own to be plagiarism.

Categories