i need help trying to fix my logic - python

multiply_until_total_reached(original,total,n): Starting with a positive integer original, keep
multiplying original by n and calculate the sum of all multiples generated including original until the
sum is no longer smaller than total. Return the minimum number of multiplications needed to reach at
value at or above the given total.
o Assume: All three arguments are integers: original and n are positive.
o Return value: an integer.
o Examples:
multiply_until_total_reached (1,5,2) → 2
# 1*2=2, (1+2)<5, 2*2=4, (1+2+4)>5, 2 multiplications needed
multiply_until_total_reached (1,15,2) → 3
# 1*2=2, (1+2)<15, 2*2=4, (1+2+4)<15, 4*2=8, (1+2+4+8)=15, 3 multiplications
multiply_until_total_reached (1,0,2) → 0
# original 1>0, no multiplication
for the remaining test cases, im above the actual needed multiplications by 1enter image description here
def multiply_until_total_reached(original,total,n):
zum=original
add=zum
count=0
if original<total:
while add<total:
zum=zum*n
add+=(zum)
count+=1
return count
print (multiply_until_total_reached(1,10,1))
this giving me correct answers on visualizer but giving me FFFFFFF on command prompt

You have some problems with your logic. If we take the first example from your post:
# 1*2=2, (1+2)<5, 2*2=4, (1+2+4)>5, 2 multiplications needed
Firstly, You are comparing the value of add to the value of total. However, in your while-loop, you are comparing zum to total. Your condition statement for the while loop is:
while zum < total
Secondly, your logic for adding does not make sense. add is sset to zero initially, so why are you doing (1+2)<5? It should be (0+2)<5. This logic error persists elsewhere in your post.
Finally, I ran your code, and I got no infinite loop. Maybe the value that you pass to the function multiply_until_total_reached(original,total,n)
EDIT: I ran the following block of code on python 3.5.2. It worked fine.
def multiply_until_total_reached(original,total,n):
zum=original
add=0
count=0
while add<total:
zum=zum*n
add+=(zum)
count+=1
return count
print (multiply_until_total_reached(1,5,2))

Related

How do you find highest value in the list then increase it with the other values increasing as well expect a value that is set as 0

I am trying to make a python program that reads a list then raises all values one by one until they reach a specific value in this case 8 being the value I want to reach, my goal is to raise a list of 9 values varying from 0 to 8 but not raising any values in the 0 field, am sort of new to programming and have yet to find a solution I started learning python a few days ago and want to make my first program, this is what I've got so far
drawbarstring = input("Put your drawbar string here(9 digits): ")
drawbarmain = list(map(int, str(drawbarstring)))
I am clueless on what to do next any advice on this the goal of this program is to in the end when I type a 9 value string check all values and raise it until one peak at 8 but not raising any zeroes as they don't count in the use case am using, the reason am rating all the others is my script is intended to assist me making patches for drawbar organs drawbars that max volume by typing a value than having the script raise all of them until one peak at 8 value than giving me the result so I can apply it in the organ, hopefully, this enough info and can be useful in assisting me and others that might have the problem I do
example of input and output code, the value could like this 327645222 or 004544220 in the case of the 2nd we would skip the values that are 0 but in the first case we would find the highest and raise them all until the highest of the values reaches 8 then the others would be raised the same number of times, for example, an if it was 4 raises until the highest hits 8 the others would be as well, I hope this makes it clear
I think that this will do it.
drawbarstring = input("Put your drawbar string here(9 digits): ")
drawbarmain = list(map(int, str(drawbarstring)))
def compute_nums(drawbarmain):
for i in range(len(drawbarmain)):
for x in range(len(drawbarmain)):
if drawbarmain[x] == 8:
return drawbarmain
for j in range(len(drawbarmain)):
if drawbarmain[j-1] < 8 and drawbarmain[j] != 0:
drawbarmain[j] += 1
else:
break
print(compute_nums(drawbarmain))
I used a function because it is very simple to cancel a function by using "return" if a number hits 8.
Also, in the third for loop, I used [j-1] because that's the number that I changed before, and we know that j can't be 8 because of the second for loop making sure that none of the existing numbers are 8s.

My Dynamic Programming program is surprisingly adding numbers instead of solution

