mirror of
https://github.com/mfocko/blog.git
synced 2024-11-14 01:59:42 +01:00
Docusaurus v3 and rename (#3)
This commit is contained in:
commit
2fb4765b1f
234 changed files with 3742 additions and 2446 deletions
|
@ -1,5 +1,5 @@
|
||||||
---
|
---
|
||||||
id: ib002-intro
|
id: algorithms-intro
|
||||||
title: Introduction
|
title: Introduction
|
||||||
slug: /
|
slug: /
|
||||||
---
|
---
|
|
@ -4,17 +4,17 @@ title: Vague postconditions and proving correctness of algorithms
|
||||||
description: |
|
description: |
|
||||||
Debugging and testing with precise postconditions.
|
Debugging and testing with precise postconditions.
|
||||||
tags:
|
tags:
|
||||||
- python
|
- python
|
||||||
- testing
|
- testing
|
||||||
- postconditions
|
- postconditions
|
||||||
- sorting
|
- sorting
|
||||||
last_update:
|
last_update:
|
||||||
date: 2021-03-18
|
date: 2021-03-18
|
||||||
---
|
---
|
||||||
|
|
||||||
## Introduction
|
## Introduction
|
||||||
|
|
||||||
[Source code](pathname:///files/ib002/algorithms-correctness/postcondition-ambiguity/test_sort.py) used later on.
|
[Source code](pathname:///files/algorithms/algorithms-correctness/postcondition-ambiguity/test_sort.py) used later on.
|
||||||
|
|
||||||
## Implementation of select sort from the exercises
|
## Implementation of select sort from the exercises
|
||||||
|
|
|
@ -4,11 +4,11 @@ title: Time complexity of ‹extend›
|
||||||
description: |
|
description: |
|
||||||
How to make inefficient algorithm unknowingly.
|
How to make inefficient algorithm unknowingly.
|
||||||
tags:
|
tags:
|
||||||
- c
|
- c
|
||||||
- python
|
- python
|
||||||
- dynamic array
|
- dynamic array
|
||||||
- time complexity
|
- time complexity
|
||||||
- recursion
|
- recursion
|
||||||
last_update:
|
last_update:
|
||||||
date: 2021-03-31
|
date: 2021-03-31
|
||||||
---
|
---
|
||||||
|
@ -86,8 +86,8 @@ As we could observe in the example above, `extend` iterates over all of the elem
|
||||||
|
|
||||||
Consider constructing of this list:
|
Consider constructing of this list:
|
||||||
|
|
||||||
![Rendered construction of the list](/files/ib002/time-complexity/extend/construction_light.svg#gh-light-mode-only)
|
![Rendered construction of the list](/files/algorithms/time-complexity/extend/construction_light.svg#gh-light-mode-only)
|
||||||
![Rendered construction of the list](/files/ib002/time-complexity/extend/construction_dark.svg#gh-dark-mode-only)
|
![Rendered construction of the list](/files/algorithms/time-complexity/extend/construction_dark.svg#gh-dark-mode-only)
|
||||||
|
|
||||||
Let us assume that you extend the result with the list that you get from the recursive call.
|
Let us assume that you extend the result with the list that you get from the recursive call.
|
||||||
|
|
||||||
|
@ -108,8 +108,8 @@ If the recursion had bigger depth and/or more elements, it would iterate through
|
||||||
|
|
||||||
There is an example of dynamic array:
|
There is an example of dynamic array:
|
||||||
|
|
||||||
- [interface (`dynlist.h`)](pathname:///files/ib002/time-complexity/extend/dynlist.h)
|
- [interface (`dynlist.h`)](pathname:///files/algorithms/time-complexity/extend/dynlist.h)
|
||||||
- [implementation (`dynlist.c`)](pathname:///files/ib002/time-complexity/extend/dynlist.c)
|
- [implementation (`dynlist.c`)](pathname:///files/algorithms/time-complexity/extend/dynlist.c)
|
||||||
|
|
||||||
For the sake of _Algorithms and Data Structures I_ we consider `APPEND` operation, i.e. adding the element to the end of the list, to have time complexity $\mathcal{O}(1)$ (**amortized**; which is out of the scope of IB002).
|
For the sake of _Algorithms and Data Structures I_ we consider `APPEND` operation, i.e. adding the element to the end of the list, to have time complexity $\mathcal{O}(1)$ (**amortized**; which is out of the scope of IB002).
|
||||||
|
|
|
@ -4,15 +4,15 @@ title: Recursion and backtracking with Robot Karel
|
||||||
description: |
|
description: |
|
||||||
A problem with too many restrictions.
|
A problem with too many restrictions.
|
||||||
tags:
|
tags:
|
||||||
- python
|
- python
|
||||||
- karel
|
- karel
|
||||||
- recursion
|
- recursion
|
||||||
- backtracking
|
- backtracking
|
||||||
last_update:
|
last_update:
|
||||||
date: 2022-11-29
|
date: 2022-11-29
|
||||||
---
|
---
|
||||||
|
|
||||||
- [Sources](pathname:///files/ib002/recursion/karel-1.tar.gz)
|
- [Sources](pathname:///files/algorithms/recursion/karel-1.tar.gz)
|
||||||
|
|
||||||
## Introduction
|
## Introduction
|
||||||
|
|
||||||
|
@ -94,6 +94,7 @@ your mind. Ideally:
|
||||||
- How can I process it?
|
- How can I process it?
|
||||||
|
|
||||||
:::
|
:::
|
||||||
|
|
||||||
- Write down list of problems that can happen, e.g.
|
- Write down list of problems that can happen, e.g.
|
||||||
|
|
||||||
:::info Example continued
|
:::info Example continued
|
||||||
|
@ -105,6 +106,7 @@ your mind. Ideally:
|
||||||
- What if my formulas are wrong?
|
- What if my formulas are wrong?
|
||||||
|
|
||||||
:::
|
:::
|
||||||
|
|
||||||
- Write down **anything** you consider important to solving the problem, e.g.
|
- Write down **anything** you consider important to solving the problem, e.g.
|
||||||
|
|
||||||
:::info Example continued once again
|
:::info Example continued once again
|
|
@ -4,13 +4,13 @@ title: Introduction to dynamic programming
|
||||||
description: |
|
description: |
|
||||||
Solving a problem in different ways.
|
Solving a problem in different ways.
|
||||||
tags:
|
tags:
|
||||||
- java
|
- java
|
||||||
- recursion
|
- recursion
|
||||||
- exponential
|
- exponential
|
||||||
- greedy
|
- greedy
|
||||||
- dynamic-programming
|
- dynamic-programming
|
||||||
- top-down-dp
|
- top-down-dp
|
||||||
- bottom-up-dp
|
- bottom-up-dp
|
||||||
last_updated:
|
last_updated:
|
||||||
date: 2023-08-17
|
date: 2023-08-17
|
||||||
---
|
---
|
||||||
|
@ -26,6 +26,7 @@ We are given a 2D array of integers and we are to find the _slide down_.
|
||||||
_Slide down_ is a maximum sum of consecutive numbers from the top to the bottom.
|
_Slide down_ is a maximum sum of consecutive numbers from the top to the bottom.
|
||||||
|
|
||||||
Let's have a look at few examples. Consider the following pyramid:
|
Let's have a look at few examples. Consider the following pyramid:
|
||||||
|
|
||||||
```
|
```
|
||||||
3
|
3
|
||||||
7 4
|
7 4
|
||||||
|
@ -34,6 +35,7 @@ Let's have a look at few examples. Consider the following pyramid:
|
||||||
```
|
```
|
||||||
|
|
||||||
This pyramid has following slide down:
|
This pyramid has following slide down:
|
||||||
|
|
||||||
```
|
```
|
||||||
*3
|
*3
|
||||||
*7 4
|
*7 4
|
||||||
|
@ -44,6 +46,7 @@ This pyramid has following slide down:
|
||||||
And its value is `23`.
|
And its value is `23`.
|
||||||
|
|
||||||
We can also have a look at a _bigger_ example:
|
We can also have a look at a _bigger_ example:
|
||||||
|
|
||||||
```
|
```
|
||||||
75
|
75
|
||||||
95 64
|
95 64
|
||||||
|
@ -61,6 +64,7 @@ We can also have a look at a _bigger_ example:
|
||||||
63 66 4 68 89 53 67 30 73 16 69 87 40 31
|
63 66 4 68 89 53 67 30 73 16 69 87 40 31
|
||||||
4 62 98 27 23 9 70 98 73 93 38 53 60 4 23
|
4 62 98 27 23 9 70 98 73 93 38 53 60 4 23
|
||||||
```
|
```
|
||||||
|
|
||||||
Slide down in this case is equal to `1074`.
|
Slide down in this case is equal to `1074`.
|
||||||
|
|
||||||
## Solving the problem
|
## Solving the problem
|
||||||
|
@ -76,6 +80,7 @@ For all of the following solutions I will be using basic `main` function that
|
||||||
will output `true`/`false` based on the expected output of our algorithm. Any
|
will output `true`/`false` based on the expected output of our algorithm. Any
|
||||||
other differences will lie only in the solutions of the problem. You can see the
|
other differences will lie only in the solutions of the problem. You can see the
|
||||||
`main` here:
|
`main` here:
|
||||||
|
|
||||||
```java
|
```java
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
System.out.print("Test #1: ");
|
System.out.print("Test #1: ");
|
||||||
|
@ -141,6 +146,7 @@ public static int longestSlideDown(int[][] pyramid) {
|
||||||
```
|
```
|
||||||
|
|
||||||
As you can see, we have 2 overloads:
|
As you can see, we have 2 overloads:
|
||||||
|
|
||||||
```java
|
```java
|
||||||
int longestSlideDown(int[][] pyramid);
|
int longestSlideDown(int[][] pyramid);
|
||||||
int longestSlideDown(int[][] pyramid, int row, int col);
|
int longestSlideDown(int[][] pyramid, int row, int col);
|
||||||
|
@ -162,6 +168,7 @@ really is a naïve solution, the time complexity is pretty bad. Let's find the
|
||||||
worst case scenario.
|
worst case scenario.
|
||||||
|
|
||||||
Let's start with the first overload:
|
Let's start with the first overload:
|
||||||
|
|
||||||
```java
|
```java
|
||||||
public static int longestSlideDown(int[][] pyramid) {
|
public static int longestSlideDown(int[][] pyramid) {
|
||||||
return longestSlideDown(pyramid, 0, 0);
|
return longestSlideDown(pyramid, 0, 0);
|
||||||
|
@ -208,6 +215,7 @@ choosing the under and right both. They are separate computations though, so we
|
||||||
are branching from each call of `longestSlideDown`, unless it's a base case.
|
are branching from each call of `longestSlideDown`, unless it's a base case.
|
||||||
|
|
||||||
What does that mean for us then? We basically get
|
What does that mean for us then? We basically get
|
||||||
|
|
||||||
$$
|
$$
|
||||||
T(y) =
|
T(y) =
|
||||||
\begin{cases}
|
\begin{cases}
|
||||||
|
@ -217,6 +225,7 @@ T(y) =
|
||||||
$$
|
$$
|
||||||
|
|
||||||
That looks rather easy to compute, isn't it? If you sum it up, you'll get:
|
That looks rather easy to compute, isn't it? If you sum it up, you'll get:
|
||||||
|
|
||||||
$$
|
$$
|
||||||
T(rows) \in \mathcal{O}(2^{rows})
|
T(rows) \in \mathcal{O}(2^{rows})
|
||||||
$$
|
$$
|
||||||
|
@ -256,6 +265,7 @@ optimal option at the moment.
|
||||||
|
|
||||||
We can try to adjust the naïve solution. The most problematic part are the
|
We can try to adjust the naïve solution. The most problematic part are the
|
||||||
recursive calls. Let's apply the greedy approach there:
|
recursive calls. Let's apply the greedy approach there:
|
||||||
|
|
||||||
```java
|
```java
|
||||||
public static int longestSlideDown(int[][] pyramid, int row, int col) {
|
public static int longestSlideDown(int[][] pyramid, int row, int col) {
|
||||||
if (row == pyramid.length - 1) {
|
if (row == pyramid.length - 1) {
|
||||||
|
@ -282,6 +292,7 @@ we simply go left.
|
||||||
We have switched from _adding the maximum_ to _following the “bigger” path_, so
|
We have switched from _adding the maximum_ to _following the “bigger” path_, so
|
||||||
we improved the time complexity tremendously. We just go down the pyramid all
|
we improved the time complexity tremendously. We just go down the pyramid all
|
||||||
the way to the bottom. Therefore we are getting:
|
the way to the bottom. Therefore we are getting:
|
||||||
|
|
||||||
$$
|
$$
|
||||||
\mathcal{O}(rows)
|
\mathcal{O}(rows)
|
||||||
$$
|
$$
|
||||||
|
@ -291,6 +302,7 @@ We have managed to convert our exponential solution into a linear one.
|
||||||
### Running the tests
|
### Running the tests
|
||||||
|
|
||||||
However, if we run the tests, we notice that the second test failed:
|
However, if we run the tests, we notice that the second test failed:
|
||||||
|
|
||||||
```
|
```
|
||||||
Test #1: passed
|
Test #1: passed
|
||||||
Test #2: failed
|
Test #2: failed
|
||||||
|
@ -301,6 +313,7 @@ algorithms are not the ideal solution to **all** problems. In this case there
|
||||||
may be a solution that is bigger than the one found using the greedy algorithm.
|
may be a solution that is bigger than the one found using the greedy algorithm.
|
||||||
|
|
||||||
Imagine the following pyramid:
|
Imagine the following pyramid:
|
||||||
|
|
||||||
```
|
```
|
||||||
1
|
1
|
||||||
2 3
|
2 3
|
||||||
|
@ -310,6 +323,7 @@ Imagine the following pyramid:
|
||||||
```
|
```
|
||||||
|
|
||||||
We start at the top:
|
We start at the top:
|
||||||
|
|
||||||
1. Current cell: `1`, we can choose from `2` and `3`, `3` looks better, so we
|
1. Current cell: `1`, we can choose from `2` and `3`, `3` looks better, so we
|
||||||
choose it.
|
choose it.
|
||||||
2. Current cell: `3`, we can choose from `6` and `7`, `7` looks better, so we
|
2. Current cell: `3`, we can choose from `6` and `7`, `7` looks better, so we
|
||||||
|
@ -429,6 +443,7 @@ that!
|
||||||
|
|
||||||
Overall we are doing the same things for almost[^2] all of the positions within
|
Overall we are doing the same things for almost[^2] all of the positions within
|
||||||
the pyramid:
|
the pyramid:
|
||||||
|
|
||||||
1. We calculate and store it (using the partial results stored in cache). This
|
1. We calculate and store it (using the partial results stored in cache). This
|
||||||
is done only once.
|
is done only once.
|
||||||
|
|
||||||
|
@ -452,6 +467,7 @@ the pyramid:
|
||||||
:::
|
:::
|
||||||
|
|
||||||
Our final upper bound of this work is therefore $\log_2{n}$.
|
Our final upper bound of this work is therefore $\log_2{n}$.
|
||||||
|
|
||||||
2. We retrieve it from the cache. Same as in first point, but only twice, so we
|
2. We retrieve it from the cache. Same as in first point, but only twice, so we
|
||||||
get $2 \cdot \log_2{n}$.
|
get $2 \cdot \log_2{n}$.
|
||||||
|
|
||||||
|
@ -465,6 +481,7 @@ Okay, we have evaluated work done for each of the cells in the pyramid and now
|
||||||
we need to put it together.
|
we need to put it together.
|
||||||
|
|
||||||
Let's split the time complexity of our solution into two operands:
|
Let's split the time complexity of our solution into two operands:
|
||||||
|
|
||||||
$$
|
$$
|
||||||
\mathcal{O}(r + s)
|
\mathcal{O}(r + s)
|
||||||
$$
|
$$
|
||||||
|
@ -473,6 +490,7 @@ $r$ will represent the _actual_ calculation of the cells and $s$ will represent
|
||||||
the additional retrievals on top of the calculation.
|
the additional retrievals on top of the calculation.
|
||||||
|
|
||||||
We calculate the values only **once**, therefore we can safely agree on:
|
We calculate the values only **once**, therefore we can safely agree on:
|
||||||
|
|
||||||
$$
|
$$
|
||||||
\begin{align*}
|
\begin{align*}
|
||||||
r &= n \cdot \log{n} \\
|
r &= n \cdot \log{n} \\
|
||||||
|
@ -482,6 +500,7 @@ $$
|
||||||
What about the $s$ though? Key observation here is the fact that we have 2
|
What about the $s$ though? Key observation here is the fact that we have 2
|
||||||
lookups on the tree in each of them **and** we do it twice, cause each cell has
|
lookups on the tree in each of them **and** we do it twice, cause each cell has
|
||||||
at most 2 parents:
|
at most 2 parents:
|
||||||
|
|
||||||
$$
|
$$
|
||||||
\begin{align*}
|
\begin{align*}
|
||||||
s &= n \cdot 2 \cdot \left( 2 \cdot \log{n} \right) \\
|
s &= n \cdot 2 \cdot \left( 2 \cdot \log{n} \right) \\
|
||||||
|
@ -496,6 +515,7 @@ of the results. This is not entirely true, since we have included the
|
||||||
`.containsKey()` and `.get()` from the `return` statement in the second part.
|
`.containsKey()` and `.get()` from the `return` statement in the second part.
|
||||||
|
|
||||||
If we were to represent this more precisely, we could've gone with:
|
If we were to represent this more precisely, we could've gone with:
|
||||||
|
|
||||||
$$
|
$$
|
||||||
\begin{align*}
|
\begin{align*}
|
||||||
r &= 3 \cdot n \cdot \log{n} \\
|
r &= 3 \cdot n \cdot \log{n} \\
|
||||||
|
@ -512,6 +532,7 @@ doesn't really matter.
|
||||||
|
|
||||||
And so our final time complexity for the whole _top-down dynamic programming_
|
And so our final time complexity for the whole _top-down dynamic programming_
|
||||||
approach is:
|
approach is:
|
||||||
|
|
||||||
$$
|
$$
|
||||||
\mathcal{O}(r + s) \\
|
\mathcal{O}(r + s) \\
|
||||||
\mathcal{O}(n \cdot \log{n} + 4 \cdot n \cdot \log{n}) \\
|
\mathcal{O}(n \cdot \log{n} + 4 \cdot n \cdot \log{n}) \\
|
||||||
|
@ -531,11 +552,13 @@ down. At the end we get the final result for `new Position(0, 0)`, so we need to
|
||||||
compute everything below.
|
compute everything below.
|
||||||
|
|
||||||
That's how we obtain:
|
That's how we obtain:
|
||||||
|
|
||||||
$$
|
$$
|
||||||
\mathcal{O}(n)
|
\mathcal{O}(n)
|
||||||
$$
|
$$
|
||||||
|
|
||||||
$n$ represents the total amount of cells in the pyramid, i.e.
|
$n$ represents the total amount of cells in the pyramid, i.e.
|
||||||
|
|
||||||
$$
|
$$
|
||||||
\sum_{y=0}^{\mathtt{pyramid.length} - 1} \mathtt{pyramid}\left[y\right]\mathtt{.length}
|
\sum_{y=0}^{\mathtt{pyramid.length} - 1} \mathtt{pyramid}\left[y\right]\mathtt{.length}
|
||||||
$$
|
$$
|
||||||
|
@ -553,6 +576,7 @@ number.
|
||||||
|
|
||||||
Yes, it can! Try to think about a way, how can you minimize the memory
|
Yes, it can! Try to think about a way, how can you minimize the memory
|
||||||
complexity of this approach. I'll give you a hint:
|
complexity of this approach. I'll give you a hint:
|
||||||
|
|
||||||
$$
|
$$
|
||||||
\mathcal{O}(rows)
|
\mathcal{O}(rows)
|
||||||
$$
|
$$
|
||||||
|
@ -578,6 +602,7 @@ to implement right from the beginning.
|
||||||
:::
|
:::
|
||||||
|
|
||||||
Let's see how we can implement it:
|
Let's see how we can implement it:
|
||||||
|
|
||||||
```java
|
```java
|
||||||
public static int longestSlideDown(int[][] pyramid) {
|
public static int longestSlideDown(int[][] pyramid) {
|
||||||
// In the beginning we declare new array. At this point it is easier to just
|
// In the beginning we declare new array. At this point it is easier to just
|
||||||
|
@ -647,6 +672,7 @@ the best **overall** result I can achieve.
|
||||||
Time complexity of this solution is rather simple. We allocate an array for the
|
Time complexity of this solution is rather simple. We allocate an array for the
|
||||||
rows and then for each row, we copy it and adjust the partial results. Doing
|
rows and then for each row, we copy it and adjust the partial results. Doing
|
||||||
this we get:
|
this we get:
|
||||||
|
|
||||||
$$
|
$$
|
||||||
\mathcal{O}(rows + 2n)
|
\mathcal{O}(rows + 2n)
|
||||||
$$
|
$$
|
||||||
|
@ -658,6 +684,7 @@ once.
|
||||||
|
|
||||||
We're allocating an array for the pyramid **again** for our partial results, so
|
We're allocating an array for the pyramid **again** for our partial results, so
|
||||||
we get:
|
we get:
|
||||||
|
|
||||||
$$
|
$$
|
||||||
\mathcal{O}(n)
|
\mathcal{O}(n)
|
||||||
$$
|
$$
|
||||||
|
@ -695,7 +722,7 @@ successor and represents the way we can enhance the existing implementation.
|
||||||
:::info source
|
:::info source
|
||||||
|
|
||||||
You can find source code referenced in the text
|
You can find source code referenced in the text
|
||||||
[here](pathname:///files/ib002/recursion/pyramid-slide-down.tar.gz).
|
[here](pathname:///files/algorithms/recursion/pyramid-slide-down.tar.gz).
|
||||||
|
|
||||||
:::
|
:::
|
||||||
|
|
|
@ -4,9 +4,9 @@ title: Použití červeno-černých stromů
|
||||||
description: |
|
description: |
|
||||||
Ukázka použití červeno-černých stromů v standardních knižnicích známých jazyků.
|
Ukázka použití červeno-černých stromů v standardních knižnicích známých jazyků.
|
||||||
tags:
|
tags:
|
||||||
- balanced trees
|
- balanced trees
|
||||||
- red-black trees
|
- red-black trees
|
||||||
- applications
|
- applications
|
||||||
last_update:
|
last_update:
|
||||||
date: 2022-04-05
|
date: 2022-04-05
|
||||||
---
|
---
|
|
@ -4,8 +4,8 @@ title: On the rules of the red-black tree
|
||||||
description: |
|
description: |
|
||||||
Shower thoughts on the rules of the red-black tree.
|
Shower thoughts on the rules of the red-black tree.
|
||||||
tags:
|
tags:
|
||||||
- red-black trees
|
- red-black trees
|
||||||
- balanced trees
|
- balanced trees
|
||||||
last_update:
|
last_update:
|
||||||
date: 2023-06-10
|
date: 2023-06-10
|
||||||
---
|
---
|
||||||
|
@ -18,6 +18,7 @@ each of the red-black tree rules and try to change, break and contemplate about
|
||||||
them.
|
them.
|
||||||
|
|
||||||
We expect that you are familiar with the following set of the rules[^1]:
|
We expect that you are familiar with the following set of the rules[^1]:
|
||||||
|
|
||||||
1. Every node is either red or black.
|
1. Every node is either red or black.
|
||||||
2. The root is black.
|
2. The root is black.
|
||||||
3. Every leaf (`nil`) is black.
|
3. Every leaf (`nil`) is black.
|
||||||
|
@ -55,13 +56,13 @@ my child would be colored red.
|
||||||
Example of a red-black tree that keeps count of black nodes on paths to the
|
Example of a red-black tree that keeps count of black nodes on paths to the
|
||||||
leaves follows:
|
leaves follows:
|
||||||
|
|
||||||
![Red-black tree with black height](/files/ib002/rb-trees/rules/rb_height_light.svg#gh-light-mode-only)
|
![Red-black tree with black height](/files/algorithms/rb-trees/rules/rb_height_light.svg#gh-light-mode-only)
|
||||||
![Red-black tree with black height](/files/ib002/rb-trees/rules/rb_height_dark.svg#gh-dark-mode-only)
|
![Red-black tree with black height](/files/algorithms/rb-trees/rules/rb_height_dark.svg#gh-dark-mode-only)
|
||||||
|
|
||||||
We mark the _black heights_ in superscript. You can see that all leaves have the
|
We mark the _black heights_ in superscript. You can see that all leaves have the
|
||||||
black height equal to $1$. Let's take a look at some of the interesting cases:
|
black height equal to $1$. Let's take a look at some of the interesting cases:
|
||||||
|
|
||||||
* If we take a look at the node with $\text{key} = 9$, we can see that it is
|
- If we take a look at the node with $\text{key} = 9$, we can see that it is
|
||||||
coloured red and its black height is 1, because it is a leaf.
|
coloured red and its black height is 1, because it is a leaf.
|
||||||
|
|
||||||
Let's look at its parent (node with $\text{key} = 8$). On its left side it has
|
Let's look at its parent (node with $\text{key} = 8$). On its left side it has
|
||||||
|
@ -71,7 +72,7 @@ black height equal to $1$. Let's take a look at some of the interesting cases:
|
||||||
We can clearly see that if a node has the same black height as its parent, it
|
We can clearly see that if a node has the same black height as its parent, it
|
||||||
is a red node.
|
is a red node.
|
||||||
|
|
||||||
* Now let's take a look at the root with $\text{key} = 3$. It has a black height
|
- Now let's take a look at the root with $\text{key} = 3$. It has a black height
|
||||||
of 3. Both of its children are black nodes and have black height of 2.
|
of 3. Both of its children are black nodes and have black height of 2.
|
||||||
|
|
||||||
We can see that if a node has its height 1 lower than its parent, it is a black
|
We can see that if a node has its height 1 lower than its parent, it is a black
|
||||||
|
@ -95,6 +96,7 @@ This rule might seem like a very important one, but overall is not. You can safe
|
||||||
omit this rule, but you also need to deal with the consequences.
|
omit this rule, but you also need to deal with the consequences.
|
||||||
|
|
||||||
Let's refresh our memory with the algorithm of _insert fixup_:
|
Let's refresh our memory with the algorithm of _insert fixup_:
|
||||||
|
|
||||||
```
|
```
|
||||||
WHILE z.p.color == Red
|
WHILE z.p.color == Red
|
||||||
IF z.p == z.p.p.left
|
IF z.p == z.p.p.left
|
||||||
|
@ -138,17 +140,17 @@ black root property.
|
||||||
If we decide to omit this condition, we need to address it in the pseudocodes
|
If we decide to omit this condition, we need to address it in the pseudocodes
|
||||||
accordingly.
|
accordingly.
|
||||||
|
|
||||||
| Usual algorithm with black root | Allowing red root |
|
| Usual algorithm with black root | Allowing red root |
|
||||||
| :-----------------------------: | :---------------: |
|
| :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: |
|
||||||
| ![1ª insertion](/files/ib002/rb-trees/rules/red-root/br_0_light.svg#gh-light-mode-only)![1ª insertion](/files/ib002/rb-trees/rules/red-root/br_0_dark.svg#gh-dark-mode-only) | ![1ª insertion](/files/ib002/rb-trees/rules/red-root/rr_0_light.svg#gh-light-mode-only)![1ª insertion](/files/ib002/rb-trees/rules/red-root/rr_0_dark.svg#gh-dark-mode-only) |
|
| ![1ª insertion](/files/algorithms/rb-trees/rules/red-root/br_0_light.svg#gh-light-mode-only)![1ª insertion](/files/algorithms/rb-trees/rules/red-root/br_0_dark.svg#gh-dark-mode-only) | ![1ª insertion](/files/algorithms/rb-trees/rules/red-root/rr_0_light.svg#gh-light-mode-only)![1ª insertion](/files/algorithms/rb-trees/rules/red-root/rr_0_dark.svg#gh-dark-mode-only) |
|
||||||
| ![2ª insertion](/files/ib002/rb-trees/rules/red-root/br_1_light.svg#gh-light-mode-only)![2ª insertion](/files/ib002/rb-trees/rules/red-root/br_1_dark.svg#gh-dark-mode-only) | ![2ª insertion](/files/ib002/rb-trees/rules/red-root/rr_1_light.svg#gh-light-mode-only)![2ª insertion](/files/ib002/rb-trees/rules/red-root/rr_1_dark.svg#gh-dark-mode-only) |
|
| ![2ª insertion](/files/algorithms/rb-trees/rules/red-root/br_1_light.svg#gh-light-mode-only)![2ª insertion](/files/algorithms/rb-trees/rules/red-root/br_1_dark.svg#gh-dark-mode-only) | ![2ª insertion](/files/algorithms/rb-trees/rules/red-root/rr_1_light.svg#gh-light-mode-only)![2ª insertion](/files/algorithms/rb-trees/rules/red-root/rr_1_dark.svg#gh-dark-mode-only) |
|
||||||
| ![3ª insertion](/files/ib002/rb-trees/rules/red-root/br_2_light.svg#gh-light-mode-only)![3ª insertion](/files/ib002/rb-trees/rules/red-root/br_2_dark.svg#gh-dark-mode-only) | ![3ª insertion](/files/ib002/rb-trees/rules/red-root/rr_2_light.svg#gh-light-mode-only)![3ª insertion](/files/ib002/rb-trees/rules/red-root/rr_2_dark.svg#gh-dark-mode-only) |
|
| ![3ª insertion](/files/algorithms/rb-trees/rules/red-root/br_2_light.svg#gh-light-mode-only)![3ª insertion](/files/algorithms/rb-trees/rules/red-root/br_2_dark.svg#gh-dark-mode-only) | ![3ª insertion](/files/algorithms/rb-trees/rules/red-root/rr_2_light.svg#gh-light-mode-only)![3ª insertion](/files/algorithms/rb-trees/rules/red-root/rr_2_dark.svg#gh-dark-mode-only) |
|
||||||
| ![4ª insertion](/files/ib002/rb-trees/rules/red-root/br_3_light.svg#gh-light-mode-only)![4ª insertion](/files/ib002/rb-trees/rules/red-root/br_3_dark.svg#gh-dark-mode-only) | ![4ª insertion](/files/ib002/rb-trees/rules/red-root/rr_3_light.svg#gh-light-mode-only)![4ª insertion](/files/ib002/rb-trees/rules/red-root/rr_3_dark.svg#gh-dark-mode-only) |
|
| ![4ª insertion](/files/algorithms/rb-trees/rules/red-root/br_3_light.svg#gh-light-mode-only)![4ª insertion](/files/algorithms/rb-trees/rules/red-root/br_3_dark.svg#gh-dark-mode-only) | ![4ª insertion](/files/algorithms/rb-trees/rules/red-root/rr_3_light.svg#gh-light-mode-only)![4ª insertion](/files/algorithms/rb-trees/rules/red-root/rr_3_dark.svg#gh-dark-mode-only) |
|
||||||
| ![5ª insertion](/files/ib002/rb-trees/rules/red-root/br_4_light.svg#gh-light-mode-only)![5ª insertion](/files/ib002/rb-trees/rules/red-root/br_4_dark.svg#gh-dark-mode-only) | ![5ª insertion](/files/ib002/rb-trees/rules/red-root/rr_4_light.svg#gh-light-mode-only)![5ª insertion](/files/ib002/rb-trees/rules/red-root/rr_4_dark.svg#gh-dark-mode-only) |
|
| ![5ª insertion](/files/algorithms/rb-trees/rules/red-root/br_4_light.svg#gh-light-mode-only)![5ª insertion](/files/algorithms/rb-trees/rules/red-root/br_4_dark.svg#gh-dark-mode-only) | ![5ª insertion](/files/algorithms/rb-trees/rules/red-root/rr_4_light.svg#gh-light-mode-only)![5ª insertion](/files/algorithms/rb-trees/rules/red-root/rr_4_dark.svg#gh-dark-mode-only) |
|
||||||
| ![6ª insertion](/files/ib002/rb-trees/rules/red-root/br_5_light.svg#gh-light-mode-only)![6ª insertion](/files/ib002/rb-trees/rules/red-root/br_5_dark.svg#gh-dark-mode-only) | ![6ª insertion](/files/ib002/rb-trees/rules/red-root/rr_5_light.svg#gh-light-mode-only)![6ª insertion](/files/ib002/rb-trees/rules/red-root/rr_5_dark.svg#gh-dark-mode-only) |
|
| ![6ª insertion](/files/algorithms/rb-trees/rules/red-root/br_5_light.svg#gh-light-mode-only)![6ª insertion](/files/algorithms/rb-trees/rules/red-root/br_5_dark.svg#gh-dark-mode-only) | ![6ª insertion](/files/algorithms/rb-trees/rules/red-root/rr_5_light.svg#gh-light-mode-only)![6ª insertion](/files/algorithms/rb-trees/rules/red-root/rr_5_dark.svg#gh-dark-mode-only) |
|
||||||
| ![7ª insertion](/files/ib002/rb-trees/rules/red-root/br_6_light.svg#gh-light-mode-only)![7ª insertion](/files/ib002/rb-trees/rules/red-root/br_6_dark.svg#gh-dark-mode-only) | ![7ª insertion](/files/ib002/rb-trees/rules/red-root/rr_6_light.svg#gh-light-mode-only)![7ª insertion](/files/ib002/rb-trees/rules/red-root/rr_6_dark.svg#gh-dark-mode-only) |
|
| ![7ª insertion](/files/algorithms/rb-trees/rules/red-root/br_6_light.svg#gh-light-mode-only)![7ª insertion](/files/algorithms/rb-trees/rules/red-root/br_6_dark.svg#gh-dark-mode-only) | ![7ª insertion](/files/algorithms/rb-trees/rules/red-root/rr_6_light.svg#gh-light-mode-only)![7ª insertion](/files/algorithms/rb-trees/rules/red-root/rr_6_dark.svg#gh-dark-mode-only) |
|
||||||
| ![8ª insertion](/files/ib002/rb-trees/rules/red-root/br_7_light.svg#gh-light-mode-only)![8ª insertion](/files/ib002/rb-trees/rules/red-root/br_7_dark.svg#gh-dark-mode-only) | ![8ª insertion](/files/ib002/rb-trees/rules/red-root/rr_7_light.svg#gh-light-mode-only)![8ª insertion](/files/ib002/rb-trees/rules/red-root/rr_7_dark.svg#gh-dark-mode-only) |
|
| ![8ª insertion](/files/algorithms/rb-trees/rules/red-root/br_7_light.svg#gh-light-mode-only)![8ª insertion](/files/algorithms/rb-trees/rules/red-root/br_7_dark.svg#gh-dark-mode-only) | ![8ª insertion](/files/algorithms/rb-trees/rules/red-root/rr_7_light.svg#gh-light-mode-only)![8ª insertion](/files/algorithms/rb-trees/rules/red-root/rr_7_dark.svg#gh-dark-mode-only) |
|
||||||
| ![9ª insertion](/files/ib002/rb-trees/rules/red-root/br_8_light.svg#gh-light-mode-only)![9ª insertion](/files/ib002/rb-trees/rules/red-root/br_8_dark.svg#gh-dark-mode-only) | ![9ª insertion](/files/ib002/rb-trees/rules/red-root/rr_8_light.svg#gh-light-mode-only)![9ª insertion](/files/ib002/rb-trees/rules/red-root/rr_8_dark.svg#gh-dark-mode-only) |
|
| ![9ª insertion](/files/algorithms/rb-trees/rules/red-root/br_8_light.svg#gh-light-mode-only)![9ª insertion](/files/algorithms/rb-trees/rules/red-root/br_8_dark.svg#gh-dark-mode-only) | ![9ª insertion](/files/algorithms/rb-trees/rules/red-root/rr_8_light.svg#gh-light-mode-only)![9ª insertion](/files/algorithms/rb-trees/rules/red-root/rr_8_dark.svg#gh-dark-mode-only) |
|
||||||
|
|
||||||
## 3ª Every leaf (`nil`) is black.
|
## 3ª Every leaf (`nil`) is black.
|
||||||
|
|
||||||
|
@ -157,8 +159,8 @@ some other way? Let's go through some of the possible ways I can look at this an
|
||||||
how would they affect the other rules and balancing.
|
how would they affect the other rules and balancing.
|
||||||
|
|
||||||
We will experiment with the following tree:
|
We will experiment with the following tree:
|
||||||
![](/files/ib002/rb-trees/rules/rb_light.svg#gh-light-mode-only)
|
![](/files/algorithms/rb-trees/rules/rb_light.svg#gh-light-mode-only)
|
||||||
![](/files/ib002/rb-trees/rules/rb_dark.svg#gh-dark-mode-only)
|
![](/files/algorithms/rb-trees/rules/rb_dark.svg#gh-dark-mode-only)
|
||||||
|
|
||||||
We should start by counting the black nodes from root to the `nil` leaves based
|
We should start by counting the black nodes from root to the `nil` leaves based
|
||||||
on the rules. We have multiple similar paths, so we will pick only the interesting
|
on the rules. We have multiple similar paths, so we will pick only the interesting
|
||||||
|
@ -170,11 +172,11 @@ ones.
|
||||||
3. What happens if we do not count the `nil` leaves, but consider nodes with at
|
3. What happens if we do not count the `nil` leaves, but consider nodes with at
|
||||||
least one `nil` descendant as leaves?
|
least one `nil` descendant as leaves?
|
||||||
|
|
||||||
| path | black nodes | 1ª idea | 2ª idea | 3ª idea |
|
| path | black nodes | 1ª idea | 2ª idea | 3ª idea |
|
||||||
| ------------------------: | ----------: | ------: | ------: | ------: |
|
| ------------------------: | ----------: | ------: | ------: | ------: |
|
||||||
| `3 → 1 → 0 → nil` | 4 | 3 | 4 | 3 |
|
| `3 → 1 → 0 → nil` | 4 | 3 | 4 | 3 |
|
||||||
| `3 → 5 → 7 → 8 → nil` | 4 | 3 | - | 3 |
|
| `3 → 5 → 7 → 8 → nil` | 4 | 3 | - | 3 |
|
||||||
| `3 → 5 → 7 → 8 → 9 → nil` | 4 | 3 | 4 | 3 |
|
| `3 → 5 → 7 → 8 → 9 → nil` | 4 | 3 | 4 | 3 |
|
||||||
|
|
||||||
First idea is very easy to execute and it is also very easy to argue about its
|
First idea is very easy to execute and it is also very easy to argue about its
|
||||||
correctness. It is correct, because we just subtract one from each of the paths.
|
correctness. It is correct, because we just subtract one from each of the paths.
|
||||||
|
@ -232,15 +234,15 @@ import TabItem from '@theme/TabItem';
|
||||||
<Tabs>
|
<Tabs>
|
||||||
<TabItem value="enforcing" label="Enforcing this rule">
|
<TabItem value="enforcing" label="Enforcing this rule">
|
||||||
|
|
||||||
![](/files/ib002/rb-trees/rules/red-node-black-children/correct_light.svg#gh-light-mode-only)
|
![](/files/algorithms/rb-trees/rules/red-node-black-children/correct_light.svg#gh-light-mode-only)
|
||||||
![](/files/ib002/rb-trees/rules/red-node-black-children/correct_dark.svg#gh-dark-mode-only)
|
![](/files/algorithms/rb-trees/rules/red-node-black-children/correct_dark.svg#gh-dark-mode-only)
|
||||||
|
|
||||||
</TabItem>
|
</TabItem>
|
||||||
|
|
||||||
<TabItem value="omitting" label="Omitting this rule">
|
<TabItem value="omitting" label="Omitting this rule">
|
||||||
|
|
||||||
![](/files/ib002/rb-trees/rules/red-node-black-children/incorrect_light.svg#gh-light-mode-only)
|
![](/files/algorithms/rb-trees/rules/red-node-black-children/incorrect_light.svg#gh-light-mode-only)
|
||||||
![](/files/ib002/rb-trees/rules/red-node-black-children/incorrect_dark.svg#gh-dark-mode-only)
|
![](/files/algorithms/rb-trees/rules/red-node-black-children/incorrect_dark.svg#gh-dark-mode-only)
|
||||||
|
|
||||||
</TabItem>
|
</TabItem>
|
||||||
</Tabs>
|
</Tabs>
|
||||||
|
@ -262,6 +264,7 @@ An important observation here is the fact that the red-black tree is a
|
||||||
:::
|
:::
|
||||||
|
|
||||||
Enforcing this rule (together with the 4th rule) keeps the tree balanced:
|
Enforcing this rule (together with the 4th rule) keeps the tree balanced:
|
||||||
|
|
||||||
1. 4th rule makes sure we can't “hack” this requirement.
|
1. 4th rule makes sure we can't “hack” this requirement.
|
||||||
2. This rule ensures that we have “similar”[^2] length to each of the leaves.
|
2. This rule ensures that we have “similar”[^2] length to each of the leaves.
|
||||||
|
|
|
@ -4,17 +4,17 @@ title: Iterative algorithms via iterators
|
||||||
description: |
|
description: |
|
||||||
Iterative DFS using iterators.
|
Iterative DFS using iterators.
|
||||||
tags:
|
tags:
|
||||||
- csharp
|
- csharp
|
||||||
- graphs
|
- graphs
|
||||||
- iterators
|
- iterators
|
||||||
- iterative
|
- iterative
|
||||||
last_update:
|
last_update:
|
||||||
date: 2021-05-18
|
date: 2021-05-18
|
||||||
---
|
---
|
||||||
|
|
||||||
## Introduction
|
## Introduction
|
||||||
|
|
||||||
- [Source code used later on.](pathname:///files/ib002/graphs/iterative-and-iterators.tar.gz)
|
- [Source code used later on.](pathname:///files/algorithms/graphs/iterative-and-iterators.tar.gz)
|
||||||
|
|
||||||
As we have talked on the seminar, iterative approach to implementing DFS is not very intuitive and is a very easy way how to create an incorrect implementation.
|
As we have talked on the seminar, iterative approach to implementing DFS is not very intuitive and is a very easy way how to create an incorrect implementation.
|
||||||
|
|
||||||
|
@ -171,7 +171,6 @@ begin
|
||||||
end DFS;
|
end DFS;
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
( The way we manipulate with the iterators is closest to the C# implementation. Apart from the `Iterator` thing :) In case you tried to implement it in C++, you would more than likely need to change the check, since you would get first successor right at the beginning )
|
( The way we manipulate with the iterators is closest to the C# implementation. Apart from the `Iterator` thing :) In case you tried to implement it in C++, you would more than likely need to change the check, since you would get first successor right at the beginning )
|
||||||
|
|
||||||
So here we don't keep indices, but the iterators. We can also check existence of other successors easily: by the iterator moving after the last successor.
|
So here we don't keep indices, but the iterators. We can also check existence of other successors easily: by the iterator moving after the last successor.
|
|
@ -4,8 +4,8 @@ title: Distance boundaries from BFS tree on undirected graphs
|
||||||
description: |
|
description: |
|
||||||
Short explanation of distance boundaries deduced from a BFS tree.
|
Short explanation of distance boundaries deduced from a BFS tree.
|
||||||
tags:
|
tags:
|
||||||
- graphs
|
- graphs
|
||||||
- bfs
|
- bfs
|
||||||
last_update:
|
last_update:
|
||||||
date: 2022-04-30
|
date: 2022-04-30
|
||||||
---
|
---
|
||||||
|
@ -21,13 +21,13 @@ As we have talked on the seminar, if we construct from some vertex $u$ BFS tree
|
||||||
|
|
||||||
Consider the following graph:
|
Consider the following graph:
|
||||||
|
|
||||||
![](/files/ib002/graphs/bfs-tree/bfs_graph_light.svg#gh-light-mode-only)
|
![](/files/algorithms/graphs/bfs-tree/bfs_graph_light.svg#gh-light-mode-only)
|
||||||
![](/files/ib002/graphs/bfs-tree/bfs_graph_dark.svg#gh-dark-mode-only)
|
![](/files/algorithms/graphs/bfs-tree/bfs_graph_dark.svg#gh-dark-mode-only)
|
||||||
|
|
||||||
We run BFS from the vertex $a$ and obtain the following BFS tree:
|
We run BFS from the vertex $a$ and obtain the following BFS tree:
|
||||||
|
|
||||||
![](/files/ib002/graphs/bfs-tree/bfs_tree_light.svg#gh-light-mode-only)
|
![](/files/algorithms/graphs/bfs-tree/bfs_tree_light.svg#gh-light-mode-only)
|
||||||
![](/files/ib002/graphs/bfs-tree/bfs_tree_dark.svg#gh-dark-mode-only)
|
![](/files/algorithms/graphs/bfs-tree/bfs_tree_dark.svg#gh-dark-mode-only)
|
||||||
|
|
||||||
Let's consider pair of vertices $e$ and $h$. For them we can safely lay, from the BFS tree, following properties:
|
Let's consider pair of vertices $e$ and $h$. For them we can safely lay, from the BFS tree, following properties:
|
||||||
|
|
||||||
|
@ -42,9 +42,8 @@ Let's keep the same graph, but break the lower bound, i.e. I have gotten a lower
|
||||||
|
|
||||||
Now the more important question, is there a shorter path in that graph? The answer is no, there's no shorter path than the one with length $2$. So what can we do about it? We'll add an edge to have a shorter path. Now we have gotten a lower bound of $2$, which means the only shorter path we can construct has $1$ edge and that is ‹$e, h$› (no intermediary vertices). Let's do this!
|
Now the more important question, is there a shorter path in that graph? The answer is no, there's no shorter path than the one with length $2$. So what can we do about it? We'll add an edge to have a shorter path. Now we have gotten a lower bound of $2$, which means the only shorter path we can construct has $1$ edge and that is ‹$e, h$› (no intermediary vertices). Let's do this!
|
||||||
|
|
||||||
![](/files/ib002/graphs/bfs-tree/bfs_graph_with_additional_edge_light.svg#gh-light-mode-only)
|
![](/files/algorithms/graphs/bfs-tree/bfs_graph_with_additional_edge_light.svg#gh-light-mode-only)
|
||||||
![](/files/ib002/graphs/bfs-tree/bfs_graph_with_additional_edge_dark.svg#gh-dark-mode-only)
|
![](/files/algorithms/graphs/bfs-tree/bfs_graph_with_additional_edge_dark.svg#gh-dark-mode-only)
|
||||||
|
|
||||||
|
|
||||||
Okay, so we have a graph that breaks the rule we have laid. However, we need to run BFS to obtain the new BFS tree, since we have changed the graph.
|
Okay, so we have a graph that breaks the rule we have laid. However, we need to run BFS to obtain the new BFS tree, since we have changed the graph.
|
||||||
|
|
||||||
|
@ -56,8 +55,8 @@ Do we need to run BFS after **every** change?
|
||||||
|
|
||||||
:::
|
:::
|
||||||
|
|
||||||
![](/files/ib002/graphs/bfs-tree/bfs_tree_with_additional_edge_light.svg#gh-light-mode-only)
|
![](/files/algorithms/graphs/bfs-tree/bfs_tree_with_additional_edge_light.svg#gh-light-mode-only)
|
||||||
![](/files/ib002/graphs/bfs-tree/bfs_tree_with_additional_edge_dark.svg#gh-dark-mode-only)
|
![](/files/algorithms/graphs/bfs-tree/bfs_tree_with_additional_edge_dark.svg#gh-dark-mode-only)
|
||||||
|
|
||||||
Oops, we have gotten a new BFS tree, that has a height difference of 1.
|
Oops, we have gotten a new BFS tree, that has a height difference of 1.
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
---
|
---
|
||||||
id: ib015-intro
|
id: automata-intro
|
||||||
title: Introduction
|
title: Introduction
|
||||||
slug: /
|
slug: /
|
||||||
---
|
---
|
|
@ -1,5 +1,5 @@
|
||||||
---
|
---
|
||||||
id: ib111-intro
|
id: c-intro
|
||||||
title: Introduction
|
title: Introduction
|
||||||
slug: /
|
slug: /
|
||||||
---
|
---
|
|
@ -30,7 +30,7 @@ Details can be found in the doxygen comments included in the source files.
|
||||||
|
|
||||||
## Light version (`main_light.c`)
|
## Light version (`main_light.c`)
|
||||||
|
|
||||||
[Source](pathname:///files/pb071/bonuses/03/main_light.c)
|
[Source](pathname:///files/c/bonuses/03/main_light.c)
|
||||||
|
|
||||||
For the light version you have 3 functions to finish:
|
For the light version you have 3 functions to finish:
|
||||||
|
|
||||||
|
@ -40,7 +40,7 @@ For the light version you have 3 functions to finish:
|
||||||
|
|
||||||
## Full fat version (`main.c`)
|
## Full fat version (`main.c`)
|
||||||
|
|
||||||
[Source](pathname:///files/pb071/bonuses/03/main.c)
|
[Source](pathname:///files/c/bonuses/03/main.c)
|
||||||
|
|
||||||
For the full fat version you have 4 functions to implement:
|
For the full fat version you have 4 functions to implement:
|
||||||
|
|
||||||
|
@ -61,6 +61,7 @@ passed a _function pointer_ to the comparator that you use for comparing the
|
||||||
respective elements in the passed in array.
|
respective elements in the passed in array.
|
||||||
|
|
||||||
If we take the parameter from one of the functions from the skeleton:
|
If we take the parameter from one of the functions from the skeleton:
|
||||||
|
|
||||||
```c
|
```c
|
||||||
int (*comp)(const void *, const void *)
|
int (*comp)(const void *, const void *)
|
||||||
```
|
```
|
||||||
|
@ -91,6 +92,7 @@ Ideally create a directory `seminar-bonuses` in the root of your repository with
|
||||||
bonuses in their own subdirectories.
|
bonuses in their own subdirectories.
|
||||||
|
|
||||||
Structure of your repository can look like this:
|
Structure of your repository can look like this:
|
||||||
|
|
||||||
```
|
```
|
||||||
.
|
.
|
||||||
├── bonuses
|
├── bonuses
|
|
@ -22,7 +22,7 @@ or just by submitting an issue [here](https://gitlab.fi.muni.cz/xfocko/kb/-/issu
|
||||||
|
|
||||||
For this bonus you can get 3 K₡ and another 0.5 K₡ for the bonus part of it.
|
For this bonus you can get 3 K₡ and another 0.5 K₡ for the bonus part of it.
|
||||||
|
|
||||||
[Source](pathname:///files/pb071/bonuses/04.tar.gz)
|
[Source](pathname:///files/c/bonuses/04.tar.gz)
|
||||||
|
|
||||||
## Introduction
|
## Introduction
|
||||||
|
|
|
@ -7,7 +7,7 @@ description: |
|
||||||
|
|
||||||
For this bonus you can get at maximum 2.5 K₡.
|
For this bonus you can get at maximum 2.5 K₡.
|
||||||
|
|
||||||
[Source](pathname:///files/pb071/bonuses/05-06.tar.gz)
|
[Source](pathname:///files/c/bonuses/05-06.tar.gz)
|
||||||
|
|
||||||
## Introduction
|
## Introduction
|
||||||
|
|
|
@ -7,7 +7,7 @@ description: |
|
||||||
|
|
||||||
# 8th seminar bonus assignment
|
# 8th seminar bonus assignment
|
||||||
|
|
||||||
[Source](pathname:///files/pb071/bonuses/08.tar.gz)
|
[Source](pathname:///files/c/bonuses/08.tar.gz)
|
||||||
|
|
||||||
## Introduction
|
## Introduction
|
||||||
|
|
||||||
|
@ -118,7 +118,7 @@ nil
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
|
|
||||||
![tree](/files/pb071/bonuses/08/tree.png)
|
![tree](/files/c/bonuses/08/tree.png)
|
||||||
|
|
||||||
</td>
|
</td>
|
||||||
</tr></table>
|
</tr></table>
|
|
@ -5,7 +5,7 @@ description: |
|
||||||
Finding bugs in a hangman.
|
Finding bugs in a hangman.
|
||||||
---
|
---
|
||||||
|
|
||||||
[Source](pathname:///files/pb071/bonuses/10.tar.gz)
|
[Source](pathname:///files/c/bonuses/10.tar.gz)
|
||||||
|
|
||||||
## Introduction
|
## Introduction
|
||||||
|
|
||||||
|
@ -86,7 +86,7 @@ As we have talked about on the seminar, I suggest you to follow
|
||||||
_Test-Driven Development_
|
_Test-Driven Development_
|
||||||
in this case.
|
in this case.
|
||||||
|
|
||||||
![TDD workflow](/files/pb071/bonuses/10/tdd_lifecycle.png)
|
![TDD workflow](/files/c/bonuses/10/tdd_lifecycle.png)
|
||||||
|
|
||||||
In our current scenario we are already in the stage of refactoring and fixing the
|
In our current scenario we are already in the stage of refactoring and fixing the
|
||||||
bugs. Therefore try to follow this succession of steps:
|
bugs. Therefore try to follow this succession of steps:
|
|
@ -11,16 +11,16 @@ last_update:
|
||||||
|
|
||||||
:::caution Exam environment
|
:::caution Exam environment
|
||||||
|
|
||||||
* During the exam you will be provided with a barebone _exam session_ on the
|
- During the exam you will be provided with a barebone _exam session_ on the
|
||||||
_faculty computers_.
|
_faculty computers_.
|
||||||
* In browser you are only allowed to have the following tabs open:
|
- In browser you are only allowed to have the following tabs open:
|
||||||
* [C documentation](https://en.cppreference.com)
|
- [C documentation](https://en.cppreference.com)
|
||||||
* page containing the assignment
|
- page containing the assignment
|
||||||
* You **are not** allowed to use your own source code, e.g. prepared beforehand
|
- You **are not** allowed to use your own source code, e.g. prepared beforehand
|
||||||
or from the seminars.
|
or from the seminars.
|
||||||
* You have **5 minutes** to read through the assignment and ask any follow-up
|
- You have **5 minutes** to read through the assignment and ask any follow-up
|
||||||
questions should be there something unclear.
|
questions should be there something unclear.
|
||||||
* You have **60 minutes** to work on the assignment, afterward your work will be
|
- You have **60 minutes** to work on the assignment, afterward your work will be
|
||||||
discussed with your seminar tutor.
|
discussed with your seminar tutor.
|
||||||
|
|
||||||
:::
|
:::
|
||||||
|
@ -43,9 +43,10 @@ can see only two commands being used:
|
||||||
At the beginning you start in the root of the filesystem (i.e. `/`).
|
At the beginning you start in the root of the filesystem (i.e. `/`).
|
||||||
|
|
||||||
You are **guaranteed** that `‹somewhere›` is:
|
You are **guaranteed** that `‹somewhere›` is:
|
||||||
* `.` that is a current working directory (i.e. does nothing),
|
|
||||||
* `..` that moves you up one level (in case you are in `/`, does nothing), or
|
- `.` that is a current working directory (i.e. does nothing),
|
||||||
* is a valid directory in the current working directory.
|
- `..` that moves you up one level (in case you are in `/`, does nothing), or
|
||||||
|
- is a valid directory in the current working directory.
|
||||||
|
|
||||||
:::caution
|
:::caution
|
||||||
|
|
||||||
|
@ -87,6 +88,7 @@ $ ls
|
||||||
```
|
```
|
||||||
|
|
||||||
For this input, you will get following file system:
|
For this input, you will get following file system:
|
||||||
|
|
||||||
```
|
```
|
||||||
- / (dir, size=48381165)
|
- / (dir, size=48381165)
|
||||||
- a (dir, size=94853)
|
- a (dir, size=94853)
|
||||||
|
@ -108,14 +110,14 @@ For this input, you will get following file system:
|
||||||
|
|
||||||
Your program should support 2 switches:
|
Your program should support 2 switches:
|
||||||
|
|
||||||
* `-gt ‹min_size›` that will print out suspiciously big files.
|
- `-gt ‹min_size›` that will print out suspiciously big files.
|
||||||
* `-f ‹total_size› ‹min_unused›` that will print out a file to be deleted.
|
- `-f ‹total_size› ‹min_unused›` that will print out a file to be deleted.
|
||||||
|
|
||||||
### `-gt ‹min_size›`
|
### `-gt ‹min_size›`
|
||||||
|
|
||||||
With this switch you are provided one additional argument:
|
With this switch you are provided one additional argument:
|
||||||
|
|
||||||
* `min_size` that is the lower bound (inclusive) for size of any file or
|
- `min_size` that is the lower bound (inclusive) for size of any file or
|
||||||
directory that is supposed to be listed.
|
directory that is supposed to be listed.
|
||||||
|
|
||||||
When your program is being run with this switch, it is is supposed to print out
|
When your program is being run with this switch, it is is supposed to print out
|
||||||
|
@ -125,13 +127,14 @@ all files **and** directories that are bigger than the provided `min_size`.
|
||||||
|
|
||||||
With this switch you are provided two additional arguments:
|
With this switch you are provided two additional arguments:
|
||||||
|
|
||||||
* `total_size` that is a total size of the filesystem[^2].
|
- `total_size` that is a total size of the filesystem[^2].
|
||||||
* `min_unused` that is a minimum of free space required for an upgrade.
|
- `min_unused` that is a minimum of free space required for an upgrade.
|
||||||
|
|
||||||
Your program should find **exactly one** file or a directory that is of the
|
Your program should find **exactly one** file or a directory that is of the
|
||||||
smallest size, but big enough to free enough space for the upgrade to proceed.
|
smallest size, but big enough to free enough space for the upgrade to proceed.
|
||||||
|
|
||||||
In other words, if that file or directory is deleted, following should hold:
|
In other words, if that file or directory is deleted, following should hold:
|
||||||
|
|
||||||
$$
|
$$
|
||||||
\mathtt{total\_size} - \mathtt{used} \geq \mathtt{min\_unused}
|
\mathtt{total\_size} - \mathtt{used} \geq \mathtt{min\_unused}
|
||||||
$$
|
$$
|
||||||
|
@ -151,19 +154,19 @@ program from the shell like
|
||||||
|
|
||||||
## Requirements and notes
|
## Requirements and notes
|
||||||
|
|
||||||
* Define **structures** (and **enumerations**, if applicable) for the parsed
|
- Define **structures** (and **enumerations**, if applicable) for the parsed
|
||||||
information from the files.
|
information from the files.
|
||||||
* For keeping the “records”, use some **dynamic** data structure.
|
- For keeping the “records”, use some **dynamic** data structure.
|
||||||
* Don't forget to consider pros and cons of using _specific_ data structures
|
- Don't forget to consider pros and cons of using _specific_ data structures
|
||||||
before going through implementing.
|
before going through implementing.
|
||||||
* You **are not required** to produce 1:1 output to the provided examples, they
|
- You **are not required** to produce 1:1 output to the provided examples, they
|
||||||
are just a hint to not waste your time tinkering with a user experience.
|
are just a hint to not waste your time tinkering with a user experience.
|
||||||
* If any of the operations on the input files should fail,
|
- If any of the operations on the input files should fail,
|
||||||
**you are expected to** handle the situation _accordingly_.
|
**you are expected to** handle the situation _accordingly_.
|
||||||
* Failures of any other common functions (e.g. functions used for memory
|
- Failures of any other common functions (e.g. functions used for memory
|
||||||
management) should be handled in **the same way** as they were in the
|
management) should be handled in **the same way** as they were in the
|
||||||
homeworks and seminars.
|
homeworks and seminars.
|
||||||
* Your program **must free** all the resources before exiting.
|
- Your program **must free** all the resources before exiting.
|
||||||
|
|
||||||
[^1]: Also applies to Fedora, but… we use arch btw :wink:
|
[^1]: Also applies to Fedora, but… we use arch btw :wink:
|
||||||
[^2]: duh!
|
[^2]: duh!
|
|
@ -11,16 +11,16 @@ last_update:
|
||||||
|
|
||||||
:::caution Exam environment
|
:::caution Exam environment
|
||||||
|
|
||||||
* During the exam you will be provided with a barebone _exam session_ on the
|
- During the exam you will be provided with a barebone _exam session_ on the
|
||||||
_faculty computers_.
|
_faculty computers_.
|
||||||
* In browser you are only allowed to have the following tabs open:
|
- In browser you are only allowed to have the following tabs open:
|
||||||
* [C documentation](https://en.cppreference.com)
|
- [C documentation](https://en.cppreference.com)
|
||||||
* page containing the assignment
|
- page containing the assignment
|
||||||
* You **are not** allowed to use your own source code, e.g. prepared beforehand
|
- You **are not** allowed to use your own source code, e.g. prepared beforehand
|
||||||
or from the seminars.
|
or from the seminars.
|
||||||
* You have **5 minutes** to read through the assignment and ask any follow-up
|
- You have **5 minutes** to read through the assignment and ask any follow-up
|
||||||
questions should be there something unclear.
|
questions should be there something unclear.
|
||||||
* You have **60 minutes** to work on the assignment, afterward your work will be
|
- You have **60 minutes** to work on the assignment, afterward your work will be
|
||||||
discussed with your seminar tutor.
|
discussed with your seminar tutor.
|
||||||
|
|
||||||
:::
|
:::
|
||||||
|
@ -31,11 +31,11 @@ print out summary based on the input data. Your contributions to the society are
|
||||||
very much appreciated and may (or may not) be used for (each or none) of the
|
very much appreciated and may (or may not) be used for (each or none) of the
|
||||||
following purposes[^1]:
|
following purposes[^1]:
|
||||||
|
|
||||||
* stalking people leaving and coming back home,
|
- stalking people leaving and coming back home,
|
||||||
* retroactively making people pay for the parking,
|
- retroactively making people pay for the parking,
|
||||||
* providing evidence of people speeding on highways,
|
- providing evidence of people speeding on highways,
|
||||||
* tracking people that don't pay tolls, or
|
- tracking people that don't pay tolls, or
|
||||||
* convict employees leaving the work prematurely.
|
- convict employees leaving the work prematurely.
|
||||||
|
|
||||||
## Format of the input file
|
## Format of the input file
|
||||||
|
|
||||||
|
@ -45,10 +45,10 @@ specify `-` (i.e. `stdin`) as the path.
|
||||||
|
|
||||||
Each “scan” (i.e. reading) of the cameras consists of the following data:
|
Each “scan” (i.e. reading) of the cameras consists of the following data:
|
||||||
|
|
||||||
* _camera ID_: non-negative integer identifying a camera
|
- _camera ID_: non-negative integer identifying a camera
|
||||||
* _plate_: string of unknown length that can consist of any characters apart
|
- _plate_: string of unknown length that can consist of any characters apart
|
||||||
from whitespace
|
from whitespace
|
||||||
* _timestamp_: date and time of the scan as an unsigned integer (represented as
|
- _timestamp_: date and time of the scan as an unsigned integer (represented as
|
||||||
a UNIX time)
|
a UNIX time)
|
||||||
|
|
||||||
:::tip
|
:::tip
|
||||||
|
@ -114,7 +114,6 @@ when outputting the date and time.
|
||||||
|
|
||||||
:::
|
:::
|
||||||
|
|
||||||
|
|
||||||
:::tip
|
:::tip
|
||||||
|
|
||||||
For a better readability you can include one more newline after the last line
|
For a better readability you can include one more newline after the last line
|
||||||
|
@ -161,18 +160,18 @@ And it will produce an output:
|
||||||
|
|
||||||
## Requirements and notes
|
## Requirements and notes
|
||||||
|
|
||||||
* Define **structures** (and **enumerations**, if applicable) for the parsed
|
- Define **structures** (and **enumerations**, if applicable) for the parsed
|
||||||
information from the files.
|
information from the files.
|
||||||
* For keeping the “records”, use some **dynamic** data structure.
|
- For keeping the “records”, use some **dynamic** data structure.
|
||||||
* Don't forget to consider pros and cons of using _specific_ data structures
|
- Don't forget to consider pros and cons of using _specific_ data structures
|
||||||
before going through implementing.
|
before going through implementing.
|
||||||
* You **are not required** to produce 1:1 output to the provided examples, they
|
- You **are not required** to produce 1:1 output to the provided examples, they
|
||||||
are just a hint to not waste your time tinkering with a user experience.
|
are just a hint to not waste your time tinkering with a user experience.
|
||||||
* If any of the operations on the input files should fail,
|
- If any of the operations on the input files should fail,
|
||||||
**you are expected to** handle the situation _accordingly_.
|
**you are expected to** handle the situation _accordingly_.
|
||||||
* Failures of any other common functions (e.g. functions used for memory
|
- Failures of any other common functions (e.g. functions used for memory
|
||||||
management) should be handled in **the same way** as they were in the
|
management) should be handled in **the same way** as they were in the
|
||||||
homeworks and seminars.
|
homeworks and seminars.
|
||||||
* Your program **must free** all the resources before exiting.
|
- Your program **must free** all the resources before exiting.
|
||||||
|
|
||||||
[^1]: Subject to NDA.
|
[^1]: Subject to NDA.
|
|
@ -1,5 +1,5 @@
|
||||||
---
|
---
|
||||||
id: pb071-intro
|
id: cpp-intro
|
||||||
title: Introduction
|
title: Introduction
|
||||||
slug: /
|
slug: /
|
||||||
---
|
---
|
|
@ -106,7 +106,7 @@ contained.
|
||||||
|
|
||||||
Since frag creates a lot of support files (majority of them are dotfiles, i.e.
|
Since frag creates a lot of support files (majority of them are dotfiles, i.e.
|
||||||
hidden files), I recommend you to use following
|
hidden files), I recommend you to use following
|
||||||
[gitignore](pathname:///files/pb161/environment/gitignore) configuration that
|
[gitignore](pathname:///files/cpp/environment/gitignore) configuration that
|
||||||
should cover most of the scenarios.
|
should cover most of the scenarios.
|
||||||
|
|
||||||
### pre-commit ([link](https://pre-commit.com/))
|
### pre-commit ([link](https://pre-commit.com/))
|
|
@ -1,17 +1,18 @@
|
||||||
// @ts-check
|
// @ts-check
|
||||||
// Note: type annotations allow type checking and IDEs autocompletion
|
// Note: type annotations allow type checking and IDEs autocompletion
|
||||||
|
|
||||||
const lightCodeTheme = require("prism-react-renderer/themes/vsLight");
|
const { themes } = require("prism-react-renderer");
|
||||||
const darkCodeTheme = require("prism-react-renderer/themes/dracula");
|
const lightCodeTheme = themes.vsLight;
|
||||||
|
const darkCodeTheme = themes.dracula;
|
||||||
|
|
||||||
const math = require("remark-math");
|
const math = require("remark-math");
|
||||||
const katex = require("rehype-katex");
|
const katex = require("rehype-katex");
|
||||||
|
|
||||||
require("dotenv").config();
|
require("dotenv").config();
|
||||||
|
|
||||||
class Subject {
|
class Docs {
|
||||||
constructor(subject, description) {
|
constructor(path, description) {
|
||||||
this.subject = subject;
|
this.path = path;
|
||||||
this.description = description;
|
this.description = description;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -19,9 +20,9 @@ class Subject {
|
||||||
return [
|
return [
|
||||||
"@docusaurus/plugin-content-docs",
|
"@docusaurus/plugin-content-docs",
|
||||||
{
|
{
|
||||||
id: this.subject,
|
id: this.path,
|
||||||
path: this.subject,
|
path: this.path,
|
||||||
routeBasePath: this.subject,
|
routeBasePath: this.path,
|
||||||
sidebarPath: require.resolve("./sidebars.js"),
|
sidebarPath: require.resolve("./sidebars.js"),
|
||||||
showLastUpdateTime: true,
|
showLastUpdateTime: true,
|
||||||
editUrl: "https://github.com/mfocko/blog/tree/main",
|
editUrl: "https://github.com/mfocko/blog/tree/main",
|
||||||
|
@ -34,27 +35,36 @@ class Subject {
|
||||||
navbar() {
|
navbar() {
|
||||||
return {
|
return {
|
||||||
type: "doc",
|
type: "doc",
|
||||||
docId: `${this.subject}-intro`,
|
docId: `${this.path}-intro`,
|
||||||
docsPluginId: this.subject,
|
docsPluginId: this.path,
|
||||||
label: `${this.subject.toUpperCase()}: ${this.description}`,
|
label: `${this.description}`,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
footer() {
|
footer() {
|
||||||
return {
|
return {
|
||||||
label: `${this.subject.toUpperCase()}: ${this.description}`,
|
label: `${this.description}`,
|
||||||
to: this.subject,
|
to: this.path,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const subjects = [
|
const subjects = [
|
||||||
new Subject("ib002", "Algorithms"),
|
new Docs("algorithms", "Algorithms"),
|
||||||
// new Subject("ib015", "Non-imperative programming"),
|
// new Docs("functional", "Non-imperative programming"),
|
||||||
// new Subject("ib110", "Introduction to informatics"),
|
// new Docs("automata", "Formal languages and automata"),
|
||||||
// new Subject("ib111", "Foundations of programming"),
|
// new Docs("foundations", "Foundations of programming"),
|
||||||
new Subject("pb071", "C"),
|
new Docs("c", "C"),
|
||||||
new Subject("pb161", "C++"),
|
new Docs("cpp", "C++"),
|
||||||
|
];
|
||||||
|
|
||||||
|
const fallbackMapping = [
|
||||||
|
{ new: "algorithms", old: ["ib002"] },
|
||||||
|
{ new: "functional", old: ["ib015"] },
|
||||||
|
{ new: "automata", old: ["ib110"] },
|
||||||
|
{ new: "foundations", old: ["ib111"] },
|
||||||
|
{ new: "c", old: ["pb071"] },
|
||||||
|
{ new: "cpp", old: ["pb161"] },
|
||||||
];
|
];
|
||||||
|
|
||||||
/** @type {import('@docusaurus/types').Config} */
|
/** @type {import('@docusaurus/types').Config} */
|
||||||
|
@ -114,6 +124,22 @@ const config = {
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
"docusaurus-plugin-sass",
|
"docusaurus-plugin-sass",
|
||||||
|
[
|
||||||
|
"@docusaurus/plugin-client-redirects",
|
||||||
|
{
|
||||||
|
createRedirects(existingPath) {
|
||||||
|
for (let mapping of fallbackMapping) {
|
||||||
|
if (existingPath.includes(`/${mapping.new}/`)) {
|
||||||
|
return mapping.old.map((old) =>
|
||||||
|
existingPath.replace(`/${mapping.new}/`, `/${old}/`)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return undefined; // no redirect created
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
],
|
],
|
||||||
|
|
||||||
stylesheets: [
|
stylesheets: [
|
||||||
|
@ -226,6 +252,7 @@ const config = {
|
||||||
"java",
|
"java",
|
||||||
"nix",
|
"nix",
|
||||||
"pascal",
|
"pascal",
|
||||||
|
"python",
|
||||||
"ruby",
|
"ruby",
|
||||||
"rust",
|
"rust",
|
||||||
],
|
],
|
||||||
|
|
5
foundations/00-intro.md
Normal file
5
foundations/00-intro.md
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
---
|
||||||
|
id: foundations-intro
|
||||||
|
title: Introduction
|
||||||
|
slug: /
|
||||||
|
---
|
|
@ -1,5 +1,5 @@
|
||||||
---
|
---
|
||||||
id: ib110-intro
|
id: functional-intro
|
||||||
title: Introduction
|
title: Introduction
|
||||||
slug: /
|
slug: /
|
||||||
---
|
---
|
21
package.json
21
package.json
|
@ -14,24 +14,25 @@
|
||||||
"write-heading-ids": "docusaurus write-heading-ids"
|
"write-heading-ids": "docusaurus write-heading-ids"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@docusaurus/core": "^2.4.1",
|
"@docusaurus/core": "^3.0.0",
|
||||||
"@docusaurus/preset-classic": "^2.4.1",
|
"@docusaurus/plugin-client-redirects": "^3.0.0",
|
||||||
"@docusaurus/theme-mermaid": "^2.4.1",
|
"@docusaurus/preset-classic": "^3.0.0",
|
||||||
"@mdx-js/react": "^1.6.22",
|
"@docusaurus/theme-mermaid": "^3.0.0",
|
||||||
|
"@mdx-js/react": "^3.0.0",
|
||||||
"clsx": "^1.2.1",
|
"clsx": "^1.2.1",
|
||||||
"docusaurus-plugin-sass": "^0.2.4",
|
"docusaurus-plugin-sass": "^0.2.4",
|
||||||
"dotenv": "^16.0.3",
|
"dotenv": "^16.0.3",
|
||||||
"hast-util-is-element": "^1.1.0",
|
"hast-util-is-element": "^1.1.0",
|
||||||
"prism": "^4.1.2",
|
"prism": "^4.1.2",
|
||||||
"prism-react-renderer": "^1.3.5",
|
"prism-react-renderer": "^2.1.0",
|
||||||
"react": "^17.0.2",
|
"react": "^18.2.0",
|
||||||
"react-dom": "^17.0.2",
|
"react-dom": "^18.2.0",
|
||||||
"rehype-katex": "^5.0.0",
|
"rehype-katex": "7",
|
||||||
"remark-math": "^3.0.1",
|
"remark-math": "6",
|
||||||
"sass": "^1.63.6"
|
"sass": "^1.63.6"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@docusaurus/module-type-aliases": "^2.4.1"
|
"@docusaurus/module-type-aliases": "^3.0.0"
|
||||||
},
|
},
|
||||||
"browserslist": {
|
"browserslist": {
|
||||||
"production": [
|
"production": [
|
||||||
|
|
|
@ -1,5 +0,0 @@
|
||||||
---
|
|
||||||
id: pb161-intro
|
|
||||||
title: Introduction
|
|
||||||
slug: /
|
|
||||||
---
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue