mirror of
https://github.com/mfocko/blog.git
synced 2024-11-09 15:59:06 +01:00
feat: don't reference FI MU subjects by their codes
Signed-off-by: Matej Focko <mfocko@redhat.com>
This commit is contained in:
parent
f81d3219e6
commit
e1dea0cdbc
232 changed files with 225 additions and 191 deletions
|
@ -1,5 +1,5 @@
|
|||
---
|
||||
id: ib002-intro
|
||||
id: algorithms-intro
|
||||
title: Introduction
|
||||
slug: /
|
||||
---
|
|
@ -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
|
||||
|
|
@ -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).
|
||||
|
|
@ -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).
|
|
@ -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
|
|
@ -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
|
||||
---
|
|
@ -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
|
|
@ -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.
|
|
@ -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.
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
---
|
||||
id: ib015-intro
|
||||
id: automata-intro
|
||||
title: Introduction
|
||||
slug: /
|
||||
---
|
|
@ -1,5 +1,5 @@
|
|||
---
|
||||
id: ib111-intro
|
||||
id: c-intro
|
||||
title: Introduction
|
||||
slug: /
|
||||
---
|
|
@ -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
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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>
|
|
@ -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:
|
|
@ -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!
|
|
@ -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.
|
|
@ -1,5 +1,5 @@
|
|||
---
|
||||
id: pb071-intro
|
||||
id: cpp-intro
|
||||
title: Introduction
|
||||
slug: /
|
||||
---
|
|
@ -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/))
|
|
@ -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
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
|
||||
slug: /
|
||||
---
|
|
@ -1,5 +0,0 @@
|
|||
---
|
||||
id: pb161-intro
|
||||
title: Introduction
|
||||
slug: /
|
||||
---
|
|
@ -14,4 +14,4 @@ graph {
|
|||
d -- h
|
||||
|
||||
h -- j
|
||||
}
|
||||
}
|
|
@ -15,4 +15,4 @@ graph {
|
|||
d -- h
|
||||
|
||||
h -- j
|
||||
}
|
||||
}
|
|
@ -10,4 +10,4 @@ digraph {
|
|||
b -> h
|
||||
|
||||
i -> d
|
||||
}
|
||||
}
|
|
@ -9,4 +9,4 @@ digraph {
|
|||
e -> j
|
||||
|
||||
i -> d
|
||||
}
|
||||
}
|
|
@ -44,4 +44,4 @@ digraph {
|
|||
"Node(value=6, rank=0)" -> "nil9"
|
||||
"Node(value=9, rank=0)" -> "nil10"
|
||||
"Node(value=9, rank=0)" -> "nil11"
|
||||
}
|
||||
}
|
|
@ -44,4 +44,4 @@ digraph {
|
|||
"Node(value=6, rank=0)" -> "nil9"
|
||||
"Node(value=9, rank=0)" -> "nil10"
|
||||
"Node(value=9, rank=0)" -> "nil11"
|
||||
}
|
||||
}
|
|
@ -31,4 +31,4 @@ digraph {
|
|||
"Node(value=4, rank=0)" -> "nil7"
|
||||
"Node(value=7, rank=0)" -> "nil8"
|
||||
"Node(value=7, rank=0)" -> "nil9"
|
||||
}
|
||||
}
|
|
@ -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
Loading…
Reference in a new issue