In the book "Introduction to Algorithms", I am trying to implement a Dynamic Programming problem which is known as "rod-cutting-program". Here I have an array defining the price of rods of variable lengths. So, array {1, 4} defines that, price of a rod with length 1 inch is 1$, and the price of a rod with length 4 is 4$ as well. I am given an input which is a length of a given rod. My goal is to cut the rod into multiple pieces so that the length of each piece remains integer and the total price of the pieces is maximized.
Here is my program
print("Input Length Prices: ")
p = [int(x) for x in input().split()]
def cut_rod(n):
if n == 0:
return 0
q = -1
for i in range(1, n+1):
q = max(q, p[i-1] + cut_rod(n-1))
return q
print("Input Length to Cut: ")
print(cut_rod(int(input())))
Here are my Input and Output.
Input
1 4
2
Output
5 (This is the sum of 1 and 4)
Expected Output
4
So instead of the maximized total price, it is giving the sum of all prices of lengths. I have tried several other inputs too. In all cases, it is giving the sum. It's very strange.
Edit: Rod can be kept uncut too.
There are two problems with your program:
#1) You need cut_rod(n-i) rather than cut_rod(n-1) in your recursive call. Once you remove a piece of length i, you have p-i remaining.
#2) You are repeatedly calling cut_rod recursively, and for large values of n, you are making O(n*n) recursive calls . The point of dynamic programming is that you calculate the value for smaller results, and then cache them rather than recalculate them every time you need them.
Fortunately, Python makes this easy. Just annotate your code with #functools.lru_cache(None)
=== Correction ===
I wrote above that this code without cacheing was O(n*n). This is actually exponential or worse. The naive recursive implementation of Fibonacci numbers is exponential, and that only makes two recursive calls for each argument n greater than 2; this program makes n - 1.

Wrong Answer python3.6

You are given a set S and Q queries. Initially, S is empty. In each query:
You are given a positive integer X.
You should insert X into S.
For each y∈S before this query such that y≠X, you should also insert y⊕X into S (⊕ denotes the XOR operation).
Then, you should find two values E and O: the number of elements of S with an even number of 1's and with an odd number of 1's in the binary representation, respectively.
I have tried splitting the problem into smaller subproblems but it seems to exceed time because of large input size and large list size. Any suggestion into the code and further optimization will be very helpful.I have mow used set but the expected output is not as same as my output. Any suggestions as where I am going wrong in the solution code..?
s=set()
def fun(n,q):
c=0
cc=0
s.add(n)
for k in range(len(list(s))):
if list(s)[k]!=n:
s.add((list(s)[k])^n)
for k in s:
if bin(k)[2::].count('1')%2==0:
c+=1
else:
cc+=1
print(c,cc)
for _ in range(int(input())):
q=int(input())
for j in range(q):
n=int(input())
fun(n,q)
Example Input:
1
3
4
2
7
Example Output:
0 1
1 2
3 4
The first thing i see wrong on your code is that S should be a set of numbers. A list can have duplicates, so you need to work with sets
And to optimize your script, you can start by improving how you count the amount of enabled bits in your number expressed in binary. Such count is called the hamming weight of a string.
Search it on the web. For instance you have this article
I think you are inserting duplicate value in your List. fix it you will be good to go.
Solution And Reference :- https://whitefox-89ea6.firebaseapp.com/

Coin tossing simulation unexpected probabilities

This is a script I wrote to simulate a coin toss game that ends in a given fixed sequence of outcomes (tosses are either ones or zeroes). This fixed sequence characterizes the game. For example, coin_series('01') simulates a series of tosses that culminate in a 0 followed by a 1; valid outcomes are x01 where x is a string of zeroes and ones not containing the pattern 01 anywhere.
The script gives the number of throws required to terminate two games, 01 and 11, and these should have the same result since the coin is not a biased one (equal chance of outcome zero or outcome one on a toss).
Yet this is not the case, with my output being 6 and 4 respectively, of which only the first is correct. So I must have a bug in the script.
My questions are: how can I make the script a little more concise, as I hope this will help find the bug; and second, is there a bug that is apparent to all but me?
import numpy as np
class coin_series(object):
def __init__(self,win_state): #win_state is a string of ones and zeroes
self.win_state=win_state
self.d=self.draw()
self.series=[self.d.next() for i in range(len(self.win_state))]
self.n=len(self.win_state)
while not self.check():
self.play()
def draw(self):
while True:
t=np.random.rand()
if t>=0.5:
yield 1
else:
yield 0
def check(self):
return(self.win_state==''.join(map(str,self.series)))
def play(self):
self.series=self.series[1:]+[self.d.next()]
self.n+=1
if __name__=='__main__':
print np.mean([coin_series('11').n for i in range(100000)])
print np.mean([coin_series('01').n for i in range(100000)])
This is no bug, your code works just fine!
As you toss the coins, if you are aiming for a 0 then a 1 and you make the 0 but the 1 ends up being another 0, then you are still already halfway there, you are just hoping for a 1 again.
On the other hand, if you are aiming for a 1 and then a 1 and make the 1, then if you don't make the second 1, you are now on a 0 and back to waiting for a first 1.
So to reword that a different way, in the first case, if you fail, you only get reset halfway, but in the second case, if you fail then you are back to the start again - thus increasing the average number of throws to get them.
Take a look at this redit post for another explanation.
No bug. You would need to be generating separate pairs of flips for those values to be equal. If you generate a continuous sequence of flips and look at overlapping pairs, 11 takes longer to come up on average than 01.

Singpath Python Error. "Your code took too long to return."

