From aebb4a736a059898f7bec2dd4e0a3bf3d8292ed4 Mon Sep 17 00:00:00 2001 From: TanzHasan Date: Wed, 17 Apr 2024 12:29:57 -0400 Subject: [PATCH] More artifacts removed --- .../Codeforces/Implementation.md | 132 ------- Algorithm-Improvement/Codeforces/README.md | 3 - .../Solutions/B.YetAnotherCoinProblem.py | 29 -- .../Solutions/C.PaprikaandPermutation.py | 35 -- .../Codeforces/Solutions/C.SashaAndCasino.py | 17 - .../Solutions/D.SashaandaWalkintheCity.cpp | 47 --- .../Solutions/E.SashaAndTreeCutting.cpp | 93 ----- .../Solutions/F.ZeroRemainderSum.cpp | 49 --- .../Leetcode/Implementation.md | 90 ----- Algorithm-Improvement/Leetcode/README.md | 17 - .../3104.FindLongestSelfContainedSubstring.py | 42 --- Algorithm-Improvement/MISC/README.md | 3 - Algorithm-Improvement/README.md | 9 - .../CPP/BeginnerOOP/README.md | 354 ------------------ Language-Improvement/CPP/CRTP1.md | 31 -- Language-Improvement/CPP/README.md | 10 - Language-Improvement/CPP/Vtables/README.md | 72 ---- Language-Improvement/Python/README.md | 3 - Language-Improvement/README.md | 11 - Language-Improvement/Rust/README.md | 3 - Language-Improvement/Typescript/README.md | 5 - MISC/Internships/README.md | 172 --------- MISC/README.md | 7 - Math/BayesianStatistics.md | 67 ---- Math/README.md | 7 - content/algos/index.md | 4 +- content/langs/index.md | 2 +- 27 files changed, 3 insertions(+), 1311 deletions(-) delete mode 100644 Algorithm-Improvement/Codeforces/Implementation.md delete mode 100644 Algorithm-Improvement/Codeforces/README.md delete mode 100644 Algorithm-Improvement/Codeforces/Solutions/B.YetAnotherCoinProblem.py delete mode 100644 Algorithm-Improvement/Codeforces/Solutions/C.PaprikaandPermutation.py delete mode 100644 Algorithm-Improvement/Codeforces/Solutions/C.SashaAndCasino.py delete mode 100644 Algorithm-Improvement/Codeforces/Solutions/D.SashaandaWalkintheCity.cpp delete mode 100644 Algorithm-Improvement/Codeforces/Solutions/E.SashaAndTreeCutting.cpp delete mode 100644 Algorithm-Improvement/Codeforces/Solutions/F.ZeroRemainderSum.cpp delete mode 100644 Algorithm-Improvement/Leetcode/Implementation.md delete mode 100644 Algorithm-Improvement/Leetcode/README.md delete mode 100644 Algorithm-Improvement/Leetcode/Solutions/3104.FindLongestSelfContainedSubstring.py delete mode 100644 Algorithm-Improvement/MISC/README.md delete mode 100644 Algorithm-Improvement/README.md delete mode 100644 Language-Improvement/CPP/BeginnerOOP/README.md delete mode 100644 Language-Improvement/CPP/CRTP1.md delete mode 100644 Language-Improvement/CPP/README.md delete mode 100644 Language-Improvement/CPP/Vtables/README.md delete mode 100644 Language-Improvement/Python/README.md delete mode 100644 Language-Improvement/README.md delete mode 100644 Language-Improvement/Rust/README.md delete mode 100644 Language-Improvement/Typescript/README.md delete mode 100644 MISC/Internships/README.md delete mode 100644 MISC/README.md delete mode 100644 Math/BayesianStatistics.md delete mode 100644 Math/README.md diff --git a/Algorithm-Improvement/Codeforces/Implementation.md b/Algorithm-Improvement/Codeforces/Implementation.md deleted file mode 100644 index a376751..0000000 --- a/Algorithm-Improvement/Codeforces/Implementation.md +++ /dev/null @@ -1,132 +0,0 @@ -# A Record of Questions I've Implemented - -## Contest 931 - [E. Sasha And Tree Cutting](https://codeforces.com/problemset/problem/1929/E) - -This problem is from a recent competition is rated 2300. This is the highest rated problem I have ever done to date. - -This problem has several moving parts so lets break them down 1 by 1. -First consider the various paths. -Do you have to deal with these paths, and if so, how? -We can get the edges of a path through a simple dfs. -Now, let's try holding all the edges of every path in memory. -What's the longest a path can be? -The answer is n-1 if it is a big linked list, so the total number of edges would be O(n\*k) which is not great. -We only want to color one edge so why do we need the entire edge set for every path? -We can describe each edge by the number of paths that go through it. -This way we don't have to consider n*k edges which have the same paths and as a result are functionally identical. -We can represent each path as a bitset or integer of k bits where k is at most 20. -An edge will have a binary value 101 if paths 0 and 2 goes through it and path 1 does not for example. - -Now, this might seem scary at first 2^20 (2^k) is only a little better than 100,000\*20 (n\*k) but it will become obvious that it's impossible to have 2^k possible path representations. -Since this is a tree, each path has the possibilityof either joining or diverging from a new path and they can only do so once each time because you can't join and leave multiple times. -So essentially, every time you add a new path, you add at most 2\*k more unique path bitsets. -Thus we are upper bounded by (2\*k)\*k/2 and this number will be no more than 400 (we can also round up to 1000 and it will still be fine). - -Now once we have all the unique bitsets for the paths we have to find the minimal combination of which will allow for all paths to be taken. -To do this we can perform a straightforward dp where we can either take or not take and edge. -The dp is the simplest part of this problem, the states are dp(current_bitset, current_edge) = min(dp(current_bitset | current_edge, next_edge) + 1, dp(current_bitset, next_edge)). - -This solution will be, at worst, O(n\*k (2^k)\*(k^2)). -The n\*k term comes from the dfs and the (2^k)\*(k^2) comes from dp(bitset, edges). - -My [code](/Algorithm-Improvement/Codeforces/Solutions/E.SashaAndTreeCutting.cpp) implements this dp. - -## Contest 931 - [B. Yet Another Coin Problem](https://codeforces.com/contest/1934/problem/B) - -This problem is from a recent competition and hasn't been rated yet. I would probably put it in the 1000-1400 range. - -At first glance it seems possible to perform dynamic programming on this problem. -This is a trap: the value of each number is 1e9. This will make your dp recurrence 1e9 * 5 which is way too much. - -What we can do is observe that 1 3 6 10 and 15 all have a common multiple of 30. -Any sufficiently high number will require multiple 30s. -This means we can just take many 30s as we need for free. -This can lower our dp to a manageable size. -Alternatively we can notice we will only ever want 2 10s, some number of 6s, etc and we can just use math to solve it. - -My [code](/Algorithm-Improvement/Codeforces/Solutions/B.YetAnotherCoinProblem.py) uses the dp followup. - -## Contest 926 - [Question D. Paprika and Permutation](https://codeforces.com/contest/1617/problem/C) - -This problem was rated 1300 in an old div-2. It's quite straightforward. - -If we have an item already in the permutation no need to change it. -If we see an item twice it must replace something smaller than it by half. -The reasoning for this is just that % can only create something of size n/2 - 1 or greater (try doing n%n-1 ... n%n/2-1, n%n/2). -If we see an item that is new we must replace it with the same. - -My [code](/Algorithm-Improvement/Codeforces/Solutions/C.PaprikaandPermutation.py). - -## Contest 926 - [Question D. Sasha and a Walk in the City](https://codeforces.com/contest/1929/problem/D) - -This problem was rated 1900 in a recent div-2. It's very hard. - -This question took me 3 hours to solve. - -I approached it like this: all the root nodes are completely free to include or exclude. -Any given path will only have 2 of them and they can only be the start and end. -So where do I go from there? -Consider the tree with the edges: 1-2 and 1-3. 3 and 2 can be our root nodes so how do I calculate how many good paths are in this tree? - -Well I know there is the empty set and the set of just 2 and the set of 1 from my previous realization that the roots are free. -Now in order to solve this further I realized I should probably consider their relationship to 1. -The set {2, 3} is valid because the simple paths 2-1-3 and 3-1-2 go through 2 and 3 at most 2 times. -Once I reach the node 1, I can choose to to include the path down to root 2 or the path down to root 3. -Now, I can find the number of sets that include both trees 2 and 3. I can do this by multiplying them together. So this gives us the ```value[node] = value[child_1] * value[child_2] * ...``` After I get all the values I can just sum, right? - -This is wrong. I don't always want go down every path. -I also have all the values = 1 at the end and the answer clearly isn't n. -So, I need to choose which path I can go down. This modification can be done by the following: -``` -value[node] = (value[child_1] + 1) * (value[child_2] + 1) * ... -``` -This makes sense because in our example, if I want to ever use 1, I can't choose both 2 and 3 so I need 1 more possiblity for both of them. - -It's easy to see if we color these nodes. -At the beginning we can do node 2, we can color that black. -Then we can color node 3 black too. -Now we get to the full tree 2-1-3. -We can color the following combinations black 1 & 2, 1 & 3, 2 & 3 and 1. -Now we have 4 + 1 + 1 = 6 nodes that have a black node. -Once I have this, I just need to consider the empty set. -To do that, I just add 1 to our answer. - -Thus my answer is $\sum value[node] + 1$. - -My [code](/Algorithm-Improvement/Codeforces/Solutions/D.SashaandaWalkintheCity.cpp) shows how to implement this approach. -This was a tough question so the explanation is not as good as it can be. I will revisit this soon - -## Contest 926 - [Question C. Sasha and the Casino](https://codeforces.com/contest/1929/problem/D) -This question was rated 1400 on a recent div-2 contest. - -This question is pretty mathematical so lets start with this: If you were a serial gambler with infinite money and playing roullette how would you make sure that you made out with at least one dollar? Well, the most surefire way is to bet one dollar on red and then keep betting half the amount of money you spent + 1 (amount_spent/2 + 1). Since you have infinite money, at some point you'll break even + 1. - -Back to the problem, Sasha always wins if he has infinite money but he wants to make back money if he wins on the Xth round. He needs a minimum amount of money to do that. If this minimum is less than what he has on round X he will win some money. Otherwise he will run out before he becomes profitable. - -At each round he needs to bet the amount_he_spent/(k - 1) + 1 to get more than he lost. The roulette here has more than 2 colors. Assuming I start by spending 1 I can just iterate through x rounds. Each round he spends just enough to make back what he would have lost, the worst case being he loses all X rounds (this is what I am looking for). - -[My code](/Algorithm-Improvement/Codeforces/Solutions/C.SashaAndCasino.py) has the implementation. - -## Contest 677 - Question F. Zero Remainder Sum -This question was rated 2100 but it's 3 years old and a div-3 so it would probably be something like a 1600 div-2 right now, maybe even less. - -I'll start with how I approached this problem: Assuming there is one row, how do I find the ways to select <= m/2 numbers? - -At each index, I can either take or not take the number. I can also take however much is needed at most. -I can represent this is as dp[ind][needed]. -It can go to the states dp[ind+1][needed-1] or dp[ind+1][needed]. -For now let's say this stores the maximum value that works. -Now lets make this multi-row. - -How do I do this? -Well for each row I can simply do the same process I did for a single row. -Now I can say that there exists a state dp[row][ind][needed] and it can go to the states dp[row][ind+1][needed-1] or dp[row][ind+1][needed]. -If ind == m that means I'm at the end of the row so dp[row][m][needed] becomes dp[row+1][0][m/2] because I go to a new row and start from the beginning while refreshing all our choices. -Another case is if needed ever hits 0 I just go to the next row so dp[row][ind][0] becomes dp[row+1][0][m/2]. - -Now, there is just one last problem. Our final value must be divisible by K. I can't just take the highest value at every index of our dp table since the final remainder must be 0. This means I need to track our current number as I can reach dp[row][ind][needed] multiple ways. -Obviously while this will give a correct answer, dp[row][ind][needed][num] is very expensive because num can be 75 * 75 * 35. -I can do better. Why do I need the exact number? -Our number will work if the remainder of num + remainder of future nums is 0. So all I need to store is the num which is of size K (75) and considerably smaller. - -[My code](/Algorithm-Improvement/Codeforces/Solutions/F.ZeroRemainderSum.cpp) has a line by line breakdown detailed explanation. \ No newline at end of file diff --git a/Algorithm-Improvement/Codeforces/README.md b/Algorithm-Improvement/Codeforces/README.md deleted file mode 100644 index bfc1389..0000000 --- a/Algorithm-Improvement/Codeforces/README.md +++ /dev/null @@ -1,3 +0,0 @@ -# Purpose - -I can't die a specialist. \ No newline at end of file diff --git a/Algorithm-Improvement/Codeforces/Solutions/B.YetAnotherCoinProblem.py b/Algorithm-Improvement/Codeforces/Solutions/B.YetAnotherCoinProblem.py deleted file mode 100644 index 0713f89..0000000 --- a/Algorithm-Improvement/Codeforces/Solutions/B.YetAnotherCoinProblem.py +++ /dev/null @@ -1,29 +0,0 @@ -import sys -from functools import lru_cache - -input = sys.stdin.readline - - -def solve(): - n = int(input()) - ans = max(n // 15 - 3, 0) - n -= ans * 15 - needed = dp((1, 3, 6, 10, 15), n) - print(needed + ans) - - -@lru_cache(None) -def dp(choose, rem): - lowest = float("inf") - if rem < 0: - return float("inf") - if rem == 0: - return 0 - for i in range(len(choose)): - lowest = min(lowest, 1 + dp(choose[i:], rem - choose[i])) - return lowest - - -t = int(input()) -for _ in range(t): - solve() diff --git a/Algorithm-Improvement/Codeforces/Solutions/C.PaprikaandPermutation.py b/Algorithm-Improvement/Codeforces/Solutions/C.PaprikaandPermutation.py deleted file mode 100644 index 0293b33..0000000 --- a/Algorithm-Improvement/Codeforces/Solutions/C.PaprikaandPermutation.py +++ /dev/null @@ -1,35 +0,0 @@ -from collections import deque -import sys - -input = sys.stdin.readline - - -def solve(): - n = int(input()) - a = list(map(int, input().split())) - seen = [0] * (n + 1) - a.sort() - missing = deque() - last_seen = 0 - ans = 0 - for i in a: - for num in range(last_seen + 1, min(n + 1, i)): - missing.append(num) - last_seen = num - last_seen = i - if i <= n and not seen[i]: - seen[i] = 1 - else: - if missing and missing[0] * 2 < i: - seen[missing.popleft()] = 1 - ans += 1 - else: - print(-1) - return - - print(ans) - - -t = int(input().strip()) -for _ in range(t): - solve() diff --git a/Algorithm-Improvement/Codeforces/Solutions/C.SashaAndCasino.py b/Algorithm-Improvement/Codeforces/Solutions/C.SashaAndCasino.py deleted file mode 100644 index 45c94de..0000000 --- a/Algorithm-Improvement/Codeforces/Solutions/C.SashaAndCasino.py +++ /dev/null @@ -1,17 +0,0 @@ -import sys - -input = sys.stdin.readline - - -def solve(): - k, x, a = map(int, input().split()) - willwin = 1 - for _ in range(x): - willwin += willwin // (k - 1) + 1 - - print("Yes" if willwin <= a else "No") - - -t = int(input().strip()) -for _ in range(t): - solve() diff --git a/Algorithm-Improvement/Codeforces/Solutions/D.SashaandaWalkintheCity.cpp b/Algorithm-Improvement/Codeforces/Solutions/D.SashaandaWalkintheCity.cpp deleted file mode 100644 index e38f49a..0000000 --- a/Algorithm-Improvement/Codeforces/Solutions/D.SashaandaWalkintheCity.cpp +++ /dev/null @@ -1,47 +0,0 @@ -#include -#include -#include -#include - -using namespace std; - -long long ans = 0; - -long long MOD = 998244353; - - -long long dfs(int ind, vector>& graph, int parent){ - long long buildup = 1; - for (int item: graph[ind]){ - if (item == parent) continue; - buildup *= dfs(item, graph, ind); - buildup %= MOD; - } - ans += buildup; - ans = ans % MOD; - return (buildup + 1)%MOD; -} - -void solve(){ - int n; std::cin>> n; - vector visited (n+1); - std::vector> graph(n+1); - for (int i = 0; i < n-1; ++i){ - int u, v; std::cin >> u >> v; - graph[u].push_back(v); - graph[v].push_back(u); - } - dfs(1, graph, 0); - cout << (ans + 1)%MOD << endl; -} - -int main(){ - cin.tie(nullptr); - ios::sync_with_stdio(false); - int t; - std::cin >> t; - while(t--){ - ans = 0; - solve(); - } -} \ No newline at end of file diff --git a/Algorithm-Improvement/Codeforces/Solutions/E.SashaAndTreeCutting.cpp b/Algorithm-Improvement/Codeforces/Solutions/E.SashaAndTreeCutting.cpp deleted file mode 100644 index a010c5e..0000000 --- a/Algorithm-Improvement/Codeforces/Solutions/E.SashaAndTreeCutting.cpp +++ /dev/null @@ -1,93 +0,0 @@ -#include -#include -#include -#include -using namespace std; - -#define ll long long -ll ans = 1e9; - -int seen[(1 << 20) + 3][21]; - -int tc = 0; -ll m; - -void dp(long long mask, const vector& edges, int ind, ll taken){ - // cout << "dp: " << mask << " " << taken << endl; - if (seen[mask][taken] == tc) return; - if (__builtin_popcountll(mask) == m){ - ans = min(ans, taken); - seen[mask][taken] = tc; - return; - } - if (ind == edges.size()){ - return; - } - //either take an edge or do not - // cout << mask << " " << taken << endl; - dp(mask, edges, ind+1, taken); - dp(mask | edges[ind], edges, ind+1, taken + 1); -} - -vector> dfs(int parent, int node, const map> &graph, int goal) { - if (node == goal) - return {{min(parent, node), max(parent, node)}}; - - for (int next : graph.at(node)) { - if (next == parent) - continue; - - auto path = dfs(node, next, graph, goal); - if (!path.empty()){ - path.push_back({min(parent, node), max(parent, node)}); - return path; - } - } - - return {}; -} - - -void solve(){ - ans = 1e9; - ll n; cin >> n; - map > a; - int j, k; - for (int i = 0; i < n-1; ++i){ - cin >> j >> k; - a[j].push_back(k); - a[k].push_back(j); - } - - cin >> m; - - map , ll> occs; - for (ll i{0}, u, v; i < m; ++i) { - cin >> u >> v; - for (const auto &edge : dfs(-1, u, a, v)) { - if (edge.first == -1) continue; - occs[edge] |= 1LL << i; - } - } - - set maskoccs; - - for(auto [edge, mask] : occs){ - maskoccs.insert(mask); - // cout << edge.first << " " << edge.second << " " << mask << endl; - } - vector edgeset (maskoccs.begin(), maskoccs.end()); - - dp(0, edgeset, 0, 0); - cout << ans << endl; -} - -int main(){ - ios::sync_with_stdio(false); cin.tie(nullptr); - int t; cin >> t; - while(t--) { - tc = t + 1; - solve(); - } - return 0; -} \ No newline at end of file diff --git a/Algorithm-Improvement/Codeforces/Solutions/F.ZeroRemainderSum.cpp b/Algorithm-Improvement/Codeforces/Solutions/F.ZeroRemainderSum.cpp deleted file mode 100644 index bcdae75..0000000 --- a/Algorithm-Improvement/Codeforces/Solutions/F.ZeroRemainderSum.cpp +++ /dev/null @@ -1,49 +0,0 @@ -#include -#include -#include - -using namespace std; - -int n, m, k; -vector> a; -vector>>> dp; - -int MOD = -1e9 - 7; - -int solve(int i, int j, int cur, int rem) { - if (i == n) { - return (rem == 0) ? 0 : MOD; // Is this a valid finish? - } - - if (j == m) - return solve(i + 1, 0, m/2, rem); // Go to the next line - - if (dp[i][j][cur][rem] != INT_MIN) // Seen - return dp[i][j][cur][rem]; - - int res = solve(i, j + 1, cur, rem); // Skip - - if (cur > 0) { - int newRem = (rem + a[i][j]) % k; // Remainer after taking - res = max(res, a[i][j] + solve(i, j + 1, cur - 1, newRem)); - } - // res is the best we can get if we take or skip - return dp[i][j][cur][rem] = res; -} - -int main() { - cin >> n >> m >> k; - a.assign(n, vector(m)); - dp.assign(n, vector>>(m, vector>(m / 2 + 1, vector(k, INT_MIN)))); - - for (int i = 0; i < n; ++i) { - for (int j = 0; j < m; ++j) { - cin >> a[i][j]; - } - } - - int result = solve(0, 0, m/2, 0); - cout << max(0, result) << endl; - - return 0; -} \ No newline at end of file diff --git a/Algorithm-Improvement/Leetcode/Implementation.md b/Algorithm-Improvement/Leetcode/Implementation.md deleted file mode 100644 index 6df237d..0000000 --- a/Algorithm-Improvement/Leetcode/Implementation.md +++ /dev/null @@ -1,90 +0,0 @@ -# A Record of Questions I've Implemented - -## [1249 - Minimum Remove to Make Valid Parentheses](https://leetcode.com/problems/minimum-remove-to-make-valid-parentheses/) - -If there is a ) and there are no ( before it, then it must be removed. -If there are ( at the end, remove them. - -```python -class Solution: - def minRemoveToMakeValid(self, s) : - stack=[] - split_str=list(s) - for i in range(len(s)): - if s[i]=='(': - stack.append(i) - elif s[i]==')': - if len(stack) !=0: - stack.pop() - else: - split_str[i]="" - for i in stack: - split_str[i]="" - return '' .join(split_str) -``` - - -not sure if its possible to one line this - -## [1614 - Maximum Nesting Depth of the Parentheses](https://leetcode.com/problems/maximum-nesting-depth-of-the-parentheses/description/) - -Easy daily. Find max depth using stack and return. -Two One line solutions below: -```c++ -class Solution { -public: - int maxDepth(string s) { - return accumulate(s.begin(), s.end(), make_pair(0, vector{0}), [](auto res, auto c) { - res.second.push_back(res.second.back() + (c == '(' ? 1 : (c == ')' ? -1 : 0))); - return make_pair(max(res.first, res.second.back()), res.second); - }).first; - } -}; -``` -and -```python -class Solution: - def maxDepth(self, s: str) -> int: - return max(accumulate([1 if (i == '(') else (-1 if i ==')' else 0) for i in s ])) -``` - -## [3104 - Find Longest Self Contained Substring](https://leetcode.com/problems/find-longest-self-contained-substring/) - -This problem was kind of trivial. -Here is the writeup I posted to the leetcode discussions: - -Intuition -A substring is valid if letters in the substring do not appear elsewhere. This means the first and last occurrence of a letter must be in the substring. - -Approach -Go through the string. Keep track of the first and last occurrences of each letter. We are also using a prefix sum to quickly determine which letters have been used and at what index. -Now, we can do combinations of the first and last occurrences of each letter. This is quadratic but since there are only 26 possibilities for letter combinations we are fine. - -Then we have to find which characters are used in the substring. This can be done by using a prefix sum and checking the counts of all the letters before and after the substring. These lines explain how: - -```python -for k in range(26): - if start[k] != stop[k]: - if stop[k] != 0: - bad = True - break - diffs.append(k) -``` -While doing this we also have to make sure that none of the letters used in the string have been used before and none are used after. These are checked in the below code on these lines -```python -if stop[k] != 0: - bad = True - break -``` -and -```python -if start[k] != prefix[0][k]: - bad = True - break -``` -Complexity -Time complexity: -O(n * 676) or O(n \* 26 \* 26) - -Space complexity: -O(n*26) diff --git a/Algorithm-Improvement/Leetcode/README.md b/Algorithm-Improvement/Leetcode/README.md deleted file mode 100644 index d5095d7..0000000 --- a/Algorithm-Improvement/Leetcode/README.md +++ /dev/null @@ -1,17 +0,0 @@ -# Purpose - -Read on [Github](https://github.com/TanzHasan/Learning/tree/main/Algorithm-Improvement/Leetcode) - -## History - -### 1249 (Medium) - Minimum Remove to Make Valid Parentheses -[Writeup](/Algorithm-Improvement/Leetcode/Implementation.md?#1249---minimum-remove-to-make-valid-parentheses) - -[Code](/Algorithm-Improvement/Leetcode/Implementation.md?#1249---minimum-remove-to-make-valid-parentheses) - -### 1614 (Easy) - Maximum Nesting Depth of the Parentheses -[Writeup](/Algorithm-Improvement/Leetcode/Implementation.md?#1614---maximum-nesting-depth-of-the-parentheses) - -[Code](/Algorithm-Improvement/Leetcode/Implementation.md?#1614---maximum-nesting-depth-of-the-parentheses) - -### 3104 (Hard) - Find Longest Self Contained Substring -[Writeup](/Algorithm-Improvement/Leetcode/Implementation.md?#3104---find-longest-self-contained-substring) - -[Code](/Algorithm-Improvement/Leetcode/Solutions/3104.FindLongestSelfContainedSubstring.py) diff --git a/Algorithm-Improvement/Leetcode/Solutions/3104.FindLongestSelfContainedSubstring.py b/Algorithm-Improvement/Leetcode/Solutions/3104.FindLongestSelfContainedSubstring.py deleted file mode 100644 index 3a72749..0000000 --- a/Algorithm-Improvement/Leetcode/Solutions/3104.FindLongestSelfContainedSubstring.py +++ /dev/null @@ -1,42 +0,0 @@ - -inf = float('inf') # this is done by LC -class Solution: - def maxSubstringLength(self, s: str) -> int: - offset = ord('a') - occurrences = [0]*26 - pos = [[inf, -inf] for _ in range(26)] - for i, letter in enumerate(s): - letter_ind = ord(letter) - offset - occurrences[letter_ind] += 1 - pos[letter_ind][0] = min(i, pos[letter_ind][0]) - pos[letter_ind][1] = max(i, pos[letter_ind][1]) - prefix = [occurrences] - for i in s: - prefix.append(list(prefix[-1])) - prefix[-1][ord(i)-offset]-=1 - ans = -1 - for i in range(26): - for j in range(26): - l, h = pos[i][0], pos[j][1] - if l > h: continue - if l == 0 and h == len(s)-1: continue - start = prefix[l] - stop = prefix[h+1] - diffs = [] - bad = False - for k in range(26): - if start[k] != stop[k]: - if stop[k] != 0: - bad = True - break - diffs.append(k) - if bad: - continue - for k in diffs: - if start[k] != prefix[0][k]: - bad = True - break - if bad: - continue - ans = max(ans, h+1-l) - return ans \ No newline at end of file diff --git a/Algorithm-Improvement/MISC/README.md b/Algorithm-Improvement/MISC/README.md deleted file mode 100644 index 9246141..0000000 --- a/Algorithm-Improvement/MISC/README.md +++ /dev/null @@ -1,3 +0,0 @@ -# Purpose - -I will be getting bodied by high schoolers and occasionally middle schoolers in USACO and other olympiads. \ No newline at end of file diff --git a/Algorithm-Improvement/README.md b/Algorithm-Improvement/README.md deleted file mode 100644 index 8e0941c..0000000 --- a/Algorithm-Improvement/README.md +++ /dev/null @@ -1,9 +0,0 @@ -# Algorithm Improvement - -# Websites - -## [Leetcode](/Learning/Algorithm-Improvement/Leetcode) - -## [Codeforces](/Learning/Algorithm-Improvement/Codeforces) - -## [MISC](/Learning/Algorithm-Improvement/MISC) \ No newline at end of file diff --git a/Language-Improvement/CPP/BeginnerOOP/README.md b/Language-Improvement/CPP/BeginnerOOP/README.md deleted file mode 100644 index 450dedd..0000000 --- a/Language-Improvement/CPP/BeginnerOOP/README.md +++ /dev/null @@ -1,354 +0,0 @@ -# Refreshing OOP Knowledge - -Lots of people have opinions on OOP. I'm not experienced enough to have a good take on the matter. My goal is to change that, of course. I, too, want to declare that OOP is an anti-pattern. - - -Below is a super basic class. - - -```c++ -class SuperBasic {}; -``` - -It doesn't actually do anything, so I'll make a less basic class. - - -```c++ -#include - -class Basic { - -private: - int a; - int b; -public: - //constructor - - Basic(int a, int b) : a(a), b(b) { - std::cout << "Creating" << std::endl; - } - //copy constructor - Basic(const Basic& other): a(other.a), b(other.b){ - std::cout << "Copying" << std::endl; - } - //assignment operator - Basic& operator=(const Basic& other){ - if (this == &other) return *this; - this->a = other.a; - this->b = other.b; - std::cout << "assigning" << std::endl; - return *this; - } - //destructor - ~Basic() { - std::cout << "Deleting" << std::endl; - } - int doSomething(){ - return a + b; - } -}; - -int main(){ - Basic a = Basic(1, 2); - Basic b = Basic(a); - Basic c = Basic(3, 2); - b = c; - std::cout << b.doSomething() << std::endl; -} -``` - - -This shows how to create 4 basic functions (constructor, copy, assignment, destructor), and running it will show how each of them of them are used. The destructor will be particularly important for preventing memory leaks, but that's not important for now. In addition, there is a public method we can use to do something with the class. - -Let's say I want an object that inherits from this Basic class. The way to do that would be the following: - -```c++ -class Advanced : public Basic { -public: - Advanced(int a, int b) : Basic(a,b){}; - - int doSomething(){ - return a * b; - } - - ~Advanced(){ - std::cout << "Deleting Advanced" << std::endl; - } -}; -``` - -This doesn't work because I declared items in Basic private. Let's fix that: - -```c++ -class Basic { -protected: - int a; - int b; - ... -``` - -Protected means it can be accessed by classes that inherit it. Now when I try the below we I expect to get 2: - -```c++ -int main(){ - Basic* a = new Advanced(1, 2); - std::cout << a->doSomething() << std::endl; - delete a; -} -``` - -I get 3. This is because I didn't override. To do that, I have to set the function I'm overriding to be virtual in the base class and add override to the derived class. I also don't see deleting advanced, so I have to set the Basic destructor to be virtual, too, which will make it so the pointer calls the derived destructor first. The reasoning behind adding virtual will be covered later when I discuss vtables and vptrs. - -```c++ -class Basic{ - ... - virtual ~Basic() { - std::cerr << "Deleting" << std::endl; - } - virtual int doSomething(){ - return a + b; - } -}; - -class Advanced : public Basic { -public: - Advanced(int a, int b) : Basic(a,b){}; - int doSomething() override { - return a * b; - } - ... -``` - -Now everything works as intended. So far, this is has been a very cursory overview of how classes work and some basic inheritance. I'm now going to use this for a bigger example to show how this would be used in practice. Traditionally this is taught with Animals eating or making noises. I'm going to gamble. - -```c++ -#include -#include -#include -#include - - -class Card { -public: - std::string suit; - std::string rank; - - Card(std::string suit, std::string rank) : suit(suit), rank(rank) {} -}; -``` - -First I'm going to include the necessary headers and then make a basic card class. -```c++ -#include -#include -#include -#include - -class Card { -public: - enum Suit { H, D, C, S }; - enum Rank { Two, Three, Four, Five, Six, Seven, Eight, Nine, Ten, J, Q, K, A }; - - Card(Suit suit, Rank rank) : suit(suit), rank(rank) {} - - Suit getSuit() const { return suit; } - Rank getRank() const { return rank; } - friend std::ostream& operator<<(std::ostream& os, const Card& card); -private: - Suit suit; - Rank rank; -}; - -std::ostream& operator<<(std::ostream& os, const Card& card) { - const char* suitNames[] = {"Hearts", "Diamonds", "Clubs", "Spades"}; - const char* rankNames[] = {"2", "3", "4", "5", "6", "7", "8", "9", "10", "Jack", "Queen", "King", "Ace"}; - - return os << rankNames[static_cast(card.rank)] << " of " << suitNames[static_cast(card.suit)]; -} -``` - -The enums here can be strings, it doesn't really matter for the purpose of this demonstration. The friend operator allows us to access private and protected members of a class from certain methods. In this case we can now std::cout a card. - -Using these cards I'll make a deck that I can shuffle, insert into, and deal from. Note that since I am using pointers to Card objects that are allocated on the heap with new, I need to clean them up with my destructor otherwise there will be a memory leak. - -```c++ -class Deck { -public: - Deck() { - for (int suit = 0; suit < 4; ++suit) { - for (int rank = 0; rank < 13; ++rank) { - cards.emplace_back(new Card(Card::Suit(suit), Card::Rank(rank))); - } - } - } - - void shuffle() { - std::shuffle(cards.begin(), cards.end(), std::default_random_engine {}); - } - - Card* dealCard() { - if (cards.empty()) { - throw std::out_of_range("Out of cards buddy..."); - } - Card* dealtCard = cards.back(); - cards.pop_back(); - return dealtCard; - } - - void insertCard(Card* newCard){ - cards.push_back(newCard); - this->shuffle(); - } - ~Deck(){ - for(Card* card: cards){ - delete card; - } - } - friend std::ostream& operator<<(std::ostream& os, const Deck& deck); - -private: - std::vector cards; -}; - -std::ostream& operator<<(std::ostream& os, const Deck& deck) { - for (const Card* card : deck.cards) { - os << *card << '\n'; - } - return os; -} -``` - -Up till now I've just been using what I've covered. Now we're going to make a Game class. There are many types of card games that all have sort of similar rules. For that reason this Game class will be an abstract class. It will have a purely virtual play method because different games can be played in different ways. - -```c++ -class Game { -public: - Game() : deck(nullptr) {}; - - virtual ~Game() { delete deck; } - - virtual void play() = 0; - - void chooseDeck (Deck* deck){ - this->deck = deck; - deck->shuffle(); - } - -protected: - Deck* deck; -}; -``` - -No matter the card game we'll probably want some or all of these methods. This is an abstract class and can't be instantiated. The reason for this is the line ```virtual void play() = 0;``` which creates the purely virtual function play. Since there is no default way to play a game, we can't create this class directly; we must inherit and override. I'm going to inherit these methods with 2 different types of games, Blackjack and Poker. - -```c++ -class Poker : public Game { -public: - Poker() : Game() {} - - void play() override { - if (this->deck == nullptr) throw std::out_of_range("No Deck..."); - std::cout << "Playing Poker..." << std::endl; - } - -}; - -class BlackJack : public Game { -public: - BlackJack() : Game() {} - - void play() override { - if (this->deck == nullptr) throw std::out_of_range("No Deck..."); - std::cout << "Playing BlackJack..." << std::endl; - } - -}; -``` - -These classes can use all the methods of the abstract class and override the purely virtual play method. Overriding play is a classic example of polymorphism, allowing objects of different classes to be treated as objects of a base class while still executing their own versions of the method. Polymorphism is very useful, especially when setting up something like the Casino class, which will take all types of Game objects. - -```c++ -class Casino { -public: - Casino(){ - for (int i = 0; i < 100; ++i) { - decks.emplace_back(new Deck); - } - } - - void startgame(Game& game){ - game.chooseDeck(decks.back()); - decks.pop_back(); - }; - - virtual ~Casino() { - for (Deck* deck: decks) { - delete deck; - } - } - -private: - std::vector decks; -}; - -int main() { - Casino vegas; - Poker losing; - BlackJack money; - // losing.play(); //will throw errors - // money.play(); - // Game emptygame; //Abstract class cannot be instantiated - vegas.startgame(losing); - vegas.startgame(money); - losing.play(); - money.play(); - return 0; -} -``` - -That covers the basic principles of OOP in C++. We could add more depth to the BlackJack and Poker classes, but that won't add anything OOP-wise. There are a few other topics to cover (vtables, vptrs, etc) which will be discussed in another Markdown file. Below are some of the terms used in this file and a little more depth about them: - -**Protected**: Data members of a class that are labeled protected can be accessed by inherited classes and friends. - -**Virtual**: Normally, C++ matches a function call with its definition at compile time. This is called static binding. Specifying virtual ensures that this is done in runtime instead. This is called dynamic binding. This is why doSomething printed 2 instead of 3 when we added the virtual keyword because it got dynamically linked Advanced::doSomething instead of Basic::doSomething even though it appeared to be a Basic pointer. - -**Purely Virtual**: The presence of these functions make a class abstract. Inherited classes must override this method if they want to be instantiated. - -**Abstract Classes**: These are classes that are designed specifically to be base classes and represent concepts (Game, Animal, Shape). They have one or more purely virtual functions. In our case, there is no way to play a Game. There are, however, ways to play Poker, Blackjack, and any other inherited classes. - -**Polymorphism**: The examples shown were example of runtime polymorphism using method overriding. There are other forms of polymorphism but they aren't OOP related. These are function overloading and method overloading which can be seen below. - -```c++ -//function overloading -void func(int a){ - std::cout << a << std::endl; -} - -void func(int a, int b){ //same name different parameters - std::cout << a + b << std::endl; -} - -int main() { - func(1); - func(1, 2); -} -``` - -```c++ -//method overloading -struct dummy{ - void func(int a){ - std::cout << a << std::endl; - } - - void func(int a, int b){ - std::cout << a + b << std::endl; - } -}; - -int main() { - dummy a; - a.func(1); - a.func(1, 2); -} -``` diff --git a/Language-Improvement/CPP/CRTP1.md b/Language-Improvement/CPP/CRTP1.md deleted file mode 100644 index 1aa9a88..0000000 --- a/Language-Improvement/CPP/CRTP1.md +++ /dev/null @@ -1,31 +0,0 @@ -# CRTP - -Many people use CRTP instead of OOP for static polymorphism. -CRTP can be used in cases where you know the type of the object at runtime. -Here is an example: - -```c++ -#include - -template -struct Base -{ - void impl(){std::cout << "Spooky";} -}; -struct D1 : public Base -{ - void impl(){std::cout << "D1\n";} -}; -struct D2 : public Base -{ - void impl(){std::cout << "D2\n";} -}; - -int main() -{ - D1 d1; d1.impl(); - D2 d2; d2.impl(); -} -``` - -In this case, we have a Base function and we can generate two more structs using D1 and D2 as the templates. \ No newline at end of file diff --git a/Language-Improvement/CPP/README.md b/Language-Improvement/CPP/README.md deleted file mode 100644 index 16ecf18..0000000 --- a/Language-Improvement/CPP/README.md +++ /dev/null @@ -1,10 +0,0 @@ -# Purpose -I do not have sufficient knowledge of CPP. - -I want to explore templating, and develop better practices. In this section, I will be discovering better ways to use CPP than I currently know. - -## History - -[Learned about Vtables](/Learning/Language-Improvement/CPP/Vtables) - -[Remembered Beginner OOP](/Learning/Language-Improvement/CPP/BeginnerOOP) diff --git a/Language-Improvement/CPP/Vtables/README.md b/Language-Improvement/CPP/Vtables/README.md deleted file mode 100644 index 2c36ff8..0000000 --- a/Language-Improvement/CPP/Vtables/README.md +++ /dev/null @@ -1,72 +0,0 @@ -# How does Virtual Work? - -## What are Vtables and how are they represented? -VTables (or virtual tables) are arrays of pointers to virtual functions. -They allow C++ to support dynamic dispatch (or run-time method binding). -Virtual functions are member functions of a C++ class that can be redefined in a child class. -A pointer to a vtable will exist as a datamember of all classes with virtual functions. -When I call a virtual method, I lookup the object's v-table and call the appropriate derived class method. - -Essentially allows the below behavior: -```c++ -#include - -struct Base{ - virtual int method(){ - return 1; - } -}; - -struct Derived: Base{ - int method() override{ - return 2; - } -}; - -int main(){ - Base* a = new Derived(); - // output is 2 - std::cout << a->method() << std::endl; - // The original can still be called with Base::method -} -``` - -So what does this look like under the hood? This is all compiler dependant but let's say I have the below code: -```c++ -struct Base{ - virtual int method(); - virtual int method2(); - virtual int method3(); -}; -``` -The compiler builds a table containing 3 function-pointers. This is a relatively small space overhead. Every object of type base will have a pointer to this object. - -Now lets say we have a Derived class. - -```c++ -struct Derived: Base { - int method() override; -}; -``` - -The compiler will build and store another static table in memory. -Since we don't add any more virtual functions the table is still of size 3. -Now, we can just use the same function pointers for method1 and method2, but we need to replace function pointer for method and any other things we might override. -The pointer for derived class objects will be to this new vtable. - -When we try to call a virtual function we dereference the pointer and use the function pointer to call the function. -This way we are able to figure out which function to use dynamically. -A good explanation of what goes on under the hood and in the hardware can be found [here](http://www.dietmar-kuehl.de/mirror/c++-faq/virtual-functions.html#faq-20.4). -Essentially there are three calls that go on in the hardware to fetch the location and load the function. - -## Why are Virtual Functions slow? - -Virtual functions need the extra steps to load the function from a vtable. -This naturally takes a little extra time. - -The real problem is that, since the compiler cannot know which functions are going to be called, it cannot inline or do many other optimizations. -This is the primary cause of slowness and why templates are often used in settings where performance is critical. -A stackexchange post going into more detail can be found [here](https://softwareengineering.stackexchange.com/questions/191637/in-c-why-and-how-are-virtual-functions-slower). - -Some work has been done for runtime optimizations that can decrease the impact of the lack of compile time optimization: [Profile Guided Optimization](https://learn.microsoft.com/en-us/cpp/build/profile-guided-optimizations?view=msvc-170). -I am not very familiar with it but it can allow for optimizations where the optimizer uses data from test runs to determine areas that need to be optimized. diff --git a/Language-Improvement/Python/README.md b/Language-Improvement/Python/README.md deleted file mode 100644 index 3409c3d..0000000 --- a/Language-Improvement/Python/README.md +++ /dev/null @@ -1,3 +0,0 @@ -# Purpose - -Python is easily my best language. In this section, I will be adding to my knowledge of Python's standard library and commonly used external libraries (numpy). diff --git a/Language-Improvement/README.md b/Language-Improvement/README.md deleted file mode 100644 index 9e41622..0000000 --- a/Language-Improvement/README.md +++ /dev/null @@ -1,11 +0,0 @@ -# Lots of Langugaes - -# Languages - -## [CPP](/Learning/Language-Improvement/CPP) - -## [Python](/Learning/Language-Improvement/Python) - -## [Rust](/Learning/Language-Improvement/Rust) - -## [Typescript](/Learning/Language-Improvement/Typescript) \ No newline at end of file diff --git a/Language-Improvement/Rust/README.md b/Language-Improvement/Rust/README.md deleted file mode 100644 index 7fe62a2..0000000 --- a/Language-Improvement/Rust/README.md +++ /dev/null @@ -1,3 +0,0 @@ -# Purpose - -It's blazing fast \ No newline at end of file diff --git a/Language-Improvement/Typescript/README.md b/Language-Improvement/Typescript/README.md deleted file mode 100644 index ec96153..0000000 --- a/Language-Improvement/Typescript/README.md +++ /dev/null @@ -1,5 +0,0 @@ -# Purpose - -I should really learn how to use this better. - -In this section, I will be exploring basic TS syntax, how it works, and new frameworks for both frontend and backend dev. \ No newline at end of file diff --git a/MISC/Internships/README.md b/MISC/Internships/README.md deleted file mode 100644 index f3192c2..0000000 --- a/MISC/Internships/README.md +++ /dev/null @@ -1,172 +0,0 @@ -# Internships - -If you are reading this, you have probably asked me how to get one, or someone sent this to you. - -There are two components to finding an internship: - -1. Getting the Interview -2. Passing the Interview - -# Table of Contents -- [Getting the Interview](#getting-the-interview) - - [How do you get your application viewed?](#how-do-you-get-your-application-viewed) - - [How do you prevent your application from being tossed out?](#how-do-you-prevent-your-application-from-being-tossed-out) - - [How do I format my resume?](#how-do-i-format-my-resume) - - [How do I get more resume content?](#how-do-i-get-more-resume-content) - - [Skipping the line](#skipping-the-line) -- [Passing the Interview](#passing-the-interview) - - [Behavioral Interviews](#behavioral-interviews) - - [Leetcode Interviews](#leetcode-interviews) - - [How do you study?](#how-do-you-study) - - [Write A Lot of Code Interviews](#write-a-lot-of-code-interviews) - - [Design Interviews](#design-interviews) - - [Language Specific Interviews](#language-specific-interviews) - - [Systems Interviews](#systems-interviews) - - [Machine Learning Interviews](#machine-learning-interviews) -- [Closing](#closing) - -## Getting the Interview - -### How do you get your application viewed? - -The first thing is to get your resume at the top of the stack as fast as possible. -This means finding and applying to a role as fast as possible. How do you do this? - -Well, there is the [simplify](https://github.com/SimplifyJobs/Summer2024-Internships) list of jobs. That's easy to use and if you check several times a day, you might find some applications as soon as they're posted. You could also try to find jobs as soon as they're posted. I will not tell you how to do this. You are a CS major; you should be able to figure this out. - -### How do you prevent your application from being tossed out? - -The second thing, once you get your resume viewed, is to not get your resume tossed out. How do you do that? - -The actual resume template doesn't matter nearly as much as the content. You can use [Jake's resume template](https://www.overleaf.com/latex/templates/jakes-resume/syzfjbzwjncs) and modify the LaTeX or make a Google doc. That's easy to use. - -### How do I format my resume? - -Now, how do you format the resume? It depends on the type of company you are applying for and who's looking at your resume. - -The traditional advice is to format bullets like this: "Achieved X by doing Y using Z." -This method is good at appealing to nontechnical recruiters, so you certainly want to have some of these. -Technical recruiters and hiring managers will care a lot more about Y and Z than traditional recruiters, so it is important to have extra points about the last two, in my opinion. - -Another point to note is that many companies hire juniors looking to convert them after graduation. Coincidentally, there is no easy way to check graduation dates. - -I would also like to remind you that if your end goal is to become a software engineer, becoming a marketing intern or having some other very unrelated internship is unlikely to help. - -### How do I get more resume content? - -If you have no experience, you might find it useful to do any of the following: - -1. Go to hackathons (no one will bully you, don't worry) -2. Do CS-related research -3. Make a nontrivial project (no YT video tutorials) -4. Try your hand at open-source commits. This is quite daunting, and you might find it easy to get into if you have used a particular open-source technology or if you join either [Google Summer of Code](https://summerofcode.withgoogle.com) or the [Major League Hacking Fellowship](https://fellowship.mlh.io/). -5. Excel in CS-related competitions. CTFs, programming competitions, etc. If you have done math competitions that will also help you significantly. -6. Unpaid internships. I hesitate to recommend this one, but if you can't do any of the above, providing free labor to a startup is a good way to get a foot in the door. That being said, make sure you're either learning or having fun. You don't want to be doing these unless necessary. -7. Get lucky. Self explanatory. - -Yes, these are hard. 120k+ in total compensation (this is an extreme lower bound) out of college is more than enough incentive, however. - -### Skipping the line - -Often you'll fail to do one or more of the above. -Maybe your resume isn't good, or you applied too late. -You can always cut the line. How? - -If you know someone willing to vouch for you, you can get a referral from them. Do not ask me, I will not refer you. - -Another way is finding someone at a company with sway who can get you directly into the recruiting pipeline. - -## Passing the Interview - -Interviews come in many flavors. I will be discussing vanilla, chocolate, strawberry, matcha, and a few others I have personally experienced. It's important to note that for technical interviews you should explain what you are doing. It is possible to solve the question and not move on or fail and move forward. - -### Behavioral Interviews - -The best advice is to talk to more people in real life. There is also the [STAR](https://www.vawizard.org/wiz-pdf/STAR_Method_Interviews.pdf) method for answering certain behavioral questions. - -Other than that, you may be asked to go into a resume deep dive, so know what you put on your resume and be able to explain it to both a technical and nontechnical audience. - -### Leetcode Interviews - -Many people do not like to do Leetcode. These are vitamins. Take them. - -Understanding Data Structures and Algorithms is important to passing many interviews. You will often get asked to use an algorithm or data structure in a creative way to solve a problem. - -#### How do you study? - -Take some time, maybe 30 minutes to 1 hour a day a few times a week, and put it into Leetcode. Try and make your way through a popular list such as [Grind75](https://www.techinterviewhandbook.org/grind75) before striking out on your own. - -Once you finish that list, you should primarily do mediums and hard problems (I suggest a ratio of 20% Easy, 60% Medium, and 20% Hard. Adjust as you get better). You will never curl 60s if you only do a few reps of 10s. Similarly, you will never be able to difficult questions if you only do easy ones. - -You should also do contests because they force you to sit for hours and bash your head against a problem until it breaks. These problems are also new, so it is one of the best technical mock interviews, and you can either do old problems virtually (the inferior method) or do the competitions live on Saturdays and Sundays. - -Optionally, you could also try your hand at [Codeforces](https://fellowship.mlh.io/) or [USACO](https://usaco.org/). These are significantly harder, and, in my opinion, more rewarding than Leetcode. They are also extremely overkill and less immediately useful. I would advise you to do Leetcode first. - -Once you can reliably solve hards, you won't fail most leetcode interviews. For context, I have failed to solve problems in only two pure algorithmic interviews (I passed the first interview and failed the second) for the entire hiring season of 2024. - -I find that most people who cannot solve easy leetcode questions or give up too quickly on them also tend to be bad programmers. -Realistically, you should be able to take a good crack at Two Sum even if you can't solve it optimally. - -### Write A Lot of Code Interviews - -This type of interview often gives you multiple problem statements that build on each other and want you to write clean code. If you write unmaintainable code, you will not be able to move from statement 1 to statement 2. *Completion* and *Quality* matter more than algorithmic ability here. - -An example is this: - -1) Implement a text editor where you can write to the end and remove from the end. -2) Now make it so you can move your cursor to the middle. -3) Add a *find* mechanism. -4) Add a *replace all* mechanism. -5) Make it so you can replace only the first X instances found. -6) ... - -You could also be asked a single open-ended problem statement. For example, "Write Tetris." These aren't all that hard. You just need to break them into manageable pieces. - -How do you pass this type of interview? Write clean and maintainable code. Write a lot of it. It often helps to write object-oriented code for these interviews, but that's not really necessary. - -### Design Interviews - -These will be pretty easy since you're most likely either an intern or a new grad. I've gotten this type of interview at a few places - -Usually, this comes in two flavors. Low-level and high-level. - -Low-level system design generally boils down to object-oriented programming. -For example, "make a package manager and code out these specific functionalities." -Usually, the code doesn't have to run. If it does, the problem is either small in scale or some code is already given to you. -High-level system design interviews will usually be talking and whiteboarding. -You're given a broad topic and it's your job to break it down into specific functionalities. -Your job is essentially to transform "Make Uber, Tinder, etc" into "Store data this way, Design X functionality this way, etc." -These are pretty easy because the bar is in the basement. -Just keep calm and break the problem down. You'll be fine. - -Here is a link for [system design concepts](https://github.com/donnemartin/system-design-primer), though I am certain you won't need it. - -### Language Specific Interviews - -I've only gotten a few of these. -These are usually "write a lot of code" interviews with an emphasis on a specific language. -You'll also be asked to talk about useful parts of the language or quirks of the language. -A C++ interview could consist mostly of templating or perhaps implementing functions from the standard library. -You could also be asked about trivia. I've heard questions like "What is your favorite version of C++" followed by "What came out in that version of C++". - -These interviews are uncommon and can generally only be passed by a familiarity with the underlying language. - -### Systems Interviews - -This is my umbrella term for low-level programming interviews. *Networking*, *operating systems*, and occasionally *computer architecture* will fall under this category. - -I will not claim to be an expert on these types of interviews. You will also not be asked these often, if at all. - -To my understanding, there are no easy ways to pass these interviews or practice for them, you just have to know and understand the material. Questions can be like this: "What is the fastest way of communicating between two processes" followed by "How does that work." - -### Machine Learning Interviews - -This is exactly what it sounds like. I am unfortunately also not an expert as I've only done a few. - -My only advice is to know how everything functions under the hood. I was asked to "implement KNN" in one interview and "K-Means Clustering" in another. You may be given access to Numpy and other libraries, you might not. - -There are also trivia deep dives to assess that you know how everything works. - -## Closing - -You can also find good advice on the [CS Majors](https://discord.com/invite/csmajors) and [CSCD](https://discord.com/invite/cscareers) discords. Just be consistent with whatever you do, and you will most likely be fine. diff --git a/MISC/README.md b/MISC/README.md deleted file mode 100644 index ca10b2a..0000000 --- a/MISC/README.md +++ /dev/null @@ -1,7 +0,0 @@ -# Purpose - -Random Stuff - -# History - -[Internships](/Learning/MISC/Internships) \ No newline at end of file diff --git a/Math/BayesianStatistics.md b/Math/BayesianStatistics.md deleted file mode 100644 index f828927..0000000 --- a/Math/BayesianStatistics.md +++ /dev/null @@ -1,67 +0,0 @@ -# Course Notes for Foundations of Data Science - - - -## Counting Example -Let's consider a bag with 4 balls. The probability of reaching in and grabbing a ball that is blue is p. I want to get the sequence Blue White Blue, sampling with replacement. How many ways are there to do this? With the below fractions its easy to count out the possibilities. - -| p | Number of Ways | Plausibility | -|---|---|---| -| 0 | 0 | 0 | -| .25 | 3 | .15 | -| .5 | 8 | .4 | -| .75 | 9 | .45 | -| 1 | 0 | 0 | - -Now I want to find the plausibility of finding B W B B. How do I do this? We can take our existing count and multiply by the number of ways to find another B. - -| p | Ways to Get BWB | Ways to get B | Plausibility| -|---|---|---|---| -| 0 | 0 | 0 | 0 | -| .25 | 3 | 1 | 3/46 | -| .5 | 8 | 2 | 16/46 | -| .75 | 9 | 3 | 27/46 | -| 1 | 0 | 4 | 0 | - -## Prior Distribution -A prior distribution could be any distribution (uniform, normal, lognormal etc). -If we have some predictions to start with, we could also use a beta distribution. The Probability Density Function(PDF) for a Beta X ∼ Beta(a, b): - -$f(x) -\begin{array}{cc} - \{ & - \begin{array}{cc} - \frac{1}{B(a,b)}x^{a-1} & 0