How can I use a while loop in python to add values in a list until they exceed a maximum value? - python-3.x

I am learning python V3 and have the following problem on a homework assignment:
In this exercise, your function will receive a list of numbers, and an integer. It will add the values in the list to a total as long as the total is less than or equal to the value of the second parameter. The sum of numbers in the list will always be larger than the second parameter's value.
I came up with the following solution:
def while11(nums,maxi):
i=0
total=0
while total<=maxi:
total+=nums[i]
return total
The test parameters are as follows:
[1,1,1,1,1,1,1,1,1], 6
[2,2,2,2,2,2,2,2,2], 6
range(10, 1, -1), 25
The my function returns 7 and 8, respectively, for the first two sets of parameters. However, it should return 27 for the third set, but it returns 30. It appears to be adding 11,10, and 9 as opposed to 10,9, and 8.

You need to increment i when you are performing your calculation.
def while11(nums,maxi):
i=0
total=0
while total<=maxi:
total+=nums[i]
i+=1
return total
Your function is simply taking the first value in a list and adding it until it is greater than the max value. You probably didn't notice this because in your first two cases, all values are the same. In your third case however, you have a list consisting of [10, 9, 8, 7, 6, 5, 4, 3, 2]. This should be taking 10 + 9 + 8 + 7... etc. until the max value, but your function is taking 10 + 10 + 10 + 10 .... etc. until the max value.

You need to change the value of i in your while loop:
def while11(nums,maxi):
i = 0
total = 0
while total <= maxi:
total += nums[i]
i += 1
return total
Otherwise it will always add the first value to total

You have forgotten to update the i variable on every iteration.
You keep adding the num[0] element

Related

What are handy Haskell concepts to generate numbers of the form 2^m*3^n*5^l [duplicate]

This question already has answers here:
New state of the art in unlimited generation of Hamming sequence
(3 answers)
Closed 10 months ago.
I am trying generate numbers of the form 2^m*3^n*5^l where m, n, and l are natural numbers including 0.
The sequence follows: 1, 2, 3, 4, 5, 6, 8, 9, 10, 12, 15, 16, 18, 20, 24, 25, 27, 30, 32, .....
I am testing it by getting the one millionth number. I implemented it using list comprehension and sorting, but it takes too long. I want a faster solution. I have been spending days trying to do this to no avail.
I do not want a complete solution. I just want to know what Haskell concepts are necessary in accomplishing it.
Here's an approach that doesn't need any Haskell concepts, just some math and computer science.
Grab a library that offers priority queues.
Initialize a priority queue containing only the number 1.
Loop the following indefinitely: extract the minimum value from the queue. Put it next in the output list. Insert that number times 2, 3, and 5 as three individual entries in the queue. Make sure the queue insert function merges duplicates, because there will be a lot of them thanks to commutativity of multiplication.
If you have a maximum you're working up to, you can use it to prune insertions to the queue as a minor optimization. Alternatively, you could take advantage of actual Haskell properties and just return an infinite list using laziness.
First, write a function of type Int -> Bool that dermines if a given integer is in the sequence you defined. It would divide the number by 2 as many times as possible (without creating a fraction), then divide it by 3 as many times as possible, and finally divide it by 5 as many times as possible. After all of this, if the number is larger than 1, then it cannot be expressed as a products of twos, threes, and fives, so the function would return false. Otherwise, the number is in your sequence, so the function returns true.
Then take the infinite sequence of integers greater than 0, and use the function above to filter out all numbers that are not in the sequence.
Carl's approach can be improved by inserting less elements when removing the minimal element x: As 2<3<4<5<6 you can just
append 3*x/2 if x is even but not divisible by 4
append 4*x/3 if x is divisible by 3
append 5*x/4 if x is divisible by 4
append 6*x/5 if x is divisible by 5
In code it looks like this:
g2 x | mod x 4 == 0 = [5*div x 4]
| even x = [3*div x 2]
| otherwise = []
g3 x | mod x 3 == 0 = [4*div x 3]
| otherwise = []
g5 x | mod x 5 == 0 = [6*div x 5]
| otherwise = []
g x = concatMap ($ x) [g2, g3, g5]
So you if your remove the minimal element x from the priority queue, you have to insert the elements of g x into the priority queue. On my laptop I get the millionth element after about 8 min, even if I use just a list instead of the better priority queue, as the list grows only to a bit more than 10000 elements.

