From 913896343eca11258dc17179862e259c089557e3 Mon Sep 17 00:00:00 2001 From: Benjamin Qi Date: Fri, 17 Jul 2020 16:38:28 -0400 Subject: [PATCH 1/5] move intro-greedy to bronze --- content/1_Intro/Running_Code.mdx | 16 +-- content/3_Bronze/Ad_Hoc.mdx | 72 ------------ content/3_Bronze/Intro_Greedy.mdx | 175 ++++++++++++++++++++++++++++++ content/4_Silver/Greedy.mdx | 95 ++-------------- content/ordering.ts | 2 +- 5 files changed, 191 insertions(+), 169 deletions(-) delete mode 100644 content/3_Bronze/Ad_Hoc.mdx create mode 100644 content/3_Bronze/Intro_Greedy.mdx diff --git a/content/1_Intro/Running_Code.mdx b/content/1_Intro/Running_Code.mdx index 59993d9..c36ecdd 100644 --- a/content/1_Intro/Running_Code.mdx +++ b/content/1_Intro/Running_Code.mdx @@ -68,16 +68,16 @@ Vim is probably the easiest way to print syntax-highlighted code on Mac, see the - Using `/usr/local/bin/subl` instead of `~/bin/subl` worked for me on OS X Mojave. - [Package - Sublime Linter (GCC)](https://packagecontrol.io/packages/SublimeLinter-gcc) - highlights compilation errors and warnings from `-Wall` +- [Package - Fast Olympic Coding](https://github.com/Jatana/FastOlympicCoding) (I don't use) + - test manager can be useful + - linting is covered by the above + - stress testing is covered in "Debugging" + - can't get debug to work + + - ## On Linux diff --git a/content/3_Bronze/Ad_Hoc.mdx b/content/3_Bronze/Ad_Hoc.mdx deleted file mode 100644 index 90bc7ef..0000000 --- a/content/3_Bronze/Ad_Hoc.mdx +++ /dev/null @@ -1,72 +0,0 @@ ---- -id: ad-hoc -title: Approaching Ad Hoc Problems -author: Michael Cao -description: "Tips on Ad Hoc problems (problems with no clear category) in the Bronze Division." -frequency: 2 ---- - -import { Problem } from "../models"; - -export const metadata = { - problems: { - general: [ - new Problem("Bronze", "Cow Tipping", "689", "Hard", false, [], "Cells in the last row and column can be toggled uniquely. Toggle the appropriate ones and then recurse to the rectangle in the previous row/column, and solve the same way."), - new Problem("Bronze", "Race", "989", "Very Hard", false, [], "Greedily increment/decrement Bessies speed to fit the conditions until her total distance exceeds K."), - ], - greedyTutorial: [ - new Problem("Bronze", "Mad Scientist", "1012", "Normal", false, [], ""), - ], - } -}; - -Some bronze problems don't fall into any specific category, such as compete search or rectangle geometry, and often require more thought while also being easier to implement. Any problem that doesn't fall under any well-defined category can be labelled as **Ad Hoc**. - -Since Ad Hoc problems don't fall under any specific category, they can be hard to generalize, so there is no fixed algorithm or idea to solving these problems. In this module, we'll go over some general tips that may be useful in approaching these problems and present some practice problems. - -## Tips for Approaching Ad Hoc Problems - - -These tips are helpful in solving Ad Hoc problems. However, in the end, the best way to get better at Ad Hoc problems (or any type of problems) is to do a lot of them. Try to solve as many practice problems below as you can, and click the solution sketch tab if you can't figure the solution out. - -## Greedy Problems - -One thing to note about Ad Hoc problems in the USACO Bronze division is that many of them, while difficult to categorize into specific algorithms or data structures, can be solved using **Greedy** techniques. While this idea will be covered more in future [modules](https://usaco-guide.netlify.app/silver/greedy), we'll introduce the general mindset in this section. - -When approaching a greedy problem, we want to make argument about the structure of the solution of the problem. Specifically, that certain "greedy" actions, or actions that create the best possible solution at some local point in the algorithm, will lead to an optimal solution at the end. - -Consider some possible greedy algorithms for the USACO Bronze problem "Mad Scientist." - - - - - - In this problem, the correct greedy solution is to continually flip the longest possible ranges of mismatching cows. - - Mad Scientist has an excellent [editorial](http://www.usaco.org/current/data/sol_breedflip_bronze_feb20.html) with a video solution and intuitive proof. - - It is highly recommended you read it to gain a better understanding of the greedy algorithm. - - -However, not all greedy problems in the bronze division necessarily require mathematical proofs of correctness. It is often sufficent to intuitively convince yourself your algorithm is correct. - - -Sometimes, if the algorithm is easy enough to implement, you don't even need to convince yourself it's correct: just let the online judge prove it for you by coding it and seeing if it passes. Competitive programmers refer to this as "Proof by AC," or "Proof by Accepted." - - - - - - - - - - - - - diff --git a/content/3_Bronze/Intro_Greedy.mdx b/content/3_Bronze/Intro_Greedy.mdx new file mode 100644 index 0000000..1643c22 --- /dev/null +++ b/content/3_Bronze/Intro_Greedy.mdx @@ -0,0 +1,175 @@ +--- +id: intro-greedy +title: Introduction to Greedy Algorithms +author: Michael Cao, Darren Yao +description: "Selecting the optimal choice at each step in your algorithm without looking at the solution space as a whole." +frequency: 2 +--- + +import { Problem } from "../models"; + +export const metadata = { + problems: { + tutorial: [ + new Problem("Bronze", "Mad Scientist", "1012", "Normal", false, [], ""), + ], + general: [ + new Problem("Bronze", "Cow Tipping", "689", "Hard", false, [], "Cells in the last row and column can be toggled uniquely. Toggle the appropriate ones and then recurse to the rectangle in the previous row/column, and solve the same way."), + new Problem("Bronze", "Race", "989", "Very Hard", false, [], "Greedily increment/decrement Bessies speed to fit the conditions until her total distance exceeds K."), + ], + } +}; + +## Ad Hoc + +Most bronze problems fall into specific categories, such as simulation and complete search. Those which don't often require more thought, although they are not necessarily more difficult to implement. + +Any problem that doesn't fall under any well-defined category can be labelled as **Ad Hoc**. Since there is no fixed algorithm or idea to solving these problems, they can be hard to generalize. In this module, we'll go over some general tips that may be useful in approaching these problems. + +
    +
  • Draw lots of small cases to gain a better understanding of the problem. If you're having trouble debugging, draw more cases. If you don't know how to start with a problem, draw more cases. Whenever you don't know how to further approach a problem, you're probably missing an important observation, so draw more cases and make observations about properties of the problem.
  • +
  • Whenever you find an observation that seems useful, write it down! Writing down ideas lets you easily come back to them later, and makes sure you don't forget about ideas that could potentially be the solution.
  • +
  • Don't get stuck on any specific idea, unless you see an entire solution. Trying to complete search an Ad Hoc problem could end up wasting a lot of your time in contest.
  • +
  • Try to approach the problem from a lot of different perspectives. Try to draw a visual depiction of the problem, mess around with formulas, or draw a graph (see Graph Theory module). One of the most helpful things you can do when solving Ad Hoc problems is to keep trying ideas until you make progress. This is something you get better at as you do more problems.
  • +
+ +These tips are helpful in solving Ad Hoc problems. However, in the end, the best way to get better at Ad Hoc problems (or any type of problems) is to do a lot of them. Try to solve as many practice problems below as you can, and click the solution sketch tab if you can't figure the solution out. + +## Greedy Algorithms + +Most USACO Bronze problems that appear to be Ad Hoc can actually be solved using **greedy** algorithms. This idea will be covered in a future [module](../silver/greedy), but we'll introduce the general mindset in this section. + + + other examples are outside scope of bronze + + +From the above: + +> A **greedy** algorithm constructs a solution to the problem by always making a +choice that looks the best at the moment. A greedy algorithm never takes back +its choices, but directly constructs the final solution. For this reason, greedy +algorithms are usually very efficient. + +**Greedy** does not refer to a single algorithm, but rather a way of thinking that is applied to problems; there's no one way to do greedy algorithms. Hence, we use a selection of well-known examples to help you understand the greedy paradigm. + +### Example: Studying Algorithms + +Steph wants to improve her knowledge of algorithms over winter break. She has a total of $X$ ($1 \leq X \leq 10^4$) minutes to dedicate to learning algorithms. There are $N$ ($1 \leq N \leq 100$) algorithms, and each one of them requires $a_i$ ($1 \leq a_i \leq 100$) minutes to learn. Find the maximum number of algorithms she can learn. + +#### Solution + + + +The first observation we make is that Steph should prioritize learning algorithms from easiest to hardest; in other words, start with learning the algorithm that requires the least amount of time, and then choose further algorithms in increasing order of time required. Let's look at the following example: + +$$ +X = 15, \qquad N = 6, \qquad a_i = \{ 4, 3, 8, 4, 7, 3 \} +$$ + +After sorting the array, we have $\{ 3, 3, 4, 4, 7, 8 \}$. Within the maximum of 15 minutes, Steph can learn four algorithms in a total of $3+3+4+4 = 14$ minutes. + +The implementation of this algorithm is very simple. We sort the array, and then take as many elements as possible while the sum of times of algorithms chosen so far is less than $X$. Sorting the array takes $O(N \log N)$ time, and iterating through the array takes $O(N)$ time, for a total time complexity of $O(N \log N)$. + + + + + +```cpp +// read in the input, store the algorithms in a vector, algorithms +sort(algorithms.begin(), algorithms.end()); +int count = 0; // number of minutes used so far +int i = 0; +while(count + algorithms[i] <= x){ + // while there is enough time, learn more algorithms + count += algorithms[i]; + i++; +} +cout << i << endl; // print the ans +``` + + + + + +```java +// read in the input, store the algorithms in int[] algorithms +Arrays.sort(algorithms); +int count = 0; // number of minutes used so far +int i = 0; +while(count + algorithms[i] <= x){ + // while there is enough time, learn more algorithms + count += algorithms[i]; + i++; +} +pw.println(i); // print the ans +pw.close(); +``` + + + + + + + +### When Greedy Fails + +We'll provide a few common examples of when greedy fails, so that you can avoid falling into obvious traps and wasting time getting wrong answers in contest. + +#### Coin Change + +This problem gives several coin denominations, and asks for the minimum number of coins needed to make a certain value. Greedy algorithms can be used to solve this problem only in very specific cases (it can be proven that it works for the American as well as the Euro coin systems). However, it doesn't work in the general case. For example, let the coin denominations be $\{1, 3, 4\}$, and say the value we want is 6. The optimal solution is $\{3, 3\}$, which requires only two coins, but the greedy method of taking the highest possible valued coin that fits in the remaining denomination gives the solution $\{4, 1, 1\}$, which is incorrect. + +#### Knapsack + +The knapsack problem gives a number of items, each having a **weight** and a **value**, and we want to choose a subset of these items. We are limited to a certain weight, and we want to maximize the value of the items that we take. + +Let's take the following example, where we have a maximum capacity of 4: + +
+ +| Item | Weight | Value | Value Per Weight | +|------|--------|-------|------------------| +| A | 3 | 18 | 6 | +| B | 2 | 10 | 5 | +| C | 2 | 10 | 5 | + +
+ +If we use greedy based on highest value first, we choose item A and then we are done, as we don't have remaining weight to fit either of the other two. Using greedy based on value per weight again selects item A and then quits. However, the optimal solution is to select items B and C, as they combined have a higher value than item A alone. In fact, there is no working greedy solution. The solution to this problem uses **dynamic programming**, which is covered in gold. + +### Example: Mad Scientist + +Try to come up with a greedy algorithm for the USACO Bronze problem "Mad Scientist." + + + + + +In this problem, the correct greedy solution is to continually flip the longest possible ranges of mismatching cows. + +Mad Scientist has an excellent [editorial](http://www.usaco.org/current/data/sol_breedflip_bronze_feb20.html) with a video solution and intuitive proof. + +It is highly recommended you read it to gain a better understanding of the greedy algorithm. + + + +However, not all greedy problems in the bronze division necessarily require mathematical proofs of correctness. It is often sufficent to intuitively convince yourself your algorithm is correct. + + + +Sometimes, if the algorithm is easy enough to implement, you don't even need to convince yourself it's correct; just code it and see if it passes. Competitive programmers refer to this as "Proof by AC," or "Proof by Accepted." + + + + + +## Problems + + + + + + + + + diff --git a/content/4_Silver/Greedy.mdx b/content/4_Silver/Greedy.mdx index 4918872..188f764 100644 --- a/content/4_Silver/Greedy.mdx +++ b/content/4_Silver/Greedy.mdx @@ -3,9 +3,10 @@ id: greedy title: "Greedy Algorithms" author: Darren Yao prerequisites: + - intro-greedy - sorting-custom - intro-ordered -description: "Greedily selecting the optimal choice at each step in your algorithm instead of looking at the solution space as a whole." +description: "Continuation of greedy problems that were introduced in Bronze." frequency: 3 --- @@ -44,7 +45,7 @@ export const metadata = { }; - Module is based off this. + Module is based off this. @@ -52,74 +53,19 @@ export const metadata = {
-**Greedy** does not refer to a single algorithm, but rather a way of thinking that is applied to problems. There's no one way to do greedy algorithms. Hence, we use a selection of well-known examples to help you understand the greedy paradigm. - -Usually, when using a greedy algorithm, there is a **heuristic** or **value function** that determines which choice is considered most optimal. Here, we'll focus on problems where some sorting step is involved. +Usually, when using a greedy algorithm, there is a **heuristic** or **value function** that determines which choice is considered most optimal. (what's a heuristic or value function?) -## Example: Studying Algorithms +Here, we'll focus on problems where some sorting step is involved. -### Statement - -Steph wants to improve her knowledge of algorithms over winter break. She has a total of $X$ ($1 \leq X \leq 10^4$) minutes to dedicate to learning algorithms. There are $N$ ($1 \leq N \leq 100$) algorithms, and each one of them requires $a_i$ ($1 \leq a_i \leq 100$) minutes to learn. Find the maximum number of algorithms she can learn. - -### Solution - -The first observation we make is that Steph should prioritize learning algorithms from easiest to hardest; in other words, start with learning the algorithm that requires the least amount of time, and then choose further algorithms in increasing order of time required. Let's look at the following example: - -$$X = 15, \qquad N = 6, \qquad a_i = \{ 4, 3, 8, 4, 7, 3 \}$$ - -After sorting the array, we have $\{ 3, 3, 4, 4, 7, 8 \}$. Within the maximum of 15 minutes, Steph can learn four algorithms in a total of $3+3+4+4 = 14$ minutes. -The implementation of this algorithm is very simple. We sort the array, and then take as many elements as possible while the sum of times of algorithms chosen so far is less than $X$. Sorting the array takes $O(N \log N)$ time, and iterating through the array takes $O(N)$ time, for a total time complexity of $O(N \log N)$. - - - - - -```cpp -// read in the input, store the algorithms in a vector, algorithms -sort(algorithms.begin(), algorithms.end()); -int count = 0; // number of minutes used so far -int i = 0; -while(count + algorithms[i] <= x){ - // while there is enough time, learn more algorithms - count += algorithms[i]; - i++; -} -cout << i << endl; // print the ans -``` - - - - - -```java -// read in the input, store the algorithms in int[] algorithms -Arrays.sort(algorithms); -int count = 0; // number of minutes used so far -int i = 0; -while(count + algorithms[i] <= x){ - // while there is enough time, learn more algorithms - count += algorithms[i]; - i++; -} -pw.println(i); // print the ans -pw.close(); -``` - - - - - - -## The Scheduling Problem +## Example: The Scheduling Problem -There are $N$ events, each described by their starting and ending times. Jason would like to attend as many events as possible, but he can only attend one event at a time, and if he chooses to attend an event, he must attend the entire event. Traveling between events is instantaneous. +There are $N$ events, each described by their starting and ending times. You can only attend one event at a time, and if you choose to attend an event, you must attend the entire event. Traveling between events is instantaneous. What's the maximum number of events you can attend? ### Bad Greedy: Earliest Starting Next Event @@ -228,33 +174,6 @@ pw.close(); -## When Greedy Fails - -We'll provide a few common examples of when greedy fails, so that you can avoid falling into obvious traps and wasting time getting wrong answers in contest. - -### Coin Change - -This problem gives several coin denominations, and asks for the minimum number of coins needed to make a certain value. Greedy algorithms can be used to solve this problem only in very specific cases (it can be proven that it works for the American as well as the Euro coin systems). However, it doesn't work in the general case. For example, let the coin denominations be $\{1, 3, 4\}$, and say the value we want is 6. The optimal solution is $\{3, 3\}$, which requires only two coins, but the greedy method of taking the highest possible valued coin that fits in the remaining denomination gives the solution $\{4, 1, 1\}$, which is incorrect. - -### Knapsack - -The knapsack problem gives a number of items, each having a weight and a value, and we want to choose a subset of these items. We are limited to a certain weight, and we want to maximize the value of the items that we take. - -Let's take the following example, where we have a maximum capacity of 4: - -
- -| Item | Weight | Value | Value Per Weight | -|------|--------|-------|------------------| -| A | 3 | 18 | 6 | -| B | 2 | 10 | 5 | -| C | 2 | 10 | 5 | - -
- -If we use greedy based on highest value first, we choose item A and then we are done, as we don't have remaining weight to fit either of the other two. Using greedy based on value per weight again selects item A and then quits. However, the optimal solution is to select items B and C, as they combined have a higher value than item A alone. In fact, there is no working greedy solution. The solution to this problem uses **dynamic programming**, which is covered in gold. - - ## CSES Problems diff --git a/content/ordering.ts b/content/ordering.ts index c20bc3a..7a921de 100644 --- a/content/ordering.ts +++ b/content/ordering.ts @@ -62,7 +62,7 @@ const MODULE_ORDERING: {[key in SectionID]: Category[]} = { "time-comp", "simulation", "rect-geo", - "ad-hoc", + "intro-greedy", ] }, { From 6673aca3bf8281a0f855841f2a73b7c241fd9a9c Mon Sep 17 00:00:00 2001 From: Nathan Wang Date: Fri, 17 Jul 2020 15:20:26 -0700 Subject: [PATCH 2/5] update problems table styling --- src/components/markdown/Problems.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/markdown/Problems.tsx b/src/components/markdown/Problems.tsx index 06b8a85..c907ccc 100644 --- a/src/components/markdown/Problems.tsx +++ b/src/components/markdown/Problems.tsx @@ -29,7 +29,7 @@ export function ProblemsListComponent(props: ProblemsListComponentProps) { Source - + Problem Name From 6d5c0c6b9e8a10793400888c1643bd5ad0128891 Mon Sep 17 00:00:00 2001 From: Nathan Wang Date: Fri, 17 Jul 2020 16:23:58 -0700 Subject: [PATCH 3/5] lots of code refactors --- .prettierignore | 6 +- README.md | 4 +- .../Content Documentation.md | 2 + .../Front End Documentation.md | 0 .../ContactUsSlideover.tsx | 8 +- .../SlideoverForm.tsx | 0 .../ModuleFrequencyDots.tsx} | 2 +- src/components/ModuleLayout/ModuleLayout.tsx | 16 +- .../ModuleLayout/SidebarNav/SidebarNav.tsx | 1 - .../TableOfContents/TableOfContentsBlock.tsx | 26 +++ .../TableOfContentsSidebar.tsx | 37 ++++ .../genLinksFromTOCHeadings.tsx | 44 +++++ .../ModuleLayout/TableOfContentsBlock.tsx | 60 ------ .../ModuleLayout/TableOfContentsSidebar.tsx | 67 ------- .../{tooltip => Tooltip}/Asterisk.tsx | 0 .../{tooltip => Tooltip}/TextTooltip.tsx | 0 .../{tooltip => Tooltip}/Tooltip.tsx | 0 .../markdown/{ => CodeBlock}/CodeBlock.tsx | 0 .../SyntaxHighlighting/Highlight.js | 0 .../SyntaxHighlighting/prism.js | 0 src/components/markdown/HTMLComponents.tsx | 67 +++++++ src/components/markdown/IncompleteSection.tsx | 4 +- src/components/markdown/Info.tsx | 33 ++++ src/components/markdown/InlineCode.tsx | 10 + src/components/markdown/LanguageSection.tsx | 26 +-- src/components/markdown/MDXProvider.tsx | 175 ++---------------- src/components/markdown/Optional.tsx | 25 +++ .../ProblemsList}/ProblemStatusCheckbox.tsx | 8 +- .../ProblemsList.tsx} | 16 +- .../{Resources.tsx => ResourcesList.tsx} | 9 +- .../{SpoilerComponent.tsx => Spoiler.tsx} | 4 +- src/components/markdown/Warning.tsx | 31 ++++ src/context/UserDataContext.tsx | 6 + 33 files changed, 349 insertions(+), 338 deletions(-) rename Content Documentation.md => docs/Content Documentation.md (97%) rename Front End Documentation.md => docs/Front End Documentation.md (100%) rename src/components/{ => ContactUsSlideover}/ContactUsSlideover.tsx (98%) rename src/components/{Slideover => ContactUsSlideover}/SlideoverForm.tsx (100%) rename src/components/{Dots.tsx => ModuleLayout/ModuleFrequencyDots.tsx} (85%) create mode 100644 src/components/ModuleLayout/TableOfContents/TableOfContentsBlock.tsx create mode 100644 src/components/ModuleLayout/TableOfContents/TableOfContentsSidebar.tsx create mode 100644 src/components/ModuleLayout/TableOfContents/genLinksFromTOCHeadings.tsx delete mode 100644 src/components/ModuleLayout/TableOfContentsBlock.tsx delete mode 100644 src/components/ModuleLayout/TableOfContentsSidebar.tsx rename src/components/{tooltip => Tooltip}/Asterisk.tsx (100%) rename src/components/{tooltip => Tooltip}/TextTooltip.tsx (100%) rename src/components/{tooltip => Tooltip}/Tooltip.tsx (100%) rename src/components/markdown/{ => CodeBlock}/CodeBlock.tsx (100%) rename src/components/markdown/{ => CodeBlock}/SyntaxHighlighting/Highlight.js (100%) rename src/components/markdown/{ => CodeBlock}/SyntaxHighlighting/prism.js (100%) create mode 100644 src/components/markdown/HTMLComponents.tsx create mode 100644 src/components/markdown/Info.tsx create mode 100644 src/components/markdown/InlineCode.tsx create mode 100644 src/components/markdown/Optional.tsx rename src/components/{ => markdown/ProblemsList}/ProblemStatusCheckbox.tsx (81%) rename src/components/markdown/{Problems.tsx => ProblemsList/ProblemsList.tsx} (95%) rename src/components/markdown/{Resources.tsx => ResourcesList.tsx} (96%) rename src/components/markdown/{SpoilerComponent.tsx => Spoiler.tsx} (93%) create mode 100644 src/components/markdown/Warning.tsx diff --git a/.prettierignore b/.prettierignore index 29fcced..2309b38 100644 --- a/.prettierignore +++ b/.prettierignore @@ -1,5 +1,7 @@ .cache package.json -package-lock.json +yarn.lock public -content \ No newline at end of file +content +docs +static \ No newline at end of file diff --git a/README.md b/README.md index ef67b3a..1e7de56 100644 --- a/README.md +++ b/README.md @@ -9,8 +9,8 @@ As much as possible, please try to keep the markdown files independent of the fr ## Documentation -- To get this site running locally, refer to the [Front End Documentation](Front%20End%20Documentation.md). -- For information regarding Content Writing, refer to the [Content Documentation](Content%20Documentation.md). +- To get this site running locally, refer to the [Front End Documentation](docs/Front%20End%20Documentation.md). +- For information regarding Content Writing, refer to the [Content Documentation](docs/Content%20Documentation.md). ## Tech Stack diff --git a/Content Documentation.md b/docs/Content Documentation.md similarity index 97% rename from Content Documentation.md rename to docs/Content Documentation.md index 71f98ef..b9ee569 100644 --- a/Content Documentation.md +++ b/docs/Content Documentation.md @@ -1,5 +1,7 @@ ## Content Formatting Documentation +**Note:** It is highly recommended to [run a local version of the site](Front%20End%20Documentation.md) in order to view your changes. + All modules are written in [Markdown](https://www.markdownguide.org/cheat-sheet/). There are special additions to the markdown that we have added to this site. These special additions are still under development, so they may change frequently. If you are confused about something, or if there's a certain feature that you want to add, reach out to Nathan Wang. diff --git a/Front End Documentation.md b/docs/Front End Documentation.md similarity index 100% rename from Front End Documentation.md rename to docs/Front End Documentation.md diff --git a/src/components/ContactUsSlideover.tsx b/src/components/ContactUsSlideover/ContactUsSlideover.tsx similarity index 98% rename from src/components/ContactUsSlideover.tsx rename to src/components/ContactUsSlideover/ContactUsSlideover.tsx index 4ba4d6c..6decc17 100644 --- a/src/components/ContactUsSlideover.tsx +++ b/src/components/ContactUsSlideover/ContactUsSlideover.tsx @@ -1,9 +1,9 @@ import * as React from 'react'; -import { ModuleInfo } from '../models/module'; -import { SECTION_LABELS } from '../../content/ordering'; -import SlideoverForm from './Slideover/SlideoverForm'; +import { ModuleInfo } from '../../models/module'; +import { SECTION_LABELS } from '../../../content/ordering'; +import SlideoverForm from './SlideoverForm'; import { useState } from 'react'; -import useStickyState from '../hooks/useStickyState'; +import useStickyState from '../../hooks/useStickyState'; // Warning: this file is insanely messy. This should be rewritten soon :) diff --git a/src/components/Slideover/SlideoverForm.tsx b/src/components/ContactUsSlideover/SlideoverForm.tsx similarity index 100% rename from src/components/Slideover/SlideoverForm.tsx rename to src/components/ContactUsSlideover/SlideoverForm.tsx diff --git a/src/components/Dots.tsx b/src/components/ModuleLayout/ModuleFrequencyDots.tsx similarity index 85% rename from src/components/Dots.tsx rename to src/components/ModuleLayout/ModuleFrequencyDots.tsx index dd807e1..002f30c 100644 --- a/src/components/Dots.tsx +++ b/src/components/ModuleLayout/ModuleFrequencyDots.tsx @@ -1,6 +1,6 @@ import * as React from 'react'; -export default function Dots({ count, color, totalCount }) { +export default function ModuleFrequencyDots({ count, color, totalCount }) { const emptyCircle = 'text-gray-300'; return ( <> diff --git a/src/components/ModuleLayout/ModuleLayout.tsx b/src/components/ModuleLayout/ModuleLayout.tsx index 8af6437..e863ff0 100644 --- a/src/components/ModuleLayout/ModuleLayout.tsx +++ b/src/components/ModuleLayout/ModuleLayout.tsx @@ -13,17 +13,17 @@ import MODULE_ORDERING, { Category, SECTION_LABELS, } from '../../../content/ordering'; -import Dots from '../Dots'; -import ContactUsSlideover from '../ContactUsSlideover'; +import ModuleFrequencyDots from './ModuleFrequencyDots'; +import ContactUsSlideover from '../ContactUsSlideover/ContactUsSlideover'; import MarkCompleteButton from './MarkCompleteButton'; import ModuleConfetti from './ModuleConfetti'; -import TextTooltip from '../tooltip/TextTooltip'; +import TextTooltip from '../Tooltip/TextTooltip'; import UserDataContext, { UserLang } from '../../context/UserDataContext'; import { NavLinkGroup, SidebarNav } from './SidebarNav/SidebarNav'; import { graphqlToModuleLinks } from '../../utils'; import ModuleLayoutContext from '../../context/ModuleLayoutContext'; -import TableOfContentsSidebar from './TableOfContentsSidebar'; -import TableOfContentsBlock from './TableOfContentsBlock'; +import TableOfContentsSidebar from './TableOfContents/TableOfContentsSidebar'; +import TableOfContentsBlock from './TableOfContents/TableOfContentsBlock'; const Frequency = ({ frequency }: { frequency: ModuleFrequency }) => { const textColors = [ @@ -59,7 +59,11 @@ const Frequency = ({ frequency }: { frequency: ModuleFrequency }) => { - + {labels[frequency]} diff --git a/src/components/ModuleLayout/SidebarNav/SidebarNav.tsx b/src/components/ModuleLayout/SidebarNav/SidebarNav.tsx index bf53ae8..fa5416f 100644 --- a/src/components/ModuleLayout/SidebarNav/SidebarNav.tsx +++ b/src/components/ModuleLayout/SidebarNav/SidebarNav.tsx @@ -1,6 +1,5 @@ import * as React from 'react'; import { ModuleLinkInfo } from '../../../models/module'; -import { Link } from 'gatsby'; import ItemLink from './ItemLink'; import Accordion from './Accordion'; import MODULE_ORDERING, { Category } from '../../../../content/ordering'; diff --git a/src/components/ModuleLayout/TableOfContents/TableOfContentsBlock.tsx b/src/components/ModuleLayout/TableOfContents/TableOfContentsBlock.tsx new file mode 100644 index 0000000..46a87ff --- /dev/null +++ b/src/components/ModuleLayout/TableOfContents/TableOfContentsBlock.tsx @@ -0,0 +1,26 @@ +import * as React from 'react'; +import { TOCHeading } from '../../../models/module'; +import genLinksFromTOCHeadings from './genLinksFromTOCHeadings'; + +const TableOfContentsBlock = ({ + tableOfContents, +}: { + tableOfContents: TOCHeading[]; +}) => { + let links = genLinksFromTOCHeadings( + tableOfContents, + _ => + 'block mb-2 transition duration-150 ease-in-out text-gray-600 hover:underline hover:text-blue-600' + ); + return ( +
+

+ Table of Contents +

+ {links} +
+
+ ); +}; + +export default TableOfContentsBlock; diff --git a/src/components/ModuleLayout/TableOfContents/TableOfContentsSidebar.tsx b/src/components/ModuleLayout/TableOfContents/TableOfContentsSidebar.tsx new file mode 100644 index 0000000..37a5a7e --- /dev/null +++ b/src/components/ModuleLayout/TableOfContents/TableOfContentsSidebar.tsx @@ -0,0 +1,37 @@ +import * as React from 'react'; +import { TOCHeading } from '../../../models/module'; +import { Link } from 'gatsby'; +import { useActiveHash } from '../../../hooks/useActiveHash'; +import { useMemo } from 'react'; +import genLinksFromTOCHeadings from './genLinksFromTOCHeadings'; + +const TableOfContentsSidebar = ({ + tableOfContents, +}: { + tableOfContents: TOCHeading[]; +}) => { + const hashes = useMemo(() => tableOfContents.map(heading => heading.slug), [ + tableOfContents, + ]); + const activeHash = useActiveHash(hashes, '10px 0px 0px 0px'); + + let links = genLinksFromTOCHeadings( + tableOfContents, + heading => + 'block mb-1 text-sm transition duration-150 ease-in-out ' + + (activeHash === heading.slug + ? 'underline text-blue-600' + : 'text-gray-600 hover:underline hover:text-blue-600') + ); + + return ( +
+

+ Table of Contents +

+ {links} +
+ ); +}; + +export default TableOfContentsSidebar; diff --git a/src/components/ModuleLayout/TableOfContents/genLinksFromTOCHeadings.tsx b/src/components/ModuleLayout/TableOfContents/genLinksFromTOCHeadings.tsx new file mode 100644 index 0000000..1e37b35 --- /dev/null +++ b/src/components/ModuleLayout/TableOfContents/genLinksFromTOCHeadings.tsx @@ -0,0 +1,44 @@ +import { TOCHeading } from '../../../models/module'; +import * as React from 'react'; +import { Link } from 'gatsby'; + +export default function genLinksFromTOCHeadings( + headings: TOCHeading[], + getClasses: (heading: TOCHeading) => string +) { + let indentationLevels = ['0', '1.5rem', '3rem', '4.5rem']; + let links: React.ReactNode[] = []; + let curDepth = -1; + let indentIdx = 0; + headings.forEach((heading, idx) => { + if (curDepth === -1) curDepth = heading.depth; + if (heading.depth > curDepth) { + indentIdx++; + } else if (heading.depth < curDepth) { + indentIdx = Math.max(0, indentIdx - (curDepth - heading.depth)); + } + curDepth = heading.depth; + links.push( + heading.depth) || + (idx !== headings.length - 1 && + headings[idx + 1].depth > heading.depth)) + ? '1rem' + : indentIdx === 0 + ? '0.5rem' + : 0, + }} + > + {heading.value} + + ); + }); + return links; +} diff --git a/src/components/ModuleLayout/TableOfContentsBlock.tsx b/src/components/ModuleLayout/TableOfContentsBlock.tsx deleted file mode 100644 index efb0bfc..0000000 --- a/src/components/ModuleLayout/TableOfContentsBlock.tsx +++ /dev/null @@ -1,60 +0,0 @@ -import * as React from 'react'; -import { TOCHeading } from '../../models/module'; -import { Link } from 'gatsby'; -import { useActiveHash } from '../../hooks/useActiveHash'; -import { useMemo } from 'react'; - -// lol this file is basically idential to the sidebar file... should consolidate - -const TableOfContentsBlock = ({ - tableOfContents, -}: { - tableOfContents: TOCHeading[]; -}) => { - let links = []; - let curDepth = -1; - let indentIdx = 0; - let indent = ['0', '1.5rem', '3rem', '4.5rem']; - tableOfContents.forEach((heading, idx) => { - if (curDepth === -1) curDepth = heading.depth; - if (heading.depth > curDepth) { - indentIdx++; - } else if (heading.depth < curDepth) { - indentIdx = Math.max(0, indentIdx - (curDepth - heading.depth)); - } - curDepth = heading.depth; - links.push( - heading.depth) || - (idx !== tableOfContents.length - 1 && - tableOfContents[idx + 1].depth > heading.depth)) - ? '1rem' - : indentIdx === 0 - ? '0.5rem' - : 0, - }} - > - {heading.value} - - ); - }); - - return ( -
-

