feat: don't reference FI MU subjects by their codes

Signed-off-by: Matej Focko <mfocko@redhat.com>
This commit is contained in:
Matej Focko 2023-11-24 16:00:45 +01:00
parent f81d3219e6
commit e1dea0cdbc
Signed by: mfocko
GPG key ID: 7C47D46246790496
232 changed files with 225 additions and 191 deletions

View file

@ -1,5 +1,5 @@
---
id: ib002-intro
id: algorithms-intro
title: Introduction
slug: /
---

View file

@ -4,17 +4,17 @@ title: Vague postconditions and proving correctness of algorithms
description: |
Debugging and testing with precise postconditions.
tags:
- python
- testing
- postconditions
- sorting
- python
- testing
- postconditions
- sorting
last_update:
date: 2021-03-18
---
## 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

View file

@ -4,11 +4,11 @@ title: Time complexity of extend
description: |
How to make inefficient algorithm unknowingly.
tags:
- c
- python
- dynamic array
- time complexity
- recursion
- c
- python
- dynamic array
- time complexity
- recursion
last_update:
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:
![Rendered construction of the list](/files/ib002/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_light.svg#gh-light-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.
@ -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:
- [interface (`dynlist.h`)](pathname:///files/ib002/time-complexity/extend/dynlist.h)
- [implementation (`dynlist.c`)](pathname:///files/ib002/time-complexity/extend/dynlist.c)
- [interface (`dynlist.h`)](pathname:///files/algorithms/time-complexity/extend/dynlist.h)
- [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).

View file

@ -4,15 +4,15 @@ title: Recursion and backtracking with Robot Karel
description: |
A problem with too many restrictions.
tags:
- python
- karel
- recursion
- backtracking
- python
- karel
- recursion
- backtracking
last_update:
date: 2022-11-29
---
- [Sources](pathname:///files/ib002/recursion/karel-1.tar.gz)
- [Sources](pathname:///files/algorithms/recursion/karel-1.tar.gz)
## Introduction
@ -81,7 +81,7 @@ your mind. Ideally:
- Write down a nested list of the problems, e.g.
:::info Example
:::info Example
Problem: I want to find out whether the display on smartphone should rotate.
@ -94,6 +94,7 @@ your mind. Ideally:
- How can I process it?
:::
- Write down list of problems that can happen, e.g.
:::info Example continued
@ -105,6 +106,7 @@ your mind. Ideally:
- What if my formulas are wrong?
:::
- Write down **anything** you consider important to solving the problem, e.g.
:::info Example continued once again
@ -164,4 +166,4 @@ it out by yourself without any influence of “example solution”.
If you want to get any feedback, feel free to mail me your solution (including
all the steps that lead to your final solution, if you wish to get feedback on
those too).
those too).

View file

@ -4,13 +4,13 @@ title: Introduction to dynamic programming
description: |
Solving a problem in different ways.
tags:
- java
- recursion
- exponential
- greedy
- dynamic-programming
- top-down-dp
- bottom-up-dp
- java
- recursion
- exponential
- greedy
- dynamic-programming
- top-down-dp
- bottom-up-dp
last_updated:
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.
Let's have a look at few examples. Consider the following pyramid:
```
3
7 4
@ -34,6 +35,7 @@ Let's have a look at few examples. Consider the following pyramid:
```
This pyramid has following slide down:
```
*3
*7 4
@ -44,6 +46,7 @@ This pyramid has following slide down:
And its value is `23`.
We can also have a look at a _bigger_ example:
```
75
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
4 62 98 27 23 9 70 98 73 93 38 53 60 4 23
```
Slide down in this case is equal to `1074`.
## 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
other differences will lie only in the solutions of the problem. You can see the
`main` here:
```java
public static void main(String[] args) {
System.out.print("Test #1: ");
@ -141,6 +146,7 @@ public static int longestSlideDown(int[][] pyramid) {
```
As you can see, we have 2 overloads:
```java
int longestSlideDown(int[][] pyramid);
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.
Let's start with the first overload:
```java
public static int longestSlideDown(int[][] pyramid) {
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.
What does that mean for us then? We basically get
$$
T(y) =
\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:
$$
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
recursive calls. Let's apply the greedy approach there:
```java
public static int longestSlideDown(int[][] pyramid, int row, int col) {
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 improved the time complexity tremendously. We just go down the pyramid all
the way to the bottom. Therefore we are getting:
$$
\mathcal{O}(rows)
$$
@ -291,6 +302,7 @@ We have managed to convert our exponential solution into a linear one.
### Running the tests
However, if we run the tests, we notice that the second test failed:
```
Test #1: passed
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.
Imagine the following pyramid:
```
1
2 3
@ -310,6 +323,7 @@ Imagine the following pyramid:
```
We start at the top:
1. Current cell: `1`, we can choose from `2` and `3`, `3` looks better, so we
choose it.
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
the pyramid:
1. We calculate and store it (using the partial results stored in cache). This
is done only once.
@ -452,8 +467,9 @@ the pyramid:
:::
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
get $2 \cdot \log_2{n}$.
get $2 \cdot \log_2{n}$.
:::caution
@ -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.
Let's split the time complexity of our solution into two operands:
$$
\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.
We calculate the values only **once**, therefore we can safely agree on:
$$
\begin{align*}
r &= n \cdot \log{n} \\
@ -482,6 +500,7 @@ $$
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
at most 2 parents:
$$
\begin{align*}
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.
If we were to represent this more precisely, we could've gone with:
$$
\begin{align*}
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_
approach is:
$$
\mathcal{O}(r + s) \\
\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.
That's how we obtain:
$$
\mathcal{O}(n)
$$
$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}
$$
@ -553,6 +576,7 @@ number.
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:
$$
\mathcal{O}(rows)
$$
@ -578,6 +602,7 @@ to implement right from the beginning.
:::
Let's see how we can implement it:
```java
public static int longestSlideDown(int[][] pyramid) {
// 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
rows and then for each row, we copy it and adjust the partial results. Doing
this we get:
$$
\mathcal{O}(rows + 2n)
$$
@ -658,6 +684,7 @@ once.
We're allocating an array for the pyramid **again** for our partial results, so
we get:
$$
\mathcal{O}(n)
$$
@ -695,11 +722,11 @@ successor and represents the way we can enhance the existing implementation.
:::info source
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).
:::
[^1]: cause why not, right!?
[^2]: except the bottom row
[^3]: definitely not an RHCP reference :wink:
[^4]: one was not correct, thus the quotes
[^4]: one was not correct, thus the quotes

View file

@ -4,9 +4,9 @@ title: Použití červeno-černých stromů
description: |
Ukázka použití červeno-černých stromů v standardních knižnicích známých jazyků.
tags:
- balanced trees
- red-black trees
- applications
- balanced trees
- red-black trees
- applications
last_update:
date: 2022-04-05
---

View file

@ -4,8 +4,8 @@ title: On the rules of the red-black tree
description: |
Shower thoughts on the rules of the red-black tree.
tags:
- red-black trees
- balanced trees
- red-black trees
- balanced trees
last_update:
date: 2023-06-10
---
@ -18,6 +18,7 @@ each of the red-black tree rules and try to change, break and contemplate about
them.
We expect that you are familiar with the following set of the rules[^1]:
1. Every node is either red or black.
2. The root 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
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/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_light.svg#gh-light-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
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.
Let's look at its parent (node with $\text{key} = 8$). On its left side it has
@ -71,12 +72,12 @@ 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
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.
We can see that if a node has its height 1 lower than its parent, it is a black
node.
The reasoning behind it is rather simple, we count the black nodes all the way
to the leaves, therefore if my parent has a higher black height, it means that
on the path from me to my parent there is a black node, but the only node added
@ -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.
Let's refresh our memory with the algorithm of _insert fixup_:
```
WHILE z.p.color == Red
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
accordingly.
| 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) |
| ![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) |
| ![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) |
| ![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) |
| ![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) |
| ![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) |
| ![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) |
| ![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) |
| ![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) |
| Usual algorithm with black root | Allowing red root |
| :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: |
| ![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/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/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/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/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/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/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/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/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.
@ -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.
We will experiment with the following tree:
![](/files/ib002/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_light.svg#gh-light-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
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
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 → 5 → 7 → 8 → nil` | 4 | 3 | - | 3 |
| `3 → 5 → 7 → 8 → 9 → 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 → 9 → nil` | 4 | 3 | 4 | 3 |
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.
@ -208,7 +210,7 @@ functions:
When we have a look at the algorithms that are used for fixing up the red-black
tree after an insertion or deletion, we will notice that all the algorithms need
is the color of the node.
is the color of the node.
> How come it is the only thing that we need?
> How come such naïve thing can be enough?
@ -232,15 +234,15 @@ import TabItem from '@theme/TabItem';
<Tabs>
<TabItem value="enforcing" label="Enforcing this rule">
![](/files/ib002/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_light.svg#gh-light-mode-only)
![](/files/algorithms/rb-trees/rules/red-node-black-children/correct_dark.svg#gh-dark-mode-only)
</TabItem>
<TabItem value="omitting" label="Omitting this rule">
![](/files/ib002/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_light.svg#gh-light-mode-only)
![](/files/algorithms/rb-trees/rules/red-node-black-children/incorrect_dark.svg#gh-dark-mode-only)
</TabItem>
</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:
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.
@ -279,4 +282,4 @@ complexity for the operations, but having more relaxed rules.
:::
[^1]: CORMEN, Thomas. Introduction to algorithms. Cambridge, Mass: MIT Press, 2009. isbn 9780262033848.
[^2]: red nodes still exist
[^2]: red nodes still exist

View file

@ -4,17 +4,17 @@ title: Iterative algorithms via iterators
description: |
Iterative DFS using iterators.
tags:
- csharp
- graphs
- iterators
- iterative
- csharp
- graphs
- iterators
- iterative
last_update:
date: 2021-05-18
---
## 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.
@ -171,7 +171,6 @@ begin
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 )
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.

View file

@ -4,8 +4,8 @@ title: Distance boundaries from BFS tree on undirected graphs
description: |
Short explanation of distance boundaries deduced from a BFS tree.
tags:
- graphs
- bfs
- graphs
- bfs
last_update:
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:
![](/files/ib002/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_light.svg#gh-light-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:
![](/files/ib002/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_light.svg#gh-light-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:
@ -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!
![](/files/ib002/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_light.svg#gh-light-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.
@ -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/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_light.svg#gh-light-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.

View file

@ -1,5 +1,5 @@
---
id: ib015-intro
id: automata-intro
title: Introduction
slug: /
---

View file

@ -1,5 +1,5 @@
---
id: ib111-intro
id: c-intro
title: Introduction
slug: /
---

View file

@ -30,7 +30,7 @@ Details can be found in the doxygen comments included in the source files.
## 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:
@ -40,7 +40,7 @@ For the light version you have 3 functions to finish:
## 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:
@ -61,6 +61,7 @@ passed a _function pointer_ to the comparator that you use for comparing the
respective elements in the passed in array.
If we take the parameter from one of the functions from the skeleton:
```c
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.
Structure of your repository can look like this:
```
.
├── bonuses

View file

@ -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.
[Source](pathname:///files/pb071/bonuses/04.tar.gz)
[Source](pathname:///files/c/bonuses/04.tar.gz)
## Introduction

View file

@ -7,7 +7,7 @@ description: |
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

View file

@ -7,7 +7,7 @@ description: |
# 8th seminar bonus assignment
[Source](pathname:///files/pb071/bonuses/08.tar.gz)
[Source](pathname:///files/c/bonuses/08.tar.gz)
## Introduction
@ -118,7 +118,7 @@ nil
</td>
<td>
![tree](/files/pb071/bonuses/08/tree.png)
![tree](/files/c/bonuses/08/tree.png)
</td>
</tr></table>

View file

@ -5,7 +5,7 @@ description: |
Finding bugs in a hangman.
---
[Source](pathname:///files/pb071/bonuses/10.tar.gz)
[Source](pathname:///files/c/bonuses/10.tar.gz)
## Introduction
@ -86,7 +86,7 @@ As we have talked about on the seminar, I suggest you to follow
_Test-Driven Development_
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
bugs. Therefore try to follow this succession of steps:

View file

@ -11,16 +11,16 @@ last_update:
:::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_.
* In browser you are only allowed to have the following tabs open:
* [C documentation](https://en.cppreference.com)
* page containing the assignment
* You **are not** allowed to use your own source code, e.g. prepared beforehand
- In browser you are only allowed to have the following tabs open:
- [C documentation](https://en.cppreference.com)
- page containing the assignment
- You **are not** allowed to use your own source code, e.g. prepared beforehand
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.
* 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.
:::
@ -41,11 +41,12 @@ can see only two commands being used:
1. `cd somewhere` that changes the current working directory.
At the beginning you start in the root of the filesystem (i.e. `/`).
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
* is a valid directory in the current working directory.
- `.` that is a current working directory (i.e. does nothing),
- `..` that moves you up one level (in case you are in `/`, does nothing), or
- is a valid directory in the current working directory.
:::caution
@ -87,6 +88,7 @@ $ ls
```
For this input, you will get following file system:
```
- / (dir, size=48381165)
- a (dir, size=94853)
@ -108,14 +110,14 @@ For this input, you will get following file system:
Your program should support 2 switches:
* `-gt min_size` that will print out suspiciously big files.
* `-f total_size min_unused` that will print out a file to be deleted.
- `-gt min_size` that will print out suspiciously big files.
- `-f total_size min_unused` that will print out a file to be deleted.
### `-gt min_size`
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.
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:
* `total_size` that is a total size of the filesystem[^2].
* `min_unused` that is a minimum of free space required for an upgrade.
- `total_size` that is a total size of the filesystem[^2].
- `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
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:
$$
\mathtt{total\_size} - \mathtt{used} \geq \mathtt{min\_unused}
$$
@ -151,19 +154,19 @@ program from the shell like
## 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.
* For keeping the “records”, use some **dynamic** data structure.
* Don't forget to consider pros and cons of using _specific_ data structures
- For keeping the “records”, use some **dynamic** data structure.
- Don't forget to consider pros and cons of using _specific_ data structures
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.
* 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_.
* 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
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:
[^2]: duh!
[^2]: duh!

View file

@ -11,16 +11,16 @@ last_update:
:::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_.
* In browser you are only allowed to have the following tabs open:
* [C documentation](https://en.cppreference.com)
* page containing the assignment
* You **are not** allowed to use your own source code, e.g. prepared beforehand
- In browser you are only allowed to have the following tabs open:
- [C documentation](https://en.cppreference.com)
- page containing the assignment
- You **are not** allowed to use your own source code, e.g. prepared beforehand
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.
* 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.
:::
@ -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
following purposes[^1]:
* stalking people leaving and coming back home,
* retroactively making people pay for the parking,
* providing evidence of people speeding on highways,
* tracking people that don't pay tolls, or
* convict employees leaving the work prematurely.
- stalking people leaving and coming back home,
- retroactively making people pay for the parking,
- providing evidence of people speeding on highways,
- tracking people that don't pay tolls, or
- convict employees leaving the work prematurely.
## 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:
* _camera ID_: non-negative integer identifying a camera
* _plate_: string of unknown length that can consist of any characters apart
- _camera ID_: non-negative integer identifying a camera
- _plate_: string of unknown length that can consist of any characters apart
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)
:::tip
@ -114,7 +114,6 @@ when outputting the date and time.
:::
:::tip
For a better readability you can include one more newline after the last line
@ -133,46 +132,46 @@ And it will produce an output:
*** ABC-12-34 ***
25: Fri Oct 1 10:50:56 2021
10: Sat Oct 1 09:18:32 2022
16: Sat Oct 1 09:23:32 2022
19: Sat Oct 1 23:27:29 2022
*** EL9-987 ***
11: Thu Mar 23 04:15:38 2023
*** Foo-666 ***
2: Thu May 4 05:14:42 2023
*** TryToCatchMe ***
42: Wed Dec 21 07:00:19 2022
42: Wed Dec 21 07:00:19 2022
1234: Wed Dec 21 07:00:19 2022
*** XYZ-98-76 ***
289: Mon Oct 10 17:40:17 2022
*** YouShould-not-pLaCe-4ny-expectations%on^the(input ***
69: Sat Apr 1 02:13:14 2023
*** YourMum ***
42: Thu May 4 05:14:42 2023
## 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.
* For keeping the “records”, use some **dynamic** data structure.
* Don't forget to consider pros and cons of using _specific_ data structures
- For keeping the “records”, use some **dynamic** data structure.
- Don't forget to consider pros and cons of using _specific_ data structures
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.
* 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_.
* 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
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.

View file

@ -1,5 +1,5 @@
---
id: pb071-intro
id: cpp-intro
title: Introduction
slug: /
---

View file

@ -106,7 +106,7 @@ contained.
Since frag creates a lot of support files (majority of them are dotfiles, i.e.
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.
### pre-commit ([link](https://pre-commit.com/))

View file

@ -1,7 +1,7 @@
// @ts-check
// Note: type annotations allow type checking and IDEs autocompletion
const {themes} = require("prism-react-renderer");
const { themes } = require("prism-react-renderer");
const lightCodeTheme = themes.vsLight;
const darkCodeTheme = themes.dracula;
@ -10,9 +10,9 @@ const katex = require("rehype-katex");
require("dotenv").config();
class Subject {
constructor(subject, description) {
this.subject = subject;
class Docs {
constructor(path, description) {
this.path = path;
this.description = description;
}
@ -20,9 +20,9 @@ class Subject {
return [
"@docusaurus/plugin-content-docs",
{
id: this.subject,
path: this.subject,
routeBasePath: this.subject,
id: this.path,
path: this.path,
routeBasePath: this.path,
sidebarPath: require.resolve("./sidebars.js"),
showLastUpdateTime: true,
editUrl: "https://github.com/mfocko/blog/tree/main",
@ -35,27 +35,27 @@ class Subject {
navbar() {
return {
type: "doc",
docId: `${this.subject}-intro`,
docsPluginId: this.subject,
label: `${this.subject.toUpperCase()}: ${this.description}`,
docId: `${this.path}-intro`,
docsPluginId: this.path,
label: `${this.description}`,
};
}
footer() {
return {
label: `${this.subject.toUpperCase()}: ${this.description}`,
to: this.subject,
label: `${this.description}`,
to: this.path,
};
}
}
const subjects = [
new Subject("ib002", "Algorithms"),
// new Subject("ib015", "Non-imperative programming"),
// new Subject("ib110", "Introduction to informatics"),
// new Subject("ib111", "Foundations of programming"),
new Subject("pb071", "C"),
new Subject("pb161", "C++"),
new Docs("algorithms", "Algorithms"),
// new Docs("functional", "Non-imperative programming"),
// new Docs("automata", "Formal languages and automata"),
// new Docs("foundations", "Foundations of programming"),
new Docs("c", "C"),
new Docs("cpp", "C++"),
];
/** @type {import('@docusaurus/types').Config} */

5
foundations/00-intro.md Normal file
View file

@ -0,0 +1,5 @@
---
id: foundations-intro
title: Introduction
slug: /
---

View file

@ -1,5 +1,5 @@
---
id: ib110-intro
id: functional-intro
title: Introduction
slug: /
---

View file

@ -1,5 +0,0 @@
---
id: pb161-intro
title: Introduction
slug: /
---

View file

@ -44,4 +44,4 @@ digraph {
"Node(value=6, rank=0)" -> "nil9"
"Node(value=9, rank=0)" -> "nil10"
"Node(value=9, rank=0)" -> "nil11"
}
}

View file

@ -44,4 +44,4 @@ digraph {
"Node(value=6, rank=0)" -> "nil9"
"Node(value=9, rank=0)" -> "nil10"
"Node(value=9, rank=0)" -> "nil11"
}
}

View file

@ -31,4 +31,4 @@ digraph {
"Node(value=4, rank=0)" -> "nil7"
"Node(value=7, rank=0)" -> "nil8"
"Node(value=7, rank=0)" -> "nil9"
}
}

View file

@ -6,7 +6,7 @@ digraph {
"Node(value=0, rank=0)" [label="0"]; #done
"Node(value=2, rank=0)" [label="2"]; #done
"Node(value=5, rank=1)" [label="5"]; #done
"nil2" [label="", color=none]
"nil3" [label="", color=none]
@ -34,7 +34,7 @@ digraph {
"Node(value=4, rank=0)" -> "nil7"
"Node(value=7, rank=0)" -> "nil8"
"Node(value=7, rank=0)" -> "8" [color="red"]
"8" -> "nil9"
"8" -> "nil10"
}
}

Some files were not shown because too many files have changed in this diff Show more