Skip to content

Commit 31cefcd

Browse files
committed
[main] added blutarsky implementation
1 parent 481b4c3 commit 31cefcd

File tree

7 files changed

+164
-0
lines changed

7 files changed

+164
-0
lines changed
Binary file not shown.
Binary file not shown.
0 Bytes
Binary file not shown.
Binary file not shown.
Binary file not shown.
0 Bytes
Binary file not shown.
Lines changed: 164 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,164 @@
1+
from __future__ import annotations
2+
from dataclasses import dataclass
3+
from typing import List
4+
5+
6+
@dataclass
7+
class Node:
8+
name: str
9+
rating: int
10+
parent: Node = None
11+
left_child: Node = None
12+
right_sib: Node = None
13+
14+
15+
def get_guest_list(root: Node, table: dict | None = None) -> tuple[list[Node], int]:
16+
# If DP table not yet initialized, initialize DP table
17+
if table is None:
18+
table = {}
19+
20+
if root == None:
21+
# if root is None, return an empty guest list and a rating of 0
22+
return [], 0
23+
elif root.name in table:
24+
# if the best guest list for this root has been calculated already, return it
25+
return table[root.name]
26+
27+
# Assume best guest list include the root, so start with the root's info
28+
guests = [root]
29+
ratings = root.rating
30+
31+
# Check the best guest lists of the child nodes, which can't necessarily be used in
32+
# a list containing the root due to the root being an immediate superior
33+
child_guests, child_ratings = get_guest_list(root.left_child, table)
34+
35+
# The siblings CAN be used with the root node, as there is no supervisor/employee
36+
# relationship to account for
37+
sibling_guests, sibling_ratings = get_guest_list(root.right_sib, table)
38+
39+
# Get best lists of grandchildren nodes, wherever possible, as they aren't immediate
40+
# employees of the root supervisor
41+
root_child = root.left_child
42+
while root_child != None:
43+
if root_child.left_child != None:
44+
grandchild_guests, grandchild_ratings = get_guest_list(
45+
root_child.left_child, table)
46+
guests += grandchild_guests
47+
ratings += grandchild_ratings
48+
49+
root_child = root_child.right_sib
50+
51+
# We can include sibling lists with our root and children lists, since the direct sibling of
52+
# the root has no significant relationship with either
53+
# guests += sibling_guests
54+
# ratings += sibling_ratings
55+
# child_guests += sibling_guests
56+
# child_ratings += sibling_ratings
57+
58+
# For this root, choose the rating-maximized list, which is either the list that contains
59+
# this node, or the list that includes the children of this node
60+
if child_ratings > ratings:
61+
if root.name not in table:
62+
table[root.name] = (child_guests + sibling_guests,
63+
child_ratings+sibling_ratings)
64+
return child_guests + sibling_guests, child_ratings+sibling_ratings
65+
else:
66+
if root.name not in table:
67+
table[root.name] = (guests + sibling_guests,
68+
ratings+sibling_ratings)
69+
return guests + sibling_guests, ratings+sibling_ratings
70+
71+
72+
computed_nodes: dict = {}
73+
list_sums = {}
74+
75+
76+
def get_guest_list_v2(node: Node | None, level: int = 0) -> int:
77+
if node == None:
78+
return 0
79+
# grandchildren sum vs child sums
80+
# first compute grandchild sums + grandchild right sums, then compute children sums
81+
max_sum = node.rating
82+
if node.left_child is not None: # GRANDCHILDREN SUM
83+
# if it has a left child, access it's grandchildren sum
84+
max_sum += get_guest_list_v2(
85+
node.left_child.left_child, level + 2)
86+
if node.left_child is not None: # gather grandchild sums from left child
87+
max_sum = max(max_sum, get_guest_list_v2(node.left_child, level + 1))
88+
if node.right_sib: # RIGHT CHILD SUM
89+
# if it doesn't have a grandchild, access it's right sib sum, that sums up the grandchild sum of the right children
90+
max_sum = get_guest_list_v2(node.right_sib, level)
91+
print(node.name)
92+
print(level, max_sum)
93+
return max_sum
94+
95+
96+
def print_guest_list(guests: list[Node]) -> None:
97+
print(f"TOTAL RATING: {sum(guest.rating for guest in guests)}")
98+
print("GUESTS:")
99+
for guest in guests:
100+
print(guest.name, guest.rating)
101+
102+
103+
if __name__ == "__main__":
104+
105+
# ####################### MAKE FIRST TESTING TREE #######################
106+
# root_1 = Node("A", 10)
107+
108+
# for i in range(3):
109+
# name = chr(ord("B")+i)
110+
# lvl_1 = Node(name, 2+i, parent=root_1)
111+
112+
# grand2 = Node(name+"2", 1, parent=lvl_1)
113+
# grand1 = Node(name+"1", 1, parent=lvl_1, right_sib=grand2)
114+
115+
# great_grand1 = Node(name+"11", 1, parent=grand1)
116+
# great_grand2 = Node(name+"22", 1, parent=grand2)
117+
118+
# grand1.left_child = great_grand1
119+
# grand2.left_child = great_grand2
120+
121+
# lvl_1.left_child = grand1
122+
123+
# if root_1.left_child == None:
124+
# root_1.left_child = lvl_1
125+
# else:
126+
# level = root_1.left_child
127+
# while level.right_sib != None:
128+
# level = level.right_sib
129+
130+
# level.right_sib = lvl_1
131+
132+
####################### MAKE SECOND TESTING TREE #######################
133+
root_2 = Node("A", 1)
134+
135+
for i in range(3):
136+
name = chr(ord("B")+i)
137+
lvl_1 = Node(name, 5+i, parent=root_2) # C
138+
139+
val = 10 if i % 2 == 0 else 1
140+
grand2 = Node(name+"2", val, parent=lvl_1) # C2
141+
grand1 = Node(name+"1", val, parent=lvl_1, right_sib=grand2) # C1
142+
143+
great_grand1 = Node(name+"11", 1, parent=grand1) # C11
144+
great_grand2 = Node(name+"22", 1, parent=grand2) # C22
145+
146+
grand1.left_child = great_grand1
147+
grand2.left_child = great_grand2
148+
149+
lvl_1.left_child = grand1
150+
151+
if root_2.left_child == None:
152+
root_2.left_child = lvl_1
153+
else:
154+
level = root_2.left_child
155+
while level.right_sib != None:
156+
level = level.right_sib
157+
158+
level.right_sib = lvl_1
159+
160+
#print(great_grand1.name, great_grand1.right_sib)
161+
162+
guests, ratings = get_guest_list_v2(root_2)
163+
print(ratings)
164+
print_guest_list(guests)

0 commit comments

Comments
 (0)