- Table of Contents -

- {links} -
-
- ); -}; - -export default TableOfContentsBlock; diff --git a/src/components/ModuleLayout/TableOfContentsSidebar.tsx b/src/components/ModuleLayout/TableOfContentsSidebar.tsx deleted file mode 100644 index 7fcfb59..0000000 --- a/src/components/ModuleLayout/TableOfContentsSidebar.tsx +++ /dev/null @@ -1,67 +0,0 @@ -import * as React from 'react'; -import { TOCHeading } from '../../models/module'; -import { Link } from 'gatsby'; -import { useActiveHash } from '../../hooks/useActiveHash'; -import { useMemo } from 'react'; - -const TableOfContentsSidebar = ({ - tableOfContents, -}: { - tableOfContents: TOCHeading[]; -}) => { - const hashes = useMemo(() => tableOfContents.map(heading => heading.slug), [ - tableOfContents, - ]); - const activeHash = useActiveHash(hashes, '10px 0px 0px 0px'); - - let links = []; - let curDepth = -1; - let indentIdx = 0; - let indent = ['0', '1.5rem', '3rem', '4.5rem']; - tableOfContents.forEach((heading, idx) => { - if (curDepth === -1) curDepth = heading.depth; - if (heading.depth > curDepth) { - indentIdx++; - } else if (heading.depth < curDepth) { - indentIdx = Math.max(0, indentIdx - (curDepth - heading.depth)); - } - curDepth = heading.depth; - links.push( - heading.depth) || - (idx !== tableOfContents.length - 1 && - tableOfContents[idx + 1].depth > heading.depth)) - ? '1rem' - : indentIdx === 0 - ? '0.5rem' - : 0, - }} - > - {heading.value} - - ); - }); - - return ( -
-

- Table of Contents -

- {links} -
- ); -}; - -export default TableOfContentsSidebar; diff --git a/src/components/tooltip/Asterisk.tsx b/src/components/Tooltip/Asterisk.tsx similarity index 100% rename from src/components/tooltip/Asterisk.tsx rename to src/components/Tooltip/Asterisk.tsx diff --git a/src/components/tooltip/TextTooltip.tsx b/src/components/Tooltip/TextTooltip.tsx similarity index 100% rename from src/components/tooltip/TextTooltip.tsx rename to src/components/Tooltip/TextTooltip.tsx diff --git a/src/components/tooltip/Tooltip.tsx b/src/components/Tooltip/Tooltip.tsx similarity index 100% rename from src/components/tooltip/Tooltip.tsx rename to src/components/Tooltip/Tooltip.tsx diff --git a/src/components/markdown/CodeBlock.tsx b/src/components/markdown/CodeBlock/CodeBlock.tsx similarity index 100% rename from src/components/markdown/CodeBlock.tsx rename to src/components/markdown/CodeBlock/CodeBlock.tsx diff --git a/src/components/markdown/SyntaxHighlighting/Highlight.js b/src/components/markdown/CodeBlock/SyntaxHighlighting/Highlight.js similarity index 100% rename from src/components/markdown/SyntaxHighlighting/Highlight.js rename to src/components/markdown/CodeBlock/SyntaxHighlighting/Highlight.js diff --git a/src/components/markdown/SyntaxHighlighting/prism.js b/src/components/markdown/CodeBlock/SyntaxHighlighting/prism.js similarity index 100% rename from src/components/markdown/SyntaxHighlighting/prism.js rename to src/components/markdown/CodeBlock/SyntaxHighlighting/prism.js diff --git a/src/components/markdown/HTMLComponents.tsx b/src/components/markdown/HTMLComponents.tsx new file mode 100644 index 0000000..8990922 --- /dev/null +++ b/src/components/markdown/HTMLComponents.tsx @@ -0,0 +1,67 @@ +import * as React from 'react'; +import classNames from 'classnames'; + +const OffsetAnchor = ({ id, ...props }) => ( + +); + +const HTMLComponents = { + table: ({ className, ...props }) => ( + + ), + th: ({ className, ...props }) => ( +
+ ), + td: ({ className, ...props }) => ( + + ), + h1: ({ id, children, ...props }) => ( +

+ + {children} +

+ ), + h2: ({ id, children, ...props }) => ( +

+ + {children} +

+ ), + h3: ({ id, children, ...props }) => ( +

+ + {children} +

+ ), + h4: ({ id, children, ...props }) => ( +

+ + {children} +

+ ), + p: props =>

, + 'ol.li': ({ children, ...props }) => ( +

  • +
    {children}
    +
  • + ), +}; + +export default HTMLComponents; diff --git a/src/components/markdown/IncompleteSection.tsx b/src/components/markdown/IncompleteSection.tsx index 6459006..51966a4 100644 --- a/src/components/markdown/IncompleteSection.tsx +++ b/src/components/markdown/IncompleteSection.tsx @@ -1,8 +1,6 @@ import * as React from 'react'; -import UserDataContext from '../../context/UserDataContext'; -import { useContext } from 'react'; -export const IncompleteSection = props => { +export const IncompleteSection = () => { return (
    This section is not complete. Feel free to file a request to diff --git a/src/components/markdown/Info.tsx b/src/components/markdown/Info.tsx new file mode 100644 index 0000000..b3a866d --- /dev/null +++ b/src/components/markdown/Info.tsx @@ -0,0 +1,33 @@ +import * as React from 'react'; + +const Info = ({ + children, + title, +}: { + children: React.ReactNode; + title: string; +}) => ( +
    +
    +
    + + + +
    +
    +

    {title}

    +
    {children}
    +
    +
    +
    +); + +export default Info; diff --git a/src/components/markdown/InlineCode.tsx b/src/components/markdown/InlineCode.tsx new file mode 100644 index 0000000..0c9bbf0 --- /dev/null +++ b/src/components/markdown/InlineCode.tsx @@ -0,0 +1,10 @@ +import * as React from 'react'; + +const InlineCode = props => ( + +); + +export default InlineCode; diff --git a/src/components/markdown/LanguageSection.tsx b/src/components/markdown/LanguageSection.tsx index e315f6a..30cb89e 100644 --- a/src/components/markdown/LanguageSection.tsx +++ b/src/components/markdown/LanguageSection.tsx @@ -1,10 +1,11 @@ import * as React from 'react'; -import UserDataContext from '../../context/UserDataContext'; +import UserDataContext, { + LANGUAGE_LABELS, +} from '../../context/UserDataContext'; import { useContext } from 'react'; export const LanguageSection = props => { - const userSettings = useContext(UserDataContext); - let lang = userSettings.lang; + const { lang } = useContext(UserDataContext); let sections = {}; React.Children.map(props.children, child => { @@ -13,24 +14,13 @@ export const LanguageSection = props => { if (type === 'JavaSection') sections['java'] = child; if (type === 'PySection') sections['py'] = child; }); - // props.children.forEach(child => { - // let type = child.props.mdxType; - // if (type === 'CPPSection') sections['cpp'] = child; - // if (type === 'JavaSection') sections['java'] = child; - // if (type === 'PySection') sections['py'] = child; - // }); - const languages = { - cpp: 'C++', - java: 'Java', - py: 'Python', - }; if (lang === 'showAll') { return ( <> {Object.keys(sections).map(lang => (
    -

    {languages[lang]}

    +

    {LANGUAGE_LABELS[lang]}

    {sections[lang]}
    ))} @@ -43,11 +33,11 @@ export const LanguageSection = props => {
    This section isn't yet available in your chosen language:{' '} - {languages[lang]}. + {LANGUAGE_LABELS[lang]}. {' '} Please choose a different default language for now. Feel free to file a - request to add support for {languages[lang]} using the "Contact Us" - button. + request to add support for {LANGUAGE_LABELS[lang]} using the "Contact + Us" button.
    ); } diff --git a/src/components/markdown/MDXProvider.tsx b/src/components/markdown/MDXProvider.tsx index 4fb8ba5..c9840e3 100644 --- a/src/components/markdown/MDXProvider.tsx +++ b/src/components/markdown/MDXProvider.tsx @@ -1,12 +1,11 @@ import * as React from 'react'; import { MDXProvider } from '@mdx-js/react'; -import SpoilerComponent from './SpoilerComponent'; -import { ProblemsListComponent } from './Problems'; -import { ResourceComponent, ResourcesListComponent } from './Resources'; -import CodeBlock from './CodeBlock'; -import classNames from 'classnames'; -import Asterisk from '../tooltip/Asterisk'; -import TextTooltip from '../tooltip/TextTooltip'; +import Spoiler from './Spoiler'; +import { ProblemsList } from './ProblemsList/ProblemsList'; +import { Resource, ResourcesList } from './ResourcesList'; +import CodeBlock from './CodeBlock/CodeBlock'; +import Asterisk from '../Tooltip/Asterisk'; +import TextTooltip from '../Tooltip/TextTooltip'; import { CPPSection, JavaSection, @@ -14,165 +13,31 @@ import { PySection, } from './LanguageSection'; import { IncompleteSection } from './IncompleteSection'; - -const OffsetAnchor = ({ id, ...props }) => ( - -); +import Info from './Info'; +import Warning from './Warning'; +import Optional from './Optional'; +import InlineCode from './InlineCode'; +import HTMLComponents from './HTMLComponents'; const components = { - 'module-excerpt': props =>
    , - spoiler: SpoilerComponent, - 'info-block': ({ - children, - title, - }: { - children: React.ReactNode; - title: string; - }) => ( -
    -
    -
    - - - -
    -
    -

    {title}

    -
    {children}
    -
    -
    -
    - ), - 'warning-block': ({ children, title }) => ( -
    -
    -
    - - - -
    -
    -

    - Warning{title ? ': ' + title : '!'} -

    -
    - {children} -
    -
    -
    -
    - ), - 'optional-content': ({ - children, - title, - className, - }: { - children: React.ReactNode; - title?: string; - className?: string; - }) => ( -
    -
    - - - - Optional{title ? `: ${title}` : ''} -
    -
    {children}
    -
    - ), - 'problems-list': ProblemsListComponent, - resources: ResourcesListComponent, - resource: ResourceComponent, + spoiler: Spoiler, + 'info-block': Info, + 'warning-block': Warning, + 'optional-content': Optional, + 'problems-list': ProblemsList, + resources: ResourcesList, + resource: Resource, code: CodeBlock, TextTooltip: TextTooltip, - inlineCode: props => ( - - ), + inlineCode: InlineCode, LanguageSection: LanguageSection, CPPSection: CPPSection, JavaSection: JavaSection, PySection: PySection, IncompleteSection: IncompleteSection, Asterisk: Asterisk, - table: ({ className, ...props }) => ( - - ), - th: ({ className, ...props }) => ( -
    - ), - td: ({ className, ...props }) => ( - - ), - h1: ({ id, children, ...props }) => ( -

    - - {children} -

    - ), - h2: ({ id, children, ...props }) => ( -

    - - {children} -

    - ), - h3: ({ id, children, ...props }) => ( -

    - - {children} -

    - ), - h4: ({ id, children, ...props }) => ( -

    - - {children} -

    - ), - p: props =>

    , - 'ol.li': ({ children, ...props }) => ( -

  • -
    {children}
    -
  • - ), + ...HTMLComponents, }; export default function ({ children }) { diff --git a/src/components/markdown/Optional.tsx b/src/components/markdown/Optional.tsx new file mode 100644 index 0000000..eaf5e57 --- /dev/null +++ b/src/components/markdown/Optional.tsx @@ -0,0 +1,25 @@ +import * as React from 'react'; + +const Optional = ({ + children, + title, + className, +}: { + children: React.ReactNode; + title?: string; + className?: string; +}) => ( +
    +
    + + + + Optional{title ? `: ${title}` : ''} +
    +
    {children}
    +
    +); + +export default Optional; diff --git a/src/components/ProblemStatusCheckbox.tsx b/src/components/markdown/ProblemsList/ProblemStatusCheckbox.tsx similarity index 81% rename from src/components/ProblemStatusCheckbox.tsx rename to src/components/markdown/ProblemsList/ProblemStatusCheckbox.tsx index 1adef0e..2d192fd 100644 --- a/src/components/ProblemStatusCheckbox.tsx +++ b/src/components/markdown/ProblemsList/ProblemStatusCheckbox.tsx @@ -1,9 +1,9 @@ import * as React from 'react'; -import Tooltip from './tooltip/Tooltip'; -import { Problem } from '../../content/models'; +import Tooltip from '../../Tooltip/Tooltip'; +import { Problem } from '../../../../content/models'; import { useContext } from 'react'; -import UserDataContext from '../context/UserDataContext'; -import { NEXT_PROBLEM_STATUS, ProblemProgress } from '../models/problem'; +import UserDataContext from '../../../context/UserDataContext'; +import { NEXT_PROBLEM_STATUS, ProblemProgress } from '../../../models/problem'; export default function ProblemStatusCheckbox({ problem, diff --git a/src/components/markdown/Problems.tsx b/src/components/markdown/ProblemsList/ProblemsList.tsx similarity index 95% rename from src/components/markdown/Problems.tsx rename to src/components/markdown/ProblemsList/ProblemsList.tsx index c907ccc..50b2a42 100644 --- a/src/components/markdown/Problems.tsx +++ b/src/components/markdown/ProblemsList/ProblemsList.tsx @@ -1,18 +1,18 @@ import * as React from 'react'; -import { Problem } from '../../../content/models'; -import Transition from '../Transition'; -import Tooltip from '../tooltip/Tooltip'; -import TextTooltip from '../tooltip/TextTooltip'; -import { sourceTooltip } from './Resources'; -import ProblemStatusCheckbox from '../ProblemStatusCheckbox'; +import { Problem } from '../../../../content/models'; +import Transition from '../../Transition'; +import Tooltip from '../../Tooltip/Tooltip'; +import TextTooltip from '../../Tooltip/TextTooltip'; +import { sourceTooltip } from '../ResourcesList'; +import ProblemStatusCheckbox from './ProblemStatusCheckbox'; -type ProblemsListComponentProps = { +type ProblemsListProps = { title?: string; children?: React.ReactChildren; problems: Problem[]; }; -export function ProblemsListComponent(props: ProblemsListComponentProps) { +export function ProblemsList(props: ProblemsListProps) { const [problem, setProblem] = React.useState(null); const [showModal, setShowModal] = React.useState(false); return ( diff --git a/src/components/markdown/Resources.tsx b/src/components/markdown/ResourcesList.tsx similarity index 96% rename from src/components/markdown/Resources.tsx rename to src/components/markdown/ResourcesList.tsx index c49d1bd..7308616 100644 --- a/src/components/markdown/Resources.tsx +++ b/src/components/markdown/ResourcesList.tsx @@ -1,11 +1,10 @@ import * as React from 'react'; -import Dots from '../Dots'; -import Tooltip from '../tooltip/Tooltip'; -import TextTooltip from '../tooltip/TextTooltip'; +import Tooltip from '../Tooltip/Tooltip'; +import TextTooltip from '../Tooltip/TextTooltip'; import { useContext } from 'react'; import UserDataContext from '../../context/UserDataContext'; -export function ResourcesListComponent(props) { +export function ResourcesList(props) { const embedded = props.embedded; return (
    @@ -91,7 +90,7 @@ export const sourceTooltip = { 'Old Gold': 'USACO Platinum did not exist prior to 2015-16.', }; -export function ResourceComponent(props) { +export function Resource(props) { const userSettings = useContext(UserDataContext); const source = props.source; diff --git a/src/components/markdown/SpoilerComponent.tsx b/src/components/markdown/Spoiler.tsx similarity index 93% rename from src/components/markdown/SpoilerComponent.tsx rename to src/components/markdown/Spoiler.tsx index 7810df7..08c2ec8 100644 --- a/src/components/markdown/SpoilerComponent.tsx +++ b/src/components/markdown/Spoiler.tsx @@ -1,6 +1,6 @@ import * as React from 'react'; -const SpoilerComponent = ({ children, title }) => { +const Spoiler = ({ children, title }) => { const [show, setShow] = React.useState(false); return ( @@ -44,4 +44,4 @@ const SpoilerComponent = ({ children, title }) => { ); }; -export default SpoilerComponent; +export default Spoiler; diff --git a/src/components/markdown/Warning.tsx b/src/components/markdown/Warning.tsx new file mode 100644 index 0000000..f827ab0 --- /dev/null +++ b/src/components/markdown/Warning.tsx @@ -0,0 +1,31 @@ +import * as React from 'react'; + +const Warning = ({ children, title }) => ( +
    +
    +
    + + + +
    +
    +

    + Warning{title ? ': ' + title : '!'} +

    +
    + {children} +
    +
    +
    +
    +); + +export default Warning; diff --git a/src/context/UserDataContext.tsx b/src/context/UserDataContext.tsx index 88243cd..cc43758 100644 --- a/src/context/UserDataContext.tsx +++ b/src/context/UserDataContext.tsx @@ -5,6 +5,12 @@ import { ModuleProgress } from '../models/module'; import { ProblemProgress } from '../models/problem'; export type UserLang = 'showAll' | 'cpp' | 'java' | 'py'; +export const LANGUAGE_LABELS: { [key in UserLang]: string } = { + showAll: 'All', + cpp: 'C++', + java: 'Java', + py: 'Python', +}; const UserDataContext = createContext<{ lang: UserLang; From 21610a686028de33bfd9844f4d2cf5755c7eddf7 Mon Sep 17 00:00:00 2001 From: Nathan Wang Date: Fri, 17 Jul 2020 16:34:37 -0700 Subject: [PATCH 4/5] add right click option to problem status checkbox --- .../ProblemsList/ProblemStatusCheckbox.tsx | 16 +++++++++++++-- src/models/problem.ts | 20 ++++++++++--------- 2 files changed, 25 insertions(+), 11 deletions(-) diff --git a/src/components/markdown/ProblemsList/ProblemStatusCheckbox.tsx b/src/components/markdown/ProblemsList/ProblemStatusCheckbox.tsx index 2d192fd..db67043 100644 --- a/src/components/markdown/ProblemsList/ProblemStatusCheckbox.tsx +++ b/src/components/markdown/ProblemsList/ProblemStatusCheckbox.tsx @@ -3,7 +3,11 @@ import Tooltip from '../../Tooltip/Tooltip'; import { Problem } from '../../../../content/models'; import { useContext } from 'react'; import UserDataContext from '../../../context/UserDataContext'; -import { NEXT_PROBLEM_STATUS, ProblemProgress } from '../../../models/problem'; +import { + NEXT_PROBLEM_STATUS, + PREV_PROBLEM_STATUS, + ProblemProgress, +} from '../../../models/problem'; export default function ProblemStatusCheckbox({ problem, @@ -25,6 +29,10 @@ export default function ProblemStatusCheckbox({ const handleClick = () => { setUserProgressOnProblems(problem, NEXT_PROBLEM_STATUS[status]); }; + const handleRightClick = e => { + e.preventDefault(); + setUserProgressOnProblems(problem, PREV_PROBLEM_STATUS[status]); + }; return ( - + Date: Fri, 17 Jul 2020 18:29:45 -0700 Subject: [PATCH 5/5] refactor components to improve consistency --- content/1_Intro/Choosing_Lang.mdx | 18 +- content/1_Intro/Code_Conventions.mdx | 6 +- content/1_Intro/Contests.mdx | 24 +- content/1_Intro/Data_Types.mdx | 10 +- content/1_Intro/Debugging_Cpp.mdx | 58 +- content/1_Intro/Expected.mdx | 20 +- content/1_Intro/Factors_Choosing.mdx | 12 +- content/1_Intro/Fast_IO.mdx | 60 +- content/1_Intro/Input_Output.mdx | 20 +- content/1_Intro/Intro.mdx | 18 +- content/1_Intro/Modules.mdx | 16 +- content/1_Intro/Olympiads.mdx | 24 +- content/1_Intro/Practicing.mdx | 6 +- content/{2_General => 1_Intro}/Proposing.mdx | 4 +- content/1_Intro/Running_Code.mdx | 88 +-- content/1_Intro/Tips.mdx | 36 +- content/1_Intro/USACO_Camp.mdx | 26 +- content/1_Intro/Using_This_Guide.mdx | 4 +- .../0_Bronze_Overview.md | 0 .../Complete_Search.mdx | 16 +- content/{3_Bronze => 2_Bronze}/Gen_Perm.mdx | 18 +- content/{3_Bronze => 2_Bronze}/Intro_DS.mdx | 16 +- .../{3_Bronze => 2_Bronze}/Intro_Graphs.mdx | 18 +- .../{3_Bronze => 2_Bronze}/Intro_Greedy.mdx | 22 +- .../{3_Bronze => 2_Bronze}/Pairs_Tuples.mdx | 20 +- content/{3_Bronze => 2_Bronze}/Rect_Geo.mdx | 26 +- content/{3_Bronze => 2_Bronze}/Simulation.mdx | 18 +- content/{3_Bronze => 2_Bronze}/Time_Comp.mdx | 744 +++++++++--------- content/{3_Bronze => 2_Bronze}/Unordered.mdx | 34 +- .../Binary_Search_Ans.mdx | 12 +- .../Binary_Search_Sorted.mdx | 36 +- .../{4_Silver => 3_Silver}/Custom_Cpp_STL.mdx | 6 +- content/{4_Silver => 3_Silver}/DFS.mdx | 38 +- content/{4_Silver => 3_Silver}/Flood_Fill.mdx | 16 +- .../{4_Silver => 3_Silver}/Func_Graphs.mdx | 10 +- content/{4_Silver => 3_Silver}/Greedy.mdx | 20 +- .../{4_Silver => 3_Silver}/Harder_Ordered.mdx | 8 +- .../{4_Silver => 3_Silver}/Intro_Ordered.mdx | 10 +- .../{4_Silver => 3_Silver}/Prefix_Sums.mdx | 28 +- content/{4_Silver => 3_Silver}/Sliding.mdx | 30 +- .../{4_Silver => 3_Silver}/Sorting_2_Old.mdx | 2 +- .../{4_Silver => 3_Silver}/Sorting_Custom.mdx | 16 +- .../Sorting_Methods.mdx | 8 +- .../{4_Silver => 3_Silver}/Sorting_Old.mdx | 14 +- .../{4_Silver => 3_Silver}/Stacks_Queues.mdx | 24 +- content/{5_Gold => 4_Gold}/.DS.swp | Bin content/{5_Gold => 4_Gold}/BFS.mdx | 22 +- content/{5_Gold => 4_Gold}/Cyc.mdx | 10 +- content/{5_Gold => 4_Gold}/DP.mdx | 38 +- content/{5_Gold => 4_Gold}/DP_Trees.mdx | 26 +- content/{5_Gold => 4_Gold}/DSU.mdx | 24 +- content/{5_Gold => 4_Gold}/Faster_Hash.mdx | 18 +- content/{5_Gold => 4_Gold}/Intro_NT.mdx | 16 +- content/{5_Gold => 4_Gold}/MST.mdx | 18 +- content/{5_Gold => 4_Gold}/PURQ.mdx | 30 +- content/{5_Gold => 4_Gold}/PURS.mdx | 46 +- content/{5_Gold => 4_Gold}/SP.mdx | 44 +- content/{5_Gold => 4_Gold}/SRQ.mdx | 26 +- content/{5_Gold => 4_Gold}/Springboards.mdx | 4 +- content/{5_Gold => 4_Gold}/String_Hashing.mdx | 22 +- content/{5_Gold => 4_Gold}/TopoSort.mdx | 30 +- content/{5_Gold => 4_Gold}/Tree_Euler.mdx | 20 +- .../{5_Gold => 4_Gold}/factoralgorithm1.png | Bin .../{5_Gold => 4_Gold}/factoralgorithm2.png | Bin content/{6_Plat => 5_Plat}/2DRQ.mdx | 40 +- content/{6_Plat => 5_Plat}/BCC_2CC.mdx | 26 +- content/{6_Plat => 5_Plat}/Bin_Jump.mdx | 18 +- content/{6_Plat => 5_Plat}/Bitsets.mdx | 48 +- content/{6_Plat => 5_Plat}/Centroid.mdx | 10 +- content/{6_Plat => 5_Plat}/DP_Bitmasks.mdx | 26 +- content/{6_Plat => 5_Plat}/DP_More.mdx | 8 +- content/{6_Plat => 5_Plat}/DP_Ranges.mdx | 2 +- content/{6_Plat => 5_Plat}/Dyna.mdx | 4 +- content/{6_Plat => 5_Plat}/Eulerian_Tours.mdx | 4 +- content/{6_Plat => 5_Plat}/Eulers_Formula.mdx | 6 +- content/{6_Plat => 5_Plat}/Flows.mdx | 24 +- content/{6_Plat => 5_Plat}/Fracture.mdx | 20 +- content/{6_Plat => 5_Plat}/Geo_Pri.mdx | 28 +- content/{6_Plat => 5_Plat}/HLD.mdx | 22 +- content/{6_Plat => 5_Plat}/Hull.mdx | 24 +- content/{6_Plat => 5_Plat}/LC.mdx | 24 +- content/{6_Plat => 5_Plat}/Lagrange.mdx | 10 +- content/{6_Plat => 5_Plat}/Merging.mdx | 26 +- content/{6_Plat => 5_Plat}/RURQ.mdx | 30 +- content/{6_Plat => 5_Plat}/SCC.mdx | 20 +- content/{6_Plat => 5_Plat}/SPneg.mdx | 24 +- content/{6_Plat => 5_Plat}/Seg_Ext.mdx | 18 +- content/{6_Plat => 5_Plat}/Slope.mdx | 50 +- content/{6_Plat => 5_Plat}/Sqrt.mdx | 20 +- content/5_Plat/String_Search.mdx | 90 +++ content/{6_Plat => 5_Plat}/Suffix_Array.mdx | 38 +- content/{6_Plat => 5_Plat}/Sweep_Line.mdx | 16 +- .../{7_Advanced => 6_Advanced}/Critical.mdx | 0 .../{7_Advanced => 6_Advanced}/FFT-ext.mdx | 22 +- content/{7_Advanced => 6_Advanced}/FFT.mdx | 0 .../Game_Theory.mdx | 4 +- content/{7_Advanced => 6_Advanced}/LCT.mdx | 8 +- .../Matroid_Isect.mdx | 0 .../MinCostFlow.mdx | 4 +- .../{7_Advanced => 6_Advanced}/More_Flows.mdx | 10 +- .../Multiplicative.mdx | 0 .../{7_Advanced => 6_Advanced}/Persistent.mdx | 4 +- .../Segtree_Beats.mdx | 8 +- .../String_Suffix.mdx | 0 content/{7_Advanced => 6_Advanced}/Treaps.mdx | 10 +- content/6_Plat/String_Search.mdx | 90 --- docs/Content Documentation.md | 25 +- docs/Front End Documentation.md | 5 +- .../CodeBlock/SyntaxHighlighting/prism.js | 2 +- src/components/markdown/HTMLComponents.tsx | 8 + src/components/markdown/Info.tsx | 6 +- src/components/markdown/InlineCode.tsx | 10 - src/components/markdown/MDXProvider.tsx | 32 +- src/styles/main.css | 10 +- 114 files changed, 1490 insertions(+), 1498 deletions(-) rename content/{2_General => 1_Intro}/Proposing.mdx (97%) rename content/{3_Bronze => 2_Bronze}/0_Bronze_Overview.md (100%) rename content/{3_Bronze => 2_Bronze}/Complete_Search.mdx (94%) rename content/{3_Bronze => 2_Bronze}/Gen_Perm.mdx (92%) rename content/{3_Bronze => 2_Bronze}/Intro_DS.mdx (95%) rename content/{3_Bronze => 2_Bronze}/Intro_Graphs.mdx (71%) rename content/{3_Bronze => 2_Bronze}/Intro_Greedy.mdx (95%) rename content/{3_Bronze => 2_Bronze}/Pairs_Tuples.mdx (94%) rename content/{3_Bronze => 2_Bronze}/Rect_Geo.mdx (93%) rename content/{3_Bronze => 2_Bronze}/Simulation.mdx (96%) rename content/{3_Bronze => 2_Bronze}/Time_Comp.mdx (93%) rename content/{3_Bronze => 2_Bronze}/Unordered.mdx (92%) rename content/{4_Silver => 3_Silver}/Binary_Search_Ans.mdx (97%) rename content/{4_Silver => 3_Silver}/Binary_Search_Sorted.mdx (72%) rename content/{4_Silver => 3_Silver}/Custom_Cpp_STL.mdx (96%) rename content/{4_Silver => 3_Silver}/DFS.mdx (75%) rename content/{4_Silver => 3_Silver}/Flood_Fill.mdx (94%) rename content/{4_Silver => 3_Silver}/Func_Graphs.mdx (91%) rename content/{4_Silver => 3_Silver}/Greedy.mdx (92%) rename content/{4_Silver => 3_Silver}/Harder_Ordered.mdx (95%) rename content/{4_Silver => 3_Silver}/Intro_Ordered.mdx (96%) rename content/{4_Silver => 3_Silver}/Prefix_Sums.mdx (95%) rename content/{4_Silver => 3_Silver}/Sliding.mdx (80%) rename content/{4_Silver => 3_Silver}/Sorting_2_Old.mdx (99%) rename content/{4_Silver => 3_Silver}/Sorting_Custom.mdx (97%) rename content/{4_Silver => 3_Silver}/Sorting_Methods.mdx (83%) rename content/{4_Silver => 3_Silver}/Sorting_Old.mdx (98%) rename content/{4_Silver => 3_Silver}/Stacks_Queues.mdx (90%) rename content/{5_Gold => 4_Gold}/.DS.swp (100%) rename content/{5_Gold => 4_Gold}/BFS.mdx (57%) rename content/{5_Gold => 4_Gold}/Cyc.mdx (90%) rename content/{5_Gold => 4_Gold}/DP.mdx (84%) rename content/{5_Gold => 4_Gold}/DP_Trees.mdx (89%) rename content/{5_Gold => 4_Gold}/DSU.mdx (61%) rename content/{5_Gold => 4_Gold}/Faster_Hash.mdx (87%) rename content/{5_Gold => 4_Gold}/Intro_NT.mdx (93%) rename content/{5_Gold => 4_Gold}/MST.mdx (69%) rename content/{5_Gold => 4_Gold}/PURQ.mdx (70%) rename content/{5_Gold => 4_Gold}/PURS.mdx (78%) rename content/{5_Gold => 4_Gold}/SP.mdx (71%) rename content/{5_Gold => 4_Gold}/SRQ.mdx (79%) rename content/{5_Gold => 4_Gold}/Springboards.mdx (96%) rename content/{5_Gold => 4_Gold}/String_Hashing.mdx (77%) rename content/{5_Gold => 4_Gold}/TopoSort.mdx (84%) rename content/{5_Gold => 4_Gold}/Tree_Euler.mdx (76%) rename content/{5_Gold => 4_Gold}/factoralgorithm1.png (100%) rename content/{5_Gold => 4_Gold}/factoralgorithm2.png (100%) rename content/{6_Plat => 5_Plat}/2DRQ.mdx (82%) rename content/{6_Plat => 5_Plat}/BCC_2CC.mdx (85%) rename content/{6_Plat => 5_Plat}/Bin_Jump.mdx (82%) rename content/{6_Plat => 5_Plat}/Bitsets.mdx (94%) rename content/{6_Plat => 5_Plat}/Centroid.mdx (81%) rename content/{6_Plat => 5_Plat}/DP_Bitmasks.mdx (71%) rename content/{6_Plat => 5_Plat}/DP_More.mdx (86%) rename content/{6_Plat => 5_Plat}/DP_Ranges.mdx (93%) rename content/{6_Plat => 5_Plat}/Dyna.mdx (88%) rename content/{6_Plat => 5_Plat}/Eulerian_Tours.mdx (89%) rename content/{6_Plat => 5_Plat}/Eulers_Formula.mdx (80%) rename content/{6_Plat => 5_Plat}/Flows.mdx (77%) rename content/{6_Plat => 5_Plat}/Fracture.mdx (97%) rename content/{6_Plat => 5_Plat}/Geo_Pri.mdx (60%) rename content/{6_Plat => 5_Plat}/HLD.mdx (78%) rename content/{6_Plat => 5_Plat}/Hull.mdx (76%) rename content/{6_Plat => 5_Plat}/LC.mdx (59%) rename content/{6_Plat => 5_Plat}/Lagrange.mdx (73%) rename content/{6_Plat => 5_Plat}/Merging.mdx (91%) rename content/{6_Plat => 5_Plat}/RURQ.mdx (70%) rename content/{6_Plat => 5_Plat}/SCC.mdx (76%) rename content/{6_Plat => 5_Plat}/SPneg.mdx (71%) rename content/{6_Plat => 5_Plat}/Seg_Ext.mdx (81%) rename content/{6_Plat => 5_Plat}/Slope.mdx (94%) rename content/{6_Plat => 5_Plat}/Sqrt.mdx (74%) create mode 100644 content/5_Plat/String_Search.mdx rename content/{6_Plat => 5_Plat}/Suffix_Array.mdx (56%) rename content/{6_Plat => 5_Plat}/Sweep_Line.mdx (68%) rename content/{7_Advanced => 6_Advanced}/Critical.mdx (100%) rename content/{7_Advanced => 6_Advanced}/FFT-ext.mdx (93%) rename content/{7_Advanced => 6_Advanced}/FFT.mdx (100%) rename content/{7_Advanced => 6_Advanced}/Game_Theory.mdx (95%) rename content/{7_Advanced => 6_Advanced}/LCT.mdx (94%) rename content/{7_Advanced => 6_Advanced}/Matroid_Isect.mdx (100%) rename content/{7_Advanced => 6_Advanced}/MinCostFlow.mdx (93%) rename content/{7_Advanced => 6_Advanced}/More_Flows.mdx (77%) rename content/{7_Advanced => 6_Advanced}/Multiplicative.mdx (100%) rename content/{7_Advanced => 6_Advanced}/Persistent.mdx (93%) rename content/{7_Advanced => 6_Advanced}/Segtree_Beats.mdx (71%) rename content/{7_Advanced => 6_Advanced}/String_Suffix.mdx (100%) rename content/{7_Advanced => 6_Advanced}/Treaps.mdx (94%) delete mode 100644 content/6_Plat/String_Search.mdx delete mode 100644 src/components/markdown/InlineCode.tsx diff --git a/content/1_Intro/Choosing_Lang.mdx b/content/1_Intro/Choosing_Lang.mdx index 8d8fb63..ac00d05 100644 --- a/content/1_Intro/Choosing_Lang.mdx +++ b/content/1_Intro/Choosing_Lang.mdx @@ -30,10 +30,10 @@ If you aren't comfortable with basic coding yet, you can use the resources below ### General - - courses for C++, Java, Python - free courses for C++, Java, Python 2 - + + courses for C++, Java, Python + free courses for C++, Java, Python 2 + @@ -41,15 +41,15 @@ If you aren't comfortable with basic coding yet, you can use the resources below Use one of the resources above or below (or find your own) to learn C++. If you use Sololearn, you don't have to complete the full course; we recommend you finish everything up to (but not including) "More on Classes." - - lots of examples, Kattis exercises - + + lots of examples, Kattis exercises + - + You do not need to learn pointers (for now). Knowledge of structs and classes is useful but not required. - + diff --git a/content/1_Intro/Code_Conventions.mdx b/content/1_Intro/Code_Conventions.mdx index e400251..f8d8e27 100644 --- a/content/1_Intro/Code_Conventions.mdx +++ b/content/1_Intro/Code_Conventions.mdx @@ -13,9 +13,9 @@ Everything should compile assuming that the templates below are included. If any ## General - - some material directly from this blog post - + + some material directly from this blog post + - Indenting with either tabs or 4 spaces is fine. - Binary operators should be spaced on both sides. For example, `a+b` should be written as `a + b` and `x=a+b` should be written as `x = a + b`. diff --git a/content/1_Intro/Contests.mdx b/content/1_Intro/Contests.mdx index 12a952d..913def2 100644 --- a/content/1_Intro/Contests.mdx +++ b/content/1_Intro/Contests.mdx @@ -54,23 +54,23 @@ See [clist.by](https://clist.by/coder/bqi343/) for an extensive list of contests Let me know if there's something else I should try to qualify for! - - 25 from R3 - 16; 4 from SRMs, 10 from R4, 2 from wildcard - 25 from R3 - 8 from AGC - + + 25 from R3 + 16; 4 from SRMs, 10 from R4, 2 from wildcard + 25 from R3 + 8 from AGC + ## US High School Only considering contests which allow C++ since the others aren't legit. (add more?) - - December, online, teams of 3, 5 hours, past problems on Kattis - Decmeber, online, individual, 4 hours - April, teams of 3, 3 hours, 2019 problems - online, teams of 4, 4 hours - + + December, online, teams of 3, 5 hours, past problems on Kattis + Decmeber, online, individual, 4 hours + April, teams of 3, 3 hours, 2019 problems + online, teams of 4, 4 hours + ## Codeforces Tools diff --git a/content/1_Intro/Data_Types.mdx b/content/1_Intro/Data_Types.mdx index b8b4e9a..670e666 100644 --- a/content/1_Intro/Data_Types.mdx +++ b/content/1_Intro/Data_Types.mdx @@ -7,11 +7,11 @@ prerequisites: - running-code --- - - module is based off this - - - + + module is based off this + + +
    diff --git a/content/1_Intro/Debugging_Cpp.mdx b/content/1_Intro/Debugging_Cpp.mdx index ef595e1..588c42c 100644 --- a/content/1_Intro/Debugging_Cpp.mdx +++ b/content/1_Intro/Debugging_Cpp.mdx @@ -11,29 +11,29 @@ description: "Debugging your code is an extremely important skill. Here are some - - + using a script to stress test - - + some parts from above video - - + + ### Style - - + {' '} don't agree with everything but important to read nonetheless - - + + ### Assertions & Warnings - - + includes static_assert and #define NDEBUG - - + + subset of above - - + #warning, #error - - + + ### Printing Variables @@ -95,17 +95,17 @@ Includes `-Wall -Wextra -Wshadow` [Variable shadowing](https://en.wikipedia.org/wiki/Variable_shadowing) should be avoided whenever possible. - - more options - + + more options + ### Other Options - + Ben - I don't use these because they can significantly slow down compilation time and I don't find these messages particularly helpful (But maybe I'm wrong? I'm not so familiar with these.) - + In Errichto's blog he says that he uses the following as part of his compilation command: @@ -135,7 +135,7 @@ zsh: segmentation fault ./prog `g++ prog.cpp -o prog -fsanitize=address && ./prog` produces: - + ``` AddressSanitizer:DEADLYSIGNAL @@ -157,11 +157,11 @@ SUMMARY: AddressSanitizer: SEGV (prog:x86_64+0x100001325) in main zsh: abort ./prog ``` - + Finally, `g++ prog.cpp -o prog -D_GLIBCXX_DEBUG -g && ./prog` produces: - + ``` /usr/local/Cellar/gcc/9.2.0_1/include/c++/9.2.0/debug/vector:427: @@ -184,7 +184,7 @@ Objects involved in the operation: zsh: abort ./prog ``` - + Another example with `prog.cpp` as the following: @@ -211,7 +211,7 @@ prog.cpp:6:13: runtime error: load of address 0x7ffee0a77a94 with insufficient s `g++ prog.cpp -o prog -fsanitize=address && ./prog` produces: - + ``` ================================================================= @@ -264,7 +264,7 @@ Shadow byte legend (one shadow byte represents 8 application bytes): zsh: abort ./prog ``` - + ## Running (on Mac) diff --git a/content/1_Intro/Expected.mdx b/content/1_Intro/Expected.mdx index f9d9db0..b3b50f6 100644 --- a/content/1_Intro/Expected.mdx +++ b/content/1_Intro/Expected.mdx @@ -40,24 +40,24 @@ In particular, contestants using Java should be familiar with roughly the first You may find the following resources helpful for familiarizing yourself with your language of choice. Resources below (including starred ones) are optional. - - can practice basics - lots of links! - basic problems, mostly loops - not up to date - generally good, although CSES problemset (see "Resources") is definitely a better place to start than USACO Training or Codechef - + + can practice basics + lots of links! + basic problems, mostly loops + not up to date + generally good, although CSES problemset (see "Resources") is definitely a better place to start than USACO Training or Codechef + ## Introductory Problems The following require relatively little programming experience and no algorithmic knowledge. - + Also check the [CSES Introductory Problems](https://cses.fi/problemset/list/) up to and including "Palindrome Reorder." Once you're done with these, you should continue onto Bronze. - + Some modules in the "Intro" section (ex. Fast Input & Output) are not relevant for USACO Bronze contestants. It is probably best to skip these for now and return to these later. However, make sure to check [Code Conventions](./code-con) for the templates that will be used for code snippets in later modules! - + diff --git a/content/1_Intro/Factors_Choosing.mdx b/content/1_Intro/Factors_Choosing.mdx index a7b7e7c..a46111f 100644 --- a/content/1_Intro/Factors_Choosing.mdx +++ b/content/1_Intro/Factors_Choosing.mdx @@ -19,7 +19,7 @@ Although both Python and Java receive two times the C++ time limit in USACO, thi Rewriting the C++ solution for [USACO Silver Wormsort](http://www.usaco.org/index.php?page=viewproblem2&cpid=992) in Python receives TLE (Time Limit Exceeded) on 2/10 cases. I'm not sure whether it is possible to pass this problem with Python. - + ```py # 8/10 test cases ... @@ -92,11 +92,11 @@ fout.write(str(-1 if lo == 0 else ed[lo-1][0])) fout.write('\n') ``` - + A similar solution in Java requires almost 3s, which is fairly close to the time limit of 4s. - + ```java import java.io.*; // from Nick Wu @@ -166,11 +166,11 @@ public class wormsort { } ``` - + A comparable C++ solution runs in less than 700ms. - + ```cpp #include @@ -226,4 +226,4 @@ int main() { cout << minW; } ``` - + diff --git a/content/1_Intro/Fast_IO.mdx b/content/1_Intro/Fast_IO.mdx index 89fd856..96e1e37 100644 --- a/content/1_Intro/Fast_IO.mdx +++ b/content/1_Intro/Fast_IO.mdx @@ -19,7 +19,7 @@ The largest USACO input file I know of is test case 11 of [USACO Platinum - Robo The slowest method. - + ```cpp #include @@ -40,13 +40,13 @@ int main() { } ``` - + ### Method 2: `freopen` with `scanf` Significantly faster. - + ```cpp #include // 281 ms @@ -66,13 +66,13 @@ int main() { } ``` - + ### Method 3: `ifstream` and `ofstream` About as fast. - + ```cpp #include @@ -93,13 +93,13 @@ int main() { // 258 ms } ``` - + ### A Faster Method I we use FastIO from [here](https://github.com/bqi343/USACO/blob/master/Implementations/content/various/FastIO.h) then the runtime is further reduced. - + ```cpp using namespace FastIO; @@ -119,35 +119,35 @@ int main() { } ``` - + ### Significance of `ios_base::sync_with_stdio(0); cin.tie(0);` Adding this line as the first line of `main()` reduced the runtime of the first method to 254 ms. - - + timing various I/O methods - - + {' '} - - + + documentation - - + + documentation - - + + You may see `cin.sync_with_stdio(0);` used in place of `ios_base::sync_with_stdio(0);` but they should have the same effect. @@ -161,7 +161,7 @@ Keep in mind that a Java program that only reads in $N$ and outputs a number tak [`Scanner`](https://docs.oracle.com/javase/8/docs/api/java/util/Scanner.html) is probably the easiest way to read input in Java, though it is also extremely slow. - + ```java import java.util.*; @@ -190,7 +190,7 @@ public class roboherd_scanner { } ``` - + A common alternative to reading input for programming contests is [`BufferedReader`](https://docs.oracle.com/javase/8/docs/api/java/io/BufferedReader.html), which reads faster from a file than `Scanner`. `BufferedReader` reads line-by-line with the `.readLine()` method, which returns a string. Methods like `Integer.parseInt()` are used to convert strings into primitives, and they can directly convert a line into a number, like in `Integer.parseInt(br.readLine())`. @@ -198,7 +198,7 @@ Reading input is more complicated when multiple, space-separated values are plac _Reading input with `BufferedReader` and `.split()`_: - + ```java import java.util.*; @@ -229,11 +229,11 @@ public class roboherd_buffered_reader_string_split { } ``` - + _Reading input with `BufferedReader` and `StringTokenizer`_: - + ```java import java.util.*; @@ -264,11 +264,11 @@ public class roboherd_buffered_reader_string_tokenizer { } ``` - + _Reading input with `BufferedReader` and `StreamTokenizer`_: - + ```java import java.util.*; @@ -299,11 +299,11 @@ public class roboherd { } ``` - + Faster methods of reading input exist too - Even faster than `BufferedReader` is a custom-written Fast I/O class that uses `InputStream`. Note that this custom class is similar to the custom-written `FastIO.h` in the C++ section, as both read input through a byte buffer. - + ```java import java.util.*; @@ -414,7 +414,7 @@ public class roboherd_is { } ``` - + The most realistic input method to implement in contest is `BufferedReader`, as it is relatively fast for the amount of code necessary. @@ -424,7 +424,7 @@ The most realistic input method to implement in contest is `BufferedReader`, as Faster than the first C++ method! Significantly less if $P$ does not need to be stored. - + ```py fin = open("roboherd.in","r") @@ -439,7 +439,7 @@ else: fout.write(str(1000000000000000000)) ``` - + diff --git a/content/1_Intro/Input_Output.mdx b/content/1_Intro/Input_Output.mdx index 30930ec..dfe2d8f 100644 --- a/content/1_Intro/Input_Output.mdx +++ b/content/1_Intro/Input_Output.mdx @@ -26,11 +26,11 @@ export const metadata = { } }; - - module is based off this - cin, getline, files - cin, getline - + + module is based off this + cin, getline, files + cin, getline + @@ -38,7 +38,7 @@ export const metadata = { In most websites (such as CodeForces and CSES), input and output are **standard**. - + Note that this problem requires **64-bit integers**. @@ -170,7 +170,7 @@ public static void main(String[] args) { ## File I/O - + In USACO, input is read from a file called `problemname.in`. After the program is run, output must be printed to a file called `problemname.out`. Note that you'll have to rename the `.in` and `.out` files depending on the problem. For example, in the above problem you would use `paint.in` and `paint.out`. @@ -268,9 +268,9 @@ instead. There is no need for this since `PrintWriter` [uses buffered output](ht ## Example Solutions - Fence Painting - - Make sure to read this. - + + Make sure to read this. +
    diff --git a/content/1_Intro/Intro.mdx b/content/1_Intro/Intro.mdx index c35c841..73a6fb6 100644 --- a/content/1_Intro/Intro.mdx +++ b/content/1_Intro/Intro.mdx @@ -14,21 +14,21 @@ For each problem, you submit the completed code to a grader, which checks the an For those of you with experience in software development, note that competitive programming is quite different, as the goal is to write programs that compute the correct answer, run quickly, and can be implemented quickly. Note that nowhere was maintainability of code mentioned. You don't need to bother documenting your code because it only needs to be readable to you during the contest. That being said, you probably want to maintain a bare minimum level of readability so you can keep track of what's going on. - +
    - - video shown above - - algorithms & programming contests - - examples of algorithms - + + video shown above + + algorithms & programming contests + + examples of algorithms + [Task](https://open.kattis.com/contests/mcpc19open/problems/basketballoneonone) that was mentioned in Kamil's video. - + ## USACO Contest Format diff --git a/content/1_Intro/Modules.mdx b/content/1_Intro/Modules.mdx index 21f2c0e..2248d9f 100644 --- a/content/1_Intro/Modules.mdx +++ b/content/1_Intro/Modules.mdx @@ -67,31 +67,31 @@ Some modules may also have additional content at the end that isn't needed for U Sometimes modules will contain interactive elements. Here are some of the more common ones. - + Helpful bits of advice provided by the author. - + - + In some modules, codes or solutions will be placed in **spoiler blocks** like this. In these cases, you should think about the problem or try to implement it yourself before revealing the solution or code. - + - + Not all content in this guide is essential to competitive programming. Skipping over optional content is fine, but if you're interested, feel free to explore further as well. - + - + A warning block like this will contain common errors that you should avoid. - + - + ## Problems - + diff --git a/content/3_Bronze/Pairs_Tuples.mdx b/content/2_Bronze/Pairs_Tuples.mdx similarity index 94% rename from content/3_Bronze/Pairs_Tuples.mdx rename to content/2_Bronze/Pairs_Tuples.mdx index 600a595..72ccf1e 100644 --- a/content/3_Bronze/Pairs_Tuples.mdx +++ b/content/2_Bronze/Pairs_Tuples.mdx @@ -17,22 +17,22 @@ If you sort one of $x_i$ and $y_i$ without considering the other, the points wil - + **Pairs are not available in Python.** Just use tuples; no need for pairs! - + - + **Pairs and tuples are not available in Java.** If you are using Java, just skip this module. - + @@ -126,9 +126,9 @@ int main() { ## Sorting Pairs & Tuples - - - + + + By default, C++ pairs are sorted by first element and then second element in case of a tie, which is precisely what we need for the example above. @@ -172,11 +172,11 @@ Use the link below (if you know of a better one, please let us know!) to learn a Python automatically sorts a list of tuples by the first element, then the second, and so on. This can save you time and keystrokes for certain problems like the one above. - + - + - + diff --git a/content/3_Bronze/Rect_Geo.mdx b/content/2_Bronze/Rect_Geo.mdx similarity index 93% rename from content/3_Bronze/Rect_Geo.mdx rename to content/2_Bronze/Rect_Geo.mdx index ae74e4d..f697e5d 100644 --- a/content/3_Bronze/Rect_Geo.mdx +++ b/content/2_Bronze/Rect_Geo.mdx @@ -20,9 +20,9 @@ export const metadata = { } }; - - module is based off this - + + module is based off this +
    @@ -30,13 +30,13 @@ Most only include two or three squares or rectangles, in which case you can simp ## Example: Blocked Billboard - + ### Naive Solution Since all coordinates are in the range $[-1000,1000]$, we can simply go through each of the $2000^2$ possible visible squares and check which ones are visible using nested for loops. - + @@ -72,7 +72,7 @@ int main() { - + Of course, this wouldn't suffice if the coordinates were up to $10^9$. @@ -103,7 +103,7 @@ This class can often lessen the implementation needed in a lot of bronze problem For example, here is a nice implementation of the problem ([editorial](http://www.usaco.org/current/data/sol_billboard_bronze_dec17.html)). - + ```java import java.awt.Rectangle; //needed to use Rectangle class @@ -136,9 +136,9 @@ public class blockedBillboard { } } ``` - + - + ```java import java.io.*; @@ -169,7 +169,7 @@ public class blockedBillboard { } } ``` - +
    @@ -177,7 +177,7 @@ public class blockedBillboard { Unfortunately, C++ doesn't have a built in rectangle class, so you need to write the functions yourself. Here is the solution to Blocked Billboard written in C++ (thanks, Brian Dean!). A C++ [`struct`](http://www.cplusplus.com/doc/tutorial/structures/) is the same as a C++ `class` but all members are `public` rather than `private` by default. - + ```cpp #include @@ -203,7 +203,7 @@ int main(){ cout << a.area()+b.area()-intersect(a,t)-intersect(b,t) << endl; } ``` - +
    @@ -212,4 +212,4 @@ int main(){ ## Problems - + diff --git a/content/3_Bronze/Simulation.mdx b/content/2_Bronze/Simulation.mdx similarity index 96% rename from content/3_Bronze/Simulation.mdx rename to content/2_Bronze/Simulation.mdx index 0a2aa9a..3e6cc94 100644 --- a/content/3_Bronze/Simulation.mdx +++ b/content/2_Bronze/Simulation.mdx @@ -29,9 +29,9 @@ export const metadata = { } }; - - module is based off this - + + module is based off this +
    @@ -53,7 +53,7 @@ The second line of the input contains $M$, $N$, $P$, and $Q$. Please output a single integer containing the number of seconds after the start at which Alice and Bob meet. If they never meet, please output $-1$. - + We can simulate the process. After inputting the values of $R$, $S$, $M$, $N$, $P$, and $Q$, we can keep track of Alice's and Bob's $x$- and $y$-coordinates. To start, we initialize variables for their respective positions. Alice's coordinates are initially $(0, 0)$, and Bob's coordinates are $(R, S)$ respectively. Every second, we increase Alice's $x$-coordinate by $M$ and her $y$-coordinate by $N$, and decrease Bob's $x$-coordinate by $P$ and his $y$-coordinate by $Q$. @@ -108,7 +108,7 @@ pw.close(); // flush the output
    - + ## Example 2 @@ -129,7 +129,7 @@ The third line of the input contains the amount of water in each bucket $A_1, A_ Please print one line of output, containing $N$ space-separated integers: the final amount of water in each bucket once Charlie is done pouring. - + Once again, we can simulate the process of pouring one bucket into the next. The amount of milk poured from bucket $B$ to bucket $B+1$ is the smaller of the amount of water in bucket $B$ (after all previous operations have been completed) and the remaining space in bucket $B+1$, which is $C_{B+1} - A_{B+1}$. We can just handle all of these operations in order, using an array $C$ to store the maximum capacities of each bucket, and an array $A$ to store the current water level in each bucket, which we update during the process. Example code is below (note that arrays are zero-indexed, so the indices of our buckets go from $0$ to $N-1$ rather than from $1$ to $N$). @@ -180,14 +180,14 @@ pw.close(); // flush the output - + ## Problems ### Easier - + ### Harder - + diff --git a/content/3_Bronze/Time_Comp.mdx b/content/2_Bronze/Time_Comp.mdx similarity index 93% rename from content/3_Bronze/Time_Comp.mdx rename to content/2_Bronze/Time_Comp.mdx index c8abbc7..a6e58db 100644 --- a/content/3_Bronze/Time_Comp.mdx +++ b/content/2_Bronze/Time_Comp.mdx @@ -1,372 +1,372 @@ ---- -id: time-comp -title: "Time Complexity" -author: Darren Yao, Benjamin Qi -description: "Evaluating a program's time complexity, or how fast your program runs." ---- - - - module is based off this - Intro and examples - More in-depth. In particular, 5.2 gives a formal definition of Big O. - - -
    - -In programming contests, your program needs to finish running within a certain timeframe in order to receive credit. For USACO, this limit is $2$ seconds for C++ submissions, and $4$ seconds for Java/Python submissions. A conservative estimate for the number of operations the grading server can handle per second is $10^8$, but it could be closer to $5 \cdot 10^8$ given good constant factorsIf you don't know what constant factors are, don't worry -- we'll explain them below.. - -## Complexity Calculations - -We want a method to calculate how many operations it takes to run each algorithm, in terms of the input size $n$. Fortunately, this can be done relatively easily using [Big O Notation](https://en.wikipedia.org/wiki/Big_O_notation), which expresses worst-case time complexity as a function of $n$ as $n$ gets arbitrarily large. Complexity is an upper bound for the number of steps an algorithm requires as a function of the input size. In Big O notation, we denote the complexity of a function as $O(f(n))$, where constant factors and lower-order terms are generally omitted from $f(n)$. We'll see some examples of how this works, as follows. - -The following code is $O(1)$, because it executes a constant number of operations. - - - - -```cpp -int a = 5; -int b = 7; -int c = 4; -int d = a + b + c + 153; -``` - - - - -```java -int a = 5; -int b = 7; -int c = 4; -int d = a + b + c + 153; -``` - - - - -```py -a = 5 -b = 7 -c = 4 -d = a + b + c + 153 -``` - - - - -Input and output operations are also assumed to be $O(1)$. In the following examples, we assume that the code inside the loops is $O(1)$. - -The time complexity of loops is the number of iterations that the loop runs. For example, the following code examples are both $O(n)$. - - - - -```cpp -for (int i = 1; i <= n; i++) { - // constant time code here -} -``` - -```cpp -int i = 0; -while (i < n) { - // constant time node here - i++; -} -``` - - - - -```java -for (int i = 1; i <= n; i++) { - // constant time code here -} -``` - -```java -int i = 0; -while (i < n) { - // constant time node here - i++; -} -``` - - - - -```py -for i in range(1, n+1): - # constant time code here -``` - -```py -i = 0 -while (i < n): - # constant time node here - i += 1 -``` - - - - -Because we ignore constant factors and lower order terms, the following examples are also $O(n)$: - - - - - -```cpp -for (int i = 1; i <= 5*n + 17; i++) { - // constant time code here -} -``` - -```cpp -for (int i = 1; i <= n + 457737; i++) { - // constant time code here -} -``` - - - - -```java -for (int i = 1; i <= 5*n + 17; i++) { - // constant time code here -} -``` - -```java -for (int i = 1; i <= n + 457737; i++) { - // constant time code here -} -``` - - - - -```py -for i in range(5*n + 17): - # constant time code here - -for i in range(n + 457737): - # constant time code here -``` - - - - - - -We can find the time complexity of multiple loops by multiplying together the time complexities of each loop. This example is $O(nm)$, because the outer loop runs $O(n)$ iterations and the inner loop $O(m)$. - - - - -```cpp -for (int i = 1; i <= n; i++) { - for (int j = 1; j <= m; j++) { - // constant time code here - } -} -``` - - - - -```java -for (int i = 1; i <= n; i++) { - for (int j = 1; j <= m; j++) { - // constant time code here - } -} -``` - - - - - -```py -for i in range(n): - for j in range(m): - # constant time code here -``` - - - - - - -In this example, the outer loop runs $O(n)$ iterations, and the inner loop runs anywhere between $1$ and $n$ iterations (which is a maximum of $n$). Since Big O notation calculates worst-case time complexity, we treat the inner loop as a factor of $n$.We can also do some math to calculate exactly how many times the code runs: 1+2+...+n = n*(n-1)/2 = (n^2 - n)/2 = O(n^2) Thus, this code is $O(n^2)$. - - - - -```cpp -for (int i = 1; i <= n; i++) { - for (int j = i; j <= n; j++) { - // constant time code here - } -} -``` - - - - -```java -for (int i = 1; i <= n; i++) { - for (int j = i; j <= n; j++) { - // constant time code here - } -} -``` - - - - -```py -for i in range(n): - for j in range(i, n): - # constant time code here -``` - - - - -If an algorithm contains multiple blocks, then its time complexity is the worst time complexity out of any block. For example, the following code is $O(n^2)$. - - - - -```cpp -for (int i = 1; i <= n; i++) { - for(int j = 1; j <= n; j++) { - // constant time code here - } -} -for (int i = 1; i <= n + 58834; i++) { - // more constant time code here -} -``` - - - - -```java -for (int i = 1; i <= n; i++) { - for(int j = 1; j <= n; j++) { - // constant time code here - } -} -for (int i = 1; i <= n + 58834; i++) { - // more constant time code here -} -``` - - - - -```py -for i in range(n): - for j in range(n): - # constant time code here - -for i in range(n + 58834): - # more constant time code here -``` - - - - -The following code is $O(n^2 + m)$, because it consists of two blocks of complexity $O(n^2)$ and $O(m)$, and neither of them is a lower order function with respect to the other. - - - - -```cpp -for (int i = 1; i <= n; i++) { - for (int j = 1; j <= n; j++) { - // constant time code here - } -} -for (int i = 1; i <= m; i++) { - // more constant time code here -} -``` - - - - -```java -for (int i = 1; i <= n; i++) { - for (int j = 1; j <= n; j++) { - // constant time code here - } -} -for (int i = i; j <= m; i++) { - // more constant time code here -} -``` - - - - -```py -for i in range(n): - for j in range(n): - # constant time code here - -for i in range(m): - # more constant time code here -``` - - - - -## Constant Factor - -The **constant factor** of an algorithm refers to the coefficient of the complexity of an algorithm. If an algorithm runs in $O(kn)$ time, where $k$ is a constant and $n$ is the input size, then the "constant factor" would be $k$. (Ben - this is not a great definition) - - - -Normally when using the big-O notation, we ignore the constant factor: $O(3n) = O(n)$. This is fine most of the time, but sometimes we have an algorithm that just barely gets TLE, perhaps by just a few hundred milliseconds. When this happens, it is worth optimizing the constant factor of our algorithm. For example, if our code currently runs in $O(n^2)$ time, perhaps we can modify our code to make it run in $O(n^2/32)$ by using a bitset. (Of course, with big-O notation, $O(n^2) = O(n^2/32)$.) - -For now, don't worry about how to optimize constant factors -- just be aware of them. - -## Common Complexities and Constraints - -Complexity factors that come from some common algorithms and data structures are as follows: - -- Mathematical formulas that just calculate an answer: $O(1)$ -- Unordered set/map: $O(1)$ per operation -- Binary search: $O(\log n)$ -- Ordered set/map or priority queue: $O(\log n)$ per operation -- Prime factorization of an integer, or checking primality or compositeness of an integer naively: $O(\sqrt{n})$ -- Reading in $n$ items of input: $O(n)$ -- Iterating through an array or a list of $n$ elements: $O(n)$ -- Sorting: usually $O(n \log n)$ for default sorting algorithms (mergesort, `Collections.sort`, `Arrays.sort`) -- Java Quicksort `Arrays.sort` function on primitives: $O(n^2)$ - - See "Introduction to Data Structures" for details. -- Iterating through all subsets of size $k$ of the input elements: $O(n^k)$. For example, iterating through all triplets is $O(n^3)$. -- Iterating through all subsets: $O(2^n)$ -- Iterating through all permutations: $O(n!)$ - - -Here are conservative upper bounds on the value of $n$ for each time complexity. You might get away with more than this, but this should allow you to quickly check whether an algorithm is viable. - -
    - -| $n$ | Possible complexities | -| --------------------- | ----------------------------------- | -| $n \le 10$ | $O(n!)$, $O(n^7)$, $O(n^6)$ | -| $n \le 20$ | $O(2^n \cdot n)$, $O(n^5)$ | -| $n \le 80$ | $O(n^4)$ | -| $n \le 400$ | $O(n^3)$ | -| $n \le 7500$ | $O(n^2)$ | -| $n \le 7 \cdot 10^4$ | $O(n \sqrt n)$ | -| $n \le 5 \cdot 10^5$ | $O(n \log n)$ | -| $n \le 5 \cdot 10^6$ | $O(n)$ | -| $n \le 10^{18}$ | $O(\log^2 n)$, $O(\log n)$, $O(1)$ | - -
    +--- +id: time-comp +title: "Time Complexity" +author: Darren Yao, Benjamin Qi +description: "Evaluating a program's time complexity, or how fast your program runs." +--- + + + module is based off this + Intro and examples + More in-depth. In particular, 5.2 gives a formal definition of Big O. + + +
    + +In programming contests, your program needs to finish running within a certain timeframe in order to receive credit. For USACO, this limit is $2$ seconds for C++ submissions, and $4$ seconds for Java/Python submissions. A conservative estimate for the number of operations the grading server can handle per second is $10^8$, but it could be closer to $5 \cdot 10^8$ given good constant factorsIf you don't know what constant factors are, don't worry -- we'll explain them below.. + +## Complexity Calculations + +We want a method to calculate how many operations it takes to run each algorithm, in terms of the input size $n$. Fortunately, this can be done relatively easily using [Big O Notation](https://en.wikipedia.org/wiki/Big_O_notation), which expresses worst-case time complexity as a function of $n$ as $n$ gets arbitrarily large. Complexity is an upper bound for the number of steps an algorithm requires as a function of the input size. In Big O notation, we denote the complexity of a function as $O(f(n))$, where constant factors and lower-order terms are generally omitted from $f(n)$. We'll see some examples of how this works, as follows. + +The following code is $O(1)$, because it executes a constant number of operations. + + + + +```cpp +int a = 5; +int b = 7; +int c = 4; +int d = a + b + c + 153; +``` + + + + +```java +int a = 5; +int b = 7; +int c = 4; +int d = a + b + c + 153; +``` + + + + +```py +a = 5 +b = 7 +c = 4 +d = a + b + c + 153 +``` + + + + +Input and output operations are also assumed to be $O(1)$. In the following examples, we assume that the code inside the loops is $O(1)$. + +The time complexity of loops is the number of iterations that the loop runs. For example, the following code examples are both $O(n)$. + + + + +```cpp +for (int i = 1; i <= n; i++) { + // constant time code here +} +``` + +```cpp +int i = 0; +while (i < n) { + // constant time node here + i++; +} +``` + + + + +```java +for (int i = 1; i <= n; i++) { + // constant time code here +} +``` + +```java +int i = 0; +while (i < n) { + // constant time node here + i++; +} +``` + + + + +```py +for i in range(1, n+1): + # constant time code here +``` + +```py +i = 0 +while (i < n): + # constant time node here + i += 1 +``` + + + + +Because we ignore constant factors and lower order terms, the following examples are also $O(n)$: + + + + + +```cpp +for (int i = 1; i <= 5*n + 17; i++) { + // constant time code here +} +``` + +```cpp +for (int i = 1; i <= n + 457737; i++) { + // constant time code here +} +``` + + + + +```java +for (int i = 1; i <= 5*n + 17; i++) { + // constant time code here +} +``` + +```java +for (int i = 1; i <= n + 457737; i++) { + // constant time code here +} +``` + + + + +```py +for i in range(5*n + 17): + # constant time code here + +for i in range(n + 457737): + # constant time code here +``` + + + + + + +We can find the time complexity of multiple loops by multiplying together the time complexities of each loop. This example is $O(nm)$, because the outer loop runs $O(n)$ iterations and the inner loop $O(m)$. + + + + +```cpp +for (int i = 1; i <= n; i++) { + for (int j = 1; j <= m; j++) { + // constant time code here + } +} +``` + + + + +```java +for (int i = 1; i <= n; i++) { + for (int j = 1; j <= m; j++) { + // constant time code here + } +} +``` + + + + + +```py +for i in range(n): + for j in range(m): + # constant time code here +``` + + + + + + +In this example, the outer loop runs $O(n)$ iterations, and the inner loop runs anywhere between $1$ and $n$ iterations (which is a maximum of $n$). Since Big O notation calculates worst-case time complexity, we treat the inner loop as a factor of $n$.We can also do some math to calculate exactly how many times the code runs: 1+2+...+n = n*(n-1)/2 = (n^2 - n)/2 = O(n^2) Thus, this code is $O(n^2)$. + + + + +```cpp +for (int i = 1; i <= n; i++) { + for (int j = i; j <= n; j++) { + // constant time code here + } +} +``` + + + + +```java +for (int i = 1; i <= n; i++) { + for (int j = i; j <= n; j++) { + // constant time code here + } +} +``` + + + + +```py +for i in range(n): + for j in range(i, n): + # constant time code here +``` + + + + +If an algorithm contains multiple blocks, then its time complexity is the worst time complexity out of any block. For example, the following code is $O(n^2)$. + + + + +```cpp +for (int i = 1; i <= n; i++) { + for(int j = 1; j <= n; j++) { + // constant time code here + } +} +for (int i = 1; i <= n + 58834; i++) { + // more constant time code here +} +``` + + + + +```java +for (int i = 1; i <= n; i++) { + for(int j = 1; j <= n; j++) { + // constant time code here + } +} +for (int i = 1; i <= n + 58834; i++) { + // more constant time code here +} +``` + + + + +```py +for i in range(n): + for j in range(n): + # constant time code here + +for i in range(n + 58834): + # more constant time code here +``` + + + + +The following code is $O(n^2 + m)$, because it consists of two blocks of complexity $O(n^2)$ and $O(m)$, and neither of them is a lower order function with respect to the other. + + + + +```cpp +for (int i = 1; i <= n; i++) { + for (int j = 1; j <= n; j++) { + // constant time code here + } +} +for (int i = 1; i <= m; i++) { + // more constant time code here +} +``` + + + + +```java +for (int i = 1; i <= n; i++) { + for (int j = 1; j <= n; j++) { + // constant time code here + } +} +for (int i = i; j <= m; i++) { + // more constant time code here +} +``` + + + + +```py +for i in range(n): + for j in range(n): + # constant time code here + +for i in range(m): + # more constant time code here +``` + + + + +## Constant Factor + +The **constant factor** of an algorithm refers to the coefficient of the complexity of an algorithm. If an algorithm runs in $O(kn)$ time, where $k$ is a constant and $n$ is the input size, then the "constant factor" would be $k$. (Ben - this is not a great definition) + + + +Normally when using the big-O notation, we ignore the constant factor: $O(3n) = O(n)$. This is fine most of the time, but sometimes we have an algorithm that just barely gets TLE, perhaps by just a few hundred milliseconds. When this happens, it is worth optimizing the constant factor of our algorithm. For example, if our code currently runs in $O(n^2)$ time, perhaps we can modify our code to make it run in $O(n^2/32)$ by using a bitset. (Of course, with big-O notation, $O(n^2) = O(n^2/32)$.) + +For now, don't worry about how to optimize constant factors -- just be aware of them. + +## Common Complexities and Constraints + +Complexity factors that come from some common algorithms and data structures are as follows: + +- Mathematical formulas that just calculate an answer: $O(1)$ +- Unordered set/map: $O(1)$ per operation +- Binary search: $O(\log n)$ +- Ordered set/map or priority queue: $O(\log n)$ per operation +- Prime factorization of an integer, or checking primality or compositeness of an integer naively: $O(\sqrt{n})$ +- Reading in $n$ items of input: $O(n)$ +- Iterating through an array or a list of $n$ elements: $O(n)$ +- Sorting: usually $O(n \log n)$ for default sorting algorithms (mergesort, `Collections.sort`, `Arrays.sort`) +- Java Quicksort `Arrays.sort` function on primitives: $O(n^2)$ + - See "Introduction to Data Structures" for details. +- Iterating through all subsets of size $k$ of the input elements: $O(n^k)$. For example, iterating through all triplets is $O(n^3)$. +- Iterating through all subsets: $O(2^n)$ +- Iterating through all permutations: $O(n!)$ + + +Here are conservative upper bounds on the value of $n$ for each time complexity. You might get away with more than this, but this should allow you to quickly check whether an algorithm is viable. + +
    + +| $n$ | Possible complexities | +| --------------------- | ----------------------------------- | +| $n \le 10$ | $O(n!)$, $O(n^7)$, $O(n^6)$ | +| $n \le 20$ | $O(2^n \cdot n)$, $O(n^5)$ | +| $n \le 80$ | $O(n^4)$ | +| $n \le 400$ | $O(n^3)$ | +| $n \le 7500$ | $O(n^2)$ | +| $n \le 7 \cdot 10^4$ | $O(n \sqrt n)$ | +| $n \le 5 \cdot 10^5$ | $O(n \log n)$ | +| $n \le 5 \cdot 10^6$ | $O(n)$ | +| $n \le 10^{18}$ | $O(\log^2 n)$, $O(\log n)$, $O(1)$ | + +
    diff --git a/content/3_Bronze/Unordered.mdx b/content/2_Bronze/Unordered.mdx similarity index 92% rename from content/3_Bronze/Unordered.mdx rename to content/2_Bronze/Unordered.mdx index 210420b..c56c0d6 100644 --- a/content/3_Bronze/Unordered.mdx +++ b/content/2_Bronze/Unordered.mdx @@ -26,9 +26,9 @@ export const metadata = { } }; - - module is based off this - + + module is based off this + ## What Are Sets and Maps? @@ -46,7 +46,7 @@ Both Java and C++ contain two versions of sets and maps; one in which the keys a ## Sets - + @@ -105,7 +105,7 @@ for(int element : set){ ## Maps - + @@ -153,9 +153,9 @@ System.out.println(map.containsKey(1)); // true - - How to create user-defined hash function for `unordered_map`. - + + How to create user-defined hash function for `unordered_map`. + The link provides an example of hashing pairs of strings. More examples (for pairs of ints) @@ -205,11 +205,11 @@ However, this hash function is quite bad; if we insert $(0,0), (1,1), (2,2) \ldo ## Hacking - + You don't need to know this for USACO, but you will need this to pass some of the problems in this module. - + In USACO contests, unordered sets and maps generally fine, but the built-in hashing algorithm for C++ is vulnerable to pathological data sets causing abnormally slow runtimes. Apparently [Java](https://codeforces.com/blog/entry/62393?#comment-464875) is not vulnerable to this, however. @@ -217,17 +217,17 @@ In USACO contests, unordered sets and maps generally fine, but the built-in hash - - Explanation of this problem and how to fix it. - + + Explanation of this problem and how to fix it. + Essentially use `unordered_map` defined in the blog above in place of `unordered_map`. ### Another Hash Function - - - + + + ```cpp struct chash { /// use most bits rather than just the lowest ones @@ -251,4 +251,4 @@ Mentioned in several of the links above. See Gold for dtails. ## Problems - + diff --git a/content/4_Silver/Binary_Search_Ans.mdx b/content/3_Silver/Binary_Search_Ans.mdx similarity index 97% rename from content/4_Silver/Binary_Search_Ans.mdx rename to content/3_Silver/Binary_Search_Ans.mdx index d3228f1..17e2d64 100644 --- a/content/4_Silver/Binary_Search_Ans.mdx +++ b/content/3_Silver/Binary_Search_Ans.mdx @@ -36,9 +36,9 @@ export const metadata = { } }; - - module is based off this - + + module is based off this +
    @@ -152,7 +152,7 @@ static long search(){ ## Example: Maximum Median - + **Statement:** Given an array $\texttt{arr}$ of $n$ integers, where $n$ is odd, we can perform the following operation on it $k$ times: take any element of the array and increase it by $1$. We want to make the median of the array as large as possible after $k$ operations. @@ -259,8 +259,8 @@ static boolean check(long x){ ## USACO Problems - + ## General Problems - + diff --git a/content/4_Silver/Binary_Search_Sorted.mdx b/content/3_Silver/Binary_Search_Sorted.mdx similarity index 72% rename from content/4_Silver/Binary_Search_Sorted.mdx rename to content/3_Silver/Binary_Search_Sorted.mdx index 2920854..ee1a896 100644 --- a/content/4_Silver/Binary_Search_Sorted.mdx +++ b/content/3_Silver/Binary_Search_Sorted.mdx @@ -24,13 +24,13 @@ export const metadata = { Suppose that we want to find an element in a sorted array of size $N$ in $O(\log N)$ time. We can do this with [**binary search**](https://en.wikipedia.org/wiki/Binary_search_algorithm); each iteration of the binary search cuts the search space in half, so the algorithm tests $O(\log N)$ values. This is efficient and much better than testing every element in an array. - - animations! - animation! - - - - + + animations! + animation! + + + + ## Library Functions @@ -38,19 +38,19 @@ Suppose that we want to find an element in a sorted array of size $N$ in $O(\log - - - - + + + + - - - - + + + + @@ -60,13 +60,13 @@ Suppose that we want to find an element in a sorted array of size $N$ in $O(\log A related topic is **coordinate compression**, which takes some points and reassigns them to remove wasted space. - + > Farmer John has just arranged his $N$ haybales $(1\le N \le 100,000)$ at various points along the one-dimensional road running across his farm. To make sure they are spaced out appropriately, please help him answer $Q$ queries ($1 \le Q \le 100,000$), each asking for the number of haybales within a specific interval along the road. However, each of the points are in the range $0 \ldots 1,000,000,000$, meaning you can't store locations of haybales in, for instance, a boolean array. - + Let's place all of the locations of the haybales into a list and sort it. @@ -79,4 +79,4 @@ Let's place all of the locations of the haybales into a list and sort it. By compressing queries and haybale positions, we've transformed the range of points to $0 \ldots N + 2Q$, allowing us to store prefix sums to effectively query for the number of haybales in a range. --> - \ No newline at end of file + \ No newline at end of file diff --git a/content/4_Silver/Custom_Cpp_STL.mdx b/content/3_Silver/Custom_Cpp_STL.mdx similarity index 96% rename from content/4_Silver/Custom_Cpp_STL.mdx rename to content/3_Silver/Custom_Cpp_STL.mdx index c8afc51..7e6fb3b 100644 --- a/content/4_Silver/Custom_Cpp_STL.mdx +++ b/content/3_Silver/Custom_Cpp_STL.mdx @@ -9,9 +9,9 @@ description: "?" frequency: 1 --- - - Covers all of this material. - + + Covers all of this material. +
    diff --git a/content/4_Silver/DFS.mdx b/content/3_Silver/DFS.mdx similarity index 75% rename from content/4_Silver/DFS.mdx rename to content/3_Silver/DFS.mdx index ac2497c..c65ce00 100644 --- a/content/4_Silver/DFS.mdx +++ b/content/3_Silver/DFS.mdx @@ -51,19 +51,19 @@ export const metadata = { ## Resources - - - interactive - - with an example problem - fast-paced - hard to parse for a beginner - - + + + interactive + + with an example problem + fast-paced + hard to parse for a beginner + + ## Counting Connected Components - + ### Implementation @@ -73,7 +73,7 @@ export const metadata = { ### Problems - + ## Tree Problems @@ -85,22 +85,22 @@ export const metadata = { ### Problems - + ## Graph Two-Coloring *Graph two-coloring* refers to assigning a boolean value to each node of the graph, dictated by the edge configuration. The most common example of a two-colored graph is a *bipartite graph*, in which each edge connects two nodes of opposite colors. - + ### Resources - - - - Uses BFS, but DFS accomplishes the same task. - + + + + Uses BFS, but DFS accomplishes the same task. + ### Implementation @@ -138,4 +138,4 @@ void dfs(int node) ### Problems - + diff --git a/content/4_Silver/Flood_Fill.mdx b/content/3_Silver/Flood_Fill.mdx similarity index 94% rename from content/4_Silver/Flood_Fill.mdx rename to content/3_Silver/Flood_Fill.mdx index 57a7afc..a7c61e7 100644 --- a/content/4_Silver/Flood_Fill.mdx +++ b/content/3_Silver/Flood_Fill.mdx @@ -32,13 +32,13 @@ export const metadata = { } }; - +
    - - module is based off this - + + module is based off this + **Flood fill** is an algorithm that identifies and labels the connected component that a particular cell belongs to, in a multi-dimensional array. Essentially, it’s DFS, but on a grid, @@ -104,9 +104,9 @@ int main(){ ## Implementation - - - + + + When doing floodfill, we will maintain an $N\times M$ array of booleans to keep track of which squares have been visited, and a global variable to maintain the size of the current @@ -208,4 +208,4 @@ static void floodfill(int r, int c, int color){ ## Problems - \ No newline at end of file + \ No newline at end of file diff --git a/content/4_Silver/Func_Graphs.mdx b/content/3_Silver/Func_Graphs.mdx similarity index 91% rename from content/4_Silver/Func_Graphs.mdx rename to content/3_Silver/Func_Graphs.mdx index 2d8dbb7..77c64e7 100644 --- a/content/4_Silver/Func_Graphs.mdx +++ b/content/3_Silver/Func_Graphs.mdx @@ -29,15 +29,15 @@ export const metadata = { We'll consider graphs like the one presented in this problem: - + < br/> Aka **successor graph**. - - - + + + ## Implementation @@ -83,4 +83,4 @@ int main() ## Problems - \ No newline at end of file + \ No newline at end of file diff --git a/content/4_Silver/Greedy.mdx b/content/3_Silver/Greedy.mdx similarity index 92% rename from content/4_Silver/Greedy.mdx rename to content/3_Silver/Greedy.mdx index 188f764..ca35f22 100644 --- a/content/4_Silver/Greedy.mdx +++ b/content/3_Silver/Greedy.mdx @@ -44,12 +44,12 @@ export const metadata = { } }; - - Module is based off this. - - - - + + Module is based off this. + + + +
    @@ -63,7 +63,7 @@ Here, we'll focus on problems where some sorting step is involved. ## Example: The Scheduling Problem - + There are $N$ events, each described by their starting and ending times. You can only attend one event at a time, and if you choose to attend an event, you must attend the entire event. Traveling between events is instantaneous. What's the maximum number of events you can attend? @@ -176,12 +176,12 @@ pw.close(); ## CSES Problems - + ## USACO Problems - + ## Other Problems - \ No newline at end of file + \ No newline at end of file diff --git a/content/4_Silver/Harder_Ordered.mdx b/content/3_Silver/Harder_Ordered.mdx similarity index 95% rename from content/4_Silver/Harder_Ordered.mdx rename to content/3_Silver/Harder_Ordered.mdx index ee970e4..a856d78 100644 --- a/content/4_Silver/Harder_Ordered.mdx +++ b/content/3_Silver/Harder_Ordered.mdx @@ -30,9 +30,9 @@ export const metadata = { ## Example: Using Iterators - + - + ```cpp #include @@ -123,10 +123,10 @@ int main() { } ``` - + ## Problems - + diff --git a/content/4_Silver/Intro_Ordered.mdx b/content/3_Silver/Intro_Ordered.mdx similarity index 96% rename from content/4_Silver/Intro_Ordered.mdx rename to content/3_Silver/Intro_Ordered.mdx index 94bc0b7..7e60a9a 100644 --- a/content/4_Silver/Intro_Ordered.mdx +++ b/content/3_Silver/Intro_Ordered.mdx @@ -19,10 +19,10 @@ export const metadata = { } }; - - module is based off this - sets, maps, set iterators - + + module is based off this + sets, maps, set iterators +
    @@ -212,4 +212,4 @@ next(), prev(), ++, -- ## Standard - \ No newline at end of file + \ No newline at end of file diff --git a/content/4_Silver/Prefix_Sums.mdx b/content/3_Silver/Prefix_Sums.mdx similarity index 95% rename from content/4_Silver/Prefix_Sums.mdx rename to content/3_Silver/Prefix_Sums.mdx index e2f783c..dbb042e 100644 --- a/content/4_Silver/Prefix_Sums.mdx +++ b/content/3_Silver/Prefix_Sums.mdx @@ -50,15 +50,15 @@ export const metadata = { }; - - module is based off this - rather brief - also rather brief - + + module is based off this + rather brief + also rather brief + ## Introduction - + Let's say we have a one-indexed integer array $\texttt{arr}$ of size $N$ and we want to compute the value of $$ @@ -205,31 +205,31 @@ These are also known as [partial sums](https://mathworld.wolfram.com/PartialSum. ### Problems - + ## Max Subarray Sum Now we'll look at some extensions. - + This problem has a solution known as [Kadane's Algorithm](https://en.wikipedia.org/wiki/Maximum_subarray_problem#Kadane's_algorithm). Please don't use that solution; try to solve it with prefix sums. - + Consider the desired maximum subarray. As you go along from left to right, the prefix sum solution will mark the start of that subarray as the "current minimum prefix sum". Kadane's Algorithm, on the other hand, will set the current value to 0 at that point. As both solutions iterate through the array, they eventually find the right side of the maximum sum, and they find the answer to the problem at that location. In essence, Kadane's Algorithm stores the maximum sum of a subarray that ends at the current location (which is what the prefix sum solution calculates on each iteration), but it calculates this value greedily instead. - + ## Prefix Minimum, XOR, etc. Similar to prefix sums, you can also take prefix minimum or maximum; but *you cannot* answer min queries over an arbitrary range with prefix minimum. (This is because minimum doesn't have an inverse operation, the way subtraction is to addition.) On the other hand, XOR is its own inverse operation, meaning that the XOR of any number with itself is zero. - + ## 2D Prefix Sums - + Now, what if we wanted to process $Q$ queries for the sum over a subrectangle of a $N$ rows by $M$ columns matrix in two dimensions? Let's assume both rows and columns are 1-indexed, and we use the following matrix as an example: @@ -474,7 +474,7 @@ as expected. Since no matter the size of the submatrix we are summing, we only need to access four values of the 2D prefix sum array, this runs in $O(1)$ per query after an $O(NM)$ preprocessing. - + ## More Complex Applications @@ -507,4 +507,4 @@ $$ Which is what we were looking for! - + diff --git a/content/4_Silver/Sliding.mdx b/content/3_Silver/Sliding.mdx similarity index 80% rename from content/4_Silver/Sliding.mdx rename to content/3_Silver/Sliding.mdx index 7459056..18030d5 100644 --- a/content/4_Silver/Sliding.mdx +++ b/content/3_Silver/Sliding.mdx @@ -44,14 +44,14 @@ export const metadata = { ## Two Pointers - + Two pointers refers to iterating two monotonic pointers across an array to search for a pair of indices satisfying some condition in linear time. - - - - + + + + ### Implementation @@ -59,7 +59,7 @@ Two pointers refers to iterating two monotonic pointers across an array to searc ## Sliding Window - + Let's envision a **sliding window** (or constant size subarray) of size $K$ moving left to right along an array, $a$. @@ -67,10 +67,10 @@ For each position of the window, we want to compute some information. For exampl To compute the sum in the range, instead of using a set, we can store a variable $s$ representing the sum. As we move the window forward, we update $s$ by subtracting $a_i$ from $s$ and adding $a_{j+1}$ to $s$. - - - - + + + + ### Implementation @@ -78,14 +78,14 @@ To compute the sum in the range, instead of using a set, we can store a variable ### Problems - + ## Sliding Window Minimum in $O(N)$ - - Mentions two ways to solve this (both are important)! - + + Mentions two ways to solve this (both are important)! + In particular, the second method allows us to solve the following generalization in linear time as well: - + diff --git a/content/4_Silver/Sorting_2_Old.mdx b/content/3_Silver/Sorting_2_Old.mdx similarity index 99% rename from content/4_Silver/Sorting_2_Old.mdx rename to content/3_Silver/Sorting_2_Old.mdx index 1251794..73eb90b 100644 --- a/content/4_Silver/Sorting_2_Old.mdx +++ b/content/3_Silver/Sorting_2_Old.mdx @@ -214,4 +214,4 @@ Comments: Comparator 1 sorts array $a$ in decreasing order. Comparator 2 sorts a ## Problems - \ No newline at end of file + \ No newline at end of file diff --git a/content/4_Silver/Sorting_Custom.mdx b/content/3_Silver/Sorting_Custom.mdx similarity index 97% rename from content/4_Silver/Sorting_Custom.mdx rename to content/3_Silver/Sorting_Custom.mdx index fab0f67..dd69e9f 100644 --- a/content/4_Silver/Sorting_Custom.mdx +++ b/content/3_Silver/Sorting_Custom.mdx @@ -26,15 +26,15 @@ export const metadata = { } }; - - - + + +
    ## Example: Wormhole Sort - + There are multiple ways to solve this problem. We won't discuss the full solution here, but all of them start by sorting the edges in nondecreasing order of weight. For example, the sample contains the following edges: @@ -187,9 +187,9 @@ Normally, sorting functions rely on moving objects with a lower value in front o - - - + + + What a comparator does is compare two objects as follows, based on our comparison criteria: @@ -571,4 +571,4 @@ public class Sol { ## Problems - \ No newline at end of file + \ No newline at end of file diff --git a/content/4_Silver/Sorting_Methods.mdx b/content/3_Silver/Sorting_Methods.mdx similarity index 83% rename from content/4_Silver/Sorting_Methods.mdx rename to content/3_Silver/Sorting_Methods.mdx index 3b3545b..9b56771 100644 --- a/content/4_Silver/Sorting_Methods.mdx +++ b/content/3_Silver/Sorting_Methods.mdx @@ -18,9 +18,9 @@ export const metadata = { } }; - - types of sorting - + + types of sorting +
    @@ -32,7 +32,7 @@ There are many sorting algorithms, here are some sources to learn about the popu ## Bubble Sort - + ### Tutorial diff --git a/content/4_Silver/Sorting_Old.mdx b/content/3_Silver/Sorting_Old.mdx similarity index 98% rename from content/4_Silver/Sorting_Old.mdx rename to content/3_Silver/Sorting_Old.mdx index e34ac45..da6a384 100644 --- a/content/4_Silver/Sorting_Old.mdx +++ b/content/3_Silver/Sorting_Old.mdx @@ -28,7 +28,7 @@ export const metadata = { ## Example: Wormhole Sort - + There are multiple ways to solve this problem. We won't discuss the full solution here, but all of them start by sorting the edges in nondecreasing order of weight. @@ -90,9 +90,9 @@ Normally, sorting functions rely on moving objects with a lower value in front o ### C++ - - - + + + What a comparator does is compare two objects as follows, based on our comparison criteria: @@ -123,9 +123,9 @@ Java has default functions for comparing `int`, `long`, `double` types. The `Int ## C++ - - - + + + ### Method 1: Operator < diff --git a/content/4_Silver/Stacks_Queues.mdx b/content/3_Silver/Stacks_Queues.mdx similarity index 90% rename from content/4_Silver/Stacks_Queues.mdx rename to content/3_Silver/Stacks_Queues.mdx index aed1b43..f8a8c83 100644 --- a/content/4_Silver/Stacks_Queues.mdx +++ b/content/3_Silver/Stacks_Queues.mdx @@ -24,12 +24,12 @@ export const metadata = { ## Additional Reading - - - - - - + + + + + + ## Stacks @@ -222,7 +222,7 @@ pq.add(6); // [7, 6, 5] ## Monotonic Stack - + Consider the following problem: @@ -241,14 +241,14 @@ The stack we used is called a **monotonic stack** because we keep popping off th ### Further Reading - - - - + + + + ## Problems - + + ```cpp #include @@ -117,7 +117,7 @@ int main() { } ``` - + Note that if it were not the case that all elements of the input array were distinct, then this code would be incorrect since `Tree` would remove duplicates. Instead, we would use an indexed set of pairs (`Tree>`), where the first element of each pair would denote the value while the second would denote the position of the value in the array. @@ -125,17 +125,17 @@ Note that if it were not the case that all elements of the input array were dist Assumes all updates are in the range $[1,N]$. - - log N - log^2 N - + + log N + log^2 N + ## Practice Problems - + ## USACO Problems Haircut, Balanced Photo, and Circle Cross are just variations on inversion counting. - + diff --git a/content/5_Gold/SP.mdx b/content/4_Gold/SP.mdx similarity index 71% rename from content/5_Gold/SP.mdx rename to content/4_Gold/SP.mdx index eba6116..4ac3c3a 100644 --- a/content/5_Gold/SP.mdx +++ b/content/4_Gold/SP.mdx @@ -37,18 +37,18 @@ export const metadata = { ## Single-Source Shortest Path - + ### Tutorial Use *Dijkstra's Algorithm*. - - code - - - - + + code + + + + ### Implementation @@ -61,39 +61,39 @@ The USACO training pages present a $O(N^2)$ version, although this is rarely use #### Part 2: $O(M\log N)$ - - - + + + (comments in code?) - + Can be done in $O(M+N\log N)$ with [Fibonacci heap](https://en.wikipedia.org/wiki/Fibonacci_heap). - + ### Problems - + ## All Pairs Shortest Path (APSP) - + Use the *Floyd-Warshall* algorithm. ### Tutorial - - example calculation, code - - - + + example calculation, code + + + - + [Paper](https://arxiv.org/pdf/1904.01210.pdf) @@ -107,10 +107,10 @@ up to constant factors. Therefore, our results suggest that, if one is confused the order of the triply nested loops, one can repeat the procedure three times just to be safe. - + ### Problems - + (more?) \ No newline at end of file diff --git a/content/5_Gold/SRQ.mdx b/content/4_Gold/SRQ.mdx similarity index 79% rename from content/5_Gold/SRQ.mdx rename to content/4_Gold/SRQ.mdx index e30edad..a9071bf 100644 --- a/content/5_Gold/SRQ.mdx +++ b/content/4_Gold/SRQ.mdx @@ -31,22 +31,22 @@ With $O(N\log N)$ time preprocessing, we can get $O(1)$ queries. First we'll consider the special case when $\ominus$ denotes `min`. - + ### Resources - - diagrams - code - - - + + diagrams + code + + + - + [CF: $O(1)$ Query RMQ with $O(N)$ build](https://codeforces.com/blog/entry/78931) - + ### Implementation @@ -54,7 +54,7 @@ First we'll consider the special case when $\ominus$ denotes `min`. ## Divide & Conquer - + **Divide & conquer** can refer to many different techniques. In this case, we use it to answer $Q$ queries offline in $O((N+Q)\log N)$ time. @@ -70,14 +70,14 @@ for each $M< r\le R$. Then the answer for all queries satisfying $l\le M< r$ is Actually, this can be adjusted to answer queries online in $O(1)$ time each. See my implementation [here](https://github.com/bqi343/USACO/blob/master/Implementations/content/data-structures/Static%20Range%20Queries%20(9.1)/RangeQuery.h). - + A data structure known as **sqrt-tree** can speed up preprocessing time to $O(N\log \log N)$. - [CF Blog Pt 1](http://codeforces.com/blog/entry/57046) - [CF Blog Pt 2](http://codeforces.com/blog/entry/59092) - + ### Implementation @@ -85,4 +85,4 @@ A data structure known as **sqrt-tree** can speed up preprocessing time to $O(N\ ## Problems - \ No newline at end of file + \ No newline at end of file diff --git a/content/5_Gold/Springboards.mdx b/content/4_Gold/Springboards.mdx similarity index 96% rename from content/5_Gold/Springboards.mdx rename to content/4_Gold/Springboards.mdx index 1e82333..570164f 100644 --- a/content/5_Gold/Springboards.mdx +++ b/content/4_Gold/Springboards.mdx @@ -24,7 +24,7 @@ export const metadata = { } }; - +
    @@ -79,4 +79,4 @@ ll query(int x) { auto it = m.lb(x); - + diff --git a/content/5_Gold/String_Hashing.mdx b/content/4_Gold/String_Hashing.mdx similarity index 77% rename from content/5_Gold/String_Hashing.mdx rename to content/4_Gold/String_Hashing.mdx index 6bc520d..a4d4e74 100644 --- a/content/5_Gold/String_Hashing.mdx +++ b/content/4_Gold/String_Hashing.mdx @@ -27,12 +27,12 @@ export const metadata = { ## Tutorial - - good intro - code - many applications + + good intro + code + many applications - + ### Implementation @@ -42,7 +42,7 @@ My implementation can be found [here](https://github.com/bqi343/USACO/blob/maste ## Example: Cownomics (Gold) - + - Use two pointers; for a fixed $l$, keep extending $r$ to the right until the positions $l\ldots r$ explain spotiness. - Hashing gives you a way to quickly check whether two substrings of different cow types are equal. So for a single $[l,r]$ pair you can check whether it works in $O(N\log N)$ time (and you only need to check $O(M)$ of these pairs in total). @@ -52,15 +52,15 @@ My implementation can be found [here](https://github.com/bqi343/USACO/blob/maste (elaborate) - + --> ## Hacking - - On CF educational rounds in particular, make sure to randomize your bases. - + + On CF educational rounds in particular, make sure to randomize your bases. + ## Problems - \ No newline at end of file + \ No newline at end of file diff --git a/content/5_Gold/TopoSort.mdx b/content/4_Gold/TopoSort.mdx similarity index 84% rename from content/5_Gold/TopoSort.mdx rename to content/4_Gold/TopoSort.mdx index cac5272..48c9b5b 100644 --- a/content/5_Gold/TopoSort.mdx +++ b/content/4_Gold/TopoSort.mdx @@ -33,22 +33,22 @@ To review, a **directed** graph consists of edges that can only be traversed in ## Topological Sort - + A [topological sort](https://en.wikipedia.org/wiki/Topological_sorting) of a directed acyclic graph is a linear ordering of its vertices such that for every directed edge $u\to v$ from vertex $u$ to vertex $v$, $u$ comes before $v$ in the ordering. ## Tutorial - - both BFS, DFS - + + both BFS, DFS + ### DFS - - DFS - DFS - + + DFS + DFS + (implementation) @@ -64,17 +64,17 @@ The BFS version, known as [Kahn's Algorithm](https://en.wikipedia.org/wiki/Topol ## Dynamic Programming - - Best Path in a DAG - + + Best Path in a DAG + One useful property of directed acyclic graphs is, as the name suggests, that no cycles exist. If we consider each node in the graph as a state, we can perform dynamic programming on the graph if we process the states in an order that guarantees for every edge $u\to v$ that $u$ is processed before $v$. Fortunately, this is the exact definition of a topological sort! - + In this task, we must find the longest path in a DAG. - + Let $dp[v]$ denote the length of the longest path ending at the node $v$. Clearly @@ -88,7 +88,7 @@ or zero if $v$ has in-degree $0$. If we process the states in topological order, - +