I am currently passing the sample tests and 2 of the other 10 cases so 4 out of 12. However, I don't make it through all of the data. I am getting a Terminated due to timeout error which means that my solution isn't fast enough.
def stockmax(prices):
total = 0
for index, price in enumerate(prices):
if index < len(prices) - 1:
section = max(prices[index+1:])
if prices[index] < section:
total += section - prices[index]
return total
I tried to do everything in only one loop. But how exactly can speed this type of question up. I also tried to cut some lines of the code but it is equally as inefficient.
def stockmax(prices):
total = 0
for index, price in enumerate(prices):
if index < len(prices) - 1 and prices[index] < max(prices[index+1:]):
total += max(prices[index+1:]) - prices[index]
return total
Though it passes the same amount of test cases.
I also tried to use heapq but it passes the same test cases and fails due to time.
def stockmax(prices):
total = 0
for index, price in enumerate(prices):
if index < len(prices) - 1:
section = heapq.nlargest(1,prices[index+1:])[0]
if prices[index] < section:
total += section - prices[index]
return total
https://www.hackerrank.com/challenges/stockmax/topics/dynamic-programming-basics
for details on the problem.
https://hr-testcases-us-east-1.s3.amazonaws.com/330/input09.txt?AWSAccessKeyId=AKIAJ4WZFDFQTZRGO3QA&Expires=1538902058&Signature=3%2FnfZzPO8XKRNyGG0Yu9qJIptgk%3D&response-content-type=text%2Fplain
for a link of some test cases but will expire after a while.
Problem
Your algorithms have become so good at predicting the market that you now know what the share price of Wooden Orange Toothpicks Inc. (WOT) will be for the next number of days.
Each day, you can either buy one share of WOT, sell any number of shares of WOT that you own, or not make any transaction at all. What is the maximum profit you can obtain with an optimum trading strategy?
For example, if you know that prices for the next two days are prices = [1,2], you should buy one share day one, and sell it day two for a profit of 1. If they are instead prices = [2,1], no profit can be made so you don't buy or sell stock those days.
Function Description
Complete the stockmax function in the editor below. It must return an integer that represents the maximum profit achievable.
stockmax has the following parameter(s):
prices: an array of integers that represent predicted daily stock prices
Input Format
The first line contains the number of test cases t.
Each of the next t pairs of lines contain:
The first line contains an integer n, the number of predicted prices for WOT.
The next line contains n space-separated integers prices [i], each a predicted stock price for day i.
Constraints
1 <= t <= 10
1 <= n <= 50000
1 <= prices [i] <= 100000
Output Format
Output lines, each containing the maximum profit which can be obtained for the corresponding test case.
Sample Input
3
3
5 3 2
3
1 2 100
4
1 3 1 2
Sample Output
0
197
3
Explanation
For the first case, you cannot obtain any profit because the share price never rises.
For the second case, you can buy one share on the first two days and sell both of them on the third day.
For the third case, you can buy one share on day 1, sell one on day 2, buy one share on day 3, and sell one share on day 4.
Clearly, for any price we can buy, we would want to sell it at the highest price. Fortunately, we are given that highest price. So, iterating backwards, we know the highest future price seen at any point we visit in our travel "back in time."
Python code:
def stockmax(prices):
n = len(prices)
highest = prices[n - 1]
m = [0] * n
# Travel back in time,
# deciding whether to buy or not
for i in xrange(n - 2, -1, -1):
# The most profit buying stock at this point
# is what we may have made the next day
# (which is stored in m[i + 1])
# and what we could make if we bought today
m[i] = m[i + 1] + max(
# buy
highest - prices[i],
# don't buy
0
)
# Update the highest "future price"
highest = max(highest, prices[i])
return m[0]
If you can use Numpy, then something similar to the below should be rather quick (I believe it's the same idea as the answer from #גלעד ברקן).
import numpy as np
with open('.../input09.txt') as fd:
numtests = int(fd.readline().strip())
counter = 0
numvals = 0
vals = None
steps = None
for line in fd:
if (counter % 2 == 0) :
numvals = int(line.strip())
else:
vals = np.fromstring(line, dtype=int, sep=' ', count=numvals)
assert len(vals) == numvals
cum_max = np.maximum.accumulate(vals[::-1])
np.roll(cum_max, -1)
cum_max[len(cum_max) - 1] = 0
delta = (cum_max - vals)
print('#', counter + 1, 'sum:', np.sum(delta * (delta > 0)))
counter += 1
it runs almost instantly on tests from the input09.txt.
Here is my solution written in ruby.
The solution obtained perfect score.
def solution(a)
gain = 0
i = a.count - 1
min = false
mi = false
while i > 0
s = a.delete_at(i)
unless min
mi = a.index(a.min)
min = a[mi]
end
g = s - min
gain = g if g > gain
i -= 1
min = false if i == mi
end
gain
end
Enter 10 for first input
enter 500 for second input
enter 20 for third input
I was wondering if there is a way where I can get the maximum profit and show it without the user having to go through and read every single line?
MP=abs(int(input("Enter the minimum number of passengers:")))
print(MP)
max_passengers=int(input("Enter the maximum number of passengers:"))
while(max_passengers <= MP):
print("\n")
max_passengers=int(input("You must enter a number that is greater than the minimum ammount of passengers:"))
print(max_passengers)
TP=float(input("Enter the ticket price"))
print(TP)
increment=10
fixed_cost=2500
print("\n")
for numberpass in range(MP,max_passengers+10,increment):
discount=.5
ticketcost = TP - (((numberpass - MP) /10) * discount)
gross=numberpass*ticketcost
profit=gross-fixed_cost
print(numberpass,"\t",ticketcost,"\t",gross,"\t",fixed_cost,
"\t",profit)
Save every profit in a list, then take the maximum value of that list:
# rest of you code above...
profits = [] # create the list to store the every profit
for numberpass in range(MP,max_passengers+10,increment):
discount=.5
ticketcost = TP - (((numberpass - MP) /10) * discount)
gross=numberpass*ticketcost
profit=gross-fixed_cost
print(numberpass,"\t",ticketcost,"\t",gross,"\t",fixed_cost,"\t",profit)
profits.append(profit) # store each profit
max_profit = max(profits)
print("Maximum profit: {}".format(max_profit))
I'm trying to produce a program that will check the highest sum value of a 2D array.Then it needs to compare each value against each other to output which is the largest of all the sums for each position in the array.
I'm able to do this for a set number of elements but i would like to do this for an unlimited number of elements depending on how many elements the user inputs.
Person = [123,321,213]
TotalMorn =[[3,5,6,4,5,3,7],
[2,1,1,2,3,4,5],
[3,4,5,6,7,6,5]]
TotalAft =[[8,7,6,2,6,7,5],
[4,3,2,3,4,3,2],
[1,1,1,1,2,3,1]]
def WeeklyTotal(K):
Total = 0
for j in range(7):
TotalM = TotalMorn[K][j]
TotslA = TotalAft[K][j]
Total = TotalM + TotalA + Total
return Total
Total1 = WeeklyTotal(0)
Total2 = WeeklyTotal(1)
Total3 = WeeklyTotal(2)
if Total1 > Total2 and Total1 > Total3:
print 'Person', (Person[0]), 'Has produced the most profit with ', Total1
elif Total2 > Total1 and Total2 > Total3:
print 'Peron', (Person[1]), 'Has produced the most profit with ', Total2
elif Total3 > Total1 and Total3 > Total2:
print 'Person', (Person[2]), 'Has produced the most profit with ', Total3
I assume what you want to do is find the max value in the array WeeklyTotal?
maxIndex, maxValue = 0,0
for i in range(0,len(WeeklyTotal)-1):
if WeeklyTotal[i] > maxValue :
maxValue = WeeklyTotal[i]
maxIndex = i
print 'Person ',Person[maxIndex],' Has produced the most profit with ',WeeklyTotal[maxIndex]
In your case, you either need to bind person to his totalScore. You would then look for the maximum score value, and so you would have the person with the maximum score affiliated with this value, such as...
arr = [('John', 15), ('Sue', 13), ('Jack', 20), ('Tom', 5)]
print max(arr, key = lambda x:x[1])
# outputs : ('Jack', 20)
Here, you have bound the score to the person into a list of tuples. You asking max function to look for the highest value using the second element of each tuple (that's what key = lambda x:x[1] means).
In your example, where data would be formatted such as...
people = ['John', 'Sue', 'Jack', 'Tom']
scores = [15, 13, 20, 5]
... you might want to use a function to determine the index of the highest value, doing :
# We set the highest score at the beginning as the first value, and save the index.
curr_score = scores[0]
saved_index = 0
# We then iterate through scores, not looping through the first item, as its index
# is already saved. We set the start of the index to `1`.
for index, score in enumerate(scores[1:], start=1):
if score > curr_score:
# We save the new highest score.
curr_score = score
# And keep its index.
saved_index = index
# At the end of the loop, we saved the maximum value index, and can use it
# on `people` array.
print people[saved_index]
# It will output the person with the highest score.
Here is a short solution using some python idioms:
(Thanks to IMCoins for reminding me about max(a, key = lambda...)
people = [123,321,213]
morning =[[3,5,6,4,5,3,7],
[2,1,1,2,3,4,5],
[3,4,5,6,7,6,5]]
afternoon =[[8,7,6,2,6,7,5],
[4,3,2,3,4,3,2],
[1,1,1,1,2,3,1]]
def makeTotals(people, morning, afternoon):
return [(p,sum(m+a)) for (p,m,a) in zip(people, morning, afternoon)]
allTotals = makeTotals(people, morning, afternoon)
print(max(allTotals, key = lambda x:x[1]))
Output:
(123, 74)
The makeTotals function zips up the arrays to align each person with their morning and afternoon scores and (p,sum(m+a)) creates a tuple of the person and their total.
The call to max uses the key = lambda x:x[1] parameter (thanks #IMCoins) to pull out the tuple with the largest sum of morning and afternoon scores.
how about a 'one-liner' (with line breaks and added whitespace for readability)
Person = [123,321,213]
TotalMorn =[[3,5,6,4,5,3,7],
[2,1,1,2,3,4,5],
[3,4,5,6,7,6,5]]
TotalAft =[[8,7,6,2,6,7,5],
[4,3,2,3,4,3,2],
[1,1,1,1,2,3,1]]
print('Person %s Has produced the most profit with %s'
% max(zip(map(sum,
zip(map(sum, TotalMorn),
map(sum, TotalAft))),
Person))[::-1])
Person 123 Has produced the most profit with 74
I have the following program to calculate the percentage of CO2 every year.
I get an error, "list index out of range", once the entire program runs on the following line:
m= co2level[i+1][1]
Code:
# Program to calculate percentage of CO2 every year
co2level = [(2001,320.93),(2003,322.16),(2004,328.07),
(2006,323.91),(2008,341.47),(2009,348.22)]
i = 0
while i!=len(co2level):
m= co2level[i+1][1] # I am getting error here as list index out of range
n= co2level[i][1]
percentage=((m-n)/n)*100
print " Change in percentage of CO2 in year %r is"%co2level[i][0],percentage
i+=1
You could avoid the bounds error like this:
co2level = [(2001,320.93),(2003,322.16),(2004,328.07),
(2006,323.91),(2008,341.47),(2009,348.22)]
i = 1
while i != len(co2level):
old = co2level[i-1][1]
act = co2level[i][1]
percentage=((act-old)/old)*100
print (" Change in percentage of CO2 in year %r is " %co2level[i][0],percentage)
i+=1
You start with the 1st year you can get a "delta" for and inspect the one before this. You compare act to old so you are not going over the bound.
Python is 0 indexed; that means for a list with n elements, the first element of a list is at index 0 and the last element is at index n - 1
Consider the following snippent from your code:
while i!=len(co2level):
m= co2level[i+1][1]
The line m = co2level[i+1][1] implies that you start iterating from the element at index 1 (2003,322.16) and tries to get the item at index 6 at the end which causes the error. Morover you have an error in how you assigned m and n. To correct this you can do:
i = 0
while i!=len(co2level):
m= co2level[i][0] # I am getting error here as list index out of range
n= co2level[i][1]
percentage=((m-n)/n)*100
print" Change in percentage of CO2 in year %r is"%co2level[i][0],percentage
i+=1
The more pythonic way (using for loops) will be
for i in co2level:
m = i[0]
n = i[1]
percentage=((m-n)/n)*100
print" Change in percentage of CO2 in year %r is"%co2level[i][0],percentage
better still:
for i in co2level:
m, n = i
percentage=((m-n)/n)*100
print" Change in percentage of CO2 in year %r is"%co2level[i][0],percentage