Alternate between printing two series of numbers

Input format: The first line of input consists of the number of test cases, T
Next T lines consist of the value of N.
Constraints: 1<= T <=100, 1<= N <= 250
Output format: For each test case, print the space-separated N terms of the series in a separate line.
Sample test case 1
Input:
1
7
Output:
1 1 2 2 4 2 6
The series is a combination of 2 series, the 1st series: 1,2,4,6,... and the 2nd series: 1,2,2,.... I have made the code for the first series but cannot find how to code the 2nd one.
Code for the first series appended into list depending on the no of elements
def firstS:
l=[1]
i=1
x=math.ceil(7/2)
while(x!=0):
l.append(i+i)
i+=1
x-=1
return l
The problem is the no of elements, for 7 elements the 1st series has 4 and 2nd series has 3 elements, for 8 elements 1st has 4 and 2nd has 4 elements and for 9 elements 1st has 5 and 2nd has 4 elements so the no of elements will be for series 1 math.ceil(n/2) and for series 2 math.floor(n/2) where n is total elements of the combined series.
For iteration, one way do something every N iterations is to use the modulus operator (%). Modulus is basically a remainder operator, so the result periodically repeats as numbers are iterated one-by-one.
Also, in Python, the standard method for doing a for-loop (iterating a certain number of times) is using range.
Here's an example demonstrating both, where every third number has the same number of exclamation marks:
# List the numbers 0-9 (repeat ten times)
for i in range(0, 10):
if i % 3 == 0:
print(i, "!")
elif i % 3 == 1:
print(i, "!!")
else:
print(i, "!!!")
Result:
0 !
1 !!
2 !!!
3 !
4 !!
5 !!!
6 !
7 !!
8 !!!
9 !
I'll leave it as an exercise for the asker to determine how to apply this to their use-case of switching between printing two different sequences.

How Do I Minus A Total From It's Next Highest Multiple Of 10

So I have a total, say 24, I need my code to find the nearest hightest multiple of 10. This would be 30 of course, so I need the code to calculate (30-24). If the number is 20 it would be 20 beucase it is equal to a highest muliple of 10. I then need to store the result for later use.
>>> def nh(val):
... return 9 - ((val + 9) % 10)
...
>>> nh(24)
6
>>> nh(20)
0

Dynamic Programming : Why the 1?

The following pseudocode finds the smallest number of coins needed to sum upto S using DP. Vj is the value of coin and min represents m as described in the following line.
For each coin j, Vj≤i, look at the minimum number of coins found for the i-Vjsum (we have already found it previously). Let this number be m. If m+1 is less than the minimum number of coins already found for current sum i, then we write the new result for it.
1 Set Min[i] equal to Infinity for all of i
2 Min[0]=0
3
4 For i = 1 to S
5 For j = 0 to N - 1
6 If (Vj<=i AND Min[i-Vj]+1<Min[i])
7 Then Min[i]=Min[i-Vj]+1
8
9 Output Min[S]
Can someone explain the significance of the "+1 " in line 6? Thanks
The +1 is because you need one extra coin. So for example, if you have:
Vj = 5
Min[17] = 4
And you want to know the number of coins it will take to get 22, then the answer isn't 4, but 5. It takes 4 coins to get to 17 (according to the previously calculated result Min[17]=4), and an additional one coin (of value Vj = 5) to get to 22.
EDIT
As requested, an overview explanation of the algorithm.
To start, imagine that somebody told you you had access to coins of value 5, 7 and 17, and needed to find the size of the smallest combination of coins which added to 1000. You could probably work out an approach to doing this, but it's certainly not trivial.
So now let's say in addition to the above, you're also given a list of all the values below 1000, and the smallest number of coins it takes to get those values. What would your approach be now?
Well, you only have coins of value 5, 7, and 23. So go back one step- the only options you have are a combination which adds to 995 + an extra 5-value coin, a combination which adds to 993 + an extra 7-value, or a combination up to 977 + an extra 23-value.
So let's say the list has this:
...
977: 53 coins
...
993: 50 coins
...
995: 54 coins
(Those examples were off the top of my head, I'm sure they're not right, and probably don't make sense, but assume they're correct for now).
So from there, you can see pretty easily that the lowest number of coins it will take to get 1000 is 51 coins, which you do by taking the same combination as the one in the list which got 993, then adding a single extra 7-coin.
This is, more or less, what your algorithm does- except instead of aiming just to calculate the number for 1000, it's aim would be to calculate every number up to 1000. And instead of being passed the list for lower numbers in from somewhere external, it would keep track of the values it had already calculated.

