Hello guys! There is a population of say, 120 million, which increases by 8% every year. I want to have a DO loop starting from 1990 to 2020 to state the year the population exceeds 125 million. Pseudocode or Fortran code will be appreciated.
This is not a problem for which loops are either necessary or appropriate. The simple equation
num_years = log(125.0/120.0)/log(1.08)
(which evaluates to approximately 0.53) is all that is necessary. This is a straightforward rewriting of the formula for compound interest calculations, that is
compound_amt = initial_amt * (1+interest_rate)**num_years
with, in this case, initial_amt = 120*10**6, compound_amt = 125*10**6 and interest_rate = 8%.
Its easy to find tutorials for loops in Fortran that solves your problems. See here for example. But generally, you want something like this:
sum=120e6
startyear=1990
do i = 1,30
sum = sum + sum*8./100.
if sum > 125e6 then
write(*,*), "Year ", i+startyear, " population exceeded ", sum
end if
end do
population = 120000.0
year = 1990
loop:
population = population + (population * 0.08)
year = year + 1
if (population > 125000.0) go to print_done
if (year > 2020) go to print_not_found
go to loop
print_done:
print "The population was " population " in the year " year
stop
print_not_found:
print "Searched to year " year " and the population only reached " population
stop
Note that there's an issue as to whether the year should be incremented before or after the population is checked. This depends on whether you want the population at the beginning of the year or the end of the year (assuming the initial value was at the beginning of the year).
Related
Given the problem to calculate the next year that has no duplicated digits on it. I created this code:
import math
# Time complexity:
# Space complexity:
def solve(year):
""" Method to identify the closest year without repeating two digits on it."""
year_str = str(year)
if year_str[3] == year_str[0] or year_str[3] == year_str[1] or year_str[3] == year_str[2]:
year = year + 1
return solve(year)
if year_str[2] == year_str[0] or year_str[2] == year_str[1]:
year = (math.floor(year/10)+1)*10
return solve(year)
if year_str[1] == year_str[0]:
year = (math.floor(year/100)+1)*100
return solve(year)
return year
y = int(input())
print(solve(y+1))
Not sure if this is the more optimal solution, but I would like to define the time complexity of this solution.
However, I am not sure how to do it in this case.
According to my tests, when it has to process the year 2222 for example, it calls the function "solve" 4 times.
But in cases near the change of decade and century, e.g. 1987 (with result 2013), it calls the function "solve" 8 times.
Does anybody have any idea?
I was asked the following question in a job interview:
Given a graduated income tax system as follows:
Up to 10000 is taxed at 10%
10001 to 50000 is taxed at 20%
50001 and above is taxed at 30%
Write a program to calculate the taxes on a given income.
Example:
Taxes on 15000 would be (20% of 5000 + 10% of 10000) = 2000
Taxes on 60000 would be (30% of 10000 + 20% of 40000 + 10% of 10000) =
12000
I came up with the following pseudocode:
list = (
(1, 10000, 0.1)
(10001, 50000, 0.2)
(50001, infinity, 0.3)
)
taxableIncome = income
taxes = 0
while taxableIncome > 0
find e in list such that taxableIncome is in range [e[1], e[2]]
taxes += taxableIncome - e[1] + 1
taxableIncome = e[1] - 1
return taxes
The above works, but takes quadratic time in the worst case in the number of items in the list. Consider the case for income = 60000; the code loops 3 times, each time potentially scanning through the whole list.
Is there a faster way to find out which range the income falls into? This question has some Python solutions, but I'm interested in a generic algorithmic solution, not a library.
Precalculate tax value for the start of each range and include this value in list.
Also I removed excessive upper limit as Dillon Davis noticed in comments and changed lower value to the end of previous range to make formula more exact
list = (
(0, 0, 0.1)
(10000, 1000, 0.2)
(50000, 9000, 0.3)
)
For given income find appropriate range with linear search (if number of ranges is small) or with binary search (if there is a lot of ranges - dozens, hundreds etc)
Then just calculate tax with simple formula
tax = e[2] + (income - e[1]) * e[3]
For income 15000 we can find
range = 2nd interval (10000, 1000, 0.2)
tax = 1000 + (15000 - 10000) * 0.2 =
1000 + 5000 * 0.2 = 2000
Or (using Dillon Davis suggestion)
tax = income * e[3] + (e[2] - e[1]) * e[3])
tax = income * e[3] + e[2]'
with precalculated e2' = (e[2] - e[1]) * e[3]) value for every range
Overall complexity is linear or logarithmic (with BS)
OP here: #MBo's answer got me thinking (upvoted him for that), but unfortunately, he didn't explain it in a manner that was lucid enough for me, so here we go.
Let N be the number of brackets.
NAIVE APPROACH: Linear search for the appropriate tax bracket, compute tax on the excess income in the bracket, and then recursively compute the taxes on the taxable income below the bracket. For example, income 15000 falls in the bracket that starts at 10001; the taxes for this bracket is (15000 - 10000) * 0.2 = 1000 + taxes on 10000.
This works, but linear search may take O(N) in the worst case, and if the initial income falls in the highest
bracket, the code would loop N times. We end up with a O(N^2) algorithm.
BETTER APPROACH: Binary search for the bracket, and then proceed as in the naive approach. O(N log(N)).
DYNAMIC PROGRAMMING APPROACH: This problem exhibits both of the two criteria for applying dynamic programming,
optimal substructure, and overlapping subproblems. Why? The total taxes for each bracket is the sum of the taxes for the current bracket, and the taxes for the remaining taxable income. For each bracket, the recursive solution computes the taxes for the lower brackets over and over again.
Thus, we precompute and memoize the taxes for the taxable income up to the previous bucket in a bottom-up fashion.
This takes O(N) time. Binary search for the bracket takes log(N) time. Computing the taxes now takes O(1) times, giving us a linear time algorithm overall.
Scala code: Feel free to adapt to your favorite programming language.
def taxes(income: Int, brackets: IndexedSeq[(Int, Double)]): Double = {
val dp = brackets
.zipWithIndex
.foldLeft((0d, IndexedSeq.empty[(Int, Double, Double)])) { case ((sum, acc), (cur, i)) =>
val taxesOnPrevBracket = if (i > 0) {
val prev = brackets(i - 1)
(cur._1 - prev._1) * prev._2
} else 0d
val cumulativeTaxes = sum + taxesOnPrevBracket
(cumulativeTaxes, acc :+ (cur._1, cur._2, cumulativeTaxes))
}
._2
#tailrec
def findBracket(start: Int, end: Int): Int = {
if (end - start <= 1) start
else {
val mid = start + (end - start) / 2
if (income > brackets(mid)._1) findBracket(mid, end)
else findBracket(start, mid)
}
}
val br = dp(findBracket(0, brackets.size - 1))
val inc = income - br._1 + 1
val tx = inc * br._2 + br._3
println(s"Taxable income: $income, bracket: $br, taxes: $tx")
tx
}
brackets here is a sequence of tuples, of the starting values (thanks #Dillon Davis for the idea) and the tax rate.
Edit July 2021:
The crucial takeaway is that the tax in the highest bracket is variable depending on the income, but taxes in the lower brackets are constant. For example, for income 15000 that falls in the second bracket, we don't know the excess amount to be taxed according to the second bracket ahead of time. Once we tax that, the remaining 10000 falls in the first bucket and the tax on that can be precomputed. Here's a Python solution.
import bisect
brackets = [
(1, 0.1),
(10001, 0.2),
(50001, 0.3)
]
starts = [x for x, _ in brackets]
precomputed = []
cumulative_sum = 0
for i in range(len(brackets) - 1):
cumulative_sum += (starts[i + 1] - starts[i]) * brackets[i][1]
precomputed.append(cumulative_sum)
for income in [9000, 15000, 60000]:
i = bisect.bisect_right(starts, income)
i -= 1
excess = income - brackets[i][0] + 1
taxes = excess * brackets[i][1]
if i > 0:
taxes += precomputed[i - 1]
print(f"Taxes on income {income} is: {taxes}")
Create a decision table to help the Municipal Bank decide whether or not to loan money to a customer. Include the criteria used by the bank to identify qualified applicants.
Conditions
Income >=40000? T T T F F F
Credit Score >=600? T F F T T F
Months at job > 12? - T F T F -
Outcomes
Approve loan? Y Y X Y X X
Use pseudo code to write an algorithm for the decision table created in question one.
If Income >= 4000 And credScore >= 600 And monthJob > 12 Then
loanApp = Yes
I am having trouble converting the table to pseudo code, I wanted to know if the partial answer to the second question is on the right track.
Generally the approach works, yes. Although if you look carefully, you will see that monthJob > 12 is not needed for the first column of your condiditions. (there is a '-' there)
A faster approach you can get if you investigate your conditions. We always get Y if 2 of the conditions are met, otherwise we get X.
So here a optimised version (pseudocode):
score = 0
If Income >= 40000 Then
score = score + 1
Endif
If credScore >= 600 Then
score = score + 1
Endif
If monthJob > 12 Then
score = score + 1
Endif
If score >= 2 Then
loanApp = Yes
Else
loanApp = No
EndIf
I've been staring at this problem for hours and I'm still as lost as I was at the beginning. It's been a while since I took discrete math or statistics so I tried watching some videos on youtube, but I couldn't find anything that would help me solve the problem in less than what seems to be exponential time. Any tips on how to approach the problem below would be very much appreciated!
A certain species of fern thrives in lush rainy regions, where it typically rains almost every day.
However, a drought is expected over the next n days, and a team of botanists is concerned about
the survival of the species through the drought. Specifically, the team is convinced of the following
hypothesis: the fern population will survive if and only if it rains on at least n/2 days during the
n-day drought. In other words, for the species to survive there must be at least as many rainy days
as non-rainy days.
Local weather experts predict that the probability that it rains on a day i ∈ {1, . . . , n} is
pi ∈ [0, 1], and that these n random events are independent. Assuming both the botanists and
weather experts are correct, show how to compute the probability that the ferns survive the drought.
Your algorithm should run in time O(n2).
Have an (n + 1)×n matrix such that C[i][j] denotes the probability that after ith day there will have been j rainy days (i runs from 1 to n, j runs from 0 to n). Initialize:
C[1][0] = 1 - p[1]
C[1][1] = p[1]
C[1][j] = 0 for j > 1
Now loop over the days and set the values of the matrix like this:
C[i][0] = (1 - p[i]) * C[i-1][0]
C[i][j] = (1 - p[i]) * C[i-1][j] + p[i] * C[i - 1][j - 1] for j > 0
Finally, sum the values from C[n][n/2] to C[n][n] to get the probability of fern survival.
Dynamic programming problems can be solved in a top down or bottom up fashion.
You've already had the bottom up version described. To do the top-down version, write a recursive function, then add a caching layer so you don't recompute any results that you already computed. In pseudo-code:
cache = {}
function whatever(args)
if args not in cache
compute result
cache[args] = result
return cache[args]
This process is called "memoization" and many languages have ways of automatically memoizing things.
Here is a Python implementation of this specific example:
def prob_survival(daily_probabilities):
days = len(daily_probabilities)
days_needed = days / 2
# An inner function to do the calculation.
cached_odds = {}
def prob_survival(day, rained):
if days_needed <= rained:
return 1.0
elif days <= day:
return 0.0
elif (day, rained) not in cached_odds:
p = daily_probabilities[day]
p_a = p * prob_survival(day+1, rained+1)
p_b = (1- p) * prob_survival(day+1, rained)
cached_odds[(day, rained)] = p_a + p_b
return cached_odds[(day, rained)]
return prob_survival(0, 0)
And then you would call it as follows:
print(prob_survival([0.2, 0.4, 0.6, 0.8])
I'm working on a small project where I need help in finding the best and cheapest tickets based on some input from the user:
Between what periods (start & end date)?
Within that period, are you skipping 1 or several dates?
How many times do you need to use the ticket each day?
There are x number of tickets. A ticket can cover:
Single ticket, to be used only once, price $5.
Period ticket (unlimited rides each day), to be used as much as you want from 1 day/$10, 3 days/$30, 7 days/$45..
I guess I'm looking for some kind of algorithm to determine the best combination of tickets based on periods (including or excluding skipping dates), and also their price.
Also, I guess there needs to be considered the case where it will be a better and cheaper outcome for me to buy a period ticket that covers more days than I actually need, but is cheaper based on how many rides I'm going for each day...
UPDATE (based on Petr suggestion..)
<?php
$tickets = array(
array("price"=>5, "label"=>"single", "period"=>null),
array("price"=>10, "label"=>"1 day", "period"=>1),
array("price"=>30, "label"=>"3 days", "period"=>3),
array("price"=>45, "label"=>"7 days", "period"=>7)
);
$trips = 2;
$startDate = new DateTime("2015-06-23");
$endDate = new DateTime("2015-06-30");
$endDate->modify("+1 day");
$interval = DateInterval::createFromDateString('1 day');
$period = new DatePeriod($startDate, $interval, $endDate);
$cost = array();
$day = 1;
foreach( $period as $date ){
$span = $startDate->diff($date);
$days = ( $span->format('%a') + 1 );
$ticket = getCheapestTicket( $days );
$cost[ $day ] = $ticket;
$day++;
}
function getCheapestTicket( $days ){
global $tickets, $trips;
$lowestSum = null;
$cheapestTicket = null;
echo "-- getCheapestTicket --" . PHP_EOL;
echo "DAYS TO COVER: " . $days . " / TRIPS: " . $trips . PHP_EOL;
foreach( $tickets as $ticket ){
$price = $ticket['price'];
$period = $ticket['period'] ? $ticket['period'] : -1;
if( $ticket['period'] ){
$units = ceil( $days / $period );
$sum = round( $units * $price );
}else{
$units = ceil( $days * $trips );
$sum = round( ( $days * $price ) * $trips );
}
if( $sum <= $lowestSum || !$lowestSum ){
if( $ticket['period'] > $cheapestTicket['period'] ){
$cheapestTicket = $ticket;
$lowestSum = $sum;
}else{
$lowestSum = $sum;
$cheapestTicket = $ticket;
}
}
echo "TICKET: " . $ticket['label'] . " / Units to cover days: " . $units . " / Sum: " . $sum . " / Period: " . $period . PHP_EOL;
}
echo "CHEAPEST TICKET: " . $cheapestTicket['label'] .
" / PRICE PER UNIT: " . $cheapestTicket['price'] . " / SUM: " . $lowestSum . PHP_EOL. PHP_EOL;
return $cheapestTicket;
}
I'm not sure if this is on the way yet :)
Lets assume you have all the data stored in some array of days and each day has the number of rides for that day written down.
Side note: I am going to relax the conditions of a ticket lasting 24 hours and just assume each periodical ticket is good for that date (i.e, not starting at 15:00 and lasting until 14:59 the next day). This could be fixed by looking at it as hourly time units instead of days.
Sub optimal solution:
Now lets assign to all the days the cost of buying one ride tickets for that day and then start iterating over the array and checking whether or not you could substitute some of them with a cheaper ticket. You finish when no changes are done. The problem here is you might miss the optimal solution. You might assign two 3-day tickets (days 1-3 and 7-9) where a 7-day ticket (2-8) and two 1-day tickets would be better.
Tree solution: (data in leafs)
The tree option would be to arrange it in a tree with each sub tree holding the best solution for that sub tree. Then, each subtree root could check if using a ticket "covering" only part of the subtree could be useful, when taking into account the values of the roots of the parts left out.
Maybe a rank tree would come in handy here.
You can solve this problem using a dynamic programming approach.
Firstly, for simplicity of the algorithm, let's for each l calculate the cheapest single ticket that can be used to cover l consecutive days. For your example this will be: 1 day $10, 2 days $30 (buy a 3-day ticket and use it only for 2 days), 3 days $30, 4-7 days $45, etc. (There will obviously be some maximal value of l beyond which there will be no such ticket.) Denote these results as cost[l].
Now the main dynamic programming solution. For each date i in your [begin, end] range, calculate ans[i] = the minimal cost to buy tickets to cover at least interval from begin to i.
Assuming that you have already calculated all the values before date i, calculation for date i is simple. You will need some ticket that ends on day i. Let's say it covers length of l days, then the price for this last ticket will be cost[l], and you will also have to cover the days from begin to i-l, which will cost ans[i-l] (or zero if i-l is before begin). So for a given i iterate over all possible ls and find the one that minimizes the solution.
This gives you the O(NL) solution, where N is the number of days and L is the maximal span of a single ticket.
This all assumes that each ticked covers several full consecutive days. If it covers, say, 24 full hours (from the hour of buying to the same hour next day), then just calculate answers for each hour.
As from my example, based on what #Petr said, I don't really know how it can solve the situation where for example the period covers 8 days (2 trips each day) and you end up with a result like this:
-- getCheapestTicket --
DAYS TO COVER: 8 / TRIPS: 2
TICKET: single / Units to cover days: 16 / Sum: 80 / Period: -1
TICKET: 1 day / Units to cover days: 8 / Sum: 80 / Period: 1
TICKET: 3 days / Units to cover days: 3 / Sum: 90 / Period: 3
TICKET: 7 days / Units to cover days: 2 / Sum: 90 / Period: 7
CHEAPEST TICKET: 1 day / PRICE PER UNIT: 10 / SUM: 80
Where it should give me a result of this combination:
7 days, $45
1 day, $10
Or is this what you mean when you said "(There will obviously be some maximal value of l beyond which there will be no such ticket.)"?
Would be really sweet to get another round of explanation on your thoughts!