Skip to content

Commit f05baa2

Browse files
alexpantyukhinpre-commit-ci[bot]cclauss
authored
add dp up - down minimum cost for tickets (TheAlgorithms#7934)
* add dp up - down minimum cost for tickets * add typints * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * add new tests and checks. * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * add more tests * add types for the dp function * Update dynamic_programming/minimum_tickets_cost.py Co-authored-by: Christian Clauss <[email protected]> * fix review notes * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * small fix * Update dynamic_programming/minimum_tickets_cost.py Co-authored-by: Christian Clauss <[email protected]> * Update dynamic_programming/minimum_tickets_cost.py Co-authored-by: Christian Clauss <[email protected]> * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * fix tests * Update dynamic_programming/minimum_tickets_cost.py Co-authored-by: Christian Clauss <[email protected]> * Update dynamic_programming/minimum_tickets_cost.py Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> Co-authored-by: Christian Clauss <[email protected]>
1 parent f512b4d commit f05baa2

File tree

1 file changed

+129
-0
lines changed

1 file changed

+129
-0
lines changed
+129
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
"""
2+
Author : Alexander Pantyukhin
3+
Date : November 1, 2022
4+
5+
Task:
6+
Given a list of days when you need to travel. Each day is integer from 1 to 365.
7+
You are able to use tickets for 1 day, 7 days and 30 days.
8+
Each ticket has a cost.
9+
10+
Find the minimum cost you need to travel every day in the given list of days.
11+
12+
Implementation notes:
13+
implementation Dynamic Programming up bottom approach.
14+
15+
Runtime complexity: O(n)
16+
17+
The implementation was tested on the
18+
leetcode: https://leetcode.com/problems/minimum-cost-for-tickets/
19+
20+
21+
Minimum Cost For Tickets
22+
Dynamic Programming: up -> down.
23+
"""
24+
25+
from functools import lru_cache
26+
27+
28+
def mincost_tickets(days: list[int], costs: list[int]) -> int:
29+
"""
30+
>>> mincost_tickets([1, 4, 6, 7, 8, 20], [2, 7, 15])
31+
11
32+
33+
>>> mincost_tickets([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 30, 31], [2, 7, 15])
34+
17
35+
36+
>>> mincost_tickets([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 30, 31], [2, 90, 150])
37+
24
38+
39+
>>> mincost_tickets([2], [2, 90, 150])
40+
2
41+
42+
>>> mincost_tickets([], [2, 90, 150])
43+
0
44+
45+
>>> mincost_tickets('hello', [2, 90, 150])
46+
Traceback (most recent call last):
47+
...
48+
ValueError: The parameter days should be a list of integers
49+
50+
>>> mincost_tickets([], 'world')
51+
Traceback (most recent call last):
52+
...
53+
ValueError: The parameter costs should be a list of three integers
54+
55+
>>> mincost_tickets([0.25, 2, 3, 4, 5, 6, 7, 8, 9, 10, 30, 31], [2, 90, 150])
56+
Traceback (most recent call last):
57+
...
58+
ValueError: The parameter days should be a list of integers
59+
60+
>>> mincost_tickets([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 30, 31], [2, 0.9, 150])
61+
Traceback (most recent call last):
62+
...
63+
ValueError: The parameter costs should be a list of three integers
64+
65+
>>> mincost_tickets([-1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 30, 31], [2, 90, 150])
66+
Traceback (most recent call last):
67+
...
68+
ValueError: All days elements should be greater than 0
69+
70+
>>> mincost_tickets([2, 367], [2, 90, 150])
71+
Traceback (most recent call last):
72+
...
73+
ValueError: All days elements should be less than 366
74+
75+
>>> mincost_tickets([2, 3, 4, 5, 6, 7, 8, 9, 10, 30, 31], [])
76+
Traceback (most recent call last):
77+
...
78+
ValueError: The parameter costs should be a list of three integers
79+
80+
>>> mincost_tickets([], [])
81+
Traceback (most recent call last):
82+
...
83+
ValueError: The parameter costs should be a list of three integers
84+
85+
>>> mincost_tickets([2, 3, 4, 5, 6, 7, 8, 9, 10, 30, 31], [1, 2, 3, 4])
86+
Traceback (most recent call last):
87+
...
88+
ValueError: The parameter costs should be a list of three integers
89+
"""
90+
91+
# Validation
92+
if not isinstance(days, list) or not all(isinstance(day, int) for day in days):
93+
raise ValueError("The parameter days should be a list of integers")
94+
95+
if len(costs) != 3 or not all(isinstance(cost, int) for cost in costs):
96+
raise ValueError("The parameter costs should be a list of three integers")
97+
98+
if len(days) == 0:
99+
return 0
100+
101+
if min(days) <= 0:
102+
raise ValueError("All days elements should be greater than 0")
103+
104+
if max(days) >= 366:
105+
raise ValueError("All days elements should be less than 366")
106+
107+
days_set = set(days)
108+
109+
@lru_cache(maxsize=None)
110+
def dynamic_programming(index: int) -> int:
111+
if index > 365:
112+
return 0
113+
114+
if index not in days_set:
115+
return dp(index + 1)
116+
117+
return min(
118+
costs[0] + dp(index + 1),
119+
costs[1] + dp(index + 7),
120+
costs[2] + dp(index + 30),
121+
)
122+
123+
return dynamic_programming(1)
124+
125+
126+
if __name__ == "__main__":
127+
import doctest
128+
129+
doctest.testmod()

0 commit comments

Comments
 (0)