find the longest increasing subsequence (LIS)

Given A= {1,4,2,9,7,5,8,2}, find the LIS. Show the filled dynamic programming table and how the solution is found.
My book doesnt cover LIS so im a bit lost on how to start. For the DP table, ive done something similar with Longest Common Subsequences. Any help on how to start this would be much appreciated.
Already plenty of answers on this topic but here's my walkthrough, I view this site as a repository of answers for future posterity and this is just to provide additional insight when I worked through it myself.
The longest Increasing Subsequence (LIS) problem is to find the length of the longest subsequence of a given sequence such that all elements of the
subsequence are sorted in increasing order. For example, length of LIS for
{ 10, 22, 9, 33, 21, 50, 41, 60, 80 } is 6 and LIS is {10, 22, 33, 50, 60, 80}.
Let S[pos] be defined as the smallest integer that ends an increasing sequence of length pos.
Now iterate through every integer X of the input set and do the following:
If X > last element in S, then append X to the end of S. This essentialy means we have found a new largest LIS.
Otherwise find the smallest element in S, which is >= than X, and change it to X. Because S is sorted at any time, the element can be found
using binary search in log(N).
Total runtime - N integers and a binary search for each of them - N * log(N) = O(N log N)
Now let's do a real example:
Set of integers: 2 6 3 4 1 2 9 5 8
Steps:
0. S = {} - Initialize S to the empty set
1. S = {2} - New largest LIS
2. S = {2, 6} - 6 > 2 so append that to S
3. S = {2, 3} - 6 is the smallest element > 3 so replace 6 with 3
4. S = {2, 3, 4} - 4 > 3 so append that to s
5. S = {1, 3, 4} - 2 is the smallest element > 1 so replace 2 with 1
6. S = {1, 2, 4} - 3 is the smallest element > 2 so replace 3 with 2
7. S = {1, 2, 4, 9} - 9 > 4 so append that to S
8. S = {1, 2, 4, 5} - 9 is the smallest element > 5 replace 9 with 5
9. S = {1, 2, 4, 5, 8} - 8 > 5 so append that to S
So the length of the LIS is 5 (the size of S).
Let's take some other sequences to see that this will cover all possible caveats, each presents its own issue
say we have 1,2,3,4,9,2,3,4,5,6,7,8,10
basically it builds out 12349 first, then 2 will replace 3, 3 will replace 4, 4 will replace 9, then append 5,6,7,8,10
so will look like 1,2,2,3,4,6,7,8,10
take the other case we have 1,2,3,4,5,9,2,10
this will give us 1,2,2,4,5,9,10
or take the case we have 1,2,3,4,5,9,6,7,8,10
this will give us 1,2,3,4,5,7,8,10
so that kind of illuminates what goes on, in the first case the critical juncture being what happens when you hit the 2 after the 9,
how do you deal with these. well the block of 2,3,4 won't do anything really, when you hit 5 you replace the 9 because the 5 and 9
are virtually indifferentiable 9 ends the block of the first 5 increasing elements, you replace 9 with 5 because 5 is smaller so there
is greater potential to hit something > 5 later on. but you only replace the smallest element > itself. for ex. in the last case,
if your 6 doesn't replace 9 but instead replaces 1 and 7 replaces 2 and 8 replaces 3, then we get a final array of 7 elements instead
of 9. So just do a couple of these and figure out the pattern, this logic isn't the easiest to translate to paper.
There's a very strong relation between LIS and LCS.
http://en.wikipedia.org/wiki/Longest_increasing_subsequence
This article explains it pretty well I think. Basically the idea is, you can reduce one problem to the other (this is the case in many situations involving Dynamic programming).

Resources