I was playing around with the Singpath Python practice questions. And came across a simple question which asks the following:
Given an input of a list of numbers and a high number,
return the number of multiples
of each of those numbers that are less than the maximum number.
For this case the list will contain a maximum of 3 numbers
that are all relatively prime to each other.
I wrote this simple program, it ran perfectly fine:
"""
Given an input of a list of numbers and a high number,
return the number of multiples
of each of those numbers that are less than the maximum number.
For this case the list will contain a maximum of 3 numbers
that are all relatively prime to each other.
>>> countMultiples([3],30)
9
>>> countMultiples([3,5],100)
46
>>> countMultiples([3,5,7],30)
16
"""
def countMultiples(l, max):
j = []
for num in l:
i = 1
count = 0
while num * i < max:
if num * i not in j:
j.append(num * i)
i += 1
return len(j)
print countMultiples([3],30)
print countMultiples([3,5],100)
print countMultiples([3, 5, 7],30)
But when I try to run the same on SingPath, it gave me this error
Your code took too long to return.
Your solution may be stuck in an infinite loop. Please try again.
Has anyone experienced the same issues with Singpath?
I suspect the error you're getting means exactly what it says. For some input that the test program gives your function, it takes too long to return. I don't know anything about singpath myself, so I don't know exactly how long that might be. But I'd guess that they give you enough time to solve the problem if you use the best algorithm.
You can see for yourself that your code is slow if you pass in a very large max value. Try passing 10000 as max and you may end up waiting for a minute or two to get a result.
There are a couple of reasons your code is slow in these situations. The first is that you have a list of every multiple that you've found so far, and you are searching the list to see if the latest value has already been seen. Each search takes time proportional to the length of the list, so for the whole run of the function, it takes quadratic time (relative to the result value).
You could improve on this quite a lot by using a set instead of a list. You can test if an object is in a set in (amortized) constant time. But if j is a set, you don't actually need to test if a value is already in it before adding, since sets ignore duplicated values anyway. This means you can just add a value to the set without any care about whether it was there already.
def countMultiples(l, max):
j = set() # use a set object, rather than a list
for num in l:
i = 1
count = 0
while num * i < max:
j.add(num*i) # add items to the set unconditionally
i += 1
return len(j) # duplicate values are ignored, and won't be counted
This runs a fair amount faster than the original code, and max values of a million or more will return in a not too unreasonable time. But if you try values larger still (say, 100 million or a billion), you'll eventually still run into trouble. That's because your code uses a loop to find all the multiples, which takes linear time (relative to the result value). Fortunately, there is a better algorithm.
(If you want to figure out the better approach on your own, you might want to stop reading here.)
The better way is to use division to find how many times you can multiply each value to get a value less than max. The number of multiples of num that are strictly less than max is (max-1) // num (the -1 is because we don't want to count max itself). Integer division is much faster than doing a loop!
There is an added complexity though. If you divide to find the number of multiples, you don't actually have the multiples themselves to put in a set like we were doing above. This means that any integer that is a multiple of more than than one of our input numbers will be counted more than once.
Fortunately, there's a good way to fix this. We just need to count how many integers were over counted, and subtract that from our total. When we have two input values, we'll have double counted every integer that is a multiple of their least common multiple (which, since we're guaranteed that they're relatively prime, means their product).
If we have three values, We can do the same subtraction for each pair of numbers. But that won't be exactly right either. The integers that are multiples of all three of our input numbers will be counted three times, then subtracted back out three times as well (since they're multiples of the LCM of each pair of values). So we need to add a final value to make sure those multiples of all three values are included in the final sum exactly once.
import itertools
def countMultiples(numbers, max):
count = 0
for i, num in enumerate(numbers):
count += (max-1) // num # count multiples of num that are less than max
for a, b in itertools.combinations(numbers, 2):
count -= (max-1) // (a*b) # remove double counted numbers
if len(numbers) == 3:
a, b, c = numbers
count += (max-1) // (a*b*c) # add the vals that were removed too many times
return count
This should run in something like constant time for any value of max.
Now, that's probably as efficient as you need to be for the problem you're given (which will always have no more than three values). But if you wanted a solution that would work for more input values, you can write a general version. It uses the same algorithm as the previous version, and uses itertools.combinations a lot more to get different numbers of input values at a time. The number of products of the LCM of odd numbers of values get added to the count, while the number of products of the LCM of even numbers of values are subtracted.
import itertools
from functools import reduce
from operator import mul
def lcm(nums):
return reduce(mul, nums) # this is only correct if nums are all relatively prime
def countMultiples(numbers, max):
count = 0
for n in range(len(numbers)):
for nums in itertools.combinations(numbers, n+1):
count += (-1)**n * (max-1) // lcm(nums)
return count
Here's an example output of this version, which is was computed very quickly:
>>> countMultiples([2,3,5,7,11,13,17], 100000000000000)
81947464300342

Categories