Skip to content

add dp up - down minimum cost for tickets #7934

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 22 commits into from
Nov 2, 2022
Merged
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
f9c1432
add dp up - down minimum cost for tickets
alexpantyukhin Nov 1, 2022
e8875b4
add typints
alexpantyukhin Nov 1, 2022
9802915
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Nov 1, 2022
c33931d
add new tests and checks.
alexpantyukhin Nov 2, 2022
c7179f1
Merge branch 'minimum_tickets_cost' of https://github.com/alexpantyuk…
alexpantyukhin Nov 2, 2022
0417cb9
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Nov 2, 2022
bfac27a
add more tests
alexpantyukhin Nov 2, 2022
cc0e45f
add types for the dp function
alexpantyukhin Nov 2, 2022
d5998b2
Merge branch 'minimum_tickets_cost' of https://github.com/alexpantyuk…
alexpantyukhin Nov 2, 2022
ef0c2db
Update dynamic_programming/minimum_tickets_cost.py
alexpantyukhin Nov 2, 2022
ea4fc07
fix review notes
alexpantyukhin Nov 2, 2022
7398ff2
Merge branch 'minimum_tickets_cost' of https://github.com/alexpantyuk…
alexpantyukhin Nov 2, 2022
157330c
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Nov 2, 2022
186ba33
small fix
alexpantyukhin Nov 2, 2022
ae0364f
Merge branch 'minimum_tickets_cost' of https://github.com/alexpantyuk…
alexpantyukhin Nov 2, 2022
99af69b
Update dynamic_programming/minimum_tickets_cost.py
alexpantyukhin Nov 2, 2022
d34a84e
Update dynamic_programming/minimum_tickets_cost.py
alexpantyukhin Nov 2, 2022
2d66c34
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Nov 2, 2022
3568f84
fix tests
alexpantyukhin Nov 2, 2022
c8c3d3c
Merge branch 'minimum_tickets_cost' of https://github.com/alexpantyuk…
alexpantyukhin Nov 2, 2022
3d6688c
Update dynamic_programming/minimum_tickets_cost.py
alexpantyukhin Nov 2, 2022
e232624
Update dynamic_programming/minimum_tickets_cost.py
cclauss Nov 2, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
129 changes: 129 additions & 0 deletions dynamic_programming/minimum_tickets_cost.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
"""
Author : Alexander Pantyukhin
Date : November 1, 2022

Task:
Given a list of days when you need to travel. Each day is integer from 1 to 365.
You are able to use tickets for 1 day, 7 days and 30 days.
Each ticket has a cost.

Find the minimum cost you need to travel every day in the given list of days.

Implementation notes:
implementation Dynamic Programming up bottom approach.

Runtime complexity: O(n)

The implementation was tested on the
leetcode: https://leetcode.com/problems/minimum-cost-for-tickets/


Minimum Cost For Tickets
Dynamic Programming: up -> down.
"""

from functools import lru_cache


def mincost_tickets(days: list[int], costs: list[int]) -> int:
"""
>>> mincost_tickets([1, 4, 6, 7, 8, 20], [2, 7, 15])
11

>>> mincost_tickets([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 30, 31], [2, 7, 15])
17

>>> mincost_tickets([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 30, 31], [2, 90, 150])
24

>>> mincost_tickets([2], [2, 90, 150])
2

>>> mincost_tickets([], [2, 90, 150])
0

>>> mincost_tickets('hello', [2, 90, 150])
Traceback (most recent call last):
...
ValueError: The parameter days should be a list of integers

>>> mincost_tickets([], 'world')
Traceback (most recent call last):
...
ValueError: The parameter costs should be a list of three integers

>>> mincost_tickets([0.25, 2, 3, 4, 5, 6, 7, 8, 9, 10, 30, 31], [2, 90, 150])
Traceback (most recent call last):
...
ValueError: The parameter days should be a list of integers

>>> mincost_tickets([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 30, 31], [2, 0.9, 150])
Traceback (most recent call last):
...
ValueError: The parameter costs should be a list of three integers

>>> mincost_tickets([-1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 30, 31], [2, 90, 150])
Traceback (most recent call last):
...
ValueError: All days elements should be greater than 0

>>> mincost_tickets([2, 367], [2, 90, 150])
Traceback (most recent call last):
...
ValueError: All days elements should be less than 366

>>> mincost_tickets([2, 3, 4, 5, 6, 7, 8, 9, 10, 30, 31], [])
Traceback (most recent call last):
...
ValueError: The parameter costs should be a list of three integers

>>> mincost_tickets([], [])
Traceback (most recent call last):
...
ValueError: The parameter costs should be a list of three integers

>>> mincost_tickets([2, 3, 4, 5, 6, 7, 8, 9, 10, 30, 31], [1, 2, 3, 4])
Traceback (most recent call last):
...
ValueError: The parameter costs should be a list of three integers
"""

# Validation
if not isinstance(days, list) or not all(isinstance(day, int) for day in days):
raise ValueError("The parameter days should be a list of integers")

if len(costs) != 3 or not all(isinstance(cost, int) for cost in costs):
raise ValueError("The parameter costs should be a list of three integers")

if len(days) == 0:
return 0

if min(days) <= 0:
raise ValueError("All days elements should be greater than 0")

if max(days) >= 366:
raise ValueError("All days elements should be less than 366")

days_set = set(days)

@lru_cache(maxsize=None)
def dynamic_programming(index: int) -> int:
if index > 365:
return 0

if index not in days_set:
return dp(index + 1)

return min(
costs[0] + dp(index + 1),
costs[1] + dp(index + 7),
costs[2] + dp(index + 30),
)

return dynamic_programming(1)


if __name__ == "__main__":
import doctest

doctest.testmod()