-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathBoom2.cpp
164 lines (146 loc) · 4.72 KB
/
Boom2.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
#include "Boom2.h"
namespace DS
{
Boom2::Boom2() :
lecture_tree(RankAVL<SubtreeSize, LectureContainer, int>(SubtreeSize())), lecture_counter(0) { }
// Returns false if the course already exist, true if the insertion succeeded.
bool Boom2::addCourse(int course_id)
{
if (course_id <= 0)
{
throw InvalidInput();
}
if (course_table.find(course_id))
{
return false;
}
course_table.insert(course_id, lectures());
return true;
}
// Returns false if there is no course with the given id, true if the deletion succeeded.
bool Boom2::removeCourse(int course_id)
{
if(course_id <= 0)
{
throw InvalidInput();
}
if(!course_table.find(course_id))
{
return false;
}
auto& lecture_arr = course_table.get(course_id).array;
int num_of_lectures = course_table.get(course_id).top;
for(int i = 0; i < num_of_lectures; i++)
{
if(lecture_arr.get(i).views)
{
lecture_tree.erase(lecture_arr.get(i));
}
}
course_table.erase(course_id);
return true;
}
// Returns false if the course doesn't exist, true if the class was added successfully.
bool Boom2::addClass(int course_id, int* class_id)
{
if(course_id <= 0)
{
throw InvalidInput();
}
if(!course_table.find(course_id))
{
return false;
}
lectures& lectures_arr = course_table.get(course_id);
int top = lectures_arr.top;
LectureContainer lecture = {0, course_id, top};
lectures_arr.array.store(top, lecture);
*class_id = top;
lectures_arr.top++;
return true;
}
// Returns false if the course doesn't exist, true if time was added successfully.
bool Boom2::watchClass(int course_id, int class_id, int time)
{
if(time <= 0 || class_id < 0 || course_id <= 0)
{
throw InvalidInput();
}
if(!course_table.find(course_id))
{
return false;
}
lectures& lecture_arr = course_table.get(course_id);
if(class_id + 1 > lecture_arr.array.initialized())
{
throw InvalidInput();
}
auto old_lecture = lecture_arr.array.get(class_id);
LectureContainer new_lecture = {old_lecture.views + time, old_lecture.course, old_lecture.lecture};
lecture_arr.array.store(class_id, new_lecture);
lecture_tree.erase(old_lecture);
lecture_tree.insert(new_lecture, 0);
return true;
}
bool Boom2::timeViewed(int course_id, int class_id, int* time_viewed)
{
if(course_id <= 0 || class_id < 0)
{
throw InvalidInput();
}
if(!course_table.find(course_id))
{
return false;
}
lectures& lecture_arr = course_table.get(course_id);
if(class_id + 1 > lecture_arr.array.initialized())
{
throw InvalidInput();
}
*time_viewed = lecture_arr.array.get(class_id).views;
return true;
}
bool Boom2::getIthWatchedClass(int i, int* course_id, int* class_id)
{
if(i <= 0)
{
throw InvalidInput();
}
if(lecture_tree.size() < i)
{
return false;
}
class FindIthWatchedClass
{
int i;
public:
FindIthWatchedClass(int i) : i(i) { }
SearchPath operator()(std::shared_ptr<graph_node<LectureContainer, int>>& node)
{
SearchPath result = SearchPath::end;
int right_rank = node->right? node->right->val : 0;
if(right_rank == i - 1) // The current node is the wanted node.
{
return result;
}
else if(right_rank > i - 1) // The node we are looking for is in the right sub-tree.
{
node = node->right;
result = SearchPath::right;
}
else // right_rank < i - 1: The node we are looking for is in the left sub-tree.
{
node = node->left;
result = SearchPath::left;
i = i - right_rank - 1;
}
return result;
}
};
FindIthWatchedClass calc_functor(i);
const std::shared_ptr<graph_node<LectureContainer, int>>& target = lecture_tree.rank(calc_functor);
*course_id = target->key.course;
*class_id = target->key.lecture;
return true;
}
}