mirror of
https://github.com/onyx-and-iris/grokking-algorithms.git
synced 2026-04-16 11:33:34 +00:00
reorganise directories
upd chapter_01/binary.py
This commit is contained in:
6
chapter_11/README.md
Normal file
6
chapter_11/README.md
Normal file
@@ -0,0 +1,6 @@
|
||||
# Dynamic Programming
|
||||
|
||||
A programming technique for decomposing a problem into smaller discrete subproblems.
|
||||
|
||||
- Useful when trying to optimize something given a constraint.
|
||||
- Example, items in a knapsack of size W that gives the greatest value.
|
||||
84
chapter_11/camping.py
Normal file
84
chapter_11/camping.py
Normal file
@@ -0,0 +1,84 @@
|
||||
import logging
|
||||
from dataclasses import dataclass
|
||||
|
||||
from tabulate import tabulate
|
||||
|
||||
logging.basicConfig(
|
||||
level=logging.DEBUG,
|
||||
format="%(asctime)s %(levelname)s\n\r%(message)s",
|
||||
datefmt="%H:%M:%S",
|
||||
)
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
@dataclass
|
||||
class Item:
|
||||
name: str
|
||||
priority: int
|
||||
weight: int
|
||||
|
||||
|
||||
def dynamic(items, n):
|
||||
# create table and zero fill it (required for calculations)
|
||||
table = [[0 for _ in range(W + 1)] for _ in range(n + 1)]
|
||||
|
||||
# calculate all possible max values for items in knapsack
|
||||
for i in range(1, n + 1):
|
||||
for w in range(1, W + 1):
|
||||
if items[i - 1].weight <= w:
|
||||
table[i][w] = max(
|
||||
items[i - 1].priority + table[i - 1][w - items[i - 1].weight],
|
||||
table[i - 1][w],
|
||||
)
|
||||
else:
|
||||
table[i][w] = table[i - 1][w]
|
||||
|
||||
format_and_print(table)
|
||||
|
||||
return get_items_in_knapsack(table[-1][-1], items, n, table)
|
||||
|
||||
|
||||
def format_and_print(table):
|
||||
# enumerate first row (headings) + label each row in column0
|
||||
for i, row in enumerate(table):
|
||||
if i == 0:
|
||||
continue
|
||||
row[0] = items[i - 1].name
|
||||
table[0] = [None, *[i for i in range(1, W + 1)]]
|
||||
|
||||
# print tabularised 2D array
|
||||
logger.info([item.name for item in items])
|
||||
logger.info(tabulate(table, tablefmt="pretty"))
|
||||
|
||||
|
||||
def get_items_in_knapsack(highest_value, items, n, table):
|
||||
in_knapsack = []
|
||||
|
||||
w = W
|
||||
res = highest_value
|
||||
for i in range(n, 0, -1):
|
||||
if res <= 0:
|
||||
break
|
||||
|
||||
if res == table[i - 1][w]:
|
||||
continue
|
||||
else:
|
||||
in_knapsack.append(items[i - 1].name)
|
||||
|
||||
res = res - items[i - 1].priority
|
||||
w = w - items[i - 1].weight
|
||||
|
||||
return in_knapsack
|
||||
|
||||
|
||||
items = [
|
||||
Item("Water", 10, 3),
|
||||
Item("Book", 3, 1),
|
||||
Item("Food", 9, 2),
|
||||
Item("Jacket", 5, 2),
|
||||
Item("Camera", 6, 1),
|
||||
]
|
||||
W = 6
|
||||
in_knapsack = dynamic(items, len(items))
|
||||
|
||||
print(f"Knapsack contains: {in_knapsack}")
|
||||
72
chapter_11/knapsack.py
Normal file
72
chapter_11/knapsack.py
Normal file
@@ -0,0 +1,72 @@
|
||||
import logging
|
||||
from dataclasses import dataclass
|
||||
|
||||
from tabulate import tabulate
|
||||
|
||||
logging.basicConfig(
|
||||
level=logging.DEBUG,
|
||||
format="%(asctime)s %(levelname)s\n\r%(message)s",
|
||||
datefmt="%H:%M:%S",
|
||||
)
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
@dataclass
|
||||
class Item:
|
||||
name: str
|
||||
value: int
|
||||
weight: int
|
||||
|
||||
|
||||
def dynamic(items, n):
|
||||
# create table and zero fill it (required for calculations)
|
||||
table = [[0 for _ in range(W + 1)] for _ in range(n + 1)]
|
||||
|
||||
# calculate all possible max values for items in knapsack
|
||||
for i in range(1, n + 1):
|
||||
for w in range(1, W + 1):
|
||||
if items[i - 1].weight <= w:
|
||||
table[i][w] = max(
|
||||
items[i - 1].value + table[i - 1][w - items[i - 1].weight],
|
||||
table[i - 1][w],
|
||||
)
|
||||
else:
|
||||
table[i][w] = table[i - 1][w]
|
||||
|
||||
format_and_print(table)
|
||||
|
||||
return table[-1][-1]
|
||||
|
||||
|
||||
def format_and_print(table):
|
||||
# enumerate first row (headings) + label each row in column0
|
||||
for i, row in enumerate(table):
|
||||
if i == 0:
|
||||
continue
|
||||
row[0] = items[i - 1].name
|
||||
table[0] = [None, *[i for i in range(1, W + 1)]]
|
||||
|
||||
# print tabularised 2D array
|
||||
logger.info([item.name for item in items])
|
||||
logger.info(tabulate(table, tablefmt="pretty"))
|
||||
|
||||
|
||||
# Where items = Guitar + Stereo + Laptop
|
||||
items = [Item("Guitar", 1500, 1), Item("Stereo", 3000, 4), Item("Laptop", 2000, 3)]
|
||||
W = 4
|
||||
greatest_value = dynamic(items, len(items))
|
||||
|
||||
print(f"Greatest value: {greatest_value}")
|
||||
|
||||
|
||||
# Where items = Guitar + Stereo + Laptop + Iphone
|
||||
items = [
|
||||
Item("Guitar", 1500, 1),
|
||||
Item("Stereo", 3000, 4),
|
||||
Item("Laptop", 2000, 3),
|
||||
Item("Iphone", 2000, 1),
|
||||
]
|
||||
W = 4
|
||||
greatest_value_with_iphone = dynamic(items, len(items))
|
||||
|
||||
print(f"Greatest value: {greatest_value_with_iphone}")
|
||||
54
chapter_11/subsequence.py
Normal file
54
chapter_11/subsequence.py
Normal file
@@ -0,0 +1,54 @@
|
||||
import logging
|
||||
|
||||
from tabulate import tabulate
|
||||
|
||||
logging.basicConfig(
|
||||
level=logging.DEBUG,
|
||||
format="%(asctime)s %(levelname)s\n\r%(message)s",
|
||||
datefmt="%H:%M:%S",
|
||||
)
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def longest_common_subsequence(X, Y, len_x, len_y):
|
||||
# create table and zero fill it
|
||||
table = [[0 for _ in range(len_x + 1)] for _ in range(len_y + 1)]
|
||||
|
||||
for i in range(1, len_y + 1):
|
||||
for j in range(1, len_x + 1):
|
||||
if X[j - 1] == Y[i - 1]:
|
||||
table[i][j] = table[i - 1][j - 1] + 1
|
||||
else:
|
||||
table[i][j] = max(table[i - 1][j], table[i][j - 1])
|
||||
|
||||
format_and_print(X, Y, table)
|
||||
|
||||
return table[-1][-1]
|
||||
|
||||
|
||||
def format_and_print(X, Y, table):
|
||||
# enumerate first row (headings) + label each row in column0
|
||||
for i, row in enumerate(table):
|
||||
if i == 0:
|
||||
continue
|
||||
row[0] = Y[i - 1]
|
||||
table[0] = [None, *X]
|
||||
|
||||
# print tabularised 2D array
|
||||
logger.info(tabulate(table, tablefmt="pretty"))
|
||||
|
||||
|
||||
X = "fosh"
|
||||
Y = "fort"
|
||||
|
||||
logger.info(f"words: {X} {Y}")
|
||||
length = longest_common_subsequence(X, Y, len(X), len(Y))
|
||||
print(f"Longest common subsequence: {length}")
|
||||
|
||||
|
||||
X = "fosh"
|
||||
Y = "fish"
|
||||
|
||||
logger.info(f"words: {X} {Y}")
|
||||
length = longest_common_subsequence(X, Y, len(X), len(Y))
|
||||
print(f"Longest common subsequence: {length}")
|
||||
57
chapter_11/substring.py
Normal file
57
chapter_11/substring.py
Normal file
@@ -0,0 +1,57 @@
|
||||
import logging
|
||||
|
||||
from tabulate import tabulate
|
||||
|
||||
logging.basicConfig(
|
||||
level=logging.DEBUG,
|
||||
format="%(asctime)s %(levelname)s\n\r%(message)s",
|
||||
datefmt="%H:%M:%S",
|
||||
)
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def longest_common_substring(X, Y, len_x, len_y):
|
||||
# create table and zero fill it
|
||||
table = [[0 for _ in range(len_x + 1)] for _ in range(len_y + 1)]
|
||||
|
||||
longest = 0
|
||||
|
||||
for i in range(1, len_y + 1):
|
||||
for j in range(1, len_x + 1):
|
||||
if X[j - 1] == Y[i - 1]:
|
||||
table[i][j] = table[i - 1][j - 1] + 1
|
||||
longest = max(longest, table[i][j])
|
||||
else:
|
||||
table[i][j] = 0
|
||||
|
||||
format_and_print(X, Y, table)
|
||||
|
||||
return longest
|
||||
|
||||
|
||||
def format_and_print(X, Y, table):
|
||||
# enumerate first row (headings) + label each row in column0
|
||||
for i, row in enumerate(table):
|
||||
if i == 0:
|
||||
continue
|
||||
row[0] = Y[i - 1]
|
||||
table[0] = [None, *X]
|
||||
|
||||
# print tabularised 2D array
|
||||
logger.info(tabulate(table, tablefmt="pretty"))
|
||||
|
||||
|
||||
X = "fish"
|
||||
Y = "vish"
|
||||
|
||||
logger.info(f"words: {X} {Y}")
|
||||
length = longest_common_substring(X, Y, len(X), len(Y))
|
||||
print(f"Longest common substring: {length}")
|
||||
|
||||
|
||||
X = "vista"
|
||||
Y = "hish"
|
||||
|
||||
logger.info(f"words: {X} {Y}")
|
||||
length = longest_common_substring(X, Y, len(X), len(Y))
|
||||
print(f"Longest common substring: {length}")
|
||||
65
chapter_11/travel.py
Normal file
65
chapter_11/travel.py
Normal file
@@ -0,0 +1,65 @@
|
||||
import logging
|
||||
from dataclasses import dataclass
|
||||
|
||||
from tabulate import tabulate
|
||||
|
||||
logging.basicConfig(
|
||||
level=logging.DEBUG,
|
||||
format="%(asctime)s %(levelname)s\n\r%(message)s",
|
||||
datefmt="%H:%M:%S",
|
||||
)
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
@dataclass
|
||||
class Location:
|
||||
name: str
|
||||
time: int
|
||||
rating: int
|
||||
|
||||
|
||||
def dynamic(items, n):
|
||||
# create table and zero fill it (required for calculations)
|
||||
table = [[0 for _ in range(2 * (W + 1) - 1)] for _ in range(n + 1)]
|
||||
|
||||
# calculate all possible max values for items in knapsack
|
||||
for i in range(1, n + 1):
|
||||
for w in range(1, 2 * (W + 1) - 1):
|
||||
if items[i - 1].time <= w:
|
||||
table[i][w] = max(
|
||||
items[i - 1].rating + table[i - 1][w - items[i - 1].time],
|
||||
table[i - 1][w],
|
||||
)
|
||||
else:
|
||||
table[i][w] = table[i - 1][w]
|
||||
|
||||
format_and_print(table)
|
||||
|
||||
return table[-1][-1]
|
||||
|
||||
|
||||
def format_and_print(table):
|
||||
# enumerate first row (headings) + label each row in column0
|
||||
for i, row in enumerate(table):
|
||||
if i == 0:
|
||||
continue
|
||||
row[0] = locations[i - 1].name
|
||||
table[0] = [None, *[i / 2 for i in range(1, 2 * (W + 1) - 1)]]
|
||||
|
||||
# print tabularised 2D array
|
||||
logger.info([item.name for item in locations])
|
||||
logger.info(tabulate(table, tablefmt="pretty"))
|
||||
|
||||
|
||||
# values converted to integers
|
||||
locations = [
|
||||
Location("Westminster Abbey", 1, 7),
|
||||
Location("Globe Theater", 1, 6),
|
||||
Location("National Gallery", 2, 9),
|
||||
Location("British Museum", 4, 9),
|
||||
Location("St. Pauls Cathedral", 1, 8),
|
||||
]
|
||||
W = 2
|
||||
greatest_value = dynamic(locations, len(locations))
|
||||
|
||||
print(f"Greatest value: {greatest_value}")
|
||||
Reference in New Issue
Block a user