From 8b13093ebd85ea6a89ed9bf6587b9942bc6ec166 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Sat, 20 Jul 2024 21:53:38 +0000 Subject: [PATCH] deploy: 4d3c19fce026569033387d363287f36024f46af6 --- 404.html | 4 ++-- .../postcondition-ambiguity/index.html | 4 ++-- .../algorithms-and-correctness/index.html | 4 ++-- .../index.html | 4 ++-- algorithms/category/graphs/index.html | 4 ++-- algorithms/category/hash-tables/index.html | 4 ++-- .../category/paths-in-graphs/index.html | 4 ++-- algorithms/category/recursion/index.html | 4 ++-- .../category/red-black-trees/index.html | 4 ++-- algorithms/graphs/bfs-tree/index.html | 4 ++-- .../graphs/iterative-and-iterators/index.html | 4 ++-- algorithms/hash-tables/breaking/index.html | 4 ++-- .../breaking/mitigations/index.html | 4 ++-- .../hash-tables/breaking/python/index.html | 4 ++-- algorithms/index.html | 6 +++--- algorithms/paths/bf-to-astar/astar/index.html | 4 ++-- algorithms/paths/bf-to-astar/bf/index.html | 4 ++-- .../paths/bf-to-astar/dijkstra/index.html | 4 ++-- algorithms/paths/bf-to-astar/index.html | 4 ++-- algorithms/rb-trees/applications/index.html | 4 ++-- algorithms/rb-trees/rules/index.html | 4 ++-- algorithms/recursion/karel/index.html | 4 ++-- .../recursion/karel/solution/index.html | 4 ++-- .../bottom-up-dp/index.html | 4 ++-- .../pyramid-slide-down/greedy/index.html | 4 ++-- .../recursion/pyramid-slide-down/index.html | 4 ++-- .../pyramid-slide-down/naive/index.html | 4 ++-- .../pyramid-slide-down/top-down-dp/index.html | 4 ++-- algorithms/tags/a-star/index.html | 4 ++-- algorithms/tags/applications/index.html | 4 ++-- algorithms/tags/astar/index.html | 4 ++-- algorithms/tags/backtracking/index.html | 4 ++-- algorithms/tags/balanced-trees/index.html | 4 ++-- algorithms/tags/bellman-ford/index.html | 4 ++-- algorithms/tags/bfs/index.html | 4 ++-- algorithms/tags/bottom-up-dp/index.html | 4 ++-- algorithms/tags/brute-force/index.html | 4 ++-- algorithms/tags/c/index.html | 4 ++-- algorithms/tags/cpp/index.html | 4 ++-- algorithms/tags/csharp/index.html | 4 ++-- algorithms/tags/dijkstra/index.html | 4 ++-- algorithms/tags/dynamic-array/index.html | 4 ++-- .../tags/dynamic-programming/index.html | 4 ++-- algorithms/tags/exponential/index.html | 4 ++-- algorithms/tags/graphs/index.html | 4 ++-- algorithms/tags/greedy/index.html | 4 ++-- algorithms/tags/hash-tables/index.html | 4 ++-- algorithms/tags/index.html | 4 ++-- algorithms/tags/iterative/index.html | 4 ++-- algorithms/tags/iterators/index.html | 4 ++-- algorithms/tags/java/index.html | 4 ++-- algorithms/tags/karel/index.html | 4 ++-- algorithms/tags/postconditions/index.html | 4 ++-- algorithms/tags/python/index.html | 4 ++-- algorithms/tags/recursion/index.html | 4 ++-- algorithms/tags/red-black-trees/index.html | 4 ++-- algorithms/tags/solution/index.html | 4 ++-- algorithms/tags/sorting/index.html | 4 ++-- algorithms/tags/testing/index.html | 4 ++-- algorithms/tags/time-complexity/index.html | 4 ++-- algorithms/tags/top-down-dp/index.html | 4 ++-- algorithms/time-complexity/extend/index.html | 4 ++-- ...5ede8.110dac4d.js => 1535ede8.1f24c022.js} | 2 +- assets/js/4200b1a9.28df9f37.js | 1 - assets/js/4200b1a9.e049437f.js | 1 + assets/js/51efb406.0bebd8d7.js | 1 - assets/js/51efb406.13dca2b5.js | 1 + ...c7293.c6b27c6e.js => 595c7293.61144ad0.js} | 2 +- ...2c0bc.9f968677.js => 7052c0bc.e0cffc16.js} | 2 +- ...ef108.5cea6ebe.js => 794ef108.03844d61.js} | 2 +- ...1e0d8.2a9a4a49.js => 84d1e0d8.377dd43e.js} | 2 +- assets/js/a9167e8d.ebc51550.js | 1 + assets/js/a9167e8d.fed08b8c.js | 1 - ...88602.7613202c.js => b1288602.88758f6b.js} | 2 +- ...e838c.f04d4535.js => d05e838c.111e6323.js} | 2 +- .../js/{main.4fda3a57.js => main.b2fc7d7d.js} | 4 ++-- ...CENSE.txt => main.b2fc7d7d.js.LICENSE.txt} | 0 ...n.82b4ba4b.js => runtime~main.fd7c060d.js} | 2 +- blog/2023/08/02/copr/index.html | 4 ++-- blog/2024/01/28/rust-opinion/index.html | 4 ++-- blog/2024/02/07/lts-distros/index.html | 4 ++-- blog/2024/06/19/devconf-2024/index.html | 4 ++-- blog/2024/07/20/raspberry-alma/index.html | 12 ++++++------ blog/aoc-2022/1st-week/index.html | 4 ++-- blog/aoc-2022/2nd-week/index.html | 4 ++-- blog/aoc-2022/3rd-week/index.html | 4 ++-- blog/aoc-2022/4th-week/index.html | 4 ++-- blog/aoc-2022/intro/index.html | 4 ++-- blog/archive/index.html | 4 ++-- blog/atom.xml | 2 +- blog/feed.json | 2 +- blog/index.html | 6 +++--- blog/leetcode/sort-diagonally/index.html | 4 ++-- blog/page/2/index.html | 4 ++-- blog/rss.xml | 2 +- blog/tags/admin/index.html | 4 ++-- blog/tags/advent-of-code-2022/index.html | 4 ++-- blog/tags/advent-of-code/index.html | 4 ++-- blog/tags/almalinux/index.html | 6 +++--- blog/tags/ansible/index.html | 6 +++--- blog/tags/conferences/index.html | 4 ++-- blog/tags/copr/index.html | 4 ++-- blog/tags/cpp/index.html | 4 ++-- blog/tags/cult/index.html | 4 ++-- blog/tags/devconf/index.html | 4 ++-- blog/tags/fedora/index.html | 4 ++-- blog/tags/hype/index.html | 4 ++-- blog/tags/index.html | 4 ++-- blog/tags/iterators/index.html | 4 ++-- blog/tags/leetcode/index.html | 4 ++-- blog/tags/linux-distributions/index.html | 4 ++-- blog/tags/lts/index.html | 4 ++-- blog/tags/memory-safety/index.html | 4 ++-- blog/tags/opensuse/index.html | 6 +++--- blog/tags/paywall/index.html | 4 ++-- blog/tags/raspberry-pi/index.html | 6 +++--- blog/tags/red-hat/index.html | 4 ++-- blog/tags/rust/index.html | 4 ++-- blog/tags/self-hosting/index.html | 6 +++--- blog/tags/support/index.html | 4 ++-- blog/tags/vps/index.html | 4 ++-- blog/tags/🏭/index.html | 4 ++-- c/bonuses/seminar-03/index.html | 4 ++-- c/bonuses/seminar-04/index.html | 4 ++-- c/bonuses/seminar-05-06/index.html | 6 +++--- c/bonuses/seminar-08/index.html | 6 +++--- c/bonuses/seminar-10/index.html | 6 +++--- c/category/bonuses/index.html | 4 ++-- c/category/practice-exams/index.html | 4 ++-- c/index.html | 6 +++--- c/mr/index.html | 6 +++--- c/pexam/cams/index.html | 4 ++-- c/pexam/garbage_collect/index.html | 4 ++-- contributions/index.html | 4 ++-- cpp/category/exceptions-and-raii/index.html | 4 ++-- cpp/environment/index.html | 4 ++-- .../placeholders/index.html | 4 ++-- cpp/index.html | 6 +++--- .../graphs/iterative-and-iterators.tar.bz2 | Bin 1937 -> 1937 bytes .../graphs/iterative-and-iterators.tar.gz | Bin 1937 -> 1938 bytes files/algorithms/paths/bf-to-astar.tar.bz2 | Bin 3168 -> 3165 bytes files/algorithms/paths/bf-to-astar.tar.gz | Bin 2995 -> 2994 bytes files/algorithms/recursion/karel-1.tar.bz2 | Bin 5885 -> 5894 bytes files/algorithms/recursion/karel-1.tar.gz | Bin 6583 -> 6583 bytes .../recursion/pyramid-slide-down.tar.bz2 | Bin 1559 -> 1548 bytes .../recursion/pyramid-slide-down.tar.gz | Bin 1422 -> 1423 bytes .../algorithms/time-complexity/extend.tar.bz2 | Bin 4078 -> 4074 bytes .../algorithms/time-complexity/extend.tar.gz | Bin 3915 -> 3913 bytes files/c/bonuses/03.tar.bz2 | Bin 2643 -> 2640 bytes files/c/bonuses/03.tar.gz | Bin 2338 -> 2337 bytes files/c/bonuses/04.tar.bz2 | Bin 2532 -> 2534 bytes files/c/bonuses/04.tar.gz | Bin 2499 -> 2498 bytes files/c/bonuses/05-06.tar.bz2 | Bin 3643 -> 3647 bytes files/c/bonuses/05-06.tar.gz | Bin 3488 -> 3489 bytes files/c/bonuses/08.tar.bz2 | Bin 75742 -> 75693 bytes files/c/bonuses/08.tar.gz | Bin 106671 -> 106659 bytes files/c/bonuses/10.tar.bz2 | Bin 234820 -> 234822 bytes files/c/bonuses/10.tar.gz | Bin 230100 -> 230103 bytes index.html | 4 ++-- search/index.html | 4 ++-- talks/index.html | 4 ++-- 161 files changed, 277 insertions(+), 277 deletions(-) rename assets/js/{1535ede8.110dac4d.js => 1535ede8.1f24c022.js} (99%) delete mode 100644 assets/js/4200b1a9.28df9f37.js create mode 100644 assets/js/4200b1a9.e049437f.js delete mode 100644 assets/js/51efb406.0bebd8d7.js create mode 100644 assets/js/51efb406.13dca2b5.js rename assets/js/{595c7293.c6b27c6e.js => 595c7293.61144ad0.js} (99%) rename assets/js/{7052c0bc.9f968677.js => 7052c0bc.e0cffc16.js} (95%) rename assets/js/{794ef108.5cea6ebe.js => 794ef108.03844d61.js} (95%) rename assets/js/{84d1e0d8.2a9a4a49.js => 84d1e0d8.377dd43e.js} (97%) create mode 100644 assets/js/a9167e8d.ebc51550.js delete mode 100644 assets/js/a9167e8d.fed08b8c.js rename assets/js/{b1288602.7613202c.js => b1288602.88758f6b.js} (99%) rename assets/js/{d05e838c.f04d4535.js => d05e838c.111e6323.js} (99%) rename assets/js/{main.4fda3a57.js => main.b2fc7d7d.js} (99%) rename assets/js/{main.4fda3a57.js.LICENSE.txt => main.b2fc7d7d.js.LICENSE.txt} (100%) rename assets/js/{runtime~main.82b4ba4b.js => runtime~main.fd7c060d.js} (94%) diff --git a/404.html b/404.html index 946e80d..bcf1b9b 100644 --- a/404.html +++ b/404.html @@ -14,8 +14,8 @@ - - + +
Skip to main content

Page Not Found

We could not find what you were looking for.

Please contact the owner of the site that linked you to the original URL and let them know their link is broken.

diff --git a/algorithms/algorithms-correctness/postcondition-ambiguity/index.html b/algorithms/algorithms-correctness/postcondition-ambiguity/index.html index 8019e1e..35b399c 100644 --- a/algorithms/algorithms-correctness/postcondition-ambiguity/index.html +++ b/algorithms/algorithms-correctness/postcondition-ambiguity/index.html @@ -16,8 +16,8 @@ - - + +
Skip to main content

Vague postconditions and proving correctness of algorithms

Introduction

diff --git a/algorithms/category/algorithms-and-correctness/index.html b/algorithms/category/algorithms-and-correctness/index.html index ee6b969..b336773 100644 --- a/algorithms/category/algorithms-and-correctness/index.html +++ b/algorithms/category/algorithms-and-correctness/index.html @@ -18,8 +18,8 @@ correctness. - - + +

Algorithms and Correctness

Materials related to basic ideas behind algorithms and proofs of their diff --git a/algorithms/category/asymptotic-notation-and-time-complexity/index.html b/algorithms/category/asymptotic-notation-and-time-complexity/index.html index 788def1..d6c2c49 100644 --- a/algorithms/category/asymptotic-notation-and-time-complexity/index.html +++ b/algorithms/category/asymptotic-notation-and-time-complexity/index.html @@ -16,8 +16,8 @@ - - + +

Asymptotic Notation and Time Complexity

Materials related to asymptotic notation and time complexity. diff --git a/algorithms/category/graphs/index.html b/algorithms/category/graphs/index.html index f271632..e7281c5 100644 --- a/algorithms/category/graphs/index.html +++ b/algorithms/category/graphs/index.html @@ -16,8 +16,8 @@ - - + +

Graphs

Materials related to basic graph algorithms and graph problems. diff --git a/algorithms/category/hash-tables/index.html b/algorithms/category/hash-tables/index.html index a8902ac..a178b7e 100644 --- a/algorithms/category/hash-tables/index.html +++ b/algorithms/category/hash-tables/index.html @@ -16,8 +16,8 @@ - - + +

Hash Tables

Materials related to hash tables. diff --git a/algorithms/category/paths-in-graphs/index.html b/algorithms/category/paths-in-graphs/index.html index 7351804..e8c3597 100644 --- a/algorithms/category/paths-in-graphs/index.html +++ b/algorithms/category/paths-in-graphs/index.html @@ -16,8 +16,8 @@ - - + +

Paths in Graphs

Materials related to finding paths in graphs. diff --git a/algorithms/category/recursion/index.html b/algorithms/category/recursion/index.html index 5ece7a0..261de2b 100644 --- a/algorithms/category/recursion/index.html +++ b/algorithms/category/recursion/index.html @@ -16,8 +16,8 @@ - - + +

Recursion

Materials related to recursive algorithms and their time complexity. diff --git a/algorithms/category/red-black-trees/index.html b/algorithms/category/red-black-trees/index.html index 3fe78bf..95ea7f5 100644 --- a/algorithms/category/red-black-trees/index.html +++ b/algorithms/category/red-black-trees/index.html @@ -16,8 +16,8 @@ - - + +

Red-Black Trees

Materials related to red-black trees. diff --git a/algorithms/graphs/bfs-tree/index.html b/algorithms/graphs/bfs-tree/index.html index e76c9e9..4e11fa9 100644 --- a/algorithms/graphs/bfs-tree/index.html +++ b/algorithms/graphs/bfs-tree/index.html @@ -16,8 +16,8 @@ - - + +

Distance boundaries from BFS tree on undirected graphs

Introduction

diff --git a/algorithms/graphs/iterative-and-iterators/index.html b/algorithms/graphs/iterative-and-iterators/index.html index d8cf3dd..734cf54 100644 --- a/algorithms/graphs/iterative-and-iterators/index.html +++ b/algorithms/graphs/iterative-and-iterators/index.html @@ -16,8 +16,8 @@ - - + +

Iterative algorithms via iterators

Introduction

diff --git a/algorithms/hash-tables/breaking/index.html b/algorithms/hash-tables/breaking/index.html index 2734fe2..d44ead6 100644 --- a/algorithms/hash-tables/breaking/index.html +++ b/algorithms/hash-tables/breaking/index.html @@ -16,8 +16,8 @@ - - + +

Breaking hash table

We will try to break a hash table and discuss possible ways how to prevent such diff --git a/algorithms/hash-tables/breaking/mitigations/index.html b/algorithms/hash-tables/breaking/mitigations/index.html index e5a28e9..9fecb5d 100644 --- a/algorithms/hash-tables/breaking/mitigations/index.html +++ b/algorithms/hash-tables/breaking/mitigations/index.html @@ -16,8 +16,8 @@ - - + +

Possible Mitigations

There are multiple ways the issues created above can be mitigated. Still we can diff --git a/algorithms/hash-tables/breaking/python/index.html b/algorithms/hash-tables/breaking/python/index.html index 153d5f6..0bf4e57 100644 --- a/algorithms/hash-tables/breaking/python/index.html +++ b/algorithms/hash-tables/breaking/python/index.html @@ -16,8 +16,8 @@ - - + +

Breaking the Hash Table in Python

diff --git a/algorithms/index.html b/algorithms/index.html index 1e850ef..ecb663f 100644 --- a/algorithms/index.html +++ b/algorithms/index.html @@ -14,8 +14,8 @@ - - + +

Introduction

In this part you can find “random” additional materials I have written over the @@ -23,6 +23,6 @@ course of teaching Algorithms and data structures I.

It is a various mix of stuff that may have been produced as a follow-up on some question asked at the seminar or spontanously.

If you have some ideas for posts, please do not hesitate to submit them as issues -in the linked GitLab.

+in the linked GitLab.

\ No newline at end of file diff --git a/algorithms/paths/bf-to-astar/astar/index.html b/algorithms/paths/bf-to-astar/astar/index.html index 821589e..d5cc169 100644 --- a/algorithms/paths/bf-to-astar/astar/index.html +++ b/algorithms/paths/bf-to-astar/astar/index.html @@ -16,8 +16,8 @@ - - + +

A* algorithm

Intro

diff --git a/algorithms/paths/bf-to-astar/bf/index.html b/algorithms/paths/bf-to-astar/bf/index.html index aed07c7..411538e 100644 --- a/algorithms/paths/bf-to-astar/bf/index.html +++ b/algorithms/paths/bf-to-astar/bf/index.html @@ -18,8 +18,8 @@ something. - - + +

BF

Basic idea

diff --git a/algorithms/paths/bf-to-astar/dijkstra/index.html b/algorithms/paths/bf-to-astar/dijkstra/index.html index 1aa7e17..2d47850 100644 --- a/algorithms/paths/bf-to-astar/dijkstra/index.html +++ b/algorithms/paths/bf-to-astar/dijkstra/index.html @@ -16,8 +16,8 @@ - - + +

Dijkstra's algorithm

Intro

diff --git a/algorithms/paths/bf-to-astar/index.html b/algorithms/paths/bf-to-astar/index.html index dcb2b83..b2a1957 100644 --- a/algorithms/paths/bf-to-astar/index.html +++ b/algorithms/paths/bf-to-astar/index.html @@ -16,8 +16,8 @@ - - + +

From BF to A*

Intro

diff --git a/algorithms/rb-trees/applications/index.html b/algorithms/rb-trees/applications/index.html index 9dd11f3..ca9b588 100644 --- a/algorithms/rb-trees/applications/index.html +++ b/algorithms/rb-trees/applications/index.html @@ -16,8 +16,8 @@ - - + +

Použití červeno-černých stromů

Použití

diff --git a/algorithms/rb-trees/rules/index.html b/algorithms/rb-trees/rules/index.html index 6c12b53..724d6f3 100644 --- a/algorithms/rb-trees/rules/index.html +++ b/algorithms/rb-trees/rules/index.html @@ -16,8 +16,8 @@ - - + +

On the rules of the red-black tree

Introduction

diff --git a/algorithms/recursion/karel/index.html b/algorithms/recursion/karel/index.html index caac626..cbb6e7f 100644 --- a/algorithms/recursion/karel/index.html +++ b/algorithms/recursion/karel/index.html @@ -16,8 +16,8 @@ - - + +

Recursion and backtracking with Robot Karel

    diff --git a/algorithms/recursion/karel/solution/index.html b/algorithms/recursion/karel/solution/index.html index 610ed5c..0410ee5 100644 --- a/algorithms/recursion/karel/solution/index.html +++ b/algorithms/recursion/karel/solution/index.html @@ -16,8 +16,8 @@ - - + +

    Solving the maze problem

    diff --git a/algorithms/recursion/pyramid-slide-down/bottom-up-dp/index.html b/algorithms/recursion/pyramid-slide-down/bottom-up-dp/index.html index df58b80..c0dfdcf 100644 --- a/algorithms/recursion/pyramid-slide-down/bottom-up-dp/index.html +++ b/algorithms/recursion/pyramid-slide-down/bottom-up-dp/index.html @@ -16,8 +16,8 @@ - - + +

    Bottom-up dynamic programming

    diff --git a/algorithms/recursion/pyramid-slide-down/greedy/index.html b/algorithms/recursion/pyramid-slide-down/greedy/index.html index 97b31b8..1c8b5b6 100644 --- a/algorithms/recursion/pyramid-slide-down/greedy/index.html +++ b/algorithms/recursion/pyramid-slide-down/greedy/index.html @@ -16,8 +16,8 @@ - - + +

    Greedy solution

    We will try to optimize it a bit. Let's start with a relatively simple greedy diff --git a/algorithms/recursion/pyramid-slide-down/index.html b/algorithms/recursion/pyramid-slide-down/index.html index 387d01b..5c46d06 100644 --- a/algorithms/recursion/pyramid-slide-down/index.html +++ b/algorithms/recursion/pyramid-slide-down/index.html @@ -16,8 +16,8 @@ - - + +

    Introduction to dynamic programming

    In this series we will try to solve one problem in different ways.

    diff --git a/algorithms/recursion/pyramid-slide-down/naive/index.html b/algorithms/recursion/pyramid-slide-down/naive/index.html index 8498b33..ba797cd 100644 --- a/algorithms/recursion/pyramid-slide-down/naive/index.html +++ b/algorithms/recursion/pyramid-slide-down/naive/index.html @@ -16,8 +16,8 @@ - - + +

    Naïve solution

    Our naïve solution consists of trying out all the possible slides and finding diff --git a/algorithms/recursion/pyramid-slide-down/top-down-dp/index.html b/algorithms/recursion/pyramid-slide-down/top-down-dp/index.html index f4484c2..29fc2f8 100644 --- a/algorithms/recursion/pyramid-slide-down/top-down-dp/index.html +++ b/algorithms/recursion/pyramid-slide-down/top-down-dp/index.html @@ -16,8 +16,8 @@ - - + +

    Top-down dynamic programming

    diff --git a/algorithms/tags/a-star/index.html b/algorithms/tags/a-star/index.html index 4d4ec31..624502b 100644 --- a/algorithms/tags/a-star/index.html +++ b/algorithms/tags/a-star/index.html @@ -14,8 +14,8 @@ - - + +

    One doc tagged with "a star"

    View All Tags

    From BF to A*

    Figuring out shortest-path problem from the BF to the A* algorithm. diff --git a/algorithms/tags/applications/index.html b/algorithms/tags/applications/index.html index f889b01..5dc6b89 100644 --- a/algorithms/tags/applications/index.html +++ b/algorithms/tags/applications/index.html @@ -14,8 +14,8 @@ - - + +

    One doc tagged with "applications"

    View All Tags

    Použití červeno-černých stromů

    Ukázka použití červeno-černých stromů v standardních knižnicích známých jazyků. diff --git a/algorithms/tags/astar/index.html b/algorithms/tags/astar/index.html index 94bc48c..c2bed5e 100644 --- a/algorithms/tags/astar/index.html +++ b/algorithms/tags/astar/index.html @@ -14,8 +14,8 @@ - - + +

    One doc tagged with "astar"

    View All Tags

    A* algorithm

    Moving from Dijkstra's algorithm into the A* algorithm. diff --git a/algorithms/tags/backtracking/index.html b/algorithms/tags/backtracking/index.html index 8f328cd..70a4c9f 100644 --- a/algorithms/tags/backtracking/index.html +++ b/algorithms/tags/backtracking/index.html @@ -14,8 +14,8 @@ - - + +

    2 docs tagged with "backtracking"

    View All Tags

    Recursion and backtracking with Robot Karel

    A problem with too many restrictions. diff --git a/algorithms/tags/balanced-trees/index.html b/algorithms/tags/balanced-trees/index.html index c3fcb29..dd45fc2 100644 --- a/algorithms/tags/balanced-trees/index.html +++ b/algorithms/tags/balanced-trees/index.html @@ -14,8 +14,8 @@ - - + +

    2 docs tagged with "balanced trees"

    View All Tags

    On the rules of the red-black tree

    Shower thoughts on the rules of the red-black tree. diff --git a/algorithms/tags/bellman-ford/index.html b/algorithms/tags/bellman-ford/index.html index 5a2c47a..29b899f 100644 --- a/algorithms/tags/bellman-ford/index.html +++ b/algorithms/tags/bellman-ford/index.html @@ -14,8 +14,8 @@ - - + +

    2 docs tagged with "bellman ford"

    View All Tags

    BF

    Solving the shortest path problem with a naïve approach that turns into diff --git a/algorithms/tags/bfs/index.html b/algorithms/tags/bfs/index.html index 35c550c..286c501 100644 --- a/algorithms/tags/bfs/index.html +++ b/algorithms/tags/bfs/index.html @@ -14,8 +14,8 @@ - - + +

    One doc tagged with "bfs"

    View All Tags

    Distance boundaries from BFS tree on undirected graphs

    Short explanation of distance boundaries deduced from a BFS tree. diff --git a/algorithms/tags/bottom-up-dp/index.html b/algorithms/tags/bottom-up-dp/index.html index ce57cd4..0620384 100644 --- a/algorithms/tags/bottom-up-dp/index.html +++ b/algorithms/tags/bottom-up-dp/index.html @@ -14,8 +14,8 @@ - - + +

    2 docs tagged with "bottom-up-dp"

    View All Tags

    Bottom-up DP solution

    Bottom-up DP solution of the Pyramid Slide Down. diff --git a/algorithms/tags/brute-force/index.html b/algorithms/tags/brute-force/index.html index 2bee52a..766930c 100644 --- a/algorithms/tags/brute-force/index.html +++ b/algorithms/tags/brute-force/index.html @@ -14,8 +14,8 @@ - - + +

    2 docs tagged with "brute force"

    View All Tags

    BF

    Solving the shortest path problem with a naïve approach that turns into diff --git a/algorithms/tags/c/index.html b/algorithms/tags/c/index.html index 4e52041..1f9e35b 100644 --- a/algorithms/tags/c/index.html +++ b/algorithms/tags/c/index.html @@ -14,8 +14,8 @@ - - + +

    One doc tagged with "c"

    View All Tags

    Time complexity of ‹extend›

    How to make inefficient algorithm unknowingly. diff --git a/algorithms/tags/cpp/index.html b/algorithms/tags/cpp/index.html index eddc481..c2214c0 100644 --- a/algorithms/tags/cpp/index.html +++ b/algorithms/tags/cpp/index.html @@ -14,8 +14,8 @@ - - + +

    7 docs tagged with "cpp"

    View All Tags

    A* algorithm

    Moving from Dijkstra's algorithm into the A* algorithm. diff --git a/algorithms/tags/csharp/index.html b/algorithms/tags/csharp/index.html index 62b20aa..8e08fbc 100644 --- a/algorithms/tags/csharp/index.html +++ b/algorithms/tags/csharp/index.html @@ -14,8 +14,8 @@ - - + +

    One doc tagged with "csharp"

    View All Tags

    Iterative algorithms via iterators

    Iterative DFS using iterators. diff --git a/algorithms/tags/dijkstra/index.html b/algorithms/tags/dijkstra/index.html index b8f5575..84993f5 100644 --- a/algorithms/tags/dijkstra/index.html +++ b/algorithms/tags/dijkstra/index.html @@ -14,8 +14,8 @@ - - + +

    2 docs tagged with "dijkstra"

    View All Tags

    Dijkstra's algorithm

    Moving from Bellman-Ford into the Dijsktra's algorithm. diff --git a/algorithms/tags/dynamic-array/index.html b/algorithms/tags/dynamic-array/index.html index 036b620..ed65f5e 100644 --- a/algorithms/tags/dynamic-array/index.html +++ b/algorithms/tags/dynamic-array/index.html @@ -14,8 +14,8 @@ - - + +

    One doc tagged with "dynamic array"

    View All Tags

    Time complexity of ‹extend›

    How to make inefficient algorithm unknowingly. diff --git a/algorithms/tags/dynamic-programming/index.html b/algorithms/tags/dynamic-programming/index.html index a620d02..abca932 100644 --- a/algorithms/tags/dynamic-programming/index.html +++ b/algorithms/tags/dynamic-programming/index.html @@ -14,8 +14,8 @@ - - + +

    7 docs tagged with "dynamic programming"

    View All Tags

    A* algorithm

    Moving from Dijkstra's algorithm into the A* algorithm. diff --git a/algorithms/tags/exponential/index.html b/algorithms/tags/exponential/index.html index 8ac14b5..0dc8ef8 100644 --- a/algorithms/tags/exponential/index.html +++ b/algorithms/tags/exponential/index.html @@ -14,8 +14,8 @@ - - + +

    2 docs tagged with "exponential"

    View All Tags

    Introduction to dynamic programming

    Solving a problem in different ways. diff --git a/algorithms/tags/graphs/index.html b/algorithms/tags/graphs/index.html index d6ce6cc..71d2ef6 100644 --- a/algorithms/tags/graphs/index.html +++ b/algorithms/tags/graphs/index.html @@ -14,8 +14,8 @@ - - + +

    2 docs tagged with "graphs"

    View All Tags

    Distance boundaries from BFS tree on undirected graphs

    Short explanation of distance boundaries deduced from a BFS tree. diff --git a/algorithms/tags/greedy/index.html b/algorithms/tags/greedy/index.html index 63301f1..07dce25 100644 --- a/algorithms/tags/greedy/index.html +++ b/algorithms/tags/greedy/index.html @@ -14,8 +14,8 @@ - - + +

    4 docs tagged with "greedy"

    View All Tags

    Dijkstra's algorithm

    Moving from Bellman-Ford into the Dijsktra's algorithm. diff --git a/algorithms/tags/hash-tables/index.html b/algorithms/tags/hash-tables/index.html index 9e7717b..cd09c2e 100644 --- a/algorithms/tags/hash-tables/index.html +++ b/algorithms/tags/hash-tables/index.html @@ -14,8 +14,8 @@ - - + +

    3 docs tagged with "hash-tables"

    View All Tags

    Breaking hash table

    How to get the linear time complexity in a hash table. diff --git a/algorithms/tags/index.html b/algorithms/tags/index.html index 1c0890c..85efb22 100644 --- a/algorithms/tags/index.html +++ b/algorithms/tags/index.html @@ -14,8 +14,8 @@ - - + +

    diff --git a/algorithms/tags/iterative/index.html b/algorithms/tags/iterative/index.html index cf55124..7175fdb 100644 --- a/algorithms/tags/iterative/index.html +++ b/algorithms/tags/iterative/index.html @@ -14,8 +14,8 @@ - - + +

    One doc tagged with "iterative"

    View All Tags

    Iterative algorithms via iterators

    Iterative DFS using iterators. diff --git a/algorithms/tags/iterators/index.html b/algorithms/tags/iterators/index.html index 0a7b247..8b10275 100644 --- a/algorithms/tags/iterators/index.html +++ b/algorithms/tags/iterators/index.html @@ -14,8 +14,8 @@ - - + +

    One doc tagged with "iterators"

    View All Tags

    Iterative algorithms via iterators

    Iterative DFS using iterators. diff --git a/algorithms/tags/java/index.html b/algorithms/tags/java/index.html index 2e69800..ee556c1 100644 --- a/algorithms/tags/java/index.html +++ b/algorithms/tags/java/index.html @@ -14,8 +14,8 @@ - - + +

    5 docs tagged with "java"

    View All Tags

    Bottom-up DP solution

    Bottom-up DP solution of the Pyramid Slide Down. diff --git a/algorithms/tags/karel/index.html b/algorithms/tags/karel/index.html index bb8e0a9..454272a 100644 --- a/algorithms/tags/karel/index.html +++ b/algorithms/tags/karel/index.html @@ -14,8 +14,8 @@ - - + +

    2 docs tagged with "karel"

    View All Tags

    Recursion and backtracking with Robot Karel

    A problem with too many restrictions. diff --git a/algorithms/tags/postconditions/index.html b/algorithms/tags/postconditions/index.html index e0b74fc..6c19463 100644 --- a/algorithms/tags/postconditions/index.html +++ b/algorithms/tags/postconditions/index.html @@ -14,8 +14,8 @@ - - + +

    One doc tagged with "postconditions"

    View All Tags

    Vague postconditions and proving correctness of algorithms

    Debugging and testing with precise postconditions. diff --git a/algorithms/tags/python/index.html b/algorithms/tags/python/index.html index 4ab1681..2fca708 100644 --- a/algorithms/tags/python/index.html +++ b/algorithms/tags/python/index.html @@ -14,8 +14,8 @@ - - + +

    7 docs tagged with "python"

    View All Tags

    Breaking hash table

    How to get the linear time complexity in a hash table. diff --git a/algorithms/tags/recursion/index.html b/algorithms/tags/recursion/index.html index 3ef9e60..12b3303 100644 --- a/algorithms/tags/recursion/index.html +++ b/algorithms/tags/recursion/index.html @@ -14,8 +14,8 @@ - - + +

    5 docs tagged with "recursion"

    View All Tags

    Introduction to dynamic programming

    Solving a problem in different ways. diff --git a/algorithms/tags/red-black-trees/index.html b/algorithms/tags/red-black-trees/index.html index 02b5e88..9492450 100644 --- a/algorithms/tags/red-black-trees/index.html +++ b/algorithms/tags/red-black-trees/index.html @@ -14,8 +14,8 @@ - - + +

    2 docs tagged with "red-black trees"

    View All Tags

    On the rules of the red-black tree

    Shower thoughts on the rules of the red-black tree. diff --git a/algorithms/tags/solution/index.html b/algorithms/tags/solution/index.html index 68ec95b..849d030 100644 --- a/algorithms/tags/solution/index.html +++ b/algorithms/tags/solution/index.html @@ -14,8 +14,8 @@ - - + +

    One doc tagged with "solution"

    View All Tags

    Solution to the problem

    Solving the problem introduced in the previous post. diff --git a/algorithms/tags/sorting/index.html b/algorithms/tags/sorting/index.html index c39d0e9..252bf5a 100644 --- a/algorithms/tags/sorting/index.html +++ b/algorithms/tags/sorting/index.html @@ -14,8 +14,8 @@ - - + +

    One doc tagged with "sorting"

    View All Tags

    Vague postconditions and proving correctness of algorithms

    Debugging and testing with precise postconditions. diff --git a/algorithms/tags/testing/index.html b/algorithms/tags/testing/index.html index 25e4760..0ae5c38 100644 --- a/algorithms/tags/testing/index.html +++ b/algorithms/tags/testing/index.html @@ -14,8 +14,8 @@ - - + +

    One doc tagged with "testing"

    View All Tags

    Vague postconditions and proving correctness of algorithms

    Debugging and testing with precise postconditions. diff --git a/algorithms/tags/time-complexity/index.html b/algorithms/tags/time-complexity/index.html index ca81208..af78b2e 100644 --- a/algorithms/tags/time-complexity/index.html +++ b/algorithms/tags/time-complexity/index.html @@ -14,8 +14,8 @@ - - + +

    One doc tagged with "time complexity"

    View All Tags

    Time complexity of ‹extend›

    How to make inefficient algorithm unknowingly. diff --git a/algorithms/tags/top-down-dp/index.html b/algorithms/tags/top-down-dp/index.html index d283d88..2b7f7ff 100644 --- a/algorithms/tags/top-down-dp/index.html +++ b/algorithms/tags/top-down-dp/index.html @@ -14,8 +14,8 @@ - - + +

    2 docs tagged with "top-down-dp"

    View All Tags

    Introduction to dynamic programming

    Solving a problem in different ways. diff --git a/algorithms/time-complexity/extend/index.html b/algorithms/time-complexity/extend/index.html index 0f81662..59f3467 100644 --- a/algorithms/time-complexity/extend/index.html +++ b/algorithms/time-complexity/extend/index.html @@ -16,8 +16,8 @@ - - + +

    Time complexity of ‹extend›

    Introduction

    diff --git a/assets/js/1535ede8.110dac4d.js b/assets/js/1535ede8.1f24c022.js similarity index 99% rename from assets/js/1535ede8.110dac4d.js rename to assets/js/1535ede8.1f24c022.js index 15f971f..7ec8de6 100644 --- a/assets/js/1535ede8.110dac4d.js +++ b/assets/js/1535ede8.1f24c022.js @@ -1 +1 @@ -"use strict";(self.webpackChunkfi=self.webpackChunkfi||[]).push([[5376],{44969:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>c,contentTitle:()=>o,default:()=>h,frontMatter:()=>r,metadata:()=>a,toc:()=>l});var s=t(85893),i=t(11151);const r={id:"seminar-10",title:"10th seminar",description:"Finding bugs in a hangman.\n"},o=void 0,a={id:"bonuses/seminar-10",title:"10th seminar",description:"Finding bugs in a hangman.\n",source:"@site/c/bonuses/10.md",sourceDirName:"bonuses",slug:"/bonuses/seminar-10",permalink:"/c/bonuses/seminar-10",draft:!1,unlisted:!1,editUrl:"https://github.com/mfocko/blog/tree/main/c/bonuses/10.md",tags:[],version:"current",lastUpdatedAt:1721511622,formattedLastUpdatedAt:"Jul 20, 2024",frontMatter:{id:"seminar-10",title:"10th seminar",description:"Finding bugs in a hangman.\n"},sidebar:"autogeneratedBar",previous:{title:"8th seminar",permalink:"/c/bonuses/seminar-08"},next:{title:"Practice Exams",permalink:"/c/category/practice-exams"}},c={},l=[{value:"Introduction",id:"introduction",level:2},{value:"Project",id:"project",level:2},{value:"Summary of the gameplay",id:"summary-of-the-gameplay",level:3},{value:"Suggested workflow",id:"suggested-workflow",level:2},{value:"Tasks",id:"tasks",level:2},{value:"Dictionary",id:"dictionary",level:2},{value:"Submitting",id:"submitting",level:2}];function d(e){const n={a:"a",blockquote:"blockquote",code:"code",em:"em",h2:"h2",h3:"h3",hr:"hr",img:"img",li:"li",ol:"ol",p:"p",pre:"pre",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,i.a)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"pathname:///files/c/bonuses/10.tar.gz",children:"Source"})}),"\n",(0,s.jsx)(n.h2,{id:"introduction",children:"Introduction"}),"\n",(0,s.jsx)(n.p,{children:"For this bonus you are given almost finished project - The Hangman Game. Your\ntask is to try the game, in case you find any bugs point them out and cover as\nmuch of the game as possible with tests."}),"\n",(0,s.jsx)(n.p,{children:"For this bonus you can get at maximum 2 K\u20a1."}),"\n",(0,s.jsxs)(n.table,{children:[(0,s.jsx)(n.thead,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.th,{children:"Item"}),(0,s.jsx)(n.th,{children:"Bonus"})]})}),(0,s.jsxs)(n.tbody,{children:[(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"Fixing bugs from failing tests"}),(0,s.jsx)(n.td,{children:"0.25"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"word_guessed"})}),(0,s.jsx)(n.td,{children:"0.50"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"Hidden bug"}),(0,s.jsx)(n.td,{children:"0.50"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"Extending tests, undetectable bugs or evil bug"}),(0,s.jsx)(n.td,{children:"0.37"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"Refactor"}),(0,s.jsx)(n.td,{children:"0.38"})]})]})]}),"\n",(0,s.jsx)(n.h2,{id:"project",children:"Project"}),"\n",(0,s.jsxs)(n.p,{children:["Project consists of 2 source files - ",(0,s.jsx)(n.code,{children:"hangman.c"})," and ",(0,s.jsx)(n.code,{children:"main.c"}),"."]}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"main.c"})," is quite short and concise, there is nothing for you to do."]}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"hangman.c"})," contains implementation of the game. In case you feel lost, consult\nthe documentation in ",(0,s.jsx)(n.code,{children:"hangman.h"})," that represents an interface that can be used\nfor implementing the game."]}),"\n",(0,s.jsxs)(n.p,{children:["Apart from those sources this project is a bit more complicated. ",(0,s.jsx)(n.em,{children:"Game loop"})," is\nrealised via single encapsulated function that complicates the testing. Because\nof that, there are 2 kinds of tests:"]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.em,{children:"Unit tests"})," - that are present in ",(0,s.jsx)(n.code,{children:"test_hangman.c"})," and can be run via:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"$ make check-unit\n"})}),"\n",(0,s.jsx)(n.p,{children:"They cover majorly functions that can be tested easily via testing framework."}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.em,{children:"Functional tests"})," - same as in ",(0,s.jsx)(n.code,{children:"seminar-08"})," and are focused on testing the\nprogram as whole. Basic smoke test is already included in ",(0,s.jsx)(n.code,{children:"usage"})," test case."]}),"\n",(0,s.jsx)(n.p,{children:"They can be run via:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"$ make check-functional\n"})}),"\n",(0,s.jsxs)(n.p,{children:["When testing ",(0,s.jsx)(n.code,{children:"hangman"})," function (the game loop), it is suggested to create\nfunctional tests."]}),"\n",(0,s.jsx)(n.p,{children:"When submitting the files for review, please leave out functional tests that\nwere given as a part of the assignment, so that it is easier to navigate, I\nwill drag the common files myself. :)"}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(n.blockquote,{children:["\n",(0,s.jsx)(n.p,{children:"Whole test suite can be run via:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"$ make check\n"})}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"summary-of-the-gameplay",children:"Summary of the gameplay"}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsx)(n.li,{children:"Secret word gets chosen from the file that's path is given as an argument."}),"\n",(0,s.jsx)(n.li,{children:"You get 8 guesses."}),"\n",(0,s.jsx)(n.li,{children:"Invalid characters don't count."}),"\n",(0,s.jsx)(n.li,{children:"Already guessed characters don't count, even if not included in the secret."}),"\n",(0,s.jsxs)(n.li,{children:["You can guess the whole word at once","\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"If you get it right, you won, game ends."}),"\n",(0,s.jsx)(n.li,{children:"If you don't get it right, you get to see the secret, game ends."}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.li,{children:"In case of end of input, game finishes via force."}),"\n",(0,s.jsx)(n.li,{children:"In case of invalid input, no guesses are subtracted, game carries on."}),"\n",(0,s.jsx)(n.li,{children:"Letters and words are not case sensitive."}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"suggested-workflow",children:"Suggested workflow"}),"\n",(0,s.jsxs)(n.p,{children:["As we have talked about on the seminar, I suggest you to follow\n",(0,s.jsx)(n.em,{children:"Test-Driven Development"}),"\nin this case."]}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.img,{alt:"TDD workflow",src:t(27420).Z+"",width:"2814",height:"1652"})}),"\n",(0,s.jsx)(n.p,{children:"In our current scenario we are already in the stage of refactoring and fixing the\nbugs. Therefore try to follow this succession of steps:"}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsx)(n.li,{children:"Try to reproduce the bug."}),"\n",(0,s.jsx)(n.li,{children:"Create a test that proves the presence of the bug."}),"\n",(0,s.jsx)(n.li,{children:"Fix the bug."}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:["In case you are submitting the bonus via GitLab, it is helpful to commit tests\nbefore commiting the fixes, so that it is apparent that the bug is manifested.\nExample of ",(0,s.jsx)(n.code,{children:"git log"})," (notice that the first line represents latest commit):"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"feat: Implement fizz_buzzer\ntest: Add tests for fizz_buzzer\nfix: Fix NULL-check in print_name\ntest: Add test for NULL in print_name\n"})}),"\n",(0,s.jsx)(n.h2,{id:"tasks",children:"Tasks"}),"\n",(0,s.jsx)(n.p,{children:"As to your tasks, there are multiple things wrong in this project."}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:'There are 2 "bugs" that cannot be detected via tests, i.e. they are not bugs\nthat affect functionality of the game.'}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["There is one evil bug in ",(0,s.jsx)(n.code,{children:"get_word"}),". It is not required to be fixed ;) Assign\nit the lowest priority."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"There are some tests failing. Please try to figure it out, so you have green\ntests for the rest :)"}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["We have gotten a bug report for ",(0,s.jsx)(n.code,{children:"word_guessed"}),", all we got is"]}),"\n",(0,s.jsxs)(n.blockquote,{children:["\n",(0,s.jsxs)(n.p,{children:["doesn't work when there are too many ",(0,s.jsx)(n.code,{children:"a"}),"s"]}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"Please try to replicate the bug and create a tests, so we don't get any\nregression later on."}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"One hidden bug :) Closely non-specified, we cannot reproduce it and we were\ndrunk while playing the game, so we don't remember a thing. :/"}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"Try to cover as much code via the tests as possible. We are not going to look\nat the metrics, but DRY is violated a lot, so as a last task try to remove as\nmuch of the duplicit code as possible."}),"\n",(0,s.jsx)(n.p,{children:"Tests should help you a lot in case there are some regressions."}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.hr,{}),"\n",(0,s.jsxs)(n.p,{children:["In case you wonder why there are always 3 same words in the file with words, it\nis because of the ",(0,s.jsx)(n.code,{children:"get_word"})," bug. It is not a bug that can be easily fixed, so\nit is a not requirement at all and you can still get all points for the bonus ;)"]}),"\n",(0,s.jsx)(n.h2,{id:"dictionary",children:"Dictionary"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"https://en.wikipedia.org/wiki/Functional_testing",children:"Functional tests"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"https://en.wikipedia.org/wiki/Smoke_testing_%28software%29",children:"Smoke test"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"https://en.wikipedia.org/wiki/Don%27t_repeat_yourself",children:"DRY"})}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"submitting",children:"Submitting"}),"\n",(0,s.jsx)(n.p,{children:"In case you have any questions, feel free to reach out to me."}),"\n",(0,s.jsx)(n.hr,{})]})}function h(e={}){const{wrapper:n}={...(0,i.a)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(d,{...e})}):d(e)}},27420:(e,n,t)=>{t.d(n,{Z:()=>s});const s=t.p+"assets/images/tdd_lifecycle-327ad9ee0ed8318ed11e19a28e02b2cc.png"},11151:(e,n,t)=>{t.d(n,{Z:()=>a,a:()=>o});var s=t(67294);const i={},r=s.createContext(i);function o(e){const n=s.useContext(r);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:o(e.components),s.createElement(r.Provider,{value:n},e.children)}}}]); \ No newline at end of file +"use strict";(self.webpackChunkfi=self.webpackChunkfi||[]).push([[5376],{44969:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>c,contentTitle:()=>o,default:()=>h,frontMatter:()=>r,metadata:()=>a,toc:()=>l});var s=t(85893),i=t(11151);const r={id:"seminar-10",title:"10th seminar",description:"Finding bugs in a hangman.\n"},o=void 0,a={id:"bonuses/seminar-10",title:"10th seminar",description:"Finding bugs in a hangman.\n",source:"@site/c/bonuses/10.md",sourceDirName:"bonuses",slug:"/bonuses/seminar-10",permalink:"/c/bonuses/seminar-10",draft:!1,unlisted:!1,editUrl:"https://github.com/mfocko/blog/tree/main/c/bonuses/10.md",tags:[],version:"current",lastUpdatedAt:1721512130,formattedLastUpdatedAt:"Jul 20, 2024",frontMatter:{id:"seminar-10",title:"10th seminar",description:"Finding bugs in a hangman.\n"},sidebar:"autogeneratedBar",previous:{title:"8th seminar",permalink:"/c/bonuses/seminar-08"},next:{title:"Practice Exams",permalink:"/c/category/practice-exams"}},c={},l=[{value:"Introduction",id:"introduction",level:2},{value:"Project",id:"project",level:2},{value:"Summary of the gameplay",id:"summary-of-the-gameplay",level:3},{value:"Suggested workflow",id:"suggested-workflow",level:2},{value:"Tasks",id:"tasks",level:2},{value:"Dictionary",id:"dictionary",level:2},{value:"Submitting",id:"submitting",level:2}];function d(e){const n={a:"a",blockquote:"blockquote",code:"code",em:"em",h2:"h2",h3:"h3",hr:"hr",img:"img",li:"li",ol:"ol",p:"p",pre:"pre",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,i.a)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"pathname:///files/c/bonuses/10.tar.gz",children:"Source"})}),"\n",(0,s.jsx)(n.h2,{id:"introduction",children:"Introduction"}),"\n",(0,s.jsx)(n.p,{children:"For this bonus you are given almost finished project - The Hangman Game. Your\ntask is to try the game, in case you find any bugs point them out and cover as\nmuch of the game as possible with tests."}),"\n",(0,s.jsx)(n.p,{children:"For this bonus you can get at maximum 2 K\u20a1."}),"\n",(0,s.jsxs)(n.table,{children:[(0,s.jsx)(n.thead,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.th,{children:"Item"}),(0,s.jsx)(n.th,{children:"Bonus"})]})}),(0,s.jsxs)(n.tbody,{children:[(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"Fixing bugs from failing tests"}),(0,s.jsx)(n.td,{children:"0.25"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"word_guessed"})}),(0,s.jsx)(n.td,{children:"0.50"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"Hidden bug"}),(0,s.jsx)(n.td,{children:"0.50"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"Extending tests, undetectable bugs or evil bug"}),(0,s.jsx)(n.td,{children:"0.37"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"Refactor"}),(0,s.jsx)(n.td,{children:"0.38"})]})]})]}),"\n",(0,s.jsx)(n.h2,{id:"project",children:"Project"}),"\n",(0,s.jsxs)(n.p,{children:["Project consists of 2 source files - ",(0,s.jsx)(n.code,{children:"hangman.c"})," and ",(0,s.jsx)(n.code,{children:"main.c"}),"."]}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"main.c"})," is quite short and concise, there is nothing for you to do."]}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"hangman.c"})," contains implementation of the game. In case you feel lost, consult\nthe documentation in ",(0,s.jsx)(n.code,{children:"hangman.h"})," that represents an interface that can be used\nfor implementing the game."]}),"\n",(0,s.jsxs)(n.p,{children:["Apart from those sources this project is a bit more complicated. ",(0,s.jsx)(n.em,{children:"Game loop"})," is\nrealised via single encapsulated function that complicates the testing. Because\nof that, there are 2 kinds of tests:"]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.em,{children:"Unit tests"})," - that are present in ",(0,s.jsx)(n.code,{children:"test_hangman.c"})," and can be run via:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"$ make check-unit\n"})}),"\n",(0,s.jsx)(n.p,{children:"They cover majorly functions that can be tested easily via testing framework."}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.em,{children:"Functional tests"})," - same as in ",(0,s.jsx)(n.code,{children:"seminar-08"})," and are focused on testing the\nprogram as whole. Basic smoke test is already included in ",(0,s.jsx)(n.code,{children:"usage"})," test case."]}),"\n",(0,s.jsx)(n.p,{children:"They can be run via:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"$ make check-functional\n"})}),"\n",(0,s.jsxs)(n.p,{children:["When testing ",(0,s.jsx)(n.code,{children:"hangman"})," function (the game loop), it is suggested to create\nfunctional tests."]}),"\n",(0,s.jsx)(n.p,{children:"When submitting the files for review, please leave out functional tests that\nwere given as a part of the assignment, so that it is easier to navigate, I\nwill drag the common files myself. :)"}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(n.blockquote,{children:["\n",(0,s.jsx)(n.p,{children:"Whole test suite can be run via:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"$ make check\n"})}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"summary-of-the-gameplay",children:"Summary of the gameplay"}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsx)(n.li,{children:"Secret word gets chosen from the file that's path is given as an argument."}),"\n",(0,s.jsx)(n.li,{children:"You get 8 guesses."}),"\n",(0,s.jsx)(n.li,{children:"Invalid characters don't count."}),"\n",(0,s.jsx)(n.li,{children:"Already guessed characters don't count, even if not included in the secret."}),"\n",(0,s.jsxs)(n.li,{children:["You can guess the whole word at once","\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"If you get it right, you won, game ends."}),"\n",(0,s.jsx)(n.li,{children:"If you don't get it right, you get to see the secret, game ends."}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.li,{children:"In case of end of input, game finishes via force."}),"\n",(0,s.jsx)(n.li,{children:"In case of invalid input, no guesses are subtracted, game carries on."}),"\n",(0,s.jsx)(n.li,{children:"Letters and words are not case sensitive."}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"suggested-workflow",children:"Suggested workflow"}),"\n",(0,s.jsxs)(n.p,{children:["As we have talked about on the seminar, I suggest you to follow\n",(0,s.jsx)(n.em,{children:"Test-Driven Development"}),"\nin this case."]}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.img,{alt:"TDD workflow",src:t(27420).Z+"",width:"2814",height:"1652"})}),"\n",(0,s.jsx)(n.p,{children:"In our current scenario we are already in the stage of refactoring and fixing the\nbugs. Therefore try to follow this succession of steps:"}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsx)(n.li,{children:"Try to reproduce the bug."}),"\n",(0,s.jsx)(n.li,{children:"Create a test that proves the presence of the bug."}),"\n",(0,s.jsx)(n.li,{children:"Fix the bug."}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:["In case you are submitting the bonus via GitLab, it is helpful to commit tests\nbefore commiting the fixes, so that it is apparent that the bug is manifested.\nExample of ",(0,s.jsx)(n.code,{children:"git log"})," (notice that the first line represents latest commit):"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"feat: Implement fizz_buzzer\ntest: Add tests for fizz_buzzer\nfix: Fix NULL-check in print_name\ntest: Add test for NULL in print_name\n"})}),"\n",(0,s.jsx)(n.h2,{id:"tasks",children:"Tasks"}),"\n",(0,s.jsx)(n.p,{children:"As to your tasks, there are multiple things wrong in this project."}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:'There are 2 "bugs" that cannot be detected via tests, i.e. they are not bugs\nthat affect functionality of the game.'}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["There is one evil bug in ",(0,s.jsx)(n.code,{children:"get_word"}),". It is not required to be fixed ;) Assign\nit the lowest priority."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"There are some tests failing. Please try to figure it out, so you have green\ntests for the rest :)"}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["We have gotten a bug report for ",(0,s.jsx)(n.code,{children:"word_guessed"}),", all we got is"]}),"\n",(0,s.jsxs)(n.blockquote,{children:["\n",(0,s.jsxs)(n.p,{children:["doesn't work when there are too many ",(0,s.jsx)(n.code,{children:"a"}),"s"]}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"Please try to replicate the bug and create a tests, so we don't get any\nregression later on."}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"One hidden bug :) Closely non-specified, we cannot reproduce it and we were\ndrunk while playing the game, so we don't remember a thing. :/"}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"Try to cover as much code via the tests as possible. We are not going to look\nat the metrics, but DRY is violated a lot, so as a last task try to remove as\nmuch of the duplicit code as possible."}),"\n",(0,s.jsx)(n.p,{children:"Tests should help you a lot in case there are some regressions."}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.hr,{}),"\n",(0,s.jsxs)(n.p,{children:["In case you wonder why there are always 3 same words in the file with words, it\nis because of the ",(0,s.jsx)(n.code,{children:"get_word"})," bug. It is not a bug that can be easily fixed, so\nit is a not requirement at all and you can still get all points for the bonus ;)"]}),"\n",(0,s.jsx)(n.h2,{id:"dictionary",children:"Dictionary"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"https://en.wikipedia.org/wiki/Functional_testing",children:"Functional tests"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"https://en.wikipedia.org/wiki/Smoke_testing_%28software%29",children:"Smoke test"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"https://en.wikipedia.org/wiki/Don%27t_repeat_yourself",children:"DRY"})}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"submitting",children:"Submitting"}),"\n",(0,s.jsx)(n.p,{children:"In case you have any questions, feel free to reach out to me."}),"\n",(0,s.jsx)(n.hr,{})]})}function h(e={}){const{wrapper:n}={...(0,i.a)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(d,{...e})}):d(e)}},27420:(e,n,t)=>{t.d(n,{Z:()=>s});const s=t.p+"assets/images/tdd_lifecycle-327ad9ee0ed8318ed11e19a28e02b2cc.png"},11151:(e,n,t)=>{t.d(n,{Z:()=>a,a:()=>o});var s=t(67294);const i={},r=s.createContext(i);function o(e){const n=s.useContext(r);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:o(e.components),s.createElement(r.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/4200b1a9.28df9f37.js b/assets/js/4200b1a9.28df9f37.js deleted file mode 100644 index a277c3d..0000000 --- a/assets/js/4200b1a9.28df9f37.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkfi=self.webpackChunkfi||[]).push([[866],{24612:e=>{e.exports=JSON.parse('{"blogPosts":[{"id":"/2024/07/20/raspberry-alma","metadata":{"permalink":"/blog/2024/07/20/raspberry-alma","editUrl":"https://github.com/mfocko/blog/tree/main/blog/2024-07-20-raspberry-alma.md","source":"@site/blog/2024-07-20-raspberry-alma.md","title":"Raspberry Alma","description":"My experience with running \u201cgaming\u201d desktop on Linux.\\n","date":"2024-07-20T00:00:00.000Z","formattedDate":"July 20, 2024","tags":[{"label":"raspberry-pi","permalink":"/blog/tags/raspberry-pi"},{"label":"opensuse","permalink":"/blog/tags/opensuse"},{"label":"almalinux","permalink":"/blog/tags/almalinux"},{"label":"ansible","permalink":"/blog/tags/ansible"},{"label":"self-hosting","permalink":"/blog/tags/self-hosting"}],"readingTime":5.945,"hasTruncateMarker":true,"authors":[{"name":"Matej Focko","email":"me+blog@mfocko.xyz","title":"a.k.a. useless admin or \u201cSir Tweak-a-Lot\u201d","url":"https://gitlab.com/mfocko","imageURL":"https://github.com/mfocko.png","key":"mf"}],"frontMatter":{"title":"Raspberry Alma","description":"My experience with running \u201cgaming\u201d desktop on Linux.\\n","date":"2024-07-20T00:00:00.000Z","authors":[{"key":"mf","title":"a.k.a. useless admin or \u201cSir Tweak-a-Lot\u201d"}],"tags":["raspberry-pi","opensuse","almalinux","ansible","self-hosting"]},"unlisted":false,"nextItem":{"title":"DevConf.cz 2024","permalink":"/blog/2024/06/19/devconf-2024"}},"content":"Every now and then I get angry at something not working on the Raspberry and so\\nI decide to swap the OSs. Now it\'s time for something new and not expected.\\n\\n\x3c!--truncate--\x3e\\n\\n## Purpose and past\\n\\nAfter I\'ve subscribed a VPS at vpsfree.cz for myself, I got an opportunity to\\ndrop using an old laptop for running a local \u201cserver\u201d. At that point all I\'ve\\nhad was self-hosted Gitea, some aliases on nginx and that was all. Out with the\\nold laptop and let\'s begin experimenting with the Raspberry, right?\\n\\nThe first OS that got on the Raspberry was _archLinux_ (BTW\u2026). I\'ve been using\\nit for a long time and had the best experience with. I haven\'t hit any issues,\\nbut at the same time, you need to keep in mind we\'re running it off the SD card\\nand they are known to get worn out quickly, especially if you write **a lot**\\nwhich\u2026 guess what, is quite common with rolling and bleeding-edge distribution\\n:smile: And the worst part is keeping up with the updates.\\n\\nAnd that\'s how I migrated to openSUSE Leap :) I\'ve been using openSUSE for at\\nleast 4 years during the high school and a bit more before and after\u2026 openSUSE\\nis very user-friendly (YaST is amazing) distribution and honestly just works.\\nHowever the cost lies in Cockpit not being available[^1] and some weird design\\ndecision, e.g., networking stack is very fragile[^2].\\n\\nAnd I\'ve got finished in the recent weeks with some issues during updates, but\\nthose can be, of course, blamed on me, cause I don\'t watch over it as I should\\n:)\\n\\nI should probably sum up the latest state of what was running before I decided\\nto go for a merciless wipe. So here it is:\\n\\n- local Gitea instance, just in case and out of habit\\n- Wireguard connection for easy administration\\n- Certbot & nginx; nginx is probably the biggest piece of work as it also\\n provides reverse proxy for mikrotik router and Ubiquiti AP provided by ISP\\n- CUPS server that has joined the journey once the HP printer was too big of\\n a pain in the :peach: to handle via USB\\n- DDNS service, cause there\'s public, but dynamic IP from ISP\\n\\n## Choosing the next distro\\n\\nI had the switch in mind for some time, but I couldn\'t decide on the\\ndistribution\u2026 In the ideal world, I\'d just slap CentOS Stream on it, **but**\\nthere\'s no Raspberry \u201csupport\u201d for CentOS[^3]. So the other choices were plain\\nDebian and something else from the RHEL-family which could be either Fedora[^4],\\nAlmaLinux or Rocky Linux.\\n\\nI should admit that I\'m not a big Debian fan :smile: Even though _12 bookworm_\\nis relatively on the same terms as anything that tries to match RHEL9, it still\\nfeels weird. That might be caused by the fact that I\'ve switched RPM-based\\ndistributions a long time ago (including screwing around with archLinux and\\n_Jean Tux_[^5]) and never looked back (except for the desktop with NVIDIA GPU\\nthat\'s pain in the :peach: and only Ubuntu runs reasonably\u2026 well).\\n\\nWearing the _red fedora_ also ruled out the Rocky Linux :slightly*smiling_face:\\nas I don\'t endorse nor support their \\\\_way of operation*\\n\\nSo AlmaLinux it is!\\n\\n## Installing AlmaLinux 9\\n\\nI\'m going with AlmaLinux 9.4 on Raspberry Pi 3B. Opened the AlmaLinux\'s wiki and\\nfirst thing I got slapped by is\\n\\n> original Raspberry Pi 3 (without \\"+\\" models) are not supported\\n\\nGREAT! I took the risk, installed it. And it didn\'t boot :grin: It turns out\\nthat the WiFi kernel module caused a kernel panic on the boot. From some people\\non Reddit I found that it caused some issues, **but** worked, so I\'ve just\\ndecided to pop the SD card back in a PC and deny the module from loading. Voil\xe0!\\nIt boots!\\n\\n## Setting up the \u201clocal server\u201d\\n\\n:::caution Public disclaimer\\n\\nI suck as admin\u2026\\n\\n:::\\n\\nBoth the Raspberry and my VPS are maintained in the _caveman-style_ :smile: And\\nthat\'s why I\'ve decided to start with the less painful one (the Raspberry) to\\nwrite the Ansible playbooks for :)\\n\\nI have already managed to migrate my dotfiles and \u201cbootstrap\u201d to be run via\\nAnsible, so I\'ve just proceeded to extend that and also reorganize it a bit,\\ncause the roles grew in size :eyes:\\n\\nAnd I have to admit that I\'ve been mostly successful. Let\'s delve into details!\\n\\n### SELinux\\n\\nYeah\u2026 that\'s something that hasn\'t been running on the openSUSE and I totally\\nforgot that hardening the SSHD config (including port change) requires notifying\\nSELinux about the port change :) Of course I managed to cut myself off :smile:\\n\\n### Certbot\\n\\nCertbot was the service I feared the most, as there is no reasonable way to\\nautomate this. You need to run it manually at least the first time. But in the\\nend, it was quite OK.\\n\\n### Cockpit\\n\\nOne downside of _caveman-style_ administration is the fact that you forget about\\nthe tweaking you do. Reverse proxy breaks Cockpit by default. I was reading\\nthrough the documentation, but haven\'t managed to find the part that mentioned\\nthe specific settings I had to change. When I was about to open the PR with\\nproposed changes, I noticed that it was in a different chapter :man_facepalming:\\n\\n### CUPS\\n\\nCups went rather smoothly\u2026 except for the fact that it doesn\'t work on the one\\nand only Ubuntu desktop and there are no logs with reason why it fails to add\\nthe printer :slightly_smiling_face:\\n\\nAdditionally installing the HP printer via `hp-setup` is very interesting\\nexperience\u2026 I would\'ve never expected the CLI to have a progress bar that opens\\nup at 0% and then just switches into _terms & conditions_\u2026 Yes, that progress\\nbar stayed at 0% even though it was downloading a PPD file **and progressing**.\\n\\n### DDNS\\n\\nI had smallish issue with deciding how to run the DDNS service. I went with\\ndropping my own buggy script and had to choose a DDNS client. Found _inadyn_\\n(that isn\'t built at all for Fedora and family) and _ddclient_. The _ddclient_\\nhad some not very nice feedback, and the version that introduced the Cloudflare\\nsupport I need, was not included, so I dropped that. _inadyn_ is not packaged,\\nso I\'ve set it up as systemd timer spawning a container :)\\n\\n## Summary\\n\\nOverall I\'ve had a very pleasant experience setting up the AlmaLinux on the\\nRaspberry. Even though I took a gamble with the officially unsupported model of\\nRPi, it works. And it also seems to be filling the purpose it has!\\n\\n[^1]:\\n AFAIK there was some issue with dependencies, so it is available on\\n Tumbleweed and also in the latest Leap 15.6\\n\\n[^2]:\\n By default uses _wicked_ and even when running it on desktop via\\n _NetworkManager_ I\'ve hit some inconsistencies with DNS, but\u2026 DNS **is** the\\n Devil, right? :grin:\\n\\n[^3]: And neither RHEL to be fair ;)\\n[^4]:\\n 6-month release cycle goes against the idea to have the least amount of\\n updates as possible\u2026 and on top of that I think that we can safely agree on\\n the fact that Fedora feels like _archLinux with extra steps_\\n\\n[^5]: Gentoo\u2026"},{"id":"/2024/06/19/devconf-2024","metadata":{"permalink":"/blog/2024/06/19/devconf-2024","editUrl":"https://github.com/mfocko/blog/tree/main/blog/2024-06-19-devconf-2024.md","source":"@site/blog/2024-06-19-devconf-2024.md","title":"DevConf.cz 2024","description":"Sharing my experience on DevConf.cz 2024.\\n","date":"2024-06-19T00:00:00.000Z","formattedDate":"June 19, 2024","tags":[{"label":"\ud83c\udfed","permalink":"/blog/tags/\ud83c\udfed"},{"label":"red-hat","permalink":"/blog/tags/red-hat"},{"label":"fedora","permalink":"/blog/tags/fedora"},{"label":"devconf","permalink":"/blog/tags/devconf"},{"label":"conferences","permalink":"/blog/tags/conferences"}],"readingTime":5.36,"hasTruncateMarker":true,"authors":[{"name":"Matej Focko","email":"me+blog@mfocko.xyz","title":"a.k.a. exhausted DevConf attendee","url":"https://gitlab.com/mfocko","imageURL":"https://github.com/mfocko.png","key":"mf"}],"frontMatter":{"title":"DevConf.cz 2024","description":"Sharing my experience on DevConf.cz 2024.\\n","date":"2024-06-19T00:00:00.000Z","authors":[{"key":"mf","title":"a.k.a. exhausted DevConf attendee"}],"tags":["\ud83c\udfed","red-hat","fedora","devconf","conferences"]},"unlisted":false,"prevItem":{"title":"Raspberry Alma","permalink":"/blog/2024/07/20/raspberry-alma"},"nextItem":{"title":"LTS distributions","permalink":"/blog/2024/02/07/lts-distros"}},"content":"I\'d like to share my experience and views on some of the talks that I\'ve\\nattended on the DevConf.cz 2024.\\n\\n\x3c!--truncate--\x3e\\n\\n## Day 1\\n\\nLet\'s start with the first day which was Thursday this year as opposed to the\\nprevious years when the conference started on Friday and finished on Sunday.\\n\\nLet\'s start with the _[keynote]_. The keynote wasn\'t very interesting, at some of\\nthe slides actually felt like advertisement for other talks on the topic of the\\nAI\u2026\\n\\nNext talk about _[event-driven Ansible]_ was way more interesting. It allows you\\nto run Ansible playbooks after provisioning hosts, or on certain events, such as\\ndiscovered vulnerabilities. On one hand it feels like a very nice thing, but on\\nthe other one I can\'t help but to think how you need to write the playbooks, so\\nthat they are generic enough. One more example that\'s been given comes from the\\npossibility to react to tickets, e.g., outages and this feels like something\\nthat could be abused to cause DoS.\\n\\nAfterwards we\'ve seen two lightning talks, one about\\n_[choosing the right OpenShift size]_ which was a pretty quick, but listed all\\nof the possible ways you can deploy OpenShift in detail. This lightning talk\\nwas followed by the first AI (lightning) talk I\'ve attended about\\n_[rapid prototyping]_ of the open-source AI models.\\n\\nAs someone who\'s involved in the automation of the RPM packaging and testing, of\\ncourse, we had to attend _[Learning from Nix]_. Nix has a very intriguing\\nconcept which is pretty powerful, but painful at the same time. This can be\\nsummed up pretty nicely by [Tsoding] who got asked about some tips & tricks for\\nsomeone who wants to try out NixOS:\\n\\n> Just don\'t.\\n\\nAnd now we\'re moving into a section where everything revolves about the Packit\\nTeam :)\\n\\nFirst talk about _[changelogs]_ was an interactive session that was (probably)\\nmeant to share different approaches we take to handle this rather convoluted\\ntopic that involves changelogs on both upstream and also on downstream with no\\nrules[^1].\\n\\n![changelogs](https://i.imgur.com/YHstMAt.jpg)\\n\\nNext one was about _[static analysis]_ done by [OpenScanHub]. I like the idea of\\nrunning the static analysis that can uncover nasty bugs (as it has been even\\nshowed in the talk) at the same time as they are introduced. I gotta admit that\\nafter seeing the UI of the [deployed OpenScanHub] on the Fedora Infra, I couldn\'t\\nhelp but to think about the [United States Graphics Company] :smile: The UI is\\nto the point, no fancy annoying shit, you get what you need, it\'s hard to get\\nlost. **Just simplicity.** Best kind of UI/UX in my opinion.\\n\\nAfter the OpenScanHub talk we\'re getting to talks that were taken in a totally\\ndifferent direction from the usual talks you\'re used to :wink: First one was\\ngiven title of _[\u201cIndiana Jones and obsoleted projects\u201d]_ by [Mirek]. He talked\\nabout projects that got obsoleted, but started with projects that had no\\nrelation to IT field at all. I\'d mark this talk as a _stand up_ without any\\nhesitation.\\n\\nAnd finally we will wrap up the first day with the talk where speakers spoke the\\nleast\u2026 _[\u201cLet the users speak!\u201d]_ that involved users of both Packit and\\nTesting Farm who spoke about their use case and benefits they gained from using\\nboth services in a symbiosis.\\n\\n## Day 2\\n\\nOn the second day I\'ve attended less talks to not burn myself out :) I\'ve\\nstarted with an AI-related talk with title _[\u201cAI: Open source will save us!\u201d]_,\\neven though this talk has been improvised, as the speakers from the schedule\\ncouldn\'t have attended, it provided a nice overview what [InstructLab] can do\\nand how can you \u201cfeed\u201d the relevant info into the language models by yourself.\\n\\nAfter that I attended a _\u201ccoffee enthusiasts Meetup\u201d_ which was very nice and,\\nof course, an organized chaos :wink:\\n\\nBefore attending the social event I wrapped up the second day with a lightning\\ntalk about _[recent updates in Toolbx]_. I\'ve used both [toolbx] and\\n[distrobox], so it\'s nice to see the improvements in progress and also that both\\nprojects are well and lively.\\n\\n## Day 3\\n\\nOn the third day I\'ve attended only in the afternoon. \u201cStarted\u201d my day with\\na discussion _[\u201cLeadership: Where people skills meet programmers\u201d]_ which was\\nvery nice for gaining an insight into how developer, manager and QE lead roles\\noverlap.\\n\\nThat talk has been followed up by a talk about [role rotation] in our Packit\\nTeam. I would say it is a nice \u201cupgrade\u201d to the agile process which allows you\\nto not create a single point of failure in the mundane and repetitive processes\\nwithin your team.\\n\\nAnd this day has been finished off with a talk about [shifting left] in Podman.\\nIt\'s nice to see how other teams utilize our Packit Service and also the\\nservices we rely on, such as [Copr] or [Testing Farm]. With the help of Cockpit\\ntests they can catch breaking changes early on, or even bugs that have been\\nintroduced and break usage of the dependent projects.\\n\\n![shifting left](https://i.imgur.com/bp6FxT9.jpg)\\n\\n## Picks from the Packit Team\\n\\nOn the Tuesday, during our Packit stand up, I have managed to abuse my\\nKanban Lead role to collect some of the talks that each of us would recommend:\\n\\n- [Rapid Prototyping] with Open Source AI Models\\n- Do you like your [changelogs]?\\n- OpenScanHub - [Static Analysis] of a Linux Distribution\\n- Creating a [Language Server] for RPM Spec Files\\n- Containers and Kubernetes Made Easy: A 15-minute dive into [Podman Desktop]\\n- [\u201cLeadership: Where people skills meet programmers\u201d]\\n\\n## Wrap up\\n\\nI have to admit that these 3 days have been pretty exhaustive, including\\ninformation overload :smile: but at the same time it was really nice to meet\\nwith the colleagues and at least some of our users who are not based in Brno.\\n\\n[^1]: except for the Fedora\'s downstream ;)\\n\\n[keynote]: https://pretalx.com/devconf-cz-2024/talk/AD3HWR/\\n[event-driven ansible]: https://pretalx.com/devconf-cz-2024/talk/3UKGLB/\\n[choosing the right openshift size]: https://pretalx.com/devconf-cz-2024/talk/KSDRWL/\\n[rapid prototyping]: https://pretalx.com/devconf-cz-2024/talk/H9QFLM/\\n[learning from nix]: https://pretalx.com/devconf-cz-2024/talk/NNKT3F/\\n[tsoding]: https://twitch.tv/tsoding\\n[changelogs]: https://pretalx.com/devconf-cz-2024/talk/ECU7QS/\\n[static analysis]: https://pretalx.com/devconf-cz-2024/talk/7C38GJ/\\n[openscanhub]: https://openscanhub.dev/\\n[deployed openscanhub]: https://openscanhub.fedoraproject.org/\\n[united states graphics company]: https://x.com/usgraphics\\n[\u201cindiana jones and obsoleted projects\u201d]: https://pretalx.com/devconf-cz-2024/talk/X8SYDG/\\n[mirek]: https://rodina-sucha.cz/@mirek\\n[\u201clet the users speak!\u201d]: https://pretalx.com/devconf-cz-2024/talk/BDMWF3/\\n[\u201cai: open source will save us!\u201d]: https://pretalx.com/devconf-cz-2024/talk/QSF9QQ/\\n[instructlab]: https://github.com/instructlab/instructlab\\n[recent updates in toolbx]: https://pretalx.com/devconf-cz-2024/talk/SXWE7K/\\n[toolbx]: https://containertoolbx.org/\\n[distrobox]: https://distrobox.it/\\n[\u201cleadership: where people skills meet programmers\u201d]: https://pretalx.com/devconf-cz-2024/talk/8PARM8/\\n[role rotation]: https://pretalx.com/devconf-cz-2024/talk/8T88MT/\\n[shifting left]: https://pretalx.com/devconf-cz-2024/talk/WVNJZS/\\n[copr]: https://copr.fedorainfracloud.org/\\n[testing farm]: https://docs.testing-farm.io/Testing%20Farm/0.1/index.html\\n[language server]: https://pretalx.com/devconf-cz-2024/talk/RXKMKA/\\n[podman desktop]: https://pretalx.com/devconf-cz-2024/talk/HKWP7V/"},{"id":"/2024/02/07/lts-distros","metadata":{"permalink":"/blog/2024/02/07/lts-distros","editUrl":"https://github.com/mfocko/blog/tree/main/blog/2024-02-07-lts-distros.md","source":"@site/blog/2024-02-07-lts-distros.md","title":"LTS distributions","description":"Shower thoughts on the LTS Linux distributions.\\n","date":"2024-02-07T00:00:00.000Z","formattedDate":"February 7, 2024","tags":[{"label":"lts","permalink":"/blog/tags/lts"},{"label":"linux distributions","permalink":"/blog/tags/linux-distributions"},{"label":"support","permalink":"/blog/tags/support"},{"label":"paywall","permalink":"/blog/tags/paywall"}],"readingTime":14.515,"hasTruncateMarker":true,"authors":[{"name":"Matej Focko","email":"me+blog@mfocko.xyz","title":"a.k.a. small Fedora maintainer","url":"https://gitlab.com/mfocko","imageURL":"https://github.com/mfocko.png","key":"mf"}],"frontMatter":{"title":"LTS distributions","description":"Shower thoughts on the LTS Linux distributions.\\n","date":"2024-02-07T00:00:00.000Z","authors":[{"key":"mf","title":"a.k.a. small Fedora maintainer"}],"tags":["lts","linux distributions","support","paywall"],"hide_table_of_contents":false},"unlisted":false,"prevItem":{"title":"DevConf.cz 2024","permalink":"/blog/2024/06/19/devconf-2024"},"nextItem":{"title":"Mixed feelings on Rust","permalink":"/blog/2024/01/28/rust-opinion"}},"content":"Linux distributions are a common choice for running the servers. There\'s a wide\\nvariety of distributions, but on the servers majority is made by only a few.\\n\\nSome corporations also profit from the support of the \u201cbig\u201d distributions. Let\'s\\ndive into the pros, cons and peculiarities of such _business_.\\n\\nThis post is inspired/triggered by the following Mastodon post:\\n[![Mastodon post about Ubuntu Pro](https://i.imgur.com/mh5RAlV.png)](https://hackers.town/@antijingoist/111864760073049505)\\n\\n\x3c!--truncate--\x3e\\n\\n:::warning Disclaimer\\n\\nYou may take my opinion with a grain of salt, since I\'m affiliated with Red Hat,\\nbut at the same time I\'ve also seen the other side of the fence, so I know how\\nit works from the perspective of the provider/maintainer.\\n\\n:::\\n\\n:::tip\\n\\nIf you are not very oriented in the matters of Linux distributions and\\nmaintaining of packages, I suggest looking at the [glossary](#glossary) at the\\nend to have a better grasp of the terms that are used throughout the post.\\n\\n:::\\n\\n## Point of linux distributions\\n\\nFirst thing I\'d like to point out is the point of the Linux distributions. What\\nbenefit do they provide? And why there are so many of them\u2026\\n\\nAs it has been brought up many times by the _rms_[^1], Linux by itself is not\\nenough, it\'s just the kernel that does the underlying work. We need more\\nsoftware to utilize the hardware. That\'s the gap that Linux distributions bridge\\nby providing the Linux and much more other software that we need.\\n\\nEach distribution is unique in its own way. Some prefer different ways of\\nhandling the software (like Gentoo that allows you to compile it yourself) and\\nothers stable releases of software (like Debian).\\n\\nIn the end it mostly boils down to the packaging. I, as a user, want to do\\nsomething like\\n\\n```\\n$ sudo dnf5 install firefox\\n```\\n\\nand not bother about anything else. I don\'t want to open browser to look the\\nthing up, download it and then click mindlessly 500\xd7 \u201cNext\u201d. I just want to run\\none command and when the maintainers decide it\'s time to move on, another one to\\nupgrade the software to the newer version.\\n\\nOf course, for some use cases you want to minimize the latter. And even make\\nsure that it\'s safe to do it when you need to. You don\'t want to break your\\nproduction deployment just because someone decided it\'s time to push something\\nout.\\n\\nThat\'s when the _maintainers_ come in. They take upon themselves the\\nresponsibility of maintaining the packages. If you\'ve ever used the Debian, you\\nknow very well how _old_ the software is, but that\'s what you might need for\\nyour servers.\\n\\n## Pain of packaging\\n\\nPackaging software _is not_ cost-free. You may as well have 80 % of packages\\nthat don\'t need much care and it\'s rather easy to push them forward, but those\\nremaining, which are complicated and raise issues regularly, will make it up and\\ntake a lot of time and also pain.\\n\\nLibraries are the most common example that might not need much work to be done.\\nOn the other hand, Linux kernel itself is a rather complicated machinery that\\nis patched **a lot** and its build process is not simple either.\\n\\nEven if you consider just those _easily-maintainble_ packages, the process can\\nbe tedious, boring and overall time consuming.\\n\\n:::tip Shameless RHEL-based ecosystem plug\\n\\n[Packit] can help tremendously with the _easily-maintainable_ packages, since it\\n**can** be automated.\\n\\n:::\\n\\n### Packaging whole ecosystems\\n\\nNow it\'s time to talk about whole ecosystems that have some kind of a packaging\\nby themselves. Yes, I mean Python (with its continuous stream of different\\npackage managers), Rust, Go, etc.\\n\\nWhole point of packaging is to have some form of _gating_. In other words, you\\nwant some kind of _quality control_ when pushing changes into the Linux distros.\\n\\nIf you want to package some tool (or even library) from the aforementioned\\necosystems, you need to package all of the dependencies to make sure something\\ndoesn\'t get updated in the meantime (and also that you can safely reproduce the\\nbuilds, if need be).\\n\\nI\'ve tried to package some utilities for EPEL both in Rust and Go. Dependencies\\nform a DAG[^2] and in case of Rust, it\'s _very_ similar to the way `npm` does\\nits packaging.\\n\\n:::danger Spoiler alert\\n\\nYou get a lot of dependencies. And since it\'s a tree of dependencies, there may\\nbe **a lot** of them.\\n\\n:::\\n\\nI have no clue how do the Rust maintainers operate, but I\'m tipping my fedora in\\ntheir direction, since it must be a _pain in the ass_.\\n\\n## Paid distributions\\n\\nYou can find few Linux distributions that are \u201cpaid\u201d. I\'m very well aware of the\\nfact I\'ve used quotes around the word, cause it\'s not that easy and not even\\nsame for all of the distributions that involve some kind of a payment.\\n\\nOne of the first non-free distributions I\'ve come into contact was _[Zorin OS]_\\nwhich basically tries to be the best _transition_ solution when moving away from\\nthe Windows or macOS. If you have a look at the _perks_ of its _Pro_ version\\nthat\'s paid, you may as well decide they are rather questionable\u2026\\n\\nIt\'s time to move into the _Ubuntu Pro_, _RHEL_ and _SLE_ territory. What\'s the\\npoint of those? They definitely offer different kind of, let\'s say,\\n_non-free experience_.\\n\\nWith those you are paying mainly for the support and bug/security patches.\\n\\n:::tip Fun fact\\n\\nThere\'s no mention of any kind of support on the Zorin page\u2026 Apart from the fact\\nthat _you are supporting_ the Zorin development.\\n\\n:::\\n\\n## Repository structure\\n\\nAs I have mentioned above, the three _services_[^3] I mentioned are providing\\nsupport with regards to bugs and security vulnerabilites. Therefore it makes\\nsense to have some kind of a process in place when you\'re pushing changes\\n(either updates, patches or _security_ patches) to the distribution. And yes,\\nthese processes are _in place_.\\n\\nIf you think about the amount of packages that is present in the community\\ndistributions like _archLinux_ (14,830 packages) or _Fedora_ (74,309 packages),\\nit is safe to come to a conclusion that _there\'s no way_ to support all of them.\\n\\n:::tip archLinux\\n\\nIt may seem that archLinux contains rather small set of packages, but one of the\\n_killer features_ of archLinux lies in the AUR (archLinux User Repository) where\\nyou can find additional **93,283** packages.\\n\\n:::\\n\\nThat\'s why the Linux distributions have some structure to their repositories\\nthat contain packages. The way you go around this is rather simple, you choose\\nsome set of _critical_ packages that you guarantee support for (like Linux\\nkernel, openSSL, etc.) and maintain those with all the QA processes in place.\\n\\n:::warning Unpopular opinion\\n\\nThis is also one of the reasons why I\'m quite against packaging anything and\\neverything into the Linux distribution. In my opinion it is impossible to\\n**properly** maintain **huge** set of packages and enforce some kind of\\n**quality control**.\\n\\n:::\\n\\n### Ubuntu\\n\\nUbuntu has pretty granular structure of their repositories, namely:\\n\\n- `main` containing the \u201ccore\u201d of the Ubuntu that is maintained by the Canonical,\\n- `universe` containing literally the \u201cuniverse\u201d, packages that everyone likes,\\n but they\'re not crucial, this repo is maintained mostly by the community,\\n- `multiverse` containing packages with some license or copyright issues, and\\n- `restricted` containing _proprietary_ packages like nvidia drivers and such.\\n\\nBy briefly checking my Ubuntu 23.10 installation, here are stats of packages in\\ntheir respective repositories:\\n\\n- `main` with 6,128 packages,\\n- `universe` with 63,380 packages,\\n- `multiverse` with 997 packages, and finally\\n- `restricted` with 784 packages.\\n\\nAs you can see, if we sum them up, they are relatively similar to the Fedora\\nnumbers.\\n\\n### CentOS\\n\\nCentOS on the other hand has a bit simpler structure with BaseOS for the base\\nand AppStream for additional packages:\\n\\n- `baseos` with 1,058 packages,\\n- `appstream` with 5,646 packages, and\\n- `extras-common` with 42 packages.\\n\\nOverall they make up the similar number as the Ubuntu\'s `main` repository. And\\nyou can also notice that there are no additional repositories.\\n\\n:::tip\\n\\nThere\'s also a CRB (CodeReady Builder) repository with dev packages like headers\\nand such.\\n\\nAnd you can also enable EPEL (Extra Packages for Enterprise Linux) which is\\ncommunity-supported and provides another 19,903 packages.\\n\\n:::\\n\\n## Ubuntu Pro\\n\\nNow it\'s time to get back to the Ubuntu Pro. There are multiple points that need\\nto be taken in account to be either positive or negative about it\u2026\\n\\nWe can start with the way Ubuntu is released and maintained. Ubuntu has regular\\n6-month release cycle and biannual LTS release. Releases are normally supported\\nfor 9 months with the exception of the LTS releases being supported for 5 years.\\n\\nIf you check out the _[Ubuntu Pro]_ website, you can find the following\\nstatement:\\n\\n> **Ubuntu Pro**\\n>\\n> The most comprehensive subscription for open-source software security\\n>\\n> 30-day trial for enterprises. Always free for personal use.\\n\\n:::tip Personal use\\n\\nUbuntu Pro for _personal use_ consists of 5 installations and in case of the\\ncommunity _ambassadors_ 50.\\n\\n:::\\n\\nOverall if you try to find what is included in the Ubuntu Pro:\\n\\n- high and critical patches,\\n- 10 years of maintenance, and\\n- (optional) 24/7 enterprise-grade support.\\n\\nIf we get back to the screenshot all the way at the beginning of the post:\\n[![Mastodon post about Ubuntu Pro](https://i.imgur.com/mh5RAlV.png)](https://hackers.town/@antijingoist/111864760073049505)\\n\\nand try to look up to which repository the packages mentioned in the screenshot\\nbelong, we will find out that they belong to `universe` repository which is\\nmaintained by the community. Not to mention nature of the packages: multimedia.\\n\\nYou may think about this as a scam, but considering repository consisting of 70k\\npackages, it is not an easy task to do. And with LTS releases we\'re talking\\nabout 5+ years of support.\\n\\n:::info Fedora\\n\\nTry to compare this state to Fedora. It also has a 6-month release cycle, but\\nthere are no LTS releases and each release is supported only for a year.\\n\\n:::\\n\\nCommon strategy, at this point, is to pull out the _open-source_. Yes, we are\\nstill dealing with the open-source, but keep in mind that you\'re trying to patch\\nsome issue in a version that\'s 5 years old, upstream definitely doesn\'t care\\nanymore[^4], the development didn\'t stop 5 years ago, it\'s going on and fixing\\nthis issue in a release from 5 years is not the same as fixing it in the current\\nrelease. At this point, if you are paying for such support, you are actually\\npaying for someone to do _software archaeology_ which **can be** _non-trivial_\\nto do.\\n\\nIn the case of Ubuntu Pro we\'re talking about community support and best-effort\\nsupport by Canonical for the paying customers. And that makes sense to me,\\nrunning LTS distro for 5+ years on a desktop seems like an odd choice, even\\nwith the help of _[podman]_ and _[distrobox]_ or _[toolbx]_ that allow us to use\\nstable or LTS distro as a base and containerized development environments on top\\nof that.\\n\\n## RHEL ecosystem\\n\\nRHEL ecosystem is much more complicated in this matter. However it\'s very\\nsimilar to the way SUSE operates with few exceptions.\\n\\nYou can see a flow diagram here:\\n\\n```mermaid\\nflowchart LR;\\n U[upstream] --\x3e FR[Fedora Rawhide];\\n FR --\x3e F[Fedora release];\\n F --\x3e C[CentOS Stream];\\n C --\x3e R[RHEL];\\n```\\n\\nKey things to take and not to take from the flow diagram:\\n\\n- getting from one upstream to its respective downstream is not as simple as the\\n presence of an arrow and it\'s not the same process for all of them\\n- lengths of the arrows are not proportional, specifically:\\n - Fedora Rawhide is _supposed to_ consume updates as soon as possible,\\n - depending on the decision of the maintainer they can, but _don\'t have to_ be\\n included in the currently supported Fedora releases (you can take [Emacs] as\\n an example of such package), but Rawhide eventually becomes the next Fedora\\n release,\\n - CentOS Stream gets branched off a specific Fedora release, and then\\n - ultimately CentOS Stream becomes the next **minor** release of RHEL.\\n- this diagram is simplified by **a lot**\\n\\n:::tip SUSE flow for comparison\\n\\nI\'ll also include a SUSE flow, so you can compare:\\n\\n```mermaid\\nflowchart LR;\\n U[upstream] --\x3e T[openSUSE Tumbleweed];\\n T --\x3e L[openSUSE Leap];\\n L --\x3e S[SUSE Linux Enterprise];\\n S --\x3e L;\\n```\\n\\nYou can notice, as opposed to the RHEL ecosystem, some changes are being\\nbackported to the openSUSE Leap.\\n\\nHowever this is subject to change as there is a new [ALP] project arising which\\nis, more than likely, going to replace the Leap.\\n\\n:::\\n\\n### Change in the model\\n\\nThe flow I\'ve shown above is in effect since late \u201820 and early \u201821. I hope you\\ncan see that it is quite similar to the way SUSE operates too. Before late \u201820\\nthe flow was following:\\n\\n```mermaid\\nflowchart LR;\\n U[upstream] --\x3e FR[Fedora Rawhide];\\n FR --\x3e F[Fedora release];\\n F --\x3e R[RHEL];\\n R --- C[CentOS];\\n```\\n\\nCentOS was the last distribution in that \u201cchain\u201d. This provides some benefits\\nand some negatives.\\n\\n#### Before the change\\n\\nFrom the point of a developer, unless you have some kind of an early access to\\nRHEL, you don\'t see the changes until they land and are already released. This\\nimpairs your ability to test and verify your software before shipping it to your\\nclients that use RHEL.\\n\\nFrom the point of a user, there is one positive, you basically get \u201cfree RHEL\u201d\\nwithout the support. This also allowed you to report bugs against the RHEL,\\nsince they were 1:1 distros (minus the branding and support). So you\'d\\ntechnically get RHEL free of charge.\\n\\nBenefit of such project, except for the cost, is questionable. The main issue,\\nwhich actually became even more apparent after changing the flow, is someone\\nelse repackaging your own product and selling it again.\\n\\n#### After the change\\n\\nFirst of all, the current flow counters the issue mentioned above. You can test\\nyour projects against the _next minor RHEL release_. CentOS Stream is free, so\\nyou can freely incorporate it into your CI pipelines.\\n\\n:::tip Shameless plug pt. 2\\n\\nAgain, [Packit] can help you on upstream to verify that you\'re not breaking your\\nRPM builds and on top of that you can also use [Testing Farm] to run tests on a\\nspecific Fedora or CentOS Stream releases.\\n\\n> Green tests may not be green everywhere and catching such issues as soon as\\n> possible costs much less than catching them further down the chain.\\n\\n:::\\n\\nThere are many people thinking that RHEL has become closed-source. It is not.\\nThe development happens _out in the open_, it\'s more open that it was before.\\nHowever with the cost of not getting the exact same thing for free. You can get\\nthe next minor RHEL, not the same that\'s normally paid for. [Packit] is an\\nexample of a service that is deployed on the CentOS 9 Stream and even used to be\\ndeployed on Fedora, but the regular 6-month release cycle caused some minor\\nissues here and there.\\n\\n_Production-ready_ is something that heavily depends on the context\u2026\\n\\n:::tip Free \u201cclones\u201d\\n\\nAfter this change so-called _free \u201cclones\u201d_ emerged. I have to admit that in\\ncase of _[AlmaLinux]_ I can see some benefits e.g., pushing for live images and\\nsupport of various desktop environments, Raspberry Pi support or even WSL images\\nbeing present in the M$ Store and easy to install.\\n\\n:::\\n\\n## Open-source and paid support\\n\\nOverall I don\'t think that paying for the support of 5 years old _non-critical_\\npackages is going against the open-source. It is a non-trivial work that, in\\nmajority of cases, cannot be included in the upstream, therefore the benefit is\\nreapt only by the paying customers. I have to admit that in the case of the\\nUbuntu Pro it may seem a bit weird (hiding patches behind the paywall). However\\nwe\'re still talking about rather big set of packages that will affect a minority\\nof server workloads, if any.\\n\\n## Glossary\\n\\n- _rolling release_ - continuously released without \u201csignificant milestones\u201d\\n\\n :::tip\\n\\n As an example of rolling distribution you can take archLinux, openSUSE\\n Tumbleweed, Fedora Rawhide, or even CentOS 9 Stream.\\n\\n As en example of **not** rolling distribution you can take Ubuntu, openSUSE\\n Leap or Fedora.\\n\\n :::\\n\\n- _bleeding edge_ - contains the latest versions as they are released on the\\n upstream\\n\\n :::tip\\n\\n As an example you can take archLinux, openSUSE Tumbleweed or Fedora Rawhide.\\n You can also notice how common it is to combine _rolling release_ with\\n _bleeding edge_.\\n\\n :::\\n\\n- _upstream_ & _downstream_\\n\\n You\'re most likely to meet these terms in the meaning of upstream being the\\n project itself and downstream being the packaging of said project in some\\n distribution.\\n\\n However this can also apply to distributions like _openSUSE Tumbleweed_ with\\n _openSUSE Leap_, _Fedora_ with _CentOS Stream_, or even _CentOS Stream_ with\\n _RHEL_. This basically means that the packages/software is being released into\\n the upstream (Tumbleweed, Fedora, or even CentOS) and then after being tested\\n is taken further down into their respective downstreams (Leap, CentOS, RHEL).\\n\\n[almalinux]: https://almalinux.org/\\n[alp]: https://susealp.io/\\n[distrobox]: https://distrobox.it/\\n[emacs]: https://src.fedoraproject.org/rpms/emacs/\\n[packit]: https://packit.dev/\\n[podman]: https://podman.io/\\n[testing farm]: https://docs.testing-farm.io/Testing%20Farm/0.1/index.html\\n[toolbx]: https://containertoolbx.org/\\n[ubuntu pro]: https://ubuntu.com/pro/\\n[zorin os]: https://zorin.com/os/pro/\\n\\n[^1]: Richard Stallman\\n[^2]: directed acyclic graph\\n[^3]:\\n Ubuntu Pro is technically a service whereas the RHEL and SLE are distros\\n with the support included.\\n\\n[^4]:\\n There are upstream projects that keep LTS branches, such as Linux kernel,\\n but even in the case of the kernel itself, they\'re planning on ending it,\\n since the cost outweighs the benefits at this point."},{"id":"/2024/01/28/rust-opinion","metadata":{"permalink":"/blog/2024/01/28/rust-opinion","editUrl":"https://github.com/mfocko/blog/tree/main/blog/2024-01-28-rust-opinion.md","source":"@site/blog/2024-01-28-rust-opinion.md","title":"Mixed feelings on Rust","description":"Discussing my mixed feelings about the Rust language.\\n","date":"2024-01-28T00:00:00.000Z","formattedDate":"January 28, 2024","tags":[{"label":"rust","permalink":"/blog/tags/rust"},{"label":"memory safety","permalink":"/blog/tags/memory-safety"},{"label":"cult","permalink":"/blog/tags/cult"},{"label":"hype","permalink":"/blog/tags/hype"}],"readingTime":15.395,"hasTruncateMarker":true,"authors":[{"name":"Matej Focko","email":"me+blog@mfocko.xyz","title":"a.k.a. passionate language hater","url":"https://gitlab.com/mfocko","imageURL":"https://github.com/mfocko.png","key":"mf"}],"frontMatter":{"title":"Mixed feelings on Rust","description":"Discussing my mixed feelings about the Rust language.\\n","date":"2024-01-28T00:00:00.000Z","authors":[{"key":"mf","title":"a.k.a. passionate language hater"}],"tags":["rust","memory safety","cult","hype"],"hide_table_of_contents":false},"unlisted":false,"prevItem":{"title":"LTS distributions","permalink":"/blog/2024/02/07/lts-distros"},"nextItem":{"title":"How can Copr help with broken dependencies","permalink":"/blog/2023/08/02/copr"}},"content":"Rust has become a rather popular language these days. I\'ve managed to get my\\nhands dirty with it during _[Advent of Code]_ \u201822 and partially \u201823. I\'ve also\\nused it for few rounds of _[Codeforces]_ and I have to try very hard to maintain\\nsome variety of languages for LeetCode challenges along with the Rust. I\'ll\\ndisclaim up front that I won\'t be only positive, since this post is a result of\\nmultiple discussions about Rust and I stand by\\n_\u201cAll that glitters is not gold\u201d_, so if you can\'t stand your favorite language\\nbeing criticized in any way, don\'t even proceed. :wink:\\n\\n\x3c!--truncate--\x3e\\n\\n## Memory safety\\n\\nI\'ll start by kicking the biggest benefit of the language, the memory safety.\\nLet\'s be honest here, majority of the checks rely on the static analysis, cause\\nyou can\'t do anything else during the compile-time, right? Therefore we can\\nbasically say that we are relying on the compiler to \u201csolve\u201d all of our issues.\\n\\n:::danger\\n\\nI\'m not doubting the fact that compiler can prevent **a lot** of the memory\\nerrors, I\'m just saying it\'s not realistic to cover **everything**.\\n\\n:::\\n\\n### Compiler\\n\\nI guess we can safely[^2] agree on the fact that we 100% rely on the compiler to\\n_have our back_. Is the compiler bug-free? I doubt it. This is not meant in an\\noffensive way to the Rust compiler developers, but we need to be realistic here.\\nIt\'s a compiler, even older and larger projects like _gcc_ or _llvm_ can\'t avoid\\nbugs to appear.\\n\\nWhen I was trying out Rust for some of the LeetCode challenges I\'ve stumbled\\nupon the following warning:\\n![Example of a compiler bug](https://i.imgur.com/NfPLF6o.png)\\n\\n:::danger [Issue](https://github.com/rust-lang/rust/issues/59159)\\n\\nThe issue here comes from the fact that we have 2 simultaneous references to the\\nsame memory (one is mutable and one immutable). If you cannot think of any way\\nthis can break, I\'ll give you a rather simple example from C++ where this could\\ncause an issue.\\n\\nImagine a function that has some complex object and also calls a coroutine which\\nutilizes read-only reference to that object. When the coroutine suspends, the\\ncaller can modify the object. This can break the integrity of data read by the\\ncoroutine.\\n\\n- Yes, this **can** cause a memory error.\\n- Yes, this **hasn\'t** been handled until someone noticed it.\\n\\nFixing this bug is not backwards compatible, cause you\'re covering a case that\\nhasn\'t been covered before.\\n\\n:::\\n\\n### Enforcing the safety\\n\\nOne of the ways Rust enforces the safety is by restricting what you can do, like\\nthe example above. Aforementioned issue _can_ happen, but **doesn\'t have to**.\\nRule of the thumb in the Rust compiler is to _\u201cblock\u201d_ anything that can be an\\nissue, static analysis can\'t do much more, it cannot decide whether it\'s safe to\\ndo it or not.\\n\\nSatisfying the Rust compiler is sometimes a brutal pain in the ass, because you\\ncannot do things like you\'re used to, you need to work around them _somehow_.\\n\\n:::tip\\n\\nKey difference between Rust and C or C++ lies in the fact that Rust chooses to\\n_ban_ all \u201cpotentially offensive\u201d actions, C and C++ _relies_ on **you** to be\\nsure it\'s safe to do.\\n\\n![C++ v. Rust](https://i.imgur.com/0vbkYPp.png)\\n\\n:::\\n\\n### Consequences\\n\\nWhere are we heading with this approach of \u201cif it compiles, it runs\u201d though?\\nIn this aspect I have a rather similar opinion as with regards to the ChatGPT\\nand its derivatives.\\n\\nIf you teach people to 100% depend on the compiler, they will do it, cause it\'s\\n_easy_. All you need to do is make the compiler _shut up_[^3]. Giving up the\\n_intellectual masturbation_ about the memory safety will make you lose your edge\\nover the time. When we get to the point of everyone being in the mindset\\nmentioned above, who\'s going to maintain the compiler? This is the place where\\nyou **need to** think about the memory safety and furthermore in a much more\\ngeneral way than in your own projects, because it is the thing that everyone\\n_blindly believes in_ in the end.\\n\\nI\'m not saying that everyone should give up Rust and think about their memory\\nmanagement and potential memory issues. I\'m just saying that going the easy way\\nwill make people _dull_ and they should think about it anyways, that\'s how the\\nissue above has been discovered. If everyone walked past and didn\'t think about\\nit, no one would discover this issue till it bit them hard.\\n\\n:::tip Standard library\\n\\nEven the standard library is littered with `unsafe` blocks that are prefixed\\nwith comments in style:\\n\\n```rs\\n// SAFETY: \u2026\\n```\\n\\nThe fact that the _casual_ Rust dev doesn\'t have to think much about safety,\\ncause the compiler has their back, doesn\'t mean that the Rust compiler dev\\ndoesn\'t either.\\n\\nI gotta admit that I adopted this concept in other languages (even in Python),\\ncause you can encounter situations where it doesn\'t have to be clear _why_ you\\ncan do _what_ you\'re doing.\\n\\n:::\\n\\n## Development & design\\n\\nDevelopment of Rust is\u2026 very fast. One positive is that they\'re trying to be as\\nbackward compatible as possible at least by verifying against all the published\\ncrates in the process. Of course, you cannot be backward compatible about fixing\\nthe bugs that have been found, but such is life.\\n\\n### Fast development cycle\\n\\nOne of the negatives of the fast development cycle is the fact that they\'re\\nusing the latest features already in the next release of the Rust. Yes, it is\\nsomething that you can use for verifying and testing your own changes, but at\\nthe same time it places a requirement of the latest release to compile the next\\none.\\n\\n:::tip\\n\\nIf you check `gcc` for example, they have a requirement of minimal version of\\ncompiler that you need for the build. Though gcc\'s requirement is not so _needy_\\nas the Rust one.\\n\\n:::\\n\\nOne of the other negatives is the introduction of bugs. If you\'re pushing\\nchanges, somewhat mindlessly, at such a fast pace, it is inevitable to introduce\\na bunch bugs in the process. Checking the GitHub issue tracker with\\n\\n```\\nis:issue is:open label:C-bug label:T-compiler\\n```\\n\\nyields **2,224** open issues at the time of writing this post.\\n\\n### RFCs\\n\\nYou can find **a lot** of RFCs for the Rust. Some of them are more questionable\\nthan the others. Fun thing is that a lot of them make it to the nightly builds,\\nso they can be tested and polished off. Even the questionable ones\u2026 I\'ll leave\\nfew examples for a better understanding.\\n\\nOne of such features is the `do yeet` expression:\\n\\n```rust\\n#![feature(yeet_expr)]\\n\\nfn foo() -> Result {\\n do yeet 4;\\n}\\nassert_eq!(foo(), Err(4));\\n\\nfn bar() -> Option {\\n do yeet;\\n}\\nassert_eq!(bar(), None);\\n```\\n\\nIt allows you to \u201cyeet\u201d the errors out of the functions that return `Result` or\\n`Option`.\\n\\n[One](https://github.com/rust-lang/rfcs/pull/3503) of the more recent ones is\\nthe ability to include Cargo manifests into the sources, so you can do something\\nlike:\\n\\n```rust\\n#!/usr/bin/env cargo\\n---\\n[dependencies]\\nclap = { version = \\"4.2\\", features = [\\"derive\\"] }\\n---\\n\\nuse clap::Parser;\\n\\n#[derive(Parser, Debug)]\\n#[clap(version)]\\nstruct Args {\\n #[clap(short, long, help = \\"Path to config\\")]\\n config: Option,\\n}\\n\\nfn main() {\\n let args = Args::parse();\\n println!(\\"{:?}\\", args);\\n}\\n```\\n\\nI would say you can get almost anything into the language\u2026\\n\\n## Community and hype train\\n\\nRust community is a rather unique thing. A lot of people will hate me for this,\\nbut I can\'t help, but to compare them to _militant vegans_. I\'ll go through some\\nof the things related to it, so I can support my opinion at least.\\n\\n_Rust is the best language._ It is not. There is no best language, each has its\\nown positives and negatives, you need to choose the language that\'s **the most**\\n**suitable for your use case**. There are areas where Rust excels, though I have\\nto admit it\'s very close to being a universal hammer regardless of how suitable\\nit is. There is a very steep learning curve to it, beginnings in Rust are very\\npainful.\\n\\n_Rewrite everything in Rust._ Just no. There are multiple feedbacks on doing\\nrewrites, it is very common to fix _N_ bugs with a rewrite while introducing\\n_N + 1_ other bugs in the process. It doesn\'t solve anything unless there are\\nsome strong reasons to go with it. Majority of such suggested rewrites don\'t\\nhave those reasons though.\\n\\n_Language \u2039x\u203a is bad, though in Rust\u2026_ Cherry-picking one specific pain point of\\none language and reflecting how it is better in other language can go both ways.\\nFor example it is rather easy to pick the limitations imposed by Rust compiler\\nand show how it\'s possible in other languages :man_shrugging:\\n\\nI don\'t mind any of those opinions, you\'re free to have them, as long as you\\ndon\'t rub them in my face which is not the usual case\u2026 This experience makes it\\njust worse for me, part of this post may be also influenced by this fact.\\n\\n### Rust in Linux\\n\\n:::warning[caution]\\n\\nAs someone who has seen the way Linux kernel is built in the RHEL ecosystem, how\\ncomplex the whole thing is and how much resources you need to proceed, I have\\nvery strong opinions on this topic.\\n\\n:::\\n\\nIt took years of work to even \u201cincorporate\u201d Rust into the Linux codebase, just\\nto get the \u201cHello World!\u201d. I don\'t have anything against the idea of writing\\ndrivers in the Rust, I bet it can catch a lot of common mistakes, but still\\nintroducing Rust to the kernel is another step to enlarge the monster.\\n\\nI have to admit though that the _Apple GPU_ driver for Linux written in Rust is\\nquite impressive. Apart from that there are not so many benefits, yet\u2026\\n\\n## Packaging\\n\\nI\'ll divide the packaging into the packaging of the language itself and the\\nprograms written in Rust.\\n\\nLet\'s start with the `cargo` itself though. Package managers of the languages\\nusually get a lot of hate (you can take `npm` or `pip` as examples[^1]). If\\nyou\'ve ever tried out Rust, I bet you already know where I\'m going with this.\\nYes, I mean the compilation times, or even Cargo downloading _whole_ index of\\ncrates just so you can update that one dependency (and 3 millions of indirect\\ndeps). When I was doing AoC \u201822 in Rust, I\'ve set up `sccache` right away on the\\nfirst day.\\n\\nLet\'s move to the packaging of the Rust itself, it\'s tedious. Rust has a very\\nfast development cycle and doesn\'t even try to make the builds backward\\ncompatible. If there is a new release of Rust, there is a very high chance that\\nyou cannot build that release with anything other than **the latest** Rust\\nrelease. If you have ever touched the packaging, you know that this is something\\nthat can cause a lot of problems, cause you need the second-to-latest version to\\ncompile the latest version, don\'t forget that this applies inductively\u2026 People\\nrunning _Gentoo_ could tell you a lot about this.\\n\\n:::info\\n\\nCompiling the compilers takes usually more time than compiling the kernel\\nitself\u2026\\n\\n:::\\n\\nI cannot speak about packaging of Rust programs in other than RHEL-based\\ndistros, though I can speak about RHEL ecosystem. Fedora packaging guidelines\\nspecify that you need to build each and every dependency of the program\\nseparately. I wanted to try out _AlmaLinux_ and install Alacritty there and I\\nfailed miserably. The solution that worked, consisted of ignoring the packaging\\nguidelines, running `cargo build` and consuming the binaries afterwards.\\nDependencies of the Rust programs are of a similar nature as JS dependencies.\\n\\n> I\'m tipping my fedora[^2] in the general direction of the maintainers of Rust\\n> packages in RHEL ecosystem. I wouldn\'t be able to do this without losing my\\n> sanity.\\n\\n## Likes\\n\\nIf you\'ve come all the way here and you\'re a Rustacean, I believe I\'ve managed\\nto get your blood boiling, so it\'s time to finish this off by stuff I like about\\nRust. I doubt I will be able to cover everything, but I can try at least. You\\nhave to admit it\'s much easier to remember the bad stuff as opposed to the good.\\n:wink:\\n\\n### Workflow and toolchain\\n\\nI prefered using Rust for the _Advent of Code_ and _Codeforces_ as it provides\\na rather easy way to test the solutions before running them with the challenge\\ninput (or test runner). I can give an example from the _Advent of Code_:\\n\\n```rust\\nuse aoc_2023::*;\\n\\ntype Output1 = i32;\\ntype Output2 = Output1;\\n\\nstruct DayXX {}\\nimpl Solution for DayXX {\\n fn new>(pathname: P) -> Self {\\n let lines: Vec = file_to_lines(pathname);\\n\\n todo!()\\n }\\n\\n fn part_1(&mut self) -> Output1 {\\n todo!()\\n }\\n\\n fn part_2(&mut self) -> Output2 {\\n todo!()\\n }\\n}\\n\\nfn main() -> Result<()> {\\n DayXX::main()\\n}\\n\\ntest_sample!(day_XX, DayXX, 42, 69);\\n```\\n\\nThis was the skeleton I\'ve used and the macro at the end is my own creation that\\nexpands to:\\n\\n```rust\\n#[cfg(test)]\\nmod day_XX {\\n use super::*;\\n\\n #[test]\\n fn part_1() {\\n let path = DayXX::get_sample(1);\\n let mut day = DayXX::new(path);\\n assert_eq!(day.part_1(), 42);\\n }\\n\\n #[test]\\n fn part_2() {\\n let path = DayXX::get_sample(2);\\n let mut day = DayXX::new(path);\\n assert_eq!(day.part_2(), 69);\\n }\\n}\\n```\\n\\nWhen you\'re solving the problem, all you need to do is switch between\\n`cargo test` and `cargo run` to check the answer to either sample or the\\nchallenge input itself.\\n\\nIntroduce [bacon] and it gets even better. Bacon is a CLI tool that wraps around\\nthe `cargo` and allows you to check, run, lint or run tests on each file save.\\nIt\'s a very pleasant thing for a so-called _compiler-assisted_ development.\\n\\nSpeaking of linting from within the bacon, you cannot leave out the [clippy].\\nNot only it can whip your ass because of errors, but it can also produce a lot\\nof helpful suggestions, for example passing slices by borrow instead of\\nborrowing the `Vec` itself when you don\'t need it.\\n\\n### Standard library\\n\\nThere\'s **a lot** included in the standard library. It almost feels like you\\nhave all you need[^4]. I like placeholders (like `todo!()`, `unreachable!()`,\\n`unimplemented!()`) to the extent of\\n[implementing](/cpp/exceptions-and-raii/placeholders) them as exceptions in C++.\\n\\nYou can find almost anything. Though you can also hit some very weird issues\\nwith some of the nuances of the type system.\\n\\n### `unsafe`\\n\\nThis might be something that people like to avoid as much as possible. However I\\nthink that forming a habit of commenting posibly unsafe operations in **any**\\nlanguage is a good habit, as I\'ve mentioned above. You should be able to argue\\nwhy you can do something safely, even if the compiler is not kicking your ass\\nbecause of it.\\n\\nExcerpt of such comment from work:\\n\\n```py\\n# SAFETY: Taking first package instead of specific package should be\\n# safe, since we have put a requirement on \xbbone\xab \u2039upstream_project_url\u203a\\n# per Packit config, i.e. even if we\'re dealing with a monorepo, there\\n# is only \xbbone\xab upstream. If there is one upstream, there is only one\\n# set of GPG keys that can be allowed.\\nreturn self.downstream_config.packages[\\n self.downstream_config._first_package\\n].allowed_gpg_keys\\n```\\n\\n### Traits\\n\\nOne of the other things I like are the traits. They are more restrictive than\\ntemplates or concepts in C++, but they\'re doing their job pretty good. If you\\nare building library and require multiple traits to be satisfied it means a lot\\nof copy-paste, but that\'s soon to be fixed by the [trait aliases].\\n\\n:::tip Comparing to other languages\\n\\nOn Wikipedia I\'ve seen trait being defined as a more restrictive type class as\\nyou may know it from the Haskell for example. C++ isn\'t behind either with its\\n_constraints and concepts_. I would say that we can order them in the following\\norder based on the complexity they can express:\\n\\n```\\nRust\'s trait < Haskell\'s type class < C++\'s concept\\n```\\n\\n:::\\n\\nYou can also hit some issues, like me when trying to support conversions between\\nunderlying numeric types of a 2D vectors or support for using an operator from\\nboth sides (I couldn\'t get `c * u` to work in the same way as `u * c` because\\nthe first one requires you to implement the trait of a built-in type).\\n\\n:::warning Implementation\\n\\nImplementing traits lies in\\n\\n```rust\\nimpl SomeTrait for SomeStruct {\\n // implementation goes here\\n}\\n```\\n\\nOne of the things I **would love to** see is being able to define the helper\\nfunctions within the same block. As of now, the only things allowed are the ones\\nthat are required by the trait, which in the end results in a randomly lying\\nfunctions around (or in a implementation of the structure itself). I don\'t like\\nthis mess at all\u2026\\n\\n:::\\n\\n### Influence of functional paradigm\\n\\nYou can see a big influence of the functional paradigm. Not only in iterators,\\nbut also in the other parts of the language. For example I prefer `Option` or\\n`Result` to `null`s and exceptions. Pattern matching together with\\ncompiler both enforces handling of the errors and rather user-friendly way of\\ndoing it.\\n\\nNot to mention `.and_then()` and such. However spending most of the time with\\nthe AoC you get pretty annoyed of the repetitive `.unwrap()` during parsing,\\nsince you are guaranteed correct input.\\n\\n### Macros\\n\\nMacros are a very strong pro of the Rust. And no, we\'re not going to talk about\\nthe procedural macros\u2026\\n\\nAs I\'ve shown above I\'ve managed to \u201ctame\u201d a lot of copy-paste in the tests for\\nthe AoC by utilizing a macro that generated a very basic template for the tests.\\n\\nAs I have mentioned the traits above, I cannot forget to give props to `derive`\\nmacro that allows you to \u201cdeduce\u201d the default implementation. It is very helpful\\nfor a tedious tasks like implementing `Debug` (for printing out the structures)\\nor comparisons, though with the comparisons you need to be careful about the\\ndefault implementation, it has already bitten me once or twice.\\n\\n## Summary\\n\\nOverall there are many things about the Rust I like and would love to see them\\nimplemented in other languages. However there are also many things I don\'t like.\\nNothing is **exclusively** black and white.\\n\\n[advent of code]: https://adventofcode.com\\n[bacon]: https://dystroy.org/bacon/\\n[clippy]: https://github.com/rust-lang/rust-clippy\\n[codeforces]: https://codeforces.com\\n[trait aliases]: https://github.com/rust-lang/rfcs/blob/master/text/1733-trait-alias.md\\n\\n[^1]:\\n not to even mention multiple different packaging standards Python has, which\\n is borderline https://xkcd.com/927/\\n\\n[^2]: pun intended\\n[^3]: It\'s not that easy with the Rust compiler, but OK\u2026\\n[^4]:\\n unlike Python where there\'s whole universe in the language itself, yet there\\n are essential things not present\u2026"},{"id":"/2023/08/02/copr","metadata":{"permalink":"/blog/2023/08/02/copr","editUrl":"https://github.com/mfocko/blog/tree/main/blog/2023-08-02-copr.md","source":"@site/blog/2023-08-02-copr.md","title":"How can Copr help with broken dependencies","description":"Copr comes to save you when maintainer doesn\'t care.","date":"2023-08-02T00:00:00.000Z","formattedDate":"August 2, 2023","tags":[{"label":"\ud83c\udfed","permalink":"/blog/tags/\ud83c\udfed"},{"label":"red-hat","permalink":"/blog/tags/red-hat"},{"label":"copr","permalink":"/blog/tags/copr"},{"label":"admin","permalink":"/blog/tags/admin"},{"label":"vps","permalink":"/blog/tags/vps"}],"readingTime":3.44,"hasTruncateMarker":true,"authors":[{"name":"Matej Focko","email":"me+blog@mfocko.xyz","title":"a.k.a. your opinionated admin","url":"https://gitlab.com/mfocko","imageURL":"https://github.com/mfocko.png","key":"mf"}],"frontMatter":{"title":"How can Copr help with broken dependencies","description":"Copr comes to save you when maintainer doesn\'t care.","date":"2023-08-02T00:00:00.000Z","authors":[{"key":"mf","title":"a.k.a. your opinionated admin"}],"tags":["\ud83c\udfed","red-hat","copr","admin","vps"]},"unlisted":false,"prevItem":{"title":"Mixed feelings on Rust","permalink":"/blog/2024/01/28/rust-opinion"},"nextItem":{"title":"4th week of Advent of Code \'22 in Rust","permalink":"/blog/aoc-2022/4th-week"}},"content":"When you decide to run Fedora on your VPS, you might get screwed over by using\\nrandom repositories\u2026\\n\\n\x3c!--truncate--\x3e\\n\\nWhen I \u201creserved\u201d my VPS[^1] back in June \'20, I slapped Fedora on it without\\nthinking. I bet 99% of people would say that I\'m crazy for doing such thing[^2],\\n**BUT** I\'ve been using Fedora on my PCs for some time already and it felt very\\nstable and natural to just use, even for VPS.\\n\\nOne of the first things I\'ve done was setting up a mail server. You may guess\\nwhat\'s the fun part about having a mail server\u2026 Yes, it\'s all the spam you\\nreceive and only then you realize how much \u201ccrap\u201d gets filtered on free mail\\nservices. To battle this problem I chose to use\\n[rspamd](https://github.com/rspamd/rspamd) that had CentOS support, but someone\\nhad a [Copr](https://copr.fedorainfracloud.org/) repository that I used to\\ninstall it.\\n\\n## How does Copr repositories work?\\n\\nIf you have ever used Ubuntu, you might be familiar with the concept since it is\\nvery close to [PPAs](https://help.ubuntu.com/community/PPA).\\n\\ntl;dr of the whole process consists of\\n\\n1. enabling the Copr repository, and\\n2. installing the desired package.\\n\\nSo in shell you would do\\n\\n```\\n# dnf copr enable \u2039copr-repository\u203a\\n# dnf install \u2039package-from-the-repository\u203a\\n```\\n\\nAnd\u2026 that\'s it! Nothing else needed! Simple, right? And literally same process\\nas you would do for the PPA.\\n\\n:::tip AUR\\n\\nOn the other hand, if you are familiar with the archLinux, you definitely know\\nAUR and what it can do for you. Copr repository is pretty similar, but the\\npackages are prebuilt in Copr and Copr repositories can carry the required\\ndependencies for said packages, which simplifies the distribution, and can even\\nhelp with installing singular packages (when you just need the dependency, not\\neverything).\\n\\n:::\\n\\n## My issue\\n\\nNow you might wonder how would I use it on my VPS. It\'s rather simple, once in\\n6 months a new Fedora release comes out. And you need to upgrade to newer\\nrelease\u2026 You don\'t need to do it right away and for such setup it probably isn\'t\\neven recommended.\\n\\n:::tip\\n\\nFedora releases are supported for a year, i.e. they live 6 months till the next\\nrelease and then another 6 months till another release.\\n\\nSome people prefer to run one version \u201cbehind\u201d. If you ever decide to run it on\\nyour home server or in a similar setup, it might be a pretty good idea to\\nfollow. I\'m using the \u201clatest greatest\u201d, cause why not :smile:\\n\\nOne way or another, you still need to bump the release every six months, unless\\nyou\'d bump 2 releases at once every year, which would be a decision, since, at\\nleast I, cannot see any benefits in it\u2026 You don\'t go for \u201cstability\u201d, cause once\\na year you switch to the latest release and then, before you bump, you use one\\nyear old software, so you\'re not even using the latest.\\n\\n:::\\n\\nFast-forward 2 years in the future, new Fedora release came out (October \'22)\\nand I was doing an upgrade. Dependencies of the rspamd have been updated and\\nrspamd builds in Copr have failed and no one fixed it. Cool, so now I can\\nupgrade, but can either ignore the dependencies or uninstall the rspamd\u2026\\n\\n## How can Copr help?\\n\\nI have managed to find\\n[specfile](https://github.com/rspamd/rspamd/blob/master/rpm/rspamd.spec) for the\\nrspamd package that they use for CentOS. There were some files apart from the\\nspecfile, so I had to make an SRPM locally and then\u2026 I just uploaded the SRPM\\nto the Copr to\\n[build](https://copr.fedorainfracloud.org/coprs/mfocko/rspamd/build/5046567/)\\nan RPM.\\n\\nI have switched the previous Copr repository for rspamd with my own and happily\\nproceeded with the upgrade.\\n\\n## Conclusion\\n\\nCopr is heavily used for testing builds on the upstream with\\n[Packit](https://packit.dev). However, as you can see, it is possible to use it\\n**very well** for packaging your own stuff and avoiding issues (such as the one\\nI have described above), if need be.\\n\\n[^1]: [vpsFree.cz](https://vpsfree.cz)\\n[^2]:\\n Even though I\'ve been running archLinux on some Raspberry Pi\'s and also\\n on one of my \u201chome servers\u201d, before getting the VPS. You could say I like\\n to live on the edge\u2026"},{"id":"aoc-2022/4th-week","metadata":{"permalink":"/blog/aoc-2022/4th-week","editUrl":"https://github.com/mfocko/blog/tree/main/blog/aoc-2022/04-week-4.md","source":"@site/blog/aoc-2022/04-week-4.md","title":"4th week of Advent of Code \'22 in Rust","description":"Surviving fourth week in Rust.","date":"2023-07-07T15:14:00.000Z","formattedDate":"July 7, 2023","tags":[{"label":"advent-of-code","permalink":"/blog/tags/advent-of-code"},{"label":"advent-of-code-2022","permalink":"/blog/tags/advent-of-code-2022"},{"label":"rust","permalink":"/blog/tags/rust"}],"readingTime":15.315,"hasTruncateMarker":true,"authors":[{"name":"Matej Focko","email":"me+blog@mfocko.xyz","title":"a.k.a. @mf","url":"https://gitlab.com/mfocko","imageURL":"https://github.com/mfocko.png","key":"mf"}],"frontMatter":{"title":"4th week of Advent of Code \'22 in Rust","description":"Surviving fourth week in Rust.","date":"2023-07-07T15:14","slug":"aoc-2022/4th-week","authors":"mf","tags":["advent-of-code","advent-of-code-2022","rust"],"hide_table_of_contents":false},"unlisted":false,"prevItem":{"title":"How can Copr help with broken dependencies","permalink":"/blog/2023/08/02/copr"},"nextItem":{"title":"3rd week of Advent of Code \'22 in Rust","permalink":"/blog/aoc-2022/3rd-week"}},"content":"Let\'s go through the fourth week of [_Advent of Code_] in Rust.\\n\\n\x3c!--truncate--\x3e\\n\\n## [Day 22: Monkey Map](https://adventofcode.com/2022/day/22)\\n\\n:::info tl;dr\\n\\nSimulating a movement on a 2D map with given instructions. Map becomes a cube in\\nthe 2nd part\u2026\\n\\n:::\\n\\n:::danger Rant\\n\\nThis was the most obnoxious problem of this year\u2026 and a lot of Rust issues have\\nbeen hit.\\n\\n:::\\n\\n### Solution\\n\\nIt seems like a very simple problem to solve, but with very obnoxious changes in\\nthe 2nd part and also it\'s relatively hard to decompose \xbbproperly\xab.\\n\\n#### Column iterator\\n\\nIn the first part of the problem it was needed to know the boundaries of each\\nrow and column, since I stored them in `Vec>` and padded with spaces\\nto ensure I have a rectangular 2D \u201carray\u201d. However when you wanted to go through\\neach row and column to determine the boundaries, it was very easy to do for the\\nrows (cause each row is a `Vec` element), but not for the columns, since they\\nspan multiple rows.\\n\\nFor this use case I have implemented my own _column iterator_:\\n\\n```rust\\npub struct ColumnIterator<\'a, T> {\\n map: &\'a [Vec],\\n column: usize,\\n\\n i: usize,\\n}\\n\\nimpl<\'a, T> ColumnIterator<\'a, T> {\\n pub fn new(map: &\'a [Vec], column: usize) -> ColumnIterator<\'a, T> {\\n Self { map, column, i: 0 }\\n }\\n}\\n\\nimpl<\'a, T> Iterator for ColumnIterator<\'a, T> {\\n type Item = &\'a T;\\n\\n fn next(&mut self) -> Option {\\n if self.i >= self.map.len() {\\n return None;\\n }\\n\\n self.i += 1;\\n Some(&self.map[self.i - 1][self.column])\\n }\\n}\\n```\\n\\nGiven this piece of an iterator, it is very easy to factor out the common\\nfunctionality between the rows and columns into:\\n\\n```rust\\nlet mut find_boundaries = |constructor: fn(usize) -> Orientation,\\n iterator: &mut dyn Iterator,\\n upper_bound,\\n i| {\\n let mut first_non_empty = iterator.enumerate().skip_while(|&(_, &c)| c == \' \');\\n let start = first_non_empty.next().unwrap().0 as isize;\\n\\n let mut last_non_empty = first_non_empty.skip_while(|&(_, &c)| c != \' \');\\n let end = last_non_empty.next().unwrap_or((upper_bound, &\'_\')).0 as isize;\\n\\n boundaries.insert(constructor(i), start..end);\\n};\\n```\\n\\nAnd then use it as such:\\n\\n```rust\\n// construct all horizontal boundaries\\n(0..map.len()).for_each(|row| {\\n find_boundaries(\\n Orientation::horizontal,\\n &mut map[row].iter(),\\n map[row].len(),\\n row,\\n );\\n});\\n\\n// construct all vertical boundaries\\n(0..map[0].len()).for_each(|col| {\\n find_boundaries(\\n Orientation::vertical,\\n &mut ColumnIterator::new(&map, col),\\n map.len(),\\n col,\\n );\\n});\\n```\\n\\n#### Walking around the map\\n\\nOnce the 2nd part got introduced, you start to think about a way how not to\\ncopy-paste a lot of stuff (I haven\'t avoided it anyways\u2026). In this problem, I\'ve\\nchosen to introduce a trait (i.e. _interface_) for 2D and 3D walker.\\n\\n```rust\\ntrait Wrap: Clone {\\n type State;\\n\\n // simulation\\n fn is_blocked(&self) -> bool;\\n fn step(&mut self, steps: isize);\\n fn turn_left(&mut self);\\n fn turn_right(&mut self);\\n\\n // movement\\n fn next(&self) -> (Self::State, Direction);\\n\\n // final answer\\n fn answer(&self) -> Output;\\n}\\n```\\n\\nEach walker maintains its own state and also provides the functions that are\\nused during the simulation. The \u201cpromised\u201d methods are separated into:\\n\\n- _simulation_-related: that are used during the simulation from the `.fold()`\\n- _movement_-related: just a one method that holds most of the logic differences\\n between 2D and 3D\\n- _final answer_: which extracts the _proof of solution_ from the\\n implementation-specific walker\\n\\nBoth 2D and 3D versions borrow the original input and therefore you must\\nannotate the lifetime of it:\\n\\n```rust\\nstruct Wrap2D<\'a> {\\n input: &\'a Input,\\n position: Position,\\n direction: Direction,\\n}\\nimpl<\'a> Wrap2D<\'a> {\\n fn new(input: &\'a Input) -> Wrap2D<\'a> {\\n// \u2026\\n```\\n\\n#### Problems\\n\\nI have used a lot of closures for this problem and once I introduced a parameter\\nthat was of unknown type (apart from the fact it implements a specific trait), I\\ngot suggested a \u201cfix\u201d for the compilation error that resulted in something that\\nwas not possible to parse, cause it, more than likely, violated the grammar.\\n\\nIn a similar fashion, I have been suggested changes that led to a code that\\ndidn\'t make sense by just looking at it (there was no need to try the changes),\\nfor example one suggested change in the closure parameter caused disapperance of\\nthe parameter name. :smile:\\n\\n#### Clippy\\n\\nI have to admit that Clippy was rather helpful here, I\'ll include two examples\\nof rather smart suggestions.\\n\\nWhen writing the parsing for this problem, the first thing I have spotted on the\\n`char` was the `.is_digit()` function that takes a radix as a parameter. Clippy\\nnoticed that I use `radix = 10` and suggested switching to `.is_ascii_digit()`\\nthat does exactly the same thing:\\n\\n```diff\\n- .take_while(|c| c.is_digit(10))\\n+ .take_while(|c| c.is_ascii_digit())\\n```\\n\\nAnother useful suggestion appeared when working with the iterators and I wanted\\nto get the $n$-th element from it. You know the `.skip()`, you know the\\n`.next()`, just \u201cslap\u201d them together and we\'re done for :grin: Well, I got\\nsuggested to use `.nth()` that does exactly the combination of the two mentioned\\nmethods on iterators:\\n\\n```diff\\n- match it.clone().skip(skip).next().unwrap() {\\n+ match it.clone().nth(skip).unwrap() {\\n```\\n\\n## [Day 23: Unstable Diffusion](https://adventofcode.com/2022/day/23)\\n\\n:::info tl;dr\\n\\nSimulating movement of elves around with a set of specific rules.\\n\\n:::\\n\\n### Solution\\n\\nThere\'s not much to mention since it\'s just a cellular automaton simulation\\n(even though the AoC rules for cellular automatons usually get out of hand\\n:wink:).\\n\\nAlthough I had a need to determine boundaries of the elves\' positions and ended\\nup with a nasty DRY violation. Knowing that you you\'re looking for maximum and\\nminimum that are, of course, exactly the same except for initial values and\\ncomparators, it looks like a rather simple fix, but typing in Rust is something\\nelse, right? In the end I settled for a function that computes both boundaries\\nwithout any duplication while using a closure:\\n\\n```rust\\nfn get_bounds(positions: &Input) -> (Vector2D, Vector2D) {\\n let f = |init, cmp: &dyn Fn(isize, isize) -> isize| {\\n positions\\n .iter()\\n .fold(Vector2D::new(init, init), |acc, elf| {\\n Vector2D::new(cmp(acc.x(), elf.x()), cmp(acc.y(), elf.y()))\\n })\\n };\\n\\n (f(isize::MAX, &min::), f(isize::MIN, &max::))\\n}\\n```\\n\\nThis function returns a pair of 2D vectors that represent opposite points of the\\nbounding rectangle of all elves.\\n\\nYou might ask why would we need a closure and the answer is that `positions`\\ncannot be captured from within the nested function, only via closure. One more\\nfun fact on top of that is the type of the comparator\\n\\n```rust\\n&dyn Fn(isize, isize) -> isize\\n```\\n\\nOnce we remove the `dyn` keyword, compiler yells at us and also includes a way\\nhow to get a more thorough explanation of the error by running\\n\\n```shell\\n$ rustc --explain E0782\\n```\\n\\nwhich shows us\\n\\n> Trait objects must include the `dyn` keyword.\\n>\\n> Erroneous code example:\\n>\\n> ```\\n> trait Foo {}\\n> fn test(arg: Box) {} // error!\\n> ```\\n>\\n> Trait objects are a way to call methods on types that are not known until\\n> runtime but conform to some trait.\\n>\\n> Trait objects should be formed with `Box`, but in the code above\\n> `dyn` is left off.\\n>\\n> This makes it harder to see that `arg` is a trait object and not a\\n> simply a heap allocated type called `Foo`.\\n>\\n> To fix this issue, add `dyn` before the trait name.\\n>\\n> ```\\n> trait Foo {}\\n> fn test(arg: Box) {} // ok!\\n> ```\\n>\\n> This used to be allowed before edition 2021, but is now an error.\\n\\n:::danger Rant\\n\\nNot all of the explanations are helpful though, in some cases they might be even\\nmore confusing than helpful, since they address _very simple_ use cases.\\n\\nAs you can see, even in this case there are two sides to the explanations:\\n\\n- it explains why you need to use `dyn`, but\\n- it still mentions that trait objects need to be heap-allocated via `Box`\\n that, as you can see in my snippet, **does not** apply here :smile: IMO it\'s\\n caused by the fact that we are borrowing it and therefore we don\'t need to\\n care about the size or whereabouts of it.\\n\\n:::\\n\\n:::info C++ parallel\\n\\nIf you dive into the explanation above, you can notice that the `Box`\\npattern is very helpful for using types that are not known during compile-time.\\nYou would use a very similar approach in C++ when parsing some data structure\\nfrom input (let\'s say JSON for example).\\n\\nOn the other hand, in this case, it doesn\'t really make much sense, cause you\\ncan clearly see that the types **are known** during the compile-time, which in\\nC++ could be easily resolved by templating the helper function.\\n\\n:::\\n\\n## [Day 24: Blizzard Basin](https://adventofcode.com/2022/day/24)\\n\\n:::info tl;dr\\n\\nNavigating your way through a basin with series of blizzards that move around\\nyou as you move.\\n\\n:::\\n\\n:::warning[caution]\\n\\nIt\'s second to last day and I went \u201c_bonkers_\u201d on the Rust :smile: Proceed to\\nread _Solution_ part on your own risk.\\n\\n:::\\n\\n### Solution\\n\\nYou are given a map with blizzards all over the place and you\'re supposed to\\nfind the minimum time it requires you to walk through the basin without getting\\nin any of the blizzards.\\n\\n#### Breakdown\\n\\nRelatively simple, yet a bit annoying, approach can be taken. It\'s technically\\na shortest-path algorithm implementation with some relaxation restrictions and\\nbeing able to stay on one position for some time, so each _vertex_ of the graph\\nis determined by the position on the map and the _timestamp_. I have chosen to\\nuse `Vector3D`, since `x` and `y` attributes can be used for the position\\nand, well, let\'s use `z` for a timestamp, cause why not, right? :wink:\\n\\n#### Evaluating the blizzards\\n\\n:::warning[caution]\\n\\nI think that this is the most perverted abuse of the traits in the whole 4 weeks\\nof AoC in Rust\u2026\\n\\n:::\\n\\nThe blizzards move along their respective directions in time and loop around in\\ntheir respective row/column. Each vertex holds position **and** time, so we can\\n_just_ index the basin with the vertex itself, right? Yes, we can :smiling_imp:\\n\\n:::tip Fun fact\\n\\nWhile writing this part, I\'ve recognized unnecessary verbosity in the code and\\ncleaned it up a bit. The changed version is shown here and the original was just\\nmore verbose.\\n\\n:::\\n\\nI\'ll skip the boring parts of checking bounds and entry/exit of the basin :wink:\\nWe can easily calculate positions of the blizzards using a modular arithmetics:\\n\\n```rust\\nimpl Index for Basin {\\n type Output = char;\\n\\n fn index(&self, index: Position) -> &Self::Output {\\n // \u2039skipped boring parts\u203a\\n\\n // We need to account for the loops of the blizzards\\n let width = self.cols - 2;\\n let height = self.rows - 2;\\n\\n let blizzard_origin = |size, d, t, i| ((i - 1 + size + d * (t % size)) % size + 1) as usize;\\n [\\n (\\n index.y() as usize,\\n blizzard_origin(width, -1, index.z(), index.x()),\\n \'>\',\\n ),\\n (\\n index.y() as usize,\\n blizzard_origin(width, 1, index.z(), index.x()),\\n \'<\',\\n ),\\n (\\n blizzard_origin(height, -1, index.z(), index.y()),\\n index.x() as usize,\\n \'v\',\\n ),\\n (\\n blizzard_origin(height, 1, index.z(), index.y()),\\n index.x() as usize,\\n \'^\',\\n ),\\n ]\\n .iter()\\n .find_map(|&(y, x, direction)| {\\n if self.map[y][x] == direction {\\n Some(&self.map[y][x])\\n } else {\\n None\\n }\\n })\\n .unwrap_or(&\'.\')\\n }\\n}\\n```\\n\\nAs you can see, there is an expression for calculating the original position and\\nit\'s used multiple times, so why not take it out to a lambda, right? :wink:\\n\\nI couldn\'t get the `rustfmt` to format the `for`-loop nicely, so I\'ve just\\ndecided to go with iterating over an elements of a slice. I have used, once\\nagain, a combination of two functions (`find_map` in this case) to do 2 things\\nat once and at the end, if we haven\'t found any blizzard, we just return the\\nempty space.\\n\\nI think it\'s a very _nice_ (and naughty) way how to use the `Index` trait, don\'t\\nyou think?\\n\\n#### Shortest-path algorithm\\n\\nFor the shortest path you can choose and adjust any of the common shortest-path\\nalgorithms, in my case, I have decided to use [_A\\\\*_] instead of Dijkstra\'s\\nalgorithm, since it better reflects the _cost_ function.\\n\\n:::info Comparison of costs\\n\\nWith the Dijkstra\'s algorithm I would proceed with the `time` attribute used as\\na priority for the queue.\\n\\nWhereas with the _A\\\\*_, I have chosen to use both time and Manhattan distance\\nthat promotes vertices closer to the exit **and** with a minimum time taken.\\n\\n:::\\n\\nCost function is, of course, a closure :wink:\\n\\n```rust\\nlet cost = |p: Position| p.z() as usize + exit.y().abs_diff(p.y()) + exit.x().abs_diff(p.x());\\n```\\n\\nAnd also for checking the possible moves from the current vertex, I have\\nimplemented, yet another, closure that yields an iterator with the next moves:\\n\\n```rust\\nlet next_positions = |p| {\\n [(0, 0, 1), (0, -1, 1), (0, 1, 1), (-1, 0, 1), (1, 0, 1)]\\n .iter()\\n .filter_map(move |&(x, y, t)| {\\n let next_p = p + Vector3D::new(x, y, t);\\n\\n if basin[next_p] == \'.\' {\\n Some(next_p)\\n } else {\\n None\\n }\\n })\\n};\\n```\\n\\n#### Min-heap\\n\\nIn this case I had a need to use the priority queue taking the elements with the\\nlowest cost as the prioritized ones. Rust only offers you the [`BinaryHeap`] and\\nthat is a max-heap. One of the ways how to achieve a min-heap is to put the\\nelements in wrapped in a [`Reverse`] (as is even showed in the linked [docs of\\nthe `BinaryHeap`]). However the wrapping affects the type of the heap and also\\npopping the most prioritized elements yields values wrapped in the `Reverse`.\\n\\nFor this purpose I have just taken the max-heap and wrapped it as a whole in a\\nseparate structure providing just the desired methods:\\n\\n```rust\\nuse std::cmp::{Ord, Reverse};\\nuse std::collections::BinaryHeap;\\n\\npub struct MinHeap {\\n heap: BinaryHeap>,\\n}\\n\\nimpl MinHeap {\\n pub fn new() -> MinHeap {\\n MinHeap {\\n heap: BinaryHeap::new(),\\n }\\n }\\n\\n pub fn push(&mut self, item: T) {\\n self.heap.push(Reverse(item))\\n }\\n\\n pub fn pop(&mut self) -> Option {\\n self.heap.pop().map(|Reverse(x)| x)\\n }\\n}\\n\\nimpl Default for MinHeap {\\n fn default() -> Self {\\n Self::new()\\n }\\n}\\n```\\n\\nRest is just the algorithm implementation which is not that interesting.\\n\\n## [Day 25: Full of Hot Air](https://adventofcode.com/2022/day/25)\\n\\n:::info tl;dr\\n\\nPlaying around with a numbers in a _special_ base.\\n\\n:::\\n\\nGetting flashbacks to the _IB111 Foundations of Programming_\u2026 Very nice \u201cproblem\u201d\\nwith a rather easy solution, as the last day always seems to be.\\n\\n### Solution\\n\\nImplementing 2 functions, converting from the _SNAFU base_ and back to the _SNAFU_\\n_base_ representation. Let\'s do a bit more though! I have implemented two functions:\\n\\n- `from_snafu`\\n- `to_snafu`\\n\\nNow it is apparent that all I do is number to string and string to number. Hmm\u2026\\nthat sounds familiar, doesn\'t it? Let\'s introduce a structure for the SNAFU numbers\\nand implement the traits that we need.\\n\\nLet\'s start with a structure:\\n\\n```rust\\n#[derive(Debug, PartialEq, Eq, PartialOrd, Ord)]\\nstruct SNAFU {\\n value: i64,\\n}\\n```\\n\\n#### Converting from `&str`\\n\\nWe will start by implementing the `FromStr` trait that will help us parse our input.\\nThis is rather simple, I can just take the `from_snafu` function, copy-paste it\\ninto the `from_str` method and the number I get will be wrapped in `Result` and\\n`SNAFU` structure.\\n\\n#### Converting to `String`\\n\\nThis is more fun. In some cases you need to implement only one trait and others\\nare automatically implemented using that one trait. In our case, if you look in\\nthe documentation, you can see that `ToString` trait is automatically implemented\\nfor any type that implements `Display` trait.\\n\\nLet\'s implement the `Display` trait then. We should be able to use the `to_snafu`\\nfunction and just take the `self.value` from the `SNAFU` structure.\\n\\nAnd for the convenience of tests, we can also implement a rather simple `From`\\ntrait for the `SNAFU`.\\n\\n#### Adjusting the code\\n\\nAfter those changes we need to adjust the code and tests.\\n\\nParsing of the input is very easy, before we have used the lines, now we parse\\neverything:\\n\\n```diff\\n fn parse_input>(pathname: P) -> Input {\\n- file_to_lines(pathname)\\n+ file_to_structs(pathname)\\n }\\n```\\n\\nPart 1 needs to be adjusted a bit too:\\n\\n```diff\\n fn part_1(input: &Input) -> Output {\\n- to_snafu(input.iter().map(|s| from_snafu(s)).sum())\\n+ SNAFU::from(input.iter().map(|s| s.value).sum::()).to_string()\\n }\\n```\\n\\nYou can also see that it simplifies the meaning a bit and it is more explicit than\\nthe previous versions.\\n\\nAnd for the tests:\\n\\n```diff\\n #[test]\\n fn test_from() {\\n- for (n, s) in EXAMPLES.iter() {\\n- assert_eq!(from_snafu(s), *n);\\n+ for (&n, s) in EXAMPLES.iter() {\\n+ assert_eq!(s.parse::().unwrap().value, n);\\n }\\n }\\n\\n #[test]\\n fn test_to() {\\n- for (n, s) in EXAMPLES.iter() {\\n- assert_eq!(to_snafu(*n), s.to_string());\\n+ for (&n, s) in EXAMPLES.iter() {\\n+ assert_eq!(SNAFU::from(n).to_string(), s.to_string());\\n }\\n```\\n\\n## Summary\\n\\nLet\'s wrap the whole thing up! Keeping in mind both AoC and the Rust\u2026\\n\\n![Finished advent calendar :smile:](/img/blog/aoc-2022/04-week-4/calendar.png)\\n\\n### Advent of Code\\n\\nThis year was quite fun, even though most of the solutions and posts came in\\nlater on (_cough_ in \'23 _cough_). Day 22 was the most obnoxious one\u2026 And also\\nit feels like I used priority queues and tree data structures **a lot** :eyes:\\n\\n### with Rust\\n\\nI must admit that a lot of compiler warnings and errors were very useful. Even\\nthough I still found some instances where they didn\'t help at all or cause even\\nworse issues than I had. Compilation times have been addressed with the caching.\\n\\nBuilding my first tree data structure in Rust has been a very \u201cinteresting\u201d\\njourney. Being able to write a more generic BFS algorithm that allows you to not\\nduplicate code while still mantaining the desired functionality contributes to\\na very readable code.\\n\\nI am definitely much more aware of the basic things that bloated Python is\\nmissing, yet Rust has them\u2026\\n\\nUsing explicit types and writing down placeholder functions with `todo!()`\\nmacros is very pleasant, since it allows you to easily navigate the type system\\nduring the development when you don\'t even need to be sure how are you going to\\nput the smaller pieces together.\\n\\nI have used a plethora of traits and also implemented some of them to either be\\nidiomatic, or exploit the syntactic sugar they offer. Deriving the default trait\\nimplementation is also very helpful in a lot of cases, e.g. debugging output,\\ncopying, equality comparison, etc.\\n\\nI confess to touching more \u201ccursed\u201d parts of the Rust, such as macros to\\ndeclutter the copy-paste for tests or writing my own structures that need to\\ncarry a lifetime for their own fields.\\n\\ntl;dr Relatively pleasant language until you hit brick wall :wink:\\n\\n---\\n\\nSee you next year! Maybe in Rust, maybe not :upside_down_face:\\n\\n[_advent of code_]: https://adventofcode.com\\n[_a\\\\*_]: https://en.wikipedia.org/wiki/A*_search_algorithm\\n[`binaryheap`]: https://doc.rust-lang.org/std/collections/struct.BinaryHeap.html\\n[`reverse`]: https://doc.rust-lang.org/std/cmp/struct.Reverse.html\\n[docs of the `binaryheap`]: https://doc.rust-lang.org/std/collections/struct.BinaryHeap.html#min-heap"},{"id":"aoc-2022/3rd-week","metadata":{"permalink":"/blog/aoc-2022/3rd-week","editUrl":"https://github.com/mfocko/blog/tree/main/blog/aoc-2022/03-week-3.md","source":"@site/blog/aoc-2022/03-week-3.md","title":"3rd week of Advent of Code \'22 in Rust","description":"Surviving third week in Rust.","date":"2023-07-06T21:00:00.000Z","formattedDate":"July 6, 2023","tags":[{"label":"advent-of-code","permalink":"/blog/tags/advent-of-code"},{"label":"advent-of-code-2022","permalink":"/blog/tags/advent-of-code-2022"},{"label":"rust","permalink":"/blog/tags/rust"}],"readingTime":11.57,"hasTruncateMarker":true,"authors":[{"name":"Matej Focko","email":"me+blog@mfocko.xyz","title":"a.k.a. @mf","url":"https://gitlab.com/mfocko","imageURL":"https://github.com/mfocko.png","key":"mf"}],"frontMatter":{"title":"3rd week of Advent of Code \'22 in Rust","description":"Surviving third week in Rust.","date":"2023-07-06T21:00","slug":"aoc-2022/3rd-week","authors":"mf","tags":["advent-of-code","advent-of-code-2022","rust"],"hide_table_of_contents":false},"unlisted":false,"prevItem":{"title":"4th week of Advent of Code \'22 in Rust","permalink":"/blog/aoc-2022/4th-week"},"nextItem":{"title":"Sort the matrix diagonally","permalink":"/blog/leetcode/sort-diagonally"}},"content":"Let\'s go through the third week of [_Advent of Code_] in Rust.\\n\\n\x3c!--truncate--\x3e\\n\\n## [Day 15: Beacon Exclusion Zone](https://adventofcode.com/2022/day/15)\\n\\n:::info tl;dr\\n\\nTriangulating a distress beacon based on the information from the sensors.\\n\\n:::\\n\\n### Solution\\n\\nRelatively easy thing to implement, no major Rust issues hit.\\n\\n## [Day 16: Proboscidea Volcanium](https://adventofcode.com/2022/day/16)\\n\\n:::info tl;dr\\n\\nFinding a max flow in a graph given some time constraints.\\n\\n:::\\n\\n### Solution\\n\\nI have used some interesting things to implement this and make it easier for me.\\n\\n#### Indexing in graph\\n\\nI have come across a situation where I needed to keep more information regarding\\nthe graph\u2026 In that case you can, of course, create a structure and keep it in,\\nbut once you have multiple members in the structure it gets harder to work with\\nsince you need to address the fields in the structure. When you work with graph,\\nyou frequently need to access the vertices and in this case it felt a lot easier\\nto implement the indexing in a graph, rather than explicitly access the\\nunderlying data structure.\\n\\nHere you can see a rather short snippet from the solution that allows you to\\n\u201cindex\u201d the graph:\\n\\n```rust\\nimpl Index<&str> for Graph {\\n type Output = Vertex;\\n\\n fn index(&self, index: &str) -> &Self::Output {\\n &self.g[index]\\n }\\n}\\n```\\n\\n#### Cartesian product\\n\\nDuring the implementation I had to utilize Floyd-Warshall algorithm for finding\\nthe shortest path between pairs of vertices and utilized the `iproduct!` macro\\nfrom the [`itertools`]. It is a very useful higher-order function that allows\\nyou to keep the nesting of the loops at a minimum level while still maintaining\\nthe same functionality.\\n\\n#### \u201cImplementing\u201d an iterator\\n\\nFor the second part, you get to split the work between 2 actors. That way you\\ncan achieve higher efficiency of the whole process that you\'re planning, but it\\nalso makes it harder to evaluate algorithmically, since you need to check the\\ndifferent ways the work can be split.\\n\\nBeing affected by _functional programming brain damage_:tm:, I have chosen to\\ndo this part by function that returns an iterator over the possible ways:\\n\\n```rust\\nfn pairings(\\n valves: &BTreeSet,\\n) -> impl Iterator, BTreeSet)> + \'_ {\\n let mapping = valves.iter().collect_vec();\\n\\n let max_mask = 1 << (valves.len() - 1);\\n\\n (0..max_mask).map(move |mask| {\\n let mut elephant = BTreeSet::new();\\n let mut human = BTreeSet::new();\\n\\n for (i, &v) in mapping.iter().enumerate() {\\n if (mask & (1 << i)) == 0 {\\n human.insert(v.clone());\\n } else {\\n elephant.insert(v.clone());\\n }\\n }\\n\\n (human, elephant)\\n })\\n}\\n```\\n\\n## [Day 17: Pyroclastic Flow](https://adventofcode.com/2022/day/17)\\n\\n:::info tl;dr\\n\\nSimulating an autonomous Tetris where pieces get affected by a series of jets of\\nhot gas.\\n\\n:::\\n\\n### Solution\\n\\nSimilarly to the previous day I have created some iterators :smile:\\n\\n#### Collision detection\\n\\nOnce you need to check for collisions it is very helpful to be able to just\\niterate through the positions that can actually collide with the wall or other\\npiece.\\n\\nTo get the desired behaviour, you can just compose few smaller functions:\\n\\n```rust\\nfn occupied(shape: &[Vec]) -> impl Iterator + \'_ {\\n shape.iter().enumerate().flat_map(|(y, row)| {\\n row.iter().enumerate().filter_map(move |(x, c)| {\\n if c == &\'#\' {\\n Some(Vector2D::new(x as isize, y as isize))\\n } else {\\n None\\n }\\n })\\n })\\n}\\n```\\n\\nIn the end, we get relative positions which we can adjust later when given the\\nspecific positions from iterator. You can see some interesting parts in this:\\n\\n- `.enumerate()` allows us to get both the indices (coordinates) and the line\\n or, later on, the character itself,\\n- `.flat_map()` flattens the iterator, i.e. when we return another iterator,\\n they just get chained instead of iterating over iterators (which sounds pretty\\n disturbing, doesn\'t it?),\\n- and finally `.filter_map()` which is pretty similar to the \u201cbasic\u201d `.map()`\\n with a one, key, difference that it expects the items of an iterator to be\\n mapped to an `Option` from which it ignores nothing (as in `None` :wink:)\\n and also unwraps the values from `Some(\u2026)`.\\n\\n#### Infinite iterator\\n\\nIn the solution we cycle through both Tetris-like shapes that fall down and the\\njets that move our pieces around. Initially I have implemented my own infinite\\niterator that just yields the indices. It is a very simple, yet powerful, piece\\nof code:\\n\\n```rust\\nstruct InfiniteIndex {\\n size: usize,\\n i: usize,\\n}\\n\\nimpl InfiniteIndex {\\n fn new(size: usize) -> InfiniteIndex {\\n InfiniteIndex { size, i: size - 1 }\\n }\\n}\\n\\nimpl Iterator for InfiniteIndex {\\n type Item = usize;\\n\\n fn next(&mut self) -> Option {\\n self.i = (self.i + 1) % self.size;\\n Some(self.i)\\n }\\n}\\n```\\n\\nHowever when I\'m looking at the code now, it doesn\'t really make much sense\u2026\\nGuess what, we can use a built-in function that is implemented on iterators for\\nthat! The function is called `.cycle()`\\n\\nOn the other hand, I am not going to switch to that function, since it would\\nintroduce an another myriad of issues caused by the fact that I create iterators\\nright away in the constructor of my structure and the iterators would borrow\\nboth the jets and shapes which would introduce a lifetime dependency into the\\nstructure.\\n\\n## [Day 18: Boiling Boulders](https://adventofcode.com/2022/day/18)\\n\\n:::info tl;dr\\n\\nLet\'s compute a surface area of some obsidian approximated via coordinates of\\ncubes.\\n\\n:::\\n\\n### Solution\\n\\nThis day is kinda interesting, because it shows how easily you can complicate the\\nproblem and also how much can you screw yourself over with the optimization and\\n\u201csmart\u201d approach.\\n\\nFor the first part you need to find the surface area of an obsidian that is\\napproximated by cubes. Now, that is a very easy thing to do, just keep the track\\nof already added cubes, and check if the newly added cube touches any face of any\\nother cube. Simple, and with a `BTreeSet` relatively efficient way to do it.\\n\\nHowever the second part lets you on a secret that there may be some surface area\\nfrom the \u201cinside\u201d too and you want to know only the one from the outside of the\\nobsidian. I have seen some solutions later, but if you check your data, you might\\nnotice that the bounding box of all the cubes isn\'t that big at all. Therefore I\\nchose to pre-construct the box beforehand, fill in the cubes and then just run a\\nBFS turning all the lava on the outside into the air. Now you just need to check\\ncubes and count how many of their faces touch the air.\\n\\n## [Day 19: Not Enough Minerals](https://adventofcode.com/2022/day/19)\\n\\n:::info tl;dr\\n\\nFinding out the best strategy for building robots to collect geodes.\\n\\n:::\\n\\n### Solution\\n\\nNot much interesting stuff to mention apart from the suggestion to never believe\\nthat the default implementation given by `derive` macro is what you want, it\\ndoesn\'t have to be. :smile:\\n\\n## [Day 20: Grove Positioning System](https://adventofcode.com/2022/day/20)\\n\\n:::info tl;dr\\n\\nShuffling around the _circular linked list_ to find the coordinates.\\n\\n:::\\n\\nNow, small rant for this day is in place. They\'ve never mentioned that coordinates\\ncan repeat and therefore the values are non-unique. This is something that did\\nnot happen in the given sample, but was present in the user input. It took \xbba lot\xab\\nto realize that this is the issue.\\n\\n### Solution\\n\\nI have tried implementing a circular linked list for this\u2026 and I have failed\\nmiserably. To be fair, I still have no clue why. It was \u201cfun\u201d to play around with\\nthe `Rc>`. In the end I failed on _wrong answer_. I have also encountered\\na rather interesting issue with `.borrow_mut()` method being used on `Rc>`.\\n\\n#### `.borrow_mut()`\\n\\nConsider the following snippet of the code (taken from the documentation):\\n\\n```rust\\nuse std::cell::{RefCell, RefMut};\\nuse std::collections::HashMap;\\nuse std::rc::Rc;\\n// use std::borrow::BorrowMut;\\n\\nfn main() {\\n let shared_map: Rc> = Rc::new(RefCell::new(HashMap::new()));\\n // Create a new block to limit the scope of the dynamic borrow\\n {\\n let mut map: RefMut<_> = shared_map.borrow_mut();\\n map.insert(\\"africa\\", 92388);\\n map.insert(\\"kyoto\\", 11837);\\n map.insert(\\"piccadilly\\", 11826);\\n map.insert(\\"marbles\\", 38);\\n }\\n\\n // Note that if we had not let the previous borrow of the cache fall out\\n // of scope then the subsequent borrow would cause a dynamic thread panic.\\n // This is the major hazard of using `RefCell`.\\n let total: i32 = shared_map.borrow().values().sum();\\n println!(\\"{total}\\");\\n}\\n```\\n\\nWe allocate a hash map on the heap and then in the inner block, we borrow it as\\na mutable reference, so that we can use it.\\n\\n:::note\\n\\nIt is a very primitive example for `Rc>` and mutable borrow.\\n\\n:::\\n\\nIf you uncomment the 4th line with `use std::borrow::BorrowMut;`, you cannot\\ncompile the code anymore, because of\\n\\n```\\n Compiling playground v0.0.1 (/playground)\\nerror[E0308]: mismatched types\\n --\x3e src/main.rs:10:34\\n |\\n10 | let mut map: RefMut<_> = shared_map.borrow_mut();\\n | --------- ^^^^^^^^^^^^^^^^^^^^^^^ expected struct `RefMut`, found mutable reference\\n | |\\n | expected due to this\\n |\\n = note: expected struct `RefMut<\'_, _>`\\n found mutable reference `&mut Rc>>`\\n\\nerror[E0599]: no method named `insert` found for struct `RefMut<\'_, _>` in the current scope\\n --\x3e src/main.rs:11:13\\n |\\n11 | map.insert(\\"africa\\", 92388);\\n | ^^^^^^ method not found in `RefMut<\'_, _>`\\n\\nerror[E0599]: no method named `insert` found for struct `RefMut<\'_, _>` in the current scope\\n --\x3e src/main.rs:12:13\\n |\\n12 | map.insert(\\"kyoto\\", 11837);\\n | ^^^^^^ method not found in `RefMut<\'_, _>`\\n\\nerror[E0599]: no method named `insert` found for struct `RefMut<\'_, _>` in the current scope\\n --\x3e src/main.rs:13:13\\n |\\n13 | map.insert(\\"piccadilly\\", 11826);\\n | ^^^^^^ method not found in `RefMut<\'_, _>`\\n\\nerror[E0599]: no method named `insert` found for struct `RefMut<\'_, _>` in the current scope\\n --\x3e src/main.rs:14:13\\n |\\n14 | map.insert(\\"marbles\\", 38);\\n | ^^^^^^ method not found in `RefMut<\'_, _>`\\n\\nSome errors have detailed explanations: E0308, E0599.\\nFor more information about an error, try `rustc --explain E0308`.\\nerror: could not compile `playground` due to 5 previous errors\\n```\\n\\nIt might seem **a bit** ridiculous. However, I got to a point where the compiler\\nsuggested `use std::borrow::BorrowMut;` and it resulted in breaking parts of the\\ncode that worked previously. I think it may be a good idea to go over what is\\nhappening here.\\n\\n##### `.borrow_mut()` on `Rc>`\\n\\nLet\'s consider a variable `x` of type `Rc>`. What happens when you\\ncall `.borrow_mut()` on it? We can look at the `Rc` type, and\u2026 hang on! There is\\nneither `.borrow_mut()` method or `BorrowMut` trait implemented. How can we do it\\nthen?\\n\\nLet\'s go further and we can see that `RefCell` implements a `.borrow_mut()`\\nmethod. OK, but how can we call it on the `Rc`? Easily! `Rc` implements\\n`Deref` and therefore you can call methods on `Rc` objects as if they were\\n`T` objects. If we read on _`Deref` coercion_, we can see the following:\\n\\n> If `T` implements `Deref`, \u2026:\\n>\\n> - \u2026\\n> - `T` implicitly implements all the (immutable) methods of the type `U`.\\n\\nWhat is the requirement for the `.borrow_mut()` on `RefCell`? Well, it needs\\n`&self`, so the `Deref` implements the `.borrow_mut()` for the `Rc>`.\\n\\n##### `BorrowMut` trait\\n\\nI have not been able to find a lot on this trait. My guess is that it provides a\\nmethod instead of a syntactic sugar (`&mut x`) for the mutable borrow. And also\\nit provides default implementations for the types:\\n\\n```rust\\nimpl BorrowMut for String\\n\\nimpl BorrowMut for &mut T\\nwhere\\n T: ?Sized,\\n\\nimpl BorrowMut for T\\nwhere\\n T: ?Sized,\\n\\nimpl BorrowMut<[T]> for Vec\\nwhere\\n A: Allocator,\\n\\nimpl BorrowMut for Box\\nwhere\\n A: Allocator,\\n T: ?Sized,\\n\\nimpl BorrowMut<[T]> for [T; N]\\n```\\n\\n##### Conflict\\n\\nNow the question is why did it break the code\u2026 My first take was that the type\\n`Rc>` has some _specialized_ implementation of the `.borrow_mut()` and\\nthe `use` overrides it with the default, which is true **in a sense**. However\\nthere is no _specialized_ implementation. Let\'s have a look at the trait and the\\ntype signature on the `RefCell`:\\n\\n```rust\\n// trait\\npub trait BorrowMut: Borrow\\nwhere\\n Borrowed: ?Sized,\\n{\\n fn borrow_mut(&mut self) -> &mut Borrowed;\\n}\\n\\n// \u2039RefCell.borrow_mut()\u203a type signature\\npub fn borrow_mut(&self) -> RefMut<\'_, T>\\n```\\n\\nI think that we can definitely agree on the fact that `RefMut<\'_, T>` is not the\\n`RefCell`.\\n\\n**In my opinion**, `RefCell` implements a **separate** `.borrow_mut()` rather\\nthan implementing the interface, because it **cannot** satisfy the type requirements\\nof the trait.\\n\\n:::warning[caution]\\n\\nI wonder how are we expected to deal with this conflict, if and when, we need\\nboth the `.borrow_mut()` of the trait and `.borrow_mut()` of the `RefCell`.\\n\\n:::\\n\\n:::tip Fun fact\\n\\nI was suggested by the compiler to do `use std::borrow::BorrowMut;` and break the\\ncode.\\n\\nSo much for the _almighty_ and _helpful_ compiler\u2026\\n\\n:::\\n\\n## [Day 21: Monkey Math](https://adventofcode.com/2022/day/21)\\n\\n:::info tl;dr\\n\\nComputing an expression tree and then also finding ideal value for a node.\\n\\n:::\\n\\n### Solution\\n\\nRelatively simple, until you get to the 2nd part where you start to practice\\na lot of the copy-paste. I have managed to sneak some perverted stuff in there\\nthough :) Let\'s go through the details.\\n\\n#### `Default` trait\\n\\nFor the first time and twice I had a need to have a default value for my types,\\nenumerations in this case. Rust offers a very nice trait[^1] that is described\\nas:\\n\\n> A trait for giving a type a useful default value.\\n\\nI guess it sums it up nicely. The more interesting part about this is the fact\\nthat you can use the _macro machinery_ to save yourself some typing. If you have\\nenumeration of which the default value doesn\'t bear any parameter, you can just\\ndo[^2]:\\n\\n```rust\\n#[derive(Default)]\\nenum Color {\\n #[default]\\n White,\\n Gray,\\n Black,\\n}\\n```\\n\\n#### Abusing negation\\n\\nIf you want to use a _unary minus_ operator on your own type, you can implement\\na `Neg` trait[^3]. I was dealing with a binary tree and needed a way how to look\\nat the other side, so I have just implemented the negation for flipping between\\nleft and right :smile:\\n\\n[^1]: [`Default`](https://doc.rust-lang.org/std/default/trait.Default.html) docs\\n[^2]: Pardon my example from the graph algorithms ;)\\n[^3]: [`Neg`](https://doc.rust-lang.org/std/ops/trait.Neg.html) docs\\n\\n[_advent of code_]: https://adventofcode.com\\n[`itertools`]: https://crates.io/crates/itertools\\n[this reddit post and the comment]: https://www.reddit.com/r/adventofcode/comments/zb98pn/comment/iyq0ono"},{"id":"leetcode/sort-diagonally","metadata":{"permalink":"/blog/leetcode/sort-diagonally","editUrl":"https://github.com/mfocko/blog/tree/main/blog/leetcode/sort-matrix-diagonally.md","source":"@site/blog/leetcode/sort-matrix-diagonally.md","title":"Sort the matrix diagonally","description":"Compiler assisted development.","date":"2023-03-04T23:15:00.000Z","formattedDate":"March 4, 2023","tags":[{"label":"cpp","permalink":"/blog/tags/cpp"},{"label":"leetcode","permalink":"/blog/tags/leetcode"},{"label":"iterators","permalink":"/blog/tags/iterators"}],"readingTime":16.99,"hasTruncateMarker":true,"authors":[{"name":"Matej Focko","email":"me+blog@mfocko.xyz","title":"a.k.a. @mf","url":"https://gitlab.com/mfocko","imageURL":"https://github.com/mfocko.png","key":"mf"}],"frontMatter":{"title":"Sort the matrix diagonally","description":"Compiler assisted development.","date":"2023-03-04T23:15","slug":"leetcode/sort-diagonally","authors":"mf","tags":["cpp","leetcode","iterators"],"hide_table_of_contents":false},"unlisted":false,"prevItem":{"title":"3rd week of Advent of Code \'22 in Rust","permalink":"/blog/aoc-2022/3rd-week"},"nextItem":{"title":"2nd week of Advent of Code \'22 in Rust","permalink":"/blog/aoc-2022/2nd-week"}},"content":"Let\'s try to solve one of the LeetCode challenges in easy and hard mode at the\\nsame time.\\n\\n\x3c!--truncate--\x3e\\n\\n- Link to the problem: https://leetcode.com/problems/sort-the-matrix-diagonally/\\n\\n## Problem description\\n\\nA **matrix diagonal** is a diagonal line of cells starting from some cell in\\neither the topmost row or leftmost column and going in the bottom-right direction\\nuntil reaching the matrix\'s end. For example, the **matrix diagonal** starting\\nfrom `mat[2][0]`, where `mat` is a `6 x 3` matrix, includes cells `mat[2][0]`,\\n`mat[3][1]`, and `mat[4][2]`.\\n\\nGiven an `m x n` matrix `mat` of integers, sort each matrix diagonal in ascending\\norder and return the resulting matrix.\\n\\n### Example\\n\\n![Image describing the problem](https://assets.leetcode.com/uploads/2020/01/21/1482_example_1_2.png)\\n\\n## Skeleton and initial adjustments\\n\\nWe are given the following skeleton for the C++ and the given challenge:\\n\\n```cpp\\nclass Solution {\\npublic:\\n vector> diagonalSort(vector>& mat) {\\n\\n }\\n};\\n```\\n\\nThe task is to sort the passed matrix diagonally and then return it. First of all,\\nI don\'t like to solve this in a web browser, so we\'ll need to adjust it accordingly\\nfor running it locally. We\'ll start by including the `vector` header and using\\nfully-qualified namespaces[^1] and also adding few tests:\\n\\n```cpp\\n#include \\n#include \\n\\nusing matrix = std::vector>;\\n\\nclass Solution {\\npublic:\\n matrix diagonalSort(matrix& mat)\\n {\\n }\\n};\\n\\nstatic void test_case_1()\\n{\\n // Input: mat = [[3,3,1,1],[2,2,1,2],[1,1,1,2]]\\n // Output: [[1,1,1,1],[1,2,2,2],[1,2,3,3]]\\n\\n Solution s;\\n assert((s.diagonalSort(std::vector { std::vector { 3, 3, 1, 1 },\\n std::vector { 2, 2, 1, 2 },\\n std::vector { 1, 1, 1, 2 } })\\n == std::vector { std::vector { 1, 1, 1, 1 },\\n std::vector { 1, 2, 2, 2 },\\n std::vector { 1, 2, 3, 3 } }));\\n}\\n\\nstatic void test_case_2()\\n{\\n // Input: mat =\\n // [[11,25,66,1,69,7],[23,55,17,45,15,52],[75,31,36,44,58,8],[22,27,33,25,68,4],[84,28,14,11,5,50]]\\n // Output:\\n // [[5,17,4,1,52,7],[11,11,25,45,8,69],[14,23,25,44,58,15],[22,27,31,36,50,66],[84,28,75,33,55,68]]\\n\\n Solution s;\\n assert((s.diagonalSort(std::vector { std::vector { 11, 25, 66, 1, 69, 7 },\\n std::vector { 23, 55, 17, 45, 15, 52 },\\n std::vector { 75, 31, 36, 44, 58, 8 },\\n std::vector { 22, 27, 33, 25, 68, 4 },\\n std::vector { 84, 28, 14, 11, 5, 50 } })\\n == std::vector { std::vector { 5, 17, 4, 1, 52, 7 },\\n std::vector { 11, 11, 25, 45, 8, 69 },\\n std::vector { 14, 23, 25, 44, 58, 15 },\\n std::vector { 22, 27, 31, 36, 50, 66 },\\n std::vector { 84, 28, 75, 33, 55, 68 } }));\\n}\\n\\nint main()\\n{\\n test_case_1();\\n test_case_2();\\n\\n return 0;\\n}\\n```\\n\\nWe need to return the matrix, but we\'re given a reference to the input matrix. We\\ncan easily abuse the C++ here and just switch the reference to value, this way\\nthe matrix will be copied when passed to the function, we can sort the copy and\\njust return it back. And we also get yelled by the compiler for the fact that the\\nmethod doesn\'t return anything yet, so to make it \u201cshut up\u201d we will just return\\nthe input for now:\\n\\n```diff\\n- matrix diagonalSort(matrix& mat)\\n+ matrix diagonalSort(matrix mat)\\n {\\n+ return mat;\\n }\\n```\\n\\nNow, we get the copy and we\'re good to go.\\n\\n## Na\xefve solution\\n\\nAs you may know, C++ offers a plethora of functions that can be used to your\\nadvantage, given that you know how to \u201cbend\u201d the data structures accordingly.\\n\\nWhat does that mean for us? Well, we have an `std::sort`, we can use it, right?\\nLet\'s have a look at it:\\n\\n```cpp\\ntemplate< class RandomIt >\\nvoid sort( RandomIt first, RandomIt last );\\n```\\n\\nThis overload is more than we need. What does it do? It just sorts the elements\\nin the range `[first, last)` using `operator<` on them. We can\'t sort the whole\\nmatrix using this, but\u2026 we can sort just \xbbone\xab diagonal without doing much work\\non our end.\\n\\nWhat is the `RandomIt` type though? If we look more into the documentation, we\\ncan easily find the requirements for it and also learn that it\'s a _random access_\\n_iterator_ and allows swapping its values at the same time.\\n\\n:::tip Random access iterator\\n\\nWhat is the _random access iterator_ though? We can find it in a documentation\\nand see the following description:\\n\\n> A **LegacyRandomAccessIterator** is a [LegacyBidirectionalIterator](https://en.cppreference.com/w/cpp/named_req/BidirectionalIterator)\\n> that can be moved to point to any element in constant time.\\n\\nAfter that we can see all the requirements for it being listed. I don\'t feel like\\nreading them right now, so we will just use it and see where the compilation blows\\nup, i.e. \u201c_compiler-assisted development_\u201d[^2] if you will ;)\\n\\n:::\\n\\nNow we know that we can use `std::sort` to sort the diagonal itself, but we also\\nneed to get the diagonals somehow. I\'m rather lazy, so I\'ll just delegate it to\\nsomeone else[^3]. And that way we get\\n\\n```cpp\\nmatrix diagonalSort(matrix mat)\\n{\\n // we iterate over the diagonals\\n for (auto d : diagonals(mat)) {\\n // and we sort each diagonal\\n std::sort(d.begin(), d.end());\\n }\\n\\n // we take the matrix by copy, so we can sort in-situ and return the copy\\n // that we sorted\\n return mat;\\n}\\n```\\n\\nThis solution looks very simple, doesn\'t it? Well, cause it is.\\nLet\'s try compiling it:\\n\\n```\\nmatrix-sort.cpp:11:23: error: use of undeclared identifier \'diagonals\' [clang-diagnostic-error]\\n for (auto d : diagonals(mat)) {\\n ^\\nFound compiler error(s).\\nmake: *** [makefile:14: tidy] Error 1\\n```\\n\\nOK, seems about right. We haven\'t implemented the `diagonals` yet. And based on\\nwhat we\'ve written so far, we need a function or a class `diagonals` that will\\ngive us the diagonals we need.\\n\\n## Implementing the `diagonals`\\n\\nCool, so we need the function that will let us go through each and every diagonal\\nin our matrix. We use the _for-range_ loop, so whatever we get back from the\\n`diagonals` must support `.begin()` and `.end()`. Since I am a masochist, we will\\ndo such functionality for a matrix of any type, not just the `int` from the challenge.\\n\\nAs I said, we need to be able to\\n\\n- construct the object\\n- get the beginning\\n- get the end (the \u201csentinel\u201d)\\n\\n```cpp\\ntemplate \\nclass diagonals {\\n using matrix_t = std::vector>;\\n\\n matrix_t& _matrix;\\n\\npublic:\\n diagonals(matrix_t& m)\\n : _matrix(m)\\n {\\n }\\n diagonals_iter begin()\\n {\\n /* TODO */\\n }\\n diagonals_iter end()\\n {\\n /* TODO */\\n }\\n};\\n```\\n\\nNow we have a `diagonals` that we can use to go through the diagonals. We haven\'t\\nimplemented the core of it yet. Let\'s go through what we have for now.\\n\\nWe have a templated class with templated `T` that is used as a placeholder for any\\ntype we would store in the matrix. Because I\'m lazy, I have defined the `matrix_t`\\ntype that is a \u201cshortcut\u201d for `std::vector>`, so I don\'t have to\\ntype it out all the time. Of course, we need to store the matrix, we are given,\\nas a private attribute. And then just have the constructor and the 2 methods we\\nneed for the _for-range_.\\n\\n### Iterating over diagonals\\n\\nNow that we have an object that will allow us to iterate through the diagonals,\\nwe need to implement the iterating itself. We need to go through all of them, so\\nwe have multiple options how to do so. I have decided to start from the \u201cmain\u201d\\ndiagonal that starts at `(0, 0)` index and then proceed with the diagonals starting\\nin the first row, followed by the rest of the diagonals in the first column.\\n\\nWe need to be able to tell that we\'ve iterated through all of them, and also we\\nneed to know which diagonal is next. For that purpose we will pass the indices\\nof the first cell on the diagonal. That way we can always tell how to move forward.\\n\\nWe will start by updating the `begin` and `end` to reflect our choice accordingly.\\n\\n```cpp\\ndiagonals_iter begin() { return diagonals_iter { _matrix, 0, 0 }; }\\ndiagonals_iter end() { return diagonals_iter { _matrix, 0, _matrix.size() }; }\\n```\\n\\nFor the `begin` we return the first diagonal that starts at `(0, 0)`. And because\\nwe have decided to do the diagonals in the first column at the end, the first\\ndiagonal that is not a valid one is the one at `(0, height)`. Apart from the\\nindices, we also need to pass reference to the matrix itself.\\n\\n:::note\\n\\nYou may have noticed that we also include the diagonals that have length 1,\\nspecifically the ones at `(0, height - 1)` and `(width - 1, 0)`. We are implementing\\nan iterator that **should not** care about the way it\'s being used. Therefore, we\\ndon\'t care about the fact they don\'t need to be sorted.\\n\\n:::\\n\\nCool, let\'s leave the iterator itself to someone else, right?[^4]\\n\\n### Implementing the iterator over diagonals\\n\\nWe can start with a simple skeleton based on the information that we pass from\\nthe `diagonals`. Also to utilize the `matrix_t` and also contain implementation\\ndetails hidden away, we will put this code into the `diagonals` class.\\n\\n```cpp\\nclass diagonals_iter {\\n matrix_t& m;\\n std::size_t x;\\n std::size_t y;\\n\\npublic:\\n diagonals_iter(matrix_t& matrix, std::size_t x, std::size_t y)\\n : m(matrix)\\n , x(x)\\n , y(y)\\n {\\n }\\n};\\n```\\n\\nIn this case we will be implementing a \u201csimple\u201d forward iterator, so we don\'t\\nneed to implement a lot. Notably it will be:\\n\\n- inequality operator (we need to know when we reach the end and have nothing to\\n iterate over)\\n- preincrementation operator (we need to be able to move around the iterable)\\n- dereference operator (we need to be able to retrieve the objects we iterate\\n over)\\n\\n```cpp\\nclass diagonals_iter {\\n matrix_t& m;\\n std::size_t x;\\n std::size_t y;\\n\\npublic:\\n diagonals_iter(matrix_t& matrix, std::size_t x, std::size_t y)\\n : m(matrix)\\n , x(x)\\n , y(y)\\n {\\n }\\n\\n bool operator!=(const diagonals_iter& rhs) const\\n {\\n // iterators are not equal if they reference different matrices, or\\n // their positions differ\\n return m != rhs.m || x != rhs.x || y != rhs.y;\\n }\\n\\n diagonals_iter& operator++()\\n {\\n if (y != 0) {\\n // iterating through diagonals down the first column\\n y++;\\n return *this;\\n }\\n\\n // iterating the diagonals along the first row\\n x++;\\n if (x == m.front().size()) {\\n // switching to diagonals in the first column\\n x = 0;\\n y++;\\n }\\n\\n return *this;\\n }\\n\\n diagonal operator*() const { return diagonal { m, x, y }; }\\n};\\n```\\n\\nLet\'s go one-by-one. Inequality operator is rather simple, just compare iterator\'s\\nattributes field-by-field. If you think about it, checking inequality of two 2D\\nvectors may be a bit inefficient, therefore, we can swap around and check it as\\na last thing.\\n\\n```diff\\n- return m != rhs.m || x != rhs.x || y != rhs.y;\\n+ return x != rhs.x || y != rhs.y || m != rhs.m;\\n```\\n\\nPreincrementation is where the magic happens. If you have a better look, you can\\nsee two branches of this operation:\\n\\n1. When `y != 0` (we\'re iterating over the diagonals in the first column)\\n In this case, we just bump the row and we\'re done.\\n2. When `y == 0` (we\'re iterating over the diagonals in the first row)\\n In this case, we bump the column and check if we haven\'t gotten out of bounds,\\n i.e. the end of the first row. If we get out of the bounds, we\'re continuing\\n with the second diagonal in the first column.\\n\\nDereferencing the iterator must \u201cyield\u201d something. In our case it will be the\\ndiagonal that we want to sort. For sorting we need just the iterators that can\\nmove around said diagonal. The simplest thing, we can do, is to delegate it to\\nsomething else. In our case it will be a class called `diagonal`.\\n\\n## Implementing the `diagonal` itself\\n\\nAfter implementing the iterator over diagonals, we know that all we need to describe\\na diagonal is the matrix itself and the \u201cstart\u201d of the diagonal (row and column).\\nAnd we also know that the diagonal must provide some iterators for the `std::sort`\\nfunction. We can start with the following skeleton:\\n\\n```cpp\\ntemplate \\nclass diagonal {\\n using matrix_t = std::vector>;\\n\\n matrix_t& matrix;\\n std::size_t x;\\n std::size_t y;\\n\\npublic:\\n diagonal(matrix_t& matrix, std::size_t x, std::size_t y)\\n : matrix(matrix)\\n , x(x)\\n , y(y)\\n {\\n }\\n\\n diagonal_iter begin() const { return diagonal_iter { matrix, x, y }; }\\n\\n diagonal_iter end() const\\n {\\n auto max_x = matrix[y].size();\\n auto max_y = matrix.size();\\n\\n // we need to find the distance in which we get out of bounds (either in\\n // column or row)\\n auto steps = std::min(max_x - x, max_y - y);\\n\\n return diagonal_iter { matrix, x + steps, y + steps };\\n }\\n};\\n```\\n\\nInitialization is rather simple, we just \u201ckeep\u201d the stuff we get, `begin` is the\\nsimplest, we just delegate.\\n\\nIn case of the `end`, it gets more complicated. We need to know where is the \u201cend\u201d\\nof the diagonal. Since `end` should point to the first element \u201cafter\u201d the iterable,\\nwe know that it\'s the first position of the iterator where either `y` becomes\\n`matrix.size()` or `x` becomes `matrix[y].size()`. Also we are moving along diagonal,\\nduh, therefore we can deduce the first \u201cposition\u201d afterwards by minimal amount of\\nsteps to get out of the any column or row, hence `std::min(max_x - x, max_y - y)`.\\nFinal position is then computed simply by adding the steps to the beginning of\\nthe diagonal.\\n\\nNow we just need to finish the iterator for the diagonal itself and we\'re done.\\n\\n### Implementing `diagonal_iter`\\n\\nThis part is the hardest from all we need to do. It\'s because of the requirements\\nof the `std::sort` that requires us to implement a _random access iterator_. I have\\nbriefly described it above, and \u201cin a nutshell\u201d it means that we need to implement\\nan iterator that can move in constant time along the diagonal in any amount of\\nsteps.\\n\\nLet\'s go through all of the functionality that our iterator needs to support to\\nbe used in `std::sort`. We need the usual operations like:\\n\\n- equality/inequality\\n- incrementation\\n- dereferencing\\n\\nWe will also add all the types that our iterator uses with the category of the\\niterator, i.e. what interface it supports:\\n\\n```cpp\\nclass diagonal_iter {\\n // we need to keep reference to the matrix itself\\n matrix_t& m;\\n\\n // we need to be able to tell our current position\\n std::size_t x;\\n std::size_t y;\\n\\npublic:\\n using difference_type = std::ptrdiff_t;\\n using value_type = T;\\n using pointer = T*;\\n using reference = T&;\\n using iterator_category = std::random_access_iterator_tag;\\n\\n diagonal_iter(matrix_t& matrix,\\n std::size_t x,\\n std::size_t y)\\n : m(matrix)\\n , x(x)\\n , y(y)\\n {\\n }\\n\\n bool operator==(const diagonal_iter& rhs) const\\n {\\n return x == rhs.x && y == rhs.y && m == rhs.m;\\n }\\n\\n diagonal_iter& operator++()\\n {\\n // we are moving along the diagonal, so we increment both \u2039x\u203a and \u2039y\u203a at\\n // the same time\\n x++;\\n y++;\\n return *this;\\n }\\n\\n reference operator*() const { return m[y][x]; }\\n};\\n```\\n\\nThis is pretty similar to the previous iterator, but now we need to implement the\\nremaining requirements of the _random access iterator_. Let\'s see what those are:\\n\\n- decrementation - cause we need to be able to move backwards too, since _random _\\n _access iterator_ extends the interface of _bidirectional iterator_\\n- moving the iterator in either direction by steps given as an integer\\n- being able to tell the distance between two iterators\\n- define an ordering on the iterators\\n\\nLet\'s fill them in:\\n\\n```cpp\\nclass diagonal_iter {\\n // we need to keep reference to the matrix itself\\n matrix_t& m;\\n\\n // we need to be able to tell our current position\\n std::size_t x;\\n std::size_t y;\\n\\npublic:\\n using difference_type = std::ptrdiff_t;\\n using value_type = T;\\n using pointer = T*;\\n using reference = T&;\\n using iterator_category = std::random_access_iterator_tag;\\n\\n diagonal_iter(matrix_t& matrix,\\n std::size_t x,\\n std::size_t y)\\n : m(matrix)\\n , x(x)\\n , y(y)\\n {\\n }\\n\\n bool operator==(const diagonal_iter& rhs) const\\n {\\n return x == rhs.x && y == rhs.y && m == rhs.m;\\n }\\n\\n diagonal_iter& operator++()\\n {\\n // we are moving along the diagonal, so we increment both \u2039x\u203a and \u2039y\u203a at\\n // the same time\\n x++;\\n y++;\\n return *this;\\n }\\n\\n reference operator*() const { return m[y][x]; }\\n\\n // exactly opposite to the incrementation\\n diagonal_iter operator--()\\n {\\n x--;\\n y--;\\n return *this;\\n }\\n\\n // moving \u2039n\u203a steps back is same as calling decrementation \u2039n\u203a-times, so we\\n // can just return a new iterator and subtract \u2039n\u203a from both coordinates in\\n // the matrix\\n diagonal_iter operator-(difference_type n) const\\n {\\n return diagonal_iter { m, x - n, y - n };\\n }\\n\\n // here we assume that we are given two iterators on the same diagonal\\n difference_type operator-(const diagonal_iter& rhs) const\\n {\\n assert(m == rhs.m);\\n return x - rhs.x;\\n }\\n\\n // counterpart of moving \u2039n\u203a steps backwards\\n diagonal_iter operator+(difference_type n) const\\n {\\n return diagonal_iter { m, x + n, y + n };\\n }\\n\\n // we compare the coordinates, and also assume that those 2 iterators are\\n // lying on the same diagonal\\n bool operator<(const diagonal_iter& rhs) const\\n {\\n assert(m == rhs.m);\\n return x < rhs.x && y < rhs.y;\\n }\\n};\\n```\\n\\nAt this point we could probably try and compile it, right? If we do so, we will\\nget yelled at by a compiler for the following reasons:\\n\\n```\\n/usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/bits/stl_algo.h:1792:11: error: object of type \'diagonal::diagonal_iter\' cannot be assigned because its copy assignment operator is implicitly deleted [clang-diagnostic-error]\\n __last = __next;\\n ^\\n/usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/bits/stl_algo.h:1817:11: note: in instantiation of function template specialization \'std::__unguarded_linear_insert::diagonal_iter, __gnu_cxx::__ops::_Val_less_iter>\' requested here\\n std::__unguarded_linear_insert(__i,\\n ^\\n/usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/bits/stl_algo.h:1849:9: note: in instantiation of function template specialization \'std::__insertion_sort::diagonal_iter, __gnu_cxx::__ops::_Iter_less_iter>\' requested here\\n std::__insertion_sort(__first, __first + int(_S_threshold), __comp);\\n ^\\n/usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/bits/stl_algo.h:1940:9: note: in instantiation of function template specialization \'std::__final_insertion_sort::diagonal_iter, __gnu_cxx::__ops::_Iter_less_iter>\' requested here\\n std::__final_insertion_sort(__first, __last, __comp);\\n ^\\n/usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/bits/stl_algo.h:4820:12: note: in instantiation of function template specialization \'std::__sort::diagonal_iter, __gnu_cxx::__ops::_Iter_less_iter>\' requested here\\n std::__sort(__first, __last, __gnu_cxx::__ops::__iter_less_iter());\\n ^\\nmatrix-sort.cpp:161:18: note: in instantiation of function template specialization \'std::sort::diagonal_iter>\' requested here\\n std::sort(d.begin(), d.end());\\n ^\\nmatrix-sort.cpp:17:19: note: copy assignment operator of \'diagonal_iter\' is implicitly deleted because field \'m\' is of reference type \'diagonal::matrix_t &\' (aka \'vector> &\')\\n matrix_t& m;\\n ^\\n/usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/bits/stl_algo.h:1830:2: error: no matching function for call to \'__unguarded_linear_insert\' [clang-diagnostic-error]\\n std::__unguarded_linear_insert(__i,\\n ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\\n/usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/bits/stl_algo.h:1850:9: note: in instantiation of function template specialization \'std::__unguarded_insertion_sort::diagonal_iter, __gnu_cxx::__ops::_Iter_less_iter>\' requested here\\n std::__unguarded_insertion_sort(__first + int(_S_threshold), __last,\\n ^\\n/usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/bits/stl_algo.h:1940:9: note: in instantiation of function template specialization \'std::__final_insertion_sort::diagonal_iter, __gnu_cxx::__ops::_Iter_less_iter>\' requested here\\n std::__final_insertion_sort(__first, __last, __comp);\\n ^\\n/usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/bits/stl_algo.h:4820:12: note: in instantiation of function template specialization \'std::__sort::diagonal_iter, __gnu_cxx::__ops::_Iter_less_iter>\' requested here\\n std::__sort(__first, __last, __gnu_cxx::__ops::__iter_less_iter());\\n ^\\nmatrix-sort.cpp:161:18: note: in instantiation of function template specialization \'std::sort::diagonal_iter>\' requested here\\n std::sort(d.begin(), d.end());\\n ^\\n/usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/bits/stl_algo.h:1782:5: note: candidate template ignored: substitution failure [with _RandomAccessIterator = diagonal::diagonal_iter, _Compare = __gnu_cxx::__ops::_Val_less_iter]\\n __unguarded_linear_insert(_RandomAccessIterator __last,\\n ^\\n/usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/bits/stl_algo.h:1923:11: error: object of type \'diagonal::diagonal_iter\' cannot be assigned because its copy assignment operator is implicitly deleted [clang-diagnostic-error]\\n __last = __cut;\\n ^\\n/usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/bits/stl_algo.h:1937:9: note: in instantiation of function template specialization \'std::__introsort_loop::diagonal_iter, long, __gnu_cxx::__ops::_Iter_less_iter>\' requested here\\n std::__introsort_loop(__first, __last,\\n ^\\n/usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/bits/stl_algo.h:4820:12: note: in instantiation of function template specialization \'std::__sort::diagonal_iter, __gnu_cxx::__ops::_Iter_less_iter>\' requested here\\n std::__sort(__first, __last, __gnu_cxx::__ops::__iter_less_iter());\\n ^\\nmatrix-sort.cpp:161:18: note: in instantiation of function template specialization \'std::sort::diagonal_iter>\' requested here\\n std::sort(d.begin(), d.end());\\n ^\\nmatrix-sort.cpp:17:19: note: copy assignment operator of \'diagonal_iter\' is implicitly deleted because field \'m\' is of reference type \'diagonal::matrix_t &\' (aka \'vector> &\')\\n matrix_t& m;\\n ^\\n```\\n\\nThat\'s a lot of noise, isn\'t it? Let\'s focus on the important parts:\\n\\n```\\n/usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/bits/stl_algo.h:1792:11: error: object of type \'diagonal::diagonal_iter\' cannot be assigned because its copy assignment operator is implicitly deleted [clang-diagnostic-error]\\n\u2026\\nmatrix-sort.cpp:17:19: note: copy assignment operator of \'diagonal_iter\' is implicitly deleted because field \'m\' is of reference type \'diagonal::matrix_t &\' (aka \'vector> &\')\\n matrix_t& m;\\n ^\\n```\\n\\nAh! We have a reference in our iterator, and this prevents us from having a copy\\nassignment operator (that is used \u201csomewhere\u201d in the sorting algorithm). Well\u2026\\nLet\'s just wrap it!\\n\\n```diff\\n# we need to keep a different type than reference\\n- matrix_t& m;\\n+ std::reference_wrapper m;\\n\\n# in comparison we need to get the reference out of the wrapper first\\n- return x == rhs.x && y == rhs.y && m == rhs.m;\\n+ return x == rhs.x && y == rhs.y && m.get() == rhs.m.get();\\n\\n# same when we return a reference to the \u201ccell\u201d in the matrix\\n- reference operator*() const { return m[y][x]; }\\n+ reference operator*() const { return m.get()[y][x]; }\\n\\n# and finally in the assertions that we set for the \u201cdistance\u201d and \u201cless than\u201d\\n- assert(m == rhs.m);\\n+ assert(m.get() == rhs.m.get());\\n```\\n\\nWe\'re done now! We have written an iterator over diagonals for a 2D `vector`. You can have a look at the final result [here](pathname:///files/blog/leetcode/sort-matrix-diagonally/matrix-sort.cpp).\\n\\n[^1]: just because I\'m used to it and don\'t care about your opinion ;)\\n[^2]: exercise at your own risk\\n[^3]: me in 5 minutes in fact, but don\'t make me scared\\n[^4]: me in the next section\u2026"},{"id":"aoc-2022/2nd-week","metadata":{"permalink":"/blog/aoc-2022/2nd-week","editUrl":"https://github.com/mfocko/blog/tree/main/blog/aoc-2022/02-week-2.md","source":"@site/blog/aoc-2022/02-week-2.md","title":"2nd week of Advent of Code \'22 in Rust","description":"Surviving second week in Rust.","date":"2022-12-25T23:15:00.000Z","formattedDate":"December 25, 2022","tags":[{"label":"advent-of-code","permalink":"/blog/tags/advent-of-code"},{"label":"advent-of-code-2022","permalink":"/blog/tags/advent-of-code-2022"},{"label":"rust","permalink":"/blog/tags/rust"}],"readingTime":20.875,"hasTruncateMarker":true,"authors":[{"name":"Matej Focko","email":"me+blog@mfocko.xyz","title":"a.k.a. @mf","url":"https://gitlab.com/mfocko","imageURL":"https://github.com/mfocko.png","key":"mf"}],"frontMatter":{"title":"2nd week of Advent of Code \'22 in Rust","description":"Surviving second week in Rust.","date":"2022-12-25T23:15","slug":"aoc-2022/2nd-week","authors":"mf","tags":["advent-of-code","advent-of-code-2022","rust"],"hide_table_of_contents":false},"unlisted":false,"prevItem":{"title":"Sort the matrix diagonally","permalink":"/blog/leetcode/sort-diagonally"},"nextItem":{"title":"1st week of Advent of Code \'22 in Rust","permalink":"/blog/aoc-2022/1st-week"}},"content":"Let\'s go through the second week of [_Advent of Code_] in Rust.\\n\\n\x3c!--truncate--\x3e\\n\\n## [Day 8: Treetop Tree House](https://adventofcode.com/2022/day/8)\\n\\n:::info tl;dr\\n\\nWe get a forest and we want to know how many trees are visible from the outside.\\nApart from that we want to find the best view.\\n\\n:::\\n\\nNothing interesting. We are moving around 2D map though. And indexing can get a\\nbit painful when doing so, let\'s refactor it a bit ;) During the preparation for\\nthe AoC, I have written `Vector2D` and now it\'s time to extend it with indexing\\nof `Vec` of `Vec`s. In my solution I was manipulating with indices in the following\\nway:\\n\\n- swapping them\\n- checking whether they are correct indices for the `Vec>`\\n- indexing `Vec>` with them\\n\\n:::warning[caution]\\n\\nI\'m getting familiar with Rust and starting to \u201cabuse\u201d it\u2026 While doing so, I\'m\\nalso uncovering some \u201cfeatures\u201d that I don\'t really like. Therefore I will mark\\nall of my rants with _thicc_ **\xab\u21af\xbb** mark and will try to \u201clock\u201d them into their\\nown \u201cbox of hell\u201d.\\n\\n:::\\n\\n#### Swapping indices\\n\\nRelatively simple implementation, just take the values, swap them and return new\\nvector.\\n\\n```rust\\nimpl Vector2D {\\n pub fn swap(&self) -> Self {\\n Self {\\n x: self.y,\\n y: self.x,\\n }\\n }\\n}\\n```\\n\\nPretty straight-forward implementation, but let\'s talk about the `T: Copy`. We\\nneed to use it, since we are returning a **new** vector, with swapped **values**.\\nIf we had values that cannot be copied, the only thing we could do, would be a\\nvector of references (and it would also introduce a lifetime, to which we\'ll get\\nlater on). This is pretty similar with the operations on sets from the first week.\\n\\n#### Indexing `Vec`\\n\\nI will start with the indexing, cause bound-checking is a bit more\u2026 complicated\\nthan I would like to.\\n\\n```rust\\npub fn index<\'a, T, U>(v: &\'a [Vec], idx: &Vector2D) -> &\'a U\\nwhere\\n usize: TryFrom,\\n >::Error: Debug,\\n T: Copy,\\n{\\n let (x, y): (usize, usize) = (idx.x.try_into().unwrap(), idx.y.try_into().unwrap());\\n &v[y][x]\\n}\\n```\\n\\nLet\'s talk about this mess\u2026 Body of the function is probably the most easy part\\nand should not be hard to understand, we just take the `x` and `y` and convert\\nthem both to `usize` type that can be used later on for indexing.\\n\\nThe type signature of the function is where the fun is at :wink: We are trying\\nto convert unknown type to `usize`, so we must bound the `T` as a type that can\\nbe converted to `usize`, that\'s how we got `usize: TryFrom` which basically\\nsays that `usize` must implement `TryFrom` trait and therefore allows us to\\nconvert the indices to actual `usize` indices. Using `.unwrap()` also forces us\\nto bound the error that can occur when converting `T` into `usize`, that\'s how\\nwe get `>::Error: Debug` which loosely means\\n\\n> error during conversion of `T` into `usize` must implement `Debug`,\\n> i.e. can be printed in some way or other\\n\\n`T: Copy` is required by `.try_into()` which takes `T` by-value.\\n\\nAnd now we are left only with the first line of the definition.\\n\\n:::note\\n\\nSkilled Rustaceans might notice that this implementation is rather flaky and can\\nbreak in multiple places at once. I\'ll get back to it\u2026\\n\\n:::\\n\\nLet\'s split it in multiple parts:\\n\\n- `v: &\'a [Vec]` represents the 2D `Vec`, we are indexing, `Vec` implements\\n `Slice` trait and _clippy_ recommends using `&[T]` to `&Vec`, exact details\\n are unknown to me\\n- `idx: &Vector2D` represents the _indices_ which we use, we take them by\\n reference to avoid an unnecessary copy\\n- `-> &\'a U` means that we are returning a _reference_ to some value of type `U`.\\n Now the question is what does the `\'a` mean, we can also see it as a generic\\n type declared along `T` and `U`. And the answer is _relatively_ simple, `\'a`\\n represents a _lifetime_. We take the `v` by a reference and return a reference,\\n borrow checker validates all of the _borrows_ (or references), so we need to\\n specify that our returned value has _the same lifetime_ as the vector we have\\n taken by a reference, i.e. returned reference must live at least as long as the\\n `v`. This way we can \u201cbe sure\u201d that the returned reference is valid.\\n\\n##### Issues\\n\\nFirst issue that our implementation has is the fact that we cannot get a mutable\\nreference out of that function. This could be easily resolved by introducing new\\nfunction, e.g. `index_mut`. Which I have actually done while writing this part:\\n\\n```rust\\npub fn index_mut<\'a, T, U>(v: &\'a mut [Vec], idx: &Vector2D) -> &\'a mut U\\nwhere\\n usize: TryFrom,\\n >::Error: Debug,\\n T: Copy,\\n{\\n let (x, y): (usize, usize) = (idx.x.try_into().unwrap(), idx.y.try_into().unwrap());\\n &mut v[y][x]\\n}\\n```\\n\\n:::warning **\xab\u21af\xbb** Why can\'t we use one function?\\n\\nWhen we consider a `Vec`, we don\'t need to consider containers as `T`, Rust\\nimplements indexing as traits `Index` and `IndexMut` that do the dirty work\\nbehind syntactic sugar of `container[idx]`.\\n\\nHowever, implementing of traits is not allowed for _external_ types, i.e. types\\nthat you haven\'t defined yourself. This means that you can implement indexing\\nover containers that you have implemented yourself, but you cannot use your own\\ntypes for indexing \u201cbuilt-in\u201d types.\\n\\nAnother part of this rabbit hole is trait `SliceIndex` that is of a relevance\\nbecause of\\n\\n```rust\\nimpl Index for [T]\\nwhere\\n I: SliceIndex<[T]>\\n\\nimpl Index for Vec\\nwhere\\n I: SliceIndex<[T]>,\\n A: Allocator\\n\\nimpl Index for [T; N]\\nwhere\\n [T]: Index\\n```\\n\\nIn other words, if your type implements `SliceIndex` trait, it can be used\\nfor indexing. As of now, this trait has all of its required methods experimental\\nand is marked as `unsafe`.\\n\\n:::\\n\\nAnother problem is a requirement for indexing either `[Vec]` or `Vec>`.\\nThis requirement could be countered by removing inner type `Vec` and constraining\\nit by a trait `Index` (or `IndexMut` respectively) in a following way\\n\\n```rust\\npub fn index<\'a, C, T>(v: &\'a [C], idx: &Vector2D) -> &\'a C::Output\\nwhere\\n usize: TryFrom,\\n >::Error: Debug,\\n T: Copy,\\n C: Index\\n{\\n let (x, y): (usize, usize) = (idx.x.try_into().unwrap(), idx.y.try_into().unwrap());\\n &v[y][x]\\n}\\n```\\n\\nGiven this, we can also give a more meaningful typename for indexing type, such\\nas `I`.\\n\\n#### Checking bounds\\n\\nNow we can get to the boundary checks, it is very similar, but a more\u2026 dirty.\\nFirst approach that came up was to convert the indices in `Vector2D` to `usize`,\\nbut when you add the indices up, e.g. when checking the neighbors, you can end\\nup with negative values which, unlike in C++, causes an error (instead of underflow\\nthat you can use to your advantage; you can easily guess how).\\n\\nSo how can we approach this then? Well\u2026 we will convert the bounds instead of\\nthe indices and that lead us to:\\n\\n```rust\\npub fn in_range(v: &[Vec], idx: &Vector2D) -> bool\\nwhere\\n usize: TryInto,\\n >::Error: Debug,\\n T: PartialOrd + Copy,\\n{\\n idx.y >= 0.try_into().unwrap()\\n && idx.y < v.len().try_into().unwrap()\\n && idx.x >= 0.try_into().unwrap()\\n && idx.x\\n < v[TryInto::::try_into(idx.y).unwrap()]\\n .len()\\n .try_into()\\n .unwrap()\\n}\\n```\\n\\nYou can tell that it\'s definitely a shitty code. Let\'s improve it now! We will\\nget back to the original idea, but do it better. We know that we cannot convert\\nnegative values into `usize`, **but** we also know that conversion like that\\nreturns a `Result` which we can use to our advantage.\\n\\n```rust\\npub fn in_range(v: &[Vec], idx: &Vector2D) -> bool\\nwhere\\n T: Copy,\\n usize: TryFrom,\\n{\\n usize::try_from(idx.y)\\n .and_then(|y| usize::try_from(idx.x).map(|x| y < v.len() && x < v[y].len()))\\n .unwrap_or(false)\\n}\\n```\\n\\n`Result` is a type similar to `Either` in Haskell and it allows us to chain\\nmultiple operations on correct results or propagate the original error without\\ndoing anything. Let\'s dissect it one-by-one.\\n\\n`try_from` is a method implemented in `TryFrom` trait, that allows you to convert\\ntypes and either successfully convert them or fail (with a reasonable error). This\\nmethod returns `Result`.\\n\\nWe call `and_then` on that _result_, let\'s have a look at the type signature of\\n`and_then`, IMO it explains more than enough:\\n\\n```rust\\npub fn and_then(self, op: F) -> Result\\nwhere\\n F: FnOnce(T) -> Result\\n```\\n\\nOK\u2026 So it takes the result and a function and returns another result with\\ndifferent value and different error. However we can see that the function, which\\nrepresents an operation on a result, takes just the value, i.e. it doesn\'t care\\nabout any previous error. To make it short:\\n\\n> `and_then` allows us to run an operation, which can fail, on the correct result\\n\\nWe parsed a `y` index and now we try to convert the `x` index with `try_from`\\nagain, but on that result we use `map` rather than `and_then`, why would that be?\\n\\n```rust\\npub fn map(self, op: F) -> Result\\nwhere\\n F: FnOnce(T) -> U\\n```\\n\\nHuh\u2026 `map` performs an operation that **cannot** fail. And finally we use\\n`unwrap_or` which takes the value from result, or in case of an error returns the\\ndefault that we define.\\n\\nHow does this work then? If `y` is negative, the conversion fails and the error\\npropagates all the way to `unwrap_or`, if `y` can be a correct `usize` value, then\\nwe do the same with `x`. If `x` is negative, we propagate the error as with `y`,\\nand if it\'s not, then we check whether it exceeds the higher bounds or not.\\n\\n### Solution\\n\\nRelatively simple, you just need follow the rules and not get too smart, otherwise\\nit will get back at you.\\n\\n## [Day 9: Rope Bridge](https://adventofcode.com/2022/day/9)\\n\\n:::info tl;dr\\n\\nWe get a rope with knots and we want to track how many different positions are\\nvisited with the rope\'s tail.\\n\\n:::\\n\\nBy this day, I have come to a conclusion that current skeleton for each day\\ngenerates a lot of boilerplate. And even though it can be easily copied, it\'s\\njust a waste of space and unnecessary code. Let\'s \u201csimplify\u201d this (on one end\\nwhile creating monster on the other end). I\'ve gone through what we need in the\\npreparations for the AoC. Let\'s sum up our requirements:\\n\\n- parsing\\n- part 1 & 2\\n- running on sample / input\\n- tests\\n\\nParsing and implementation of both parts is code that changes each day and we\\ncannot do anything about it. However running and testing can be simplified!\\n\\nLet\'s introduce and export a new module `solution` that will take care of all of\\nthis. We will start by introducing a trait for each day.\\n\\n```rust\\npub trait Solution {\\n fn parse_input>(pathname: P) -> Input;\\n\\n fn part_1(input: &Input) -> Output;\\n fn part_2(input: &Input) -> Output;\\n}\\n```\\n\\nThis does a lot of work for us already, we have defined a trait and for each day\\nwe will create a structure representing a specific day. That structure will also\\nimplement the `Solution` trait.\\n\\nNow we need to get rid of the boilerplate, we can\'t get rid of the `main` function,\\nbut we can at least move out the functionality.\\n\\n```rust\\nfn run(type_of_input: &str) -> Result<()>\\nwhere\\n Self: Sized,\\n{\\n tracing_subscriber::fmt()\\n .with_env_filter(EnvFilter::from_default_env())\\n .with_target(false)\\n .with_file(true)\\n .with_line_number(true)\\n .without_time()\\n .compact()\\n .init();\\n color_eyre::install()?;\\n\\n let input = Self::parse_input(format!(\\"{}s/{}.txt\\", type_of_input, Self::day()));\\n\\n info!(\\"Part 1: {}\\", Self::part_1(&input));\\n info!(\\"Part 2: {}\\", Self::part_2(&input));\\n\\n Ok(())\\n}\\n\\nfn main() -> Result<()>\\nwhere\\n Self: Sized,\\n{\\n Self::run(\\"input\\")\\n}\\n```\\n\\nThis is all part of the `Solution` trait, which can implement methods while being\\ndependent on what is provided by the implementing types. In this case, we just\\nneed to bound the `Output` type to implement `Display` that is necessary for the\\n`info!` and format string there.\\n\\nNow we can get to first of the nasty things we are going to do\u2026 And it is the\\n`day()` method that you can see being used when constructing path to the input\\nfile. That method will generate a name of the file, e.g. `day01` and we know that\\nwe can _somehow_ deduce it from the structure name, given we name it reasonably.\\n\\n```rust\\nfn day() -> String {\\n let mut day = String::from(type_name::().split(\\"::\\").next().unwrap());\\n day.make_ascii_lowercase();\\n\\n day.to_string()\\n}\\n```\\n\\n:::warning `type_name`\\n\\nThis feature is still experimental and considered to be internal, it is not\\nadvised to use it any production code.\\n\\n:::\\n\\nAnd now we can get to the nastiest stuff :weary: We will **generate** the tests!\\n\\nWe want to be able to generate tests for sample input in a following way:\\n\\n```rust\\ntest_sample!(day_01, Day01, 42, 69);\\n```\\n\\nThere\'s not much we can do, so we will write a macro to generate the tests for us.\\n\\n```rust\\n#[macro_export]\\nmacro_rules! test_sample {\\n ($mod_name:ident, $day_struct:tt, $part_1:expr, $part_2:expr) => {\\n #[cfg(test)]\\n mod $mod_name {\\n use super::*;\\n\\n #[test]\\n fn test_part_1() {\\n let sample =\\n $day_struct::parse_input(&format!(\\"samples/{}.txt\\", $day_struct::day()));\\n assert_eq!($day_struct::part_1(&sample), $part_1);\\n }\\n\\n #[test]\\n fn test_part_2() {\\n let sample =\\n $day_struct::parse_input(&format!(\\"samples/{}.txt\\", $day_struct::day()));\\n assert_eq!($day_struct::part_2(&sample), $part_2);\\n }\\n }\\n };\\n}\\n```\\n\\nWe have used it in a similar way as macros in C/C++, one of the things that we\\ncan use to our advantage is defining \u201ctype\u201d of the parameters for the macro. All\\nparameters have their name prefixed with `$` sign and you can define various \u201cforms\u201d\\nof your macro. Let\'s go through it!\\n\\nWe have following parameters:\\n\\n- `$mod_name` which represents the name for the module with tests, it is typed\\n with `ident` which means that we want a valid identifier to be passed in.\\n- `$day_struct` represents the structure that will be used for tests, it is typed\\n with `tt` which represents a _token tree_, in our case it is a type.\\n- `$part_X` represents the expected output for the `X`th part and is of type `expr`\\n which literally means an _expression_.\\n\\nApart from that we need to use `#[macro_export]` to mark the macro as exported\\nfor usage outside of the module. Now our skeleton looks like:\\n\\n```rust\\nuse aoc_2022::*;\\n\\ntype Input = String;\\ntype Output = String;\\n\\nstruct DayXX;\\nimpl Solution for DayXX {\\n fn parse_input>(pathname: P) -> Input {\\n file_to_string(pathname)\\n }\\n\\n fn part_1(input: &Input) -> Output {\\n todo!()\\n }\\n\\n fn part_2(input: &Input) -> Output {\\n todo!()\\n }\\n}\\n\\nfn main() -> Result<()> {\\n // DayXX::run(\\"sample\\")\\n DayXX::main()\\n}\\n\\n// test_sample!(day_XX, DayXX, , );\\n```\\n\\n### Solution\\n\\nNot much to talk about, it is relatively easy to simulate.\\n\\n## [Day 10: Cathode-Ray Tube](https://adventofcode.com/2022/day/10)\\n\\n:::info tl;dr\\n\\nEmulating basic arithmetic operations on a CPU and drawing on CRT based on the\\nCPU\'s accumulator.\\n\\n:::\\n\\nIn this day I have discovered an issue with my design of the `Solution` trait.\\nAnd the issue is caused by different types of `Output` for the part 1 and part 2.\\n\\nProblem is relatively simple and consists of simulating a CPU, I have approached\\nit in a following way:\\n\\n```rust\\nfn evaluate_instructions(instructions: &[Instruction], mut out: Output) -> Output {\\n instructions\\n .iter()\\n .fold(State::new(), |state, instruction| {\\n state.execute(instruction, &mut out)\\n });\\n\\n out\\n}\\n```\\n\\nWe just take the instructions, we have some state of the CPU and we execute the\\ninstructions one-by-one. Perfect usage of the `fold` (or `reduce` as you may know\\nit from other languages).\\n\\nYou can also see that we have an `Output` type, so the question is how can we fix\\nthat problem. And the answer is very simple and _functional_. Rust allows you to\\nhave an `enumeration` that can _bear_ some other values apart from the type itself.\\n\\n:::tip\\n\\nWe could\'ve seen something like this with the `Result` type that can be\\ndefined as\\n\\n```rust\\nenum Result {\\n Ok(T),\\n Err(E)\\n}\\n```\\n\\n###### What does that mean though?\\n\\nWhen we have an `Ok` value, it has the result itself, and when we get an `Err`\\nvalue, it has the error. This also allows us to handle _results_ in a rather\\npretty way:\\n\\n```rust\\nmatch do_something(x) {\\n Ok(y) => {\\n println!(\\"SUCCESS: {}\\", y);\\n },\\n Err(y) => {\\n eprintln!(\\"ERROR: {}\\", y);\\n }\\n}\\n```\\n\\n:::\\n\\nMy solution has a following outline:\\n\\n```rust\\nfn execute(&self, i: &Instruction, output: &mut Output) -> State {\\n // execute the instruction\\n\\n // collect results if necessary\\n match output {\\n Output::Part1(x) => self.execute_part_1(y, x),\\n Output::Part2(x) => self.execute_part_2(y, x),\\n }\\n\\n // return the obtained state\\n new_state\\n}\\n```\\n\\nYou might think that it\'s a perfectly reasonable thing to do. Yes, **but** notice\\nthat the `match` statement doesn\'t _collect_ the changes in any way and also we\\npass `output` by `&mut`, so it is shared across each _iteration_ of the `fold`.\\n\\nThe dirty and ingenious thing is that `x`s are passed by `&mut` too and therefore\\nthey are directly modified by the helper functions. To sum it up and let it sit\\n\\n> We are **collecting** the result **into** an **enumeration** that is **shared**\\n> across **all** iterations of `fold`.\\n\\n### Solution\\n\\nSimilar to _Day 9_, but there are some technical details that can get you.\\n\\n## [Day 11: Monkey in the Middle](https://adventofcode.com/2022/day/11)\\n\\n:::info tl;dr\\n\\nSimulation of monkeys throwing stuff around and measuring your stress levels\\nwhile your stuff is being passed around.\\n\\n:::\\n\\nI think I decided to use regular expressions here for the first time, cause\\nparsing the input was a pain.\\n\\nAlso I didn\'t expect to implement Euclidean algorithm in Rust\u2026\\n\\n### Solution\\n\\nAgain, we\'re just running a simulation. Though I must admit it was very easy to\\nmake a small technical mistakes that could affect the final results very late.\\n\\n## [Day 12: Hill Climbing Algorithm](https://adventofcode.com/2022/day/12)\\n\\n:::info tl;dr\\n\\nFinding shortest path up the hill and also shortest path down to the ground while\\nalso rolling down the hill\u2026\\n\\n:::\\n\\nAs I have said in the _tl;dr_, we are looking for the shortest path, but the start\\nand goal differ for the part 1 and 2. So I have decided to refactor my solution\\nto a BFS algorithm that takes necessary parameters via functions:\\n\\n```rust\\nfn bfs(\\n graph: &[Vec], start: &Position, has_edge: F, is_target: G\\n) -> Option\\nwhere\\n F: Fn(&[Vec], &Position, &Position) -> bool,\\n G: Fn(&[Vec], &Position) -> bool\\n```\\n\\nWe pass the initial vertex from the caller and everything else is left to the BFS\\nalgorithm, based on the `has_edge` and `is_target` functions.\\n\\nThis was easy! And that is not very usual in Rust once you want to pass around\\nfunctions. :eyes:\\n\\n### Solution\\n\\nLooking for the shortest path\u2026 Must be Dijkstra, right? **Nope!** Half of the\\nReddit got jebaited though. In all fairness, nothing stops you from implementing\\nthe Dijkstra\'s algorithm for finding the shortest path, **but** if you know that\\nall connected vertices are in a unit (actually $d = 1$) distance from each other,\\nthen you know that running Dijkstra is equivalent to running BFS, only with worse\\ntime complexity, because of the priority heap instead of the queue.\\n\\n## [Day 13: Distress Signal](https://adventofcode.com/2022/day/13)\\n\\n:::info tl;dr\\n\\nProcessing packets with structured data from the distress signal.\\n\\n:::\\n\\nYou can implement a lot of traits if you want to. It is _imperative_ to implement\\nordering on the packets. I had a typo, so I also proceeded to implement a `Display`\\ntrait for debugging purposes:\\n\\n```rust\\nimpl Display for Packet {\\n fn fmt(&self, f: &mut std::fmt::Formatter<\'_>) -> std::fmt::Result {\\n match self {\\n Packet::Integer(x) => write!(f, \\"{x}\\"),\\n Packet::List(lst) => write!(f, \\"[{}]\\", lst.iter().map(|p| format!(\\"{p}\\")).join(\\",\\")),\\n }\\n }\\n}\\n```\\n\\n### Solution\\n\\nA lot of technical details\u2026 Parsing is nasty too\u2026\\n\\n## [Day 14: Regolith Reservoir](https://adventofcode.com/2022/day/14)\\n\\n:::info tl;dr\\n\\nLet\'s simulate falling sand grain-by-grain.\\n\\n:::\\n\\nAgain, both parts are relatively similar with minimal changes, so it is a good\\nidea to refactor it a bit. Similar approach to the [BFS above]. Also this is the\\nfirst day where I ran into efficiency issues and had to redo my solution to speed\\nit up just a bit.\\n\\n### Solution\\n\\nTedious.\\n\\n## Post Mortem\\n\\n### Indexing\\n\\nI was asked about the indexing after publishing the blog. And truly it is rather\\ncomplicated topic, especially after releasing `SliceIndex` trait. I couldn\'t\\nleave it be, so I tried to implement the `Index` and `IndexMut` trait.\\n\\n:::note\\n\\nI have also mentioned that the `SliceIndex` trait is `unsafe`, but truth be told,\\nonly _unsafe_ part are the 2 methods that are named `*unchecked*`. Anyways, I will\\nbe implementing the `Index*` traits for now, rather than the `SliceIndex`.\\n\\n:::\\n\\nIt\'s relatively straightforward\u2026\\n\\n```rust\\nimpl Index> for [C]\\nwhere\\n I: Copy + TryInto,\\n >::Error: Debug,\\n C: Index,\\n{\\n type Output = C::Output;\\n\\n fn index(&self, index: Vector2D) -> &Self::Output {\\n let (x, y): (usize, usize) =\\n (index.x.try_into().unwrap(), index.y.try_into().unwrap());\\n &self[y][x]\\n }\\n}\\n\\nimpl IndexMut> for [C]\\nwhere\\n I: Copy + TryInto,\\n >::Error: Debug,\\n C: IndexMut,\\n{\\n fn index_mut(&mut self, index: Vector2D) -> &mut Self::Output {\\n let (x, y): (usize, usize) =\\n (index.x.try_into().unwrap(), index.y.try_into().unwrap());\\n &mut self[y][x]\\n }\\n}\\n```\\n\\nWe can see a lot of similarities to the implementation of `index` and `index_mut`\\nfunctions. In the end, they are 1:1, just wrapped in the trait that provides a\\nsyntax sugar for `container[idx]`.\\n\\n:::note\\n\\nI have also switched from using the `TryFrom` to `TryInto` trait, since it better\\nmatches what we are using, the `.try_into` rather than `usize::try_from`.\\n\\nAlso implementing `TryFrom` automatically provides you with a `TryInto` trait,\\nsince it is relatively easy to implement. Just compare the following:\\n\\n```rust\\npub trait TryFrom: Sized {\\n type Error;\\n\\n fn try_from(value: T) -> Result;\\n}\\n\\npub trait TryInto: Sized {\\n type Error;\\n\\n fn try_into(self) -> Result;\\n}\\n```\\n\\n:::\\n\\nOK, so we have our trait implemented, we should be able to use `container[index]`,\\nright? Yes\u2026 but actually no :frowning:\\n\\n```\\nerror[E0277]: the type `[std::vec::Vec]` cannot be indexed by `aoc_2022::Vector2D`\\n --\x3e src/bin/day08.rs:26:18\\n |\\n26 | if trees[pos] > tallest {\\n | ^^^ slice indices are of type `usize` or ranges of `usize`\\n |\\n = help: the trait `std::slice::SliceIndex<[std::vec::Vec]>` is not implemented for `aoc_2022::Vector2D`\\n = note: required for `std::vec::Vec>` to implement `std::ops::Index>`\\n\\nerror[E0277]: the type `[std::vec::Vec]` cannot be indexed by `aoc_2022::Vector2D`\\n --\x3e src/bin/day08.rs:30:28\\n |\\n30 | max(tallest, trees[pos])\\n | ^^^ slice indices are of type `usize` or ranges of `usize`\\n |\\n = help: the trait `std::slice::SliceIndex<[std::vec::Vec]>` is not implemented for `aoc_2022::Vector2D`\\n = note: required for `std::vec::Vec>` to implement `std::ops::Index>`\\n\\nerror[E0277]: the type `[std::vec::Vec]` cannot be indexed by `aoc_2022::Vector2D`\\n --\x3e src/bin/day08.rs:52:28\\n |\\n52 | let max_height = trees[position];\\n | ^^^^^^^^ slice indices are of type `usize` or ranges of `usize`\\n |\\n = help: the trait `std::slice::SliceIndex<[std::vec::Vec]>` is not implemented for `aoc_2022::Vector2D`\\n = note: required for `std::vec::Vec>` to implement `std::ops::Index>`\\n```\\n\\nWhy? We have it implemented for the slices (`[C]`), why doesn\'t it work? Well,\\nthe fun part consists of the fact that in other place, where we were using it,\\nwe were passing the `&[Vec]`, but this is coming from a helper functions that\\ntake `&Vec>` instead. And\u2026 we don\'t implement `Index` and `IndexMut` for\\nthose. Just for the slices. \ud83e\udd2f _What are we going to do about it?_\\n\\nWe can either start copy-pasting or be smarter about it\u2026 I choose to be smarter,\\nso let\'s implement a macro! The only difference across the implementations are\\nthe types of the outer containers. Implementation doesn\'t differ **at all**!\\n\\nImplementing the macro can be done in a following way:\\n\\n```rust\\nmacro_rules! generate_indices {\\n ($container:ty) => {\\n impl Index> for $container\\n where\\n I: Copy + TryInto,\\n >::Error: Debug,\\n C: Index,\\n {\\n type Output = C::Output;\\n\\n fn index(&self, index: Vector2D) -> &Self::Output {\\n let (x, y): (usize, usize) =\\n (index.x.try_into().unwrap(), index.y.try_into().unwrap());\\n &self[y][x]\\n }\\n }\\n\\n impl IndexMut> for $container\\n where\\n I: Copy + TryInto,\\n >::Error: Debug,\\n C: IndexMut,\\n {\\n fn index_mut(&mut self, index: Vector2D) -> &mut Self::Output {\\n let (x, y): (usize, usize) =\\n (index.x.try_into().unwrap(), index.y.try_into().unwrap());\\n &mut self[y][x]\\n }\\n }\\n };\\n}\\n```\\n\\nAnd now we can simply do\\n\\n```rust\\ngenerate_indices!(VecDeque);\\ngenerate_indices!([C]);\\ngenerate_indices!(Vec);\\n// generate_indices!([C; N], const N: usize);\\n```\\n\\nThe last type (I took the inspiration from the implementations of the `Index` and\\n`IndexMut` traits) is a bit problematic, because of the `const N: usize` part,\\nwhich I haven\'t managed to be able to parse. And that\'s how I got rid of the error.\\n\\n:::note\\n\\nIf I were to use 2D-indexing over `[C; N]` slices, I\'d probably just go with the\\ncopy-paste, cause the cost of this \u201cmonstrosity\u201d outweighs the benefits of no DRY.\\n\\n:::\\n\\n#### Cause of the problem\\n\\nThis issue is relatively funny. If you don\'t use any type aliases, just the raw\\ntypes, you\'ll get suggested certain changes by the _clippy_. For example if you\\nconsider the following piece of code\\n\\n```rust\\nfn get_sum(nums: &Vec) -> i32 {\\n nums.iter().sum()\\n}\\n\\nfn main() {\\n let nums = vec![1, 2, 3];\\n println!(\\"Sum: {}\\", get_sum(&nums));\\n}\\n```\\n\\nand you run _clippy_ on it, you will get\\n\\n```\\nChecking playground v0.0.1 (/playground)\\nwarning: writing `&Vec` instead of `&[_]` involves a new object where a slice will do\\n --\x3e src/main.rs:1:18\\n |\\n1 | fn get_sum(nums: &Vec) -> i32 {\\n | ^^^^^^^^^ help: change this to: `&[i32]`\\n |\\n = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#ptr_arg\\n = note: `#[warn(clippy::ptr_arg)]` on by default\\n\\nwarning: `playground` (bin \\"playground\\") generated 1 warning\\n Finished dev [unoptimized + debuginfo] target(s) in 0.61s\\n```\\n\\nHowever, if you introduce a type alias, such as\\n\\n```rust\\ntype Numbers = Vec;\\n```\\n\\nThen _clippy_ won\'t say anything, cause there is literally nothing to suggest.\\nHowever the outcome is not the same\u2026\\n\\n[_advent of code_]: https://adventofcode.com\\n[bfs above]: #day-12-hill-climbing-algorithm"},{"id":"aoc-2022/1st-week","metadata":{"permalink":"/blog/aoc-2022/1st-week","editUrl":"https://github.com/mfocko/blog/tree/main/blog/aoc-2022/01-week-1.md","source":"@site/blog/aoc-2022/01-week-1.md","title":"1st week of Advent of Code \'22 in Rust","description":"Surviving first week in Rust.","date":"2022-12-15T01:15:00.000Z","formattedDate":"December 15, 2022","tags":[{"label":"advent-of-code","permalink":"/blog/tags/advent-of-code"},{"label":"advent-of-code-2022","permalink":"/blog/tags/advent-of-code-2022"},{"label":"rust","permalink":"/blog/tags/rust"}],"readingTime":12.4,"hasTruncateMarker":true,"authors":[{"name":"Matej Focko","email":"me+blog@mfocko.xyz","title":"a.k.a. @mf","url":"https://gitlab.com/mfocko","imageURL":"https://github.com/mfocko.png","key":"mf"}],"frontMatter":{"title":"1st week of Advent of Code \'22 in Rust","description":"Surviving first week in Rust.","date":"2022-12-15T01:15","slug":"aoc-2022/1st-week","authors":"mf","tags":["advent-of-code","advent-of-code-2022","rust"],"hide_table_of_contents":false},"unlisted":false,"prevItem":{"title":"2nd week of Advent of Code \'22 in Rust","permalink":"/blog/aoc-2022/2nd-week"},"nextItem":{"title":"Advent of Code \'22 in Rust","permalink":"/blog/aoc-2022/intro"}},"content":"Let\'s go through the first week of [_Advent of Code_] in Rust.\\n\\n\x3c!--truncate--\x3e\\n\\n:::note\\n\\nIf you wish to have a look at the solutions, you can follow them on my [GitLab].\\nMore specifically in the [`/src/bin/`].\\n\\n:::\\n\\nI will try to summarize my experience with using Rust for the AoC. Trying it out\\nages ago, I believe it will be _pain and suffering_, but we will see. For each\\nday I will also try to give a tl;dr of the problem, so that you can better imagine\\nthe relation to my woes or :+1: moments.\\n\\n## [Day 1: Calorie Counting](https://adventofcode.com/2022/day/1)\\n\\n:::info tl;dr\\n\\nAs the name suggests, we get the calories of the food contained in the elves\\nbackpacks and we want to choose the elf that has the most food ;)\\n\\n:::\\n\\n> Wakey wakey!\\n\\nProgramming in Rust at 6am definitely hits. I\'ve also forgotten to mention how I\\nhandle samples. With each puzzle you usually get a sample input and expected\\noutput. You can use them to verify that your solution works, or usually doesn\'t.\\n\\nAt first I\'ve decided to put asserts into my `main`, something like\\n\\n```rust\\nassert_eq!(part_1(&sample), 24000);\\ninfo!(\\"Part 1: {}\\", part_1(&input));\\n\\nassert_eq!(part_2(&sample), 45000);\\ninfo!(\\"Part 2: {}\\", part_2(&input));\\n```\\n\\nHowever, once you get further, the sample input may take some time to run itself.\\nSo in the end, I have decided to turn them into unit tests:\\n\\n```rust\\n#[cfg(test)]\\nmod tests {\\n use super::*;\\n\\n #[test]\\n fn test_part_1() {\\n let sample = parse_input(\\"samples/day01.txt\\");\\n assert_eq!(part_1(&sample), 24000);\\n }\\n\\n #[test]\\n fn test_part_2() {\\n let sample = parse_input(\\"samples/day01.txt\\");\\n assert_eq!(part_2(&sample), 45000);\\n }\\n}\\n```\\n\\nAnd later on I have noticed, it\'s hard to tell the difference between the days,\\nso I further renamed the `mod` from generic `tests` to reflect the days.\\n\\nAlso after finishing the first day puzzle, I have installed an [`sccache`] to\\ncache the builds, so that the build time is lower, cause it was kinda unbearable.\\n\\n### Solution\\n\\nWell, it\'s a pretty simple problem. You just take the input, sum the calories and\\nfind the biggest one. However, if we try to generalize to more than the biggest\\none, the fun appears. We have few options:\\n\\n- keep all the calories, sort them, take what we need\\n- keep all the calories and use max heap\\n- use min heap and maintain at most N calories that we need\\n\\n## [Day 2: Rock Paper Scissors](https://adventofcode.com/2022/day/2)\\n\\n:::info tl;dr\\n\\nYou want to know what score did you achieve while playing _Rock Paper Scissors_.\\nAnd then you want to be strategic about it.\\n\\n:::\\n\\nApart from the technical details of the puzzle, it went relatively smooth.\\n\\n### Solution\\n\\nI took relatively na\xefve approach and then tried to simplify it.\\n\\n## [Day 3: Rucksack Reorganization](https://adventofcode.com/2022/day/3)\\n\\n:::info tl;dr\\n\\nLet\'s go reorganize elves\' backpacks! Each backpacks has 2 compartments and you\\nwant to find the common item among those compartments. Each of them has priority,\\nyou care only about the sum.\\n\\n:::\\n\\nThis is the day where I started to fight the compiler and neither of us decided\\nto give up. Let\'s dive into it \\\\o/\\n\\n:::tip Fun fact\\n\\nFighting the compiler took me 30 minutes.\\n\\n:::\\n\\nWe need to find a common item among 2 collections, that\'s an easy task, right?\\nWe can construct 2 sets and find an intersection:\\n\\n```rust\\nlet top: HashSet = [1, 2, 3].iter().collect();\\nlet bottom: HashSet = [3, 4, 5].iter().collect();\\n```\\n\\nNow, the first issue that we encounter is caused by the fact that we are using\\na slice (the `[\u2026]`), iterator of that returns **references** to the numbers.\\nAnd we get immediately yelled at by the compiler, because the numbers are discarded\\nafter running the `.collect`. To fix this, we can use `.into_iter`:\\n\\n```rust\\nlet top: HashSet = [1, 2, 3].into_iter().collect();\\nlet bottom: HashSet = [3, 4, 5].into_iter().collect();\\n```\\n\\nThis way the numbers will get copied instead of referenced. OK, let\'s find the\\nintersection of those 2 collections:\\n\\n```rust\\nprintln!(\\"Common elements: {:?}\\", top.intersection(&bottom));\\n```\\n\\n```\\nCommon elements: [3]\\n```\\n\\n:::warning[caution]\\n\\nNotice that we need to do `&bottom`. It explicitly specifies that `.intersection`\\n**borrows** the `bottom`, i.e. takes an immutable reference to it.\\n\\n:::\\n\\nThat\'s what we want, right? Looks like it! \\\\o/\\n\\nNext part wants us to find the common element among all of the backpacks. OK, so\\nthat should be fairly easy, we have an intersection and we want to find intersection\\nover all of them.\\n\\nLet\'s have a look at the type of the `.intersection`\\n\\n```rust\\npub fn intersection<\'a>(\\n\xa0\xa0\xa0\xa0&\'a self,\\n\xa0\xa0\xa0\xa0other: &\'a HashSet\\n) -> Intersection<\'a, T, S>\\n```\\n\\nOK\u2026 Huh\u2026 But we have an example there!\\n\\n```rust\\nlet intersection: HashSet<_> = a.intersection(&b).collect();\\n```\\n\\nCool, that\'s all we need.\\n\\n```rust\\nlet top: HashSet = [1, 2, 3, 4].into_iter().collect();\\nlet bottom: HashSet = [3, 4, 5, 6].into_iter().collect();\\nlet top_2: HashSet = [2, 3, 4, 5, 6].into_iter().collect();\\nlet bottom_2: HashSet = [4, 5, 6].into_iter().collect();\\n\\nlet intersection: HashSet<_> = top.intersection(&bottom).collect();\\nprintln!(\\"Intersection: {:?}\\", intersection);\\n```\\n\\n```\\nIntersection: {3, 4}\\n```\\n\\nCool, so let\'s do the intersection with the `top_2`:\\n\\n```rust\\nlet top: HashSet = [1, 2, 3, 4].into_iter().collect();\\nlet bottom: HashSet = [3, 4, 5, 6].into_iter().collect();\\nlet top_2: HashSet = [2, 3, 4, 5, 6].into_iter().collect();\\nlet bottom_2: HashSet = [4, 5, 6].into_iter().collect();\\n\\nlet intersection: HashSet<_> = top.intersection(&bottom).collect();\\nlet intersection: HashSet<_> = intersection.intersection(&top_2).collect();\\nprintln!(\\"Intersection: {:?}\\", intersection);\\n```\\n\\nAnd we get yelled at by the compiler:\\n\\n```\\nerror[E0308]: mismatched types\\n --\x3e src/main.rs:10:58\\n |\\n10 | let intersection: HashSet<_> = intersection.intersection(&top_2).collect();\\n | ------------ ^^^^^^ expected `&i32`, found `i32`\\n | |\\n | arguments to this function are incorrect\\n |\\n = note: expected reference `&HashSet<&i32>`\\n found reference `&HashSet`\\n```\\n\\n/o\\\\ What the hell is going on here? Well, the funny thing is, that this operation\\ndoesn\'t return the elements themselves, but the references to them and when we pass\\nthe third set, it has just the values themselves, without any references.\\n\\n:::tip\\n\\nIt may seem as a very weird decision, but in fact it makes some sense\u2026 It allows\\nyou to do intersection of items that may not be possible to copy. Overall this is\\na \u201ctax\u201d for having a borrow checker ~~drilling your ass~~ having your back and\\nmaking sure you\'re not doing something naughty that may cause an **undefined**\\n**behavior**.\\n\\n:::\\n\\nTo resolve this we need to get an iterator that **clones** the elements:\\n\\n```rust\\nlet top: HashSet = [1, 2, 3, 4].into_iter().collect();\\nlet bottom: HashSet = [3, 4, 5, 6].into_iter().collect();\\nlet top_2: HashSet = [2, 3, 4, 5, 6].into_iter().collect();\\nlet bottom_2: HashSet = [4, 5, 6].into_iter().collect();\\n\\nlet intersection: HashSet<_> = top.intersection(&bottom).cloned().collect();\\nlet intersection: HashSet<_> = intersection.intersection(&top_2).cloned().collect();\\nlet intersection: HashSet<_> = intersection.intersection(&bottom_2).cloned().collect();\\nprintln!(\\"Intersection: {:?}\\", intersection);\\n```\\n\\n```\\nIntersection: {4}\\n```\\n\\n### Solution\\n\\nThe approach is pretty simple, if you omit the _1on1 with the compiler_. You just\\nhave some fun with the set operations :)\\n\\n## [Day 4: Camp Cleanup](https://adventofcode.com/2022/day/4)\\n\\n:::info tl;dr\\n\\nElves are cleaning up the camp and they got overlapping sections to clean up.\\nFind how many overlap and can take the day off.\\n\\n:::\\n\\n[`RangeInclusive`] is your friend not an enemy :)\\n\\n### Solution\\n\\nRelatively easy, you just need to parse the input and know what you want. Rust\'s\\n`RangeInclusive` type helped a lot, cause it took care of all abstractions.\\n\\n## [Day 5: Supply Stacks](https://adventofcode.com/2022/day/5)\\n\\n:::info tl;dr\\n\\nLet\'s play with stacks of crates.\\n\\n:::\\n\\nVery easy problem with very annoying input. You can judge yourself:\\n\\n```\\n [D]\\n[N] [C]\\n[Z] [M] [P]\\n 1 2 3\\n\\nmove 1 from 2 to 1\\nmove 3 from 1 to 3\\nmove 2 from 2 to 1\\nmove 1 from 1 to 2\\n```\\n\\nGood luck transforming that into something reasonable :)\\n\\n:::tip Fun fact\\n\\nTook me 40 minutes to parse this reasonably, including fighting the compiler.\\n\\n:::\\n\\n### Solution\\n\\nFor the initial solution I went with a manual solution (as in _I have done all_\\n_the work_. Later on I have decided to explore the `std` and interface of the\\n`std::vec::Vec` and found [`split_off`] which takes an index and splits (duh)\\nthe vector:\\n\\n```rust\\nlet mut vec = vec![1, 2, 3];\\nlet vec2 = vec.split_off(1);\\nassert_eq!(vec, [1]);\\nassert_eq!(vec2, [2, 3]);\\n```\\n\\nThis helped me simplify my solution a lot and also get rid of some _edge cases_.\\n\\n## [Day 6: Tuning Trouble](https://adventofcode.com/2022/day/6)\\n\\n:::info tl;dr\\n\\nFinding start of the message in a very weird protocol. Start of the message is\\ndenoted by $N$ unique consecutive characters.\\n\\n:::\\n\\n### Solution\\n\\nA lot of different approaches, knowing that we are dealing with input consisting\\nsolely of ASCII letters, I bit the bullet and went with sliding window and\\nconstructing sets from that window, checking if the set is as big as the window.\\n\\nOne possible optimization could consist of keeping a bit-vector (i.e. `usize`\\nvariable) of encountered characters and updating it as we go. However this has\\na different issue and that is removal of the characters from the left side of the\\nwindow. We don\'t know if the same character is not included later on.\\n\\nOther option is to do similar thing, but keeping the frequencies of the letters,\\nand again knowing we have only ASCII letters we can optimize by having a vector\\nof 26 elements that keeps count for each lowercase letter.\\n\\n## [Day 7: No Space Left On Device](https://adventofcode.com/2022/day/7)\\n\\n:::info tl;dr\\n\\nLet\'s simulate [`du`] to get some stats about our file system and then pinpoint\\ndirectories that take a lot of space and should be deleted.\\n\\n:::\\n\\n> I was waiting for this moment, and yet it got me!\\n> _imagine me swearing for hours_\\n\\n### Solution\\n\\nWe need to \u201c_build_\u201d a file system from the input that is given in a following form:\\n\\n```\\n$ cd /\\n$ ls\\ndir a\\n14848514 b.txt\\n8504156 c.dat\\ndir d\\n$ cd a\\n$ ls\\ndir e\\n29116 f\\n2557 g\\n62596 h.lst\\n$ cd e\\n$ ls\\n584 i\\n$ cd ..\\n$ cd ..\\n$ cd d\\n$ ls\\n4060174 j\\n8033020 d.log\\n5626152 d.ext\\n7214296 k\\n```\\n\\nThere are few ways in which you can achieve this and also you can assume some\\npreconditions, but why would we do that, right? :)\\n\\nYou can \u201cslap\u201d this in either [`HashMap`] or [`BTreeMap`] and call it a day.\\nAnd that would be boring\u2026\\n\\n:::tip\\n\\n`BTreeMap` is quite fitting for this, don\'t you think?\\n\\n:::\\n\\nI always wanted to try allocation on heap in Rust, so I chose to implement a tree.\\nI fought with the `Box` for some time and was losing\u2026\\n\\nThen I looked up some implementations of trees or linked lists and decided to try\\n`Rc>`. And I got my _ass whopped_ by the compiler once again. /o\\\\\\n\\n:::tip\\n\\n`Box` represents a dynamically allocated memory on heap. It is a single pointer,\\nyou can imagine this as `std::unique_ptr` in C++.\\n\\n`Rc` represents a dynamically allocated memory on heap. On top of that it is\\n_reference counted_ (that\'s what the `Rc` stands for). You can imagine this as\\n`std::shared_ptr` in C++.\\n\\nNow the fun stuff. Neither of them lets you **mutate** the contents of the memory.\\n\\n`Cell` allows you to mutate the memory. Can be used reasonably with types that\\ncan be copied, because the memory safety is guaranteed by copying the contents\\nwhen there is more than one **mutable** reference to the memory.\\n\\n`RefCell` is similar to the `Cell`, but the borrowing rules (how many mutable\\nreferences are present) are checked dynamically.\\n\\nSo in the end, if you want something like `std::shared_ptr` in Rust, you want\\nto have `Rc>`.\\n\\n:::\\n\\nSo, how are we going to represent the file system then? We will use an enumeration,\\nhehe, which is an algebraic data type that can store some stuff in itself :weary:\\n\\n```rust\\ntype FileHandle = Rc>;\\n\\n#[derive(Debug)]\\nenum AocFile {\\n File(usize),\\n Directory(BTreeMap),\\n}\\n```\\n\\nLet\'s go over it! `FileHandle` represents dynamically allocated `AocFile`, not\\nmuch to discuss. What does the `#[derive(Debug)]` do though? It lets us to print\\nout the value of that enumeration, it\'s derived, so it\'s not as good as if we had\\nimplemented it ourselves, but it\'s good enough for debugging, hence the name.\\n\\nNow to the fun part! `AocFile` value can be represented in two ways:\\n\\n- `File(usize)`, e.g. `AocFile::File(123)` and we can pattern match it, if we\\n need to\\n- `Directory(BTreeMap)` will represent the directory and will\\n contain map matching the name of the files (or directories) within to their\\n respective file handles\\n\\nI will omit the details about constructing this file system, cause there are a lot\\nof technicalities introduced by the nature of the input. However if you are\\ninterested, you can have a look at my solution.\\n\\nWe need to find small enough directories and also find the smallest directory that\\nwill free enough space. Now the question is, how could we do that. And there are\\nmultiple ways I will describe.\\n\\nI have chosen to implement [_tree catamorphism_] :weary:. It is basically a fold\\nover a tree data structure. We descent down into the leaves and propagate computed\\nresults all the way to the root. You can also notice that this approach is very\\nsimilar to _dynamic programming_, we find overlapping sections of the computation\\nand try to minimize the additional work (in this case: we need to know sizes of\\nour descendants, but we have already been there).\\n\\nAnother approach that has been suggested to me few days later is running DFS on\\nthe graph. And, funnily enough, we would still need to combine what we found in\\nthe branches where we descent. So in the end, it would work very similarly to my\\nsolution.\\n\\nOne of the more exotic options would be precomputing the required information at\\nthe same time as parsing. That could be done by adding additional fields to the\\nnodes which would allow storing such information and updating it as we construct\\nthe file system.\\n\\n## Post Mortem\\n\\nThings that have been brought up in the discussion later on.\\n\\n### `Rc` vs `Rc>`\\n\\nIt has been brought up that I have a contradicting statement regarding the\\ndynamically allocated memory. Specifically:\\n\\n- You can imagine `Rc` as an `std::shared_ptr` (in C++)\\n- When you want an equivalent of `std::shared_ptr`, you want to use\\n `Rc>`\\n\\nNow, in Rust it is a bit more complicated, because the type that represents the\\n\u201cshared pointer\u201d is `Rc`. What `RefCell` does is making sure that there is\\nonly one \u201cowner\u201d of a mutable reference at a time (and dynamically, as opposed\\nto the `Cell`).\\n\\nTherefore to be precise and correct about the equivalents of `std::shared_ptr`\\nin Rust, we can say that\\n\\n- `Rc` is an equivalent of a `const std::shared_ptr`,\\n- and `Rc>` is an equivalent of a `std::shared_ptr`.\\n\\nYou can easily see that they only differ in the mutability. (And even that is not\\nas simple as it seems, because there is also `Cell`)\\n\\n[_advent of code_]: https://adventofcode.com\\n[gitlab]: https://gitlab.com/mfocko/advent-of-code-2022\\n[`/src/bin/`]: https://gitlab.com/mfocko/advent-of-code-2022/-/tree/main/src/bin\\n[`sccache`]: https://github.com/mozilla/sccache\\n[`rangeinclusive`]: https://doc.rust-lang.org/std/ops/struct.RangeInclusive.html\\n[`split_off`]: https://doc.rust-lang.org/std/vec/struct.Vec.html#method.split_off\\n[`du`]: https://www.man7.org/linux/man-pages/man1/du.1.html\\n[`hashmap`]: https://doc.rust-lang.org/std/collections/struct.HashMap.html\\n[`btreemap`]: https://doc.rust-lang.org/std/collections/struct.BTreeMap.html\\n[_tree catamorphism_]: https://en.wikipedia.org/wiki/Catamorphism#Tree_fold"},{"id":"aoc-2022/intro","metadata":{"permalink":"/blog/aoc-2022/intro","editUrl":"https://github.com/mfocko/blog/tree/main/blog/aoc-2022/00-intro.md","source":"@site/blog/aoc-2022/00-intro.md","title":"Advent of Code \'22 in Rust","description":"Preparing for Advent of Code \'22.","date":"2022-12-14T21:45:00.000Z","formattedDate":"December 14, 2022","tags":[{"label":"advent-of-code","permalink":"/blog/tags/advent-of-code"},{"label":"advent-of-code-2022","permalink":"/blog/tags/advent-of-code-2022"},{"label":"rust","permalink":"/blog/tags/rust"}],"readingTime":8.665,"hasTruncateMarker":true,"authors":[{"name":"Matej Focko","email":"me+blog@mfocko.xyz","title":"a.k.a. @mf","url":"https://gitlab.com/mfocko","imageURL":"https://github.com/mfocko.png","key":"mf"}],"frontMatter":{"title":"Advent of Code \'22 in Rust","description":"Preparing for Advent of Code \'22.","date":"2022-12-14T21:45","slug":"aoc-2022/intro","authors":"mf","tags":["advent-of-code","advent-of-code-2022","rust"],"hide_table_of_contents":false},"unlisted":false,"prevItem":{"title":"1st week of Advent of Code \'22 in Rust","permalink":"/blog/aoc-2022/1st-week"}},"content":"Let\'s talk about the preparations for this year\'s [_Advent of Code_].\\n\\n\x3c!--truncate--\x3e\\n\\n## Choosing a language\\n\\nWhen choosing a language for AoC, you usually want a language that gives you a\\nquick feedback which allows you to iterate quickly to the solution of the puzzle.\\nOne of the most common choices is Python, many people also use JavaScript or Ruby.\\n\\nGiven the competitive nature of the AoC and popularity among competitive programming,\\nC++ might be also a very good choice. Only if you are familiar with it, I guess\u2026\\n\\nIf you want a challenge, you might also choose to rotate the languages each day.\\nThough I prefer to use only one language.\\n\\nFor this year I have been deciding between _Rust_, _C++_ and _Pascal_ or _Ada_.\\n\\nI have tried Rust last year and have survived with it for 3 days and then gave\\nup and switched to _Kotlin_, which was pretty good given it is \u201cJava undercover\u201d.\\nI pretty much like the ideas behind Rust, I am not sure about the whole cult and\\nimplementation of those ideas though. After some years with C/C++, I would say\\nthat Rust feels _too safe_ for my taste and tries to \u201c_punish me_\u201d even for the\\nmost trivial things.\\n\\nC++ is a very robust, but also comes with a wide variety of options providing you\\nthe ability to shoot yourself in the leg. I have tried to solve few days of previous\\nAdvent of Code events, it was _relatively easy_ to solve the problems in C++, given\\nthat I do not admit writing my own iterator for `enumerate`\u2026\\n\\nPascal or Ada were meme choices :) Ada is heavily inspired by Pascal and has a\\npretty nice standard library that offers enough to be able to quickly solve some\\nproblems in it. However the toolkit is questionable :/\\n\\n## Choosing libraries\\n\\n## Preparations for Rust\\n\\nAll of the sources, later on including solutions, can be found at my\\n[GitLab].\\n\\n### Toolkit\\n\\nSince we are using Rust, we are going to use a [Cargo] and more than likely VSCode\\nwith [`rust-analyzer`]. Because of my choice of libraries, we will also introduce\\na `.envrc` file that can be used by [`direnv`], which allows you to set specific\\nenvironment variables when you enter a directory. In our case, we will use\\n\\n```bash\\n# to show nice backtrace when using the color-eyre\\nexport RUST_BACKTRACE=1\\n\\n# to catch logs generated by tracing\\nexport RUST_LOG=trace\\n```\\n\\nAnd for the one of the most obnoxious things ever, we will use a script to download\\nthe inputs instead of \u201c_clicking, opening and copying to a file_\u201d[^1]. There is\\nno need to be _fancy_, so we will adjust Python script by Martin[^2].\\n\\n```py\\n#!/usr/bin/env python3\\n\\nimport datetime\\nimport yaml\\nimport requests\\nimport sys\\n\\n\\ndef load_config():\\n with open(\\"env.yaml\\", \\"r\\") as f:\\n js = yaml.load(f, Loader=yaml.Loader)\\n return js[\\"session\\"], js[\\"year\\"]\\n\\n\\ndef get_input(session, year, day):\\n return requests.get(\\n f\\"https://adventofcode.com/{year}/day/{day}/input\\",\\n cookies={\\"session\\": session},\\n headers={\\n \\"User-Agent\\": \\"{repo} by {mail}\\".format(\\n repo=\\"gitlab.com/mfocko/advent-of-code-2022\\",\\n mail=\\"me@mfocko.xyz\\",\\n )\\n },\\n ).content.decode(\\"utf-8\\")\\n\\n\\ndef main():\\n day = datetime.datetime.now().day\\n if len(sys.argv) == 2:\\n day = sys.argv[1]\\n\\n session, year = load_config()\\n problem_input = get_input(session, year, day)\\n\\n with open(f\\"./inputs/day{day:>02}.txt\\", \\"w\\") as f:\\n f.write(problem_input)\\n\\n\\nif __name__ == \\"__main__\\":\\n main()\\n```\\n\\nIf the script is called without any arguments, it will deduce the day from the\\nsystem, so we do not need to change the day every morning. It also requires a\\nconfiguration file:\\n\\n```yaml\\n# env.yaml\\nsession: \u2039your session cookie\u203a\\nyear: 2022\\n```\\n\\n### Libraries\\n\\nLooking at the list of the libraries, I have chosen \u201ca lot\u201d of them. Let\'s walk\\nthrough each of them.\\n\\n[`tracing`] and [`tracing-subscriber`] are the crates that can be used for tracing\\nand logging of your Rust programs, there are also other crates that can help you\\nwith providing backtrace to the Sentry in case you have deployed your application\\nsomewhere and you want to watch over it. In our use case we will just utilize the\\nmacros for debugging in the terminal.\\n\\n[`thiserror`], [`anyhow`] and [`color-eyre`] are used for error reporting.\\n`thiserror` is a very good choice for libraries, cause it extends the `Error`\\nfrom the `std` and allows you to create more convenient error types. Next is\\n`anyhow` which kinda builds on top of the `thiserror` and provides you with simpler\\nerror handling in binaries[^3]. And finally we have `color-eyre` which, as I found\\nout later, is a colorful (_wink wink_) extension of `eyre` which is fork of `anyhow`\\nwhile supporting customized reports.\\n\\nIn the end I have decided to remove `thiserror` and `anyhow`, since first one is\\nsuitable for libraries and the latter was basically fully replaced by `{color-,}eyre`.\\n\\n[`regex`] and [`lazy_static`] are a very good and also, I hope, self-explanatory\\ncombination. `lazy_static` allows you to have static variables that must be initialized\\nduring runtime.\\n\\n[`itertools`] provides some nice extensions to the iterators from the `std`.\\n\\n### My own \u201clibrary\u201d\\n\\nWhen creating the crate for this year\'s Advent of Code, I have chosen a library\\ntype. Even though standard library is huge, some things might not be included and\\nalso we can follow _KISS_. I have 2 modules that my \u201clibrary\u201d exports, one for\\nparsing and one for 2D vector (that gets used quite often during Advent of Code).\\n\\nKey part is, of course, processing the input and my library exports following\\nfunctions that get used a lot:\\n\\n```rust\\n/// Reads file to the string.\\npub fn file_to_string>(pathname: P) -> String;\\n\\n/// Reads file and returns it as a vector of characters.\\npub fn file_to_chars>(pathname: P) -> Vec;\\n\\n/// Reads file and returns a vector of parsed structures. Expects each structure\\n/// on its own line in the file. And `T` needs to implement `FromStr` trait.\\npub fn file_to_structs, T: FromStr>(pathname: P) -> Vec\\nwhere\\n ::Err: Debug;\\n\\n/// Converts iterator over strings to a vector of parsed structures. `T` needs\\n/// to implement `FromStr` trait and its error must derive `Debug` trait.\\npub fn strings_to_structs(\\n iter: impl Iterator\\n) -> Vec\\nwhere\\n ::Err: std::fmt::Debug,\\n U: Deref;\\n\\n/// Reads file and returns it as a vector of its lines.\\npub fn file_to_lines>(pathname: P) -> Vec;\\n```\\n\\nAs for the vector, I went with a rather simple implementation that allows only\\naddition of the vectors for now and accessing the elements via functions `x()`\\nand `y()`. Also the vector is generic, so we can use it with any numeric type we\\nneed.\\n\\n### Skeleton\\n\\nWe can also prepare a template to quickly bootstrap each of the days. We know\\nthat each puzzle has 2 parts, which means that we can start with 2 functions that\\nwill solve them.\\n\\n```rust\\nfn part1(input: &Input) -> Output {\\n todo!()\\n}\\n\\nfn part2(input: &Input) -> Output {\\n todo!()\\n}\\n```\\n\\nBoth functions take reference to the input and return some output (in majority\\nof puzzles, it is the same type). `todo!()` can be used as a nice placeholder,\\nit also causes a panic when reached and we could also provide some string with\\nan explanation, e.g. `todo!(\\"part 1\\")`. We have not given functions a specific\\ntype and to avoid as much copy-paste as possible, we will introduce type aliases.\\n\\n```rust\\ntype Input = String;\\ntype Output = i32;\\n```\\n\\n:::tip\\n\\nThis allows us to quickly adjust the types only in one place without the need to\\ndo _regex-replace_ or replace them manually.\\n\\n:::\\n\\nFor each day we get a personalized input that is provided as a text file. Almost\\nall the time, we would like to get some structured type out of that input, and\\ntherefore it makes sense to introduce a new function that will provide the parsing\\nof the input.\\n\\n```rust\\nfn parse_input(path: &str) -> Input {\\n todo!()\\n}\\n```\\n\\nThis \u201cparser\u201d will take a path to the file, just in case we would like to run the\\nsample instead of input.\\n\\nOK, so now we can write a `main` function that will take all of the pieces and\\nrun them.\\n\\n```rust\\nfn main() {\\n let input = parse_input(\\"inputs/dayXX.txt\\");\\n\\n println!(\\"Part 1: {}\\", part_1(&input));\\n println!(\\"Part 2: {}\\", part_2(&input));\\n}\\n```\\n\\nThis would definitely do :) But we have installed a few libraries and we want to\\nuse them. In this part we are going to utilize _[`tracing`]_ (for tracing, duh\u2026)\\nand _[`color-eyre`]_ (for better error reporting, e.g. from parsing).\\n\\n```rust\\nfn main() -> Result<()> {\\n tracing_subscriber::fmt()\\n .with_env_filter(EnvFilter::from_default_env())\\n .with_target(false)\\n .with_file(true)\\n .with_line_number(true)\\n .without_time()\\n .compact()\\n .init();\\n color_eyre::install()?;\\n\\n let input = parse_input(\\"inputs/dayXX.txt\\");\\n\\n info!(\\"Part 1: {}\\", part_1(&input));\\n info!(\\"Part 2: {}\\", part_2(&input));\\n\\n Ok(())\\n}\\n```\\n\\nThe first statement will set up tracing and configure it to print out the logs to\\nterminal, based on the environment variable. We also change the formatting a bit,\\nsince we do not need all the _fancy_ features of the logger. Pure initialization\\nwould get us logs like this:\\n\\n```\\n2022-12-11T19:53:19.975343Z INFO day01: Part 1: 0\\n```\\n\\nHowever after running that command, we will get the following:\\n\\n```\\n INFO src/bin/day01.rs:35: Part 1: 0\\n```\\n\\nAnd the `color_eyre::install()?` is quite straightforward. We just initialize the\\nerror reporting by _color eyre_.\\n\\n:::warning[caution]\\n\\nNotice that we had to add `Ok(())` to the end of the function and adjust the\\nreturn type of the `main` to `Result<()>`. It is caused by the _color eyre_ that\\ncan be installed only once and therefore it can fail, that is how we got the `?`\\nat the end of the `::install` which _unwraps_ the **\xbbresult\xab** of the installation.\\n\\n:::\\n\\nOverall we will get to a template like this:\\n\\n```rust\\nuse aoc_2022::*;\\n\\nuse color_eyre::eyre::Result;\\nuse tracing::info;\\nuse tracing_subscriber::EnvFilter;\\n\\ntype Input = String;\\ntype Output = i32;\\n\\nfn parse_input(path: &str) -> Input {\\n todo!()\\n}\\n\\nfn part1(input: &Input) -> Output {\\n todo!()\\n}\\n\\nfn part2(input: &Input) -> Output {\\n todo!()\\n}\\n\\nfn main() -> Result<()> {\\n tracing_subscriber::fmt()\\n .with_env_filter(EnvFilter::from_default_env())\\n .with_target(false)\\n .with_file(true)\\n .with_line_number(true)\\n .without_time()\\n .compact()\\n .init();\\n color_eyre::install()?;\\n\\n let input = parse_input(\\"inputs/dayXX.txt\\");\\n\\n info!(\\"Part 1: {}\\", part_1(&input));\\n info!(\\"Part 2: {}\\", part_2(&input));\\n\\n Ok(())\\n}\\n```\\n\\n[^1]:\\n Copy-pasting might be a relaxing thing to do, but you can also discover\\n nasty stuff about your PC. See [this Reddit post and the comment].\\n\\n[^2]: [GitHub profile](https://github.com/martinjonas)\\n[^3]:\\n Even though you can use it even for libraries, but handling errors from\\n libraries using `anyhow` is nasty\u2026 You will be the stinky one ;)\\n\\n[_advent of code_]: https://adventofcode.com\\n[gitlab]: https://gitlab.com/mfocko/advent-of-code-2022\\n[cargo]: https://doc.rust-lang.org/cargo/\\n[`rust-analyzer`]: https://rust-analyzer.github.io/\\n[`direnv`]: https://direnv.net/\\n[`tracing`]: https://crates.io/crates/tracing\\n[`tracing-subscriber`]: https://crates.io/crates/tracing-subscriber\\n[`thiserror`]: https://crates.io/crates/thiserror\\n[`anyhow`]: https://crates.io/crates/anyhow\\n[`color-eyre`]: https://crates.io/crates/color-eyre\\n[`regex`]: https://crates.io/crates/regex\\n[`lazy_static`]: https://crates.io/crates/lazy_static\\n[`itertools`]: https://crates.io/crates/itertools\\n[this reddit post and the comment]: https://www.reddit.com/r/adventofcode/comments/zb98pn/comment/iyq0ono"}]}')}}]); \ No newline at end of file diff --git a/assets/js/4200b1a9.e049437f.js b/assets/js/4200b1a9.e049437f.js new file mode 100644 index 0000000..10bc30d --- /dev/null +++ b/assets/js/4200b1a9.e049437f.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkfi=self.webpackChunkfi||[]).push([[866],{24612:e=>{e.exports=JSON.parse('{"blogPosts":[{"id":"/2024/07/20/raspberry-alma","metadata":{"permalink":"/blog/2024/07/20/raspberry-alma","editUrl":"https://github.com/mfocko/blog/tree/main/blog/2024-07-20-raspberry-alma.md","source":"@site/blog/2024-07-20-raspberry-alma.md","title":"Raspberry Alma","description":"Finally migrating to a stable distro on Raspberry\u2026\\n","date":"2024-07-20T00:00:00.000Z","formattedDate":"July 20, 2024","tags":[{"label":"raspberry-pi","permalink":"/blog/tags/raspberry-pi"},{"label":"opensuse","permalink":"/blog/tags/opensuse"},{"label":"almalinux","permalink":"/blog/tags/almalinux"},{"label":"ansible","permalink":"/blog/tags/ansible"},{"label":"self-hosting","permalink":"/blog/tags/self-hosting"}],"readingTime":5.945,"hasTruncateMarker":true,"authors":[{"name":"Matej Focko","email":"me+blog@mfocko.xyz","title":"a.k.a. useless admin or \u201cSir Tweak-a-Lot\u201d","url":"https://gitlab.com/mfocko","imageURL":"https://github.com/mfocko.png","key":"mf"}],"frontMatter":{"title":"Raspberry Alma","description":"Finally migrating to a stable distro on Raspberry\u2026\\n","date":"2024-07-20T00:00:00.000Z","authors":[{"key":"mf","title":"a.k.a. useless admin or \u201cSir Tweak-a-Lot\u201d"}],"tags":["raspberry-pi","opensuse","almalinux","ansible","self-hosting"]},"unlisted":false,"nextItem":{"title":"DevConf.cz 2024","permalink":"/blog/2024/06/19/devconf-2024"}},"content":"Every now and then I get angry at something not working on the Raspberry and so\\nI decide to swap the OSs. Now it\'s time for something new and not expected.\\n\\n\x3c!--truncate--\x3e\\n\\n## Purpose and past\\n\\nAfter I\'ve subscribed a VPS at vpsfree.cz for myself, I got an opportunity to\\ndrop using an old laptop for running a local \u201cserver\u201d. At that point all I\'ve\\nhad was self-hosted Gitea, some aliases on nginx and that was all. Out with the\\nold laptop and let\'s begin experimenting with the Raspberry, right?\\n\\nThe first OS that got on the Raspberry was _archLinux_ (BTW\u2026). I\'ve been using\\nit for a long time and had the best experience with. I haven\'t hit any issues,\\nbut at the same time, you need to keep in mind we\'re running it off the SD card\\nand they are known to get worn out quickly, especially if you write **a lot**\\nwhich\u2026 guess what, is quite common with rolling and bleeding-edge distribution\\n:smile: And the worst part is keeping up with the updates.\\n\\nAnd that\'s how I migrated to openSUSE Leap :) I\'ve been using openSUSE for at\\nleast 4 years during the high school and a bit more before and after\u2026 openSUSE\\nis very user-friendly (YaST is amazing) distribution and honestly just works.\\nHowever the cost lies in Cockpit not being available[^1] and some weird design\\ndecision, e.g., networking stack is very fragile[^2].\\n\\nAnd I\'ve got finished in the recent weeks with some issues during updates, but\\nthose can be, of course, blamed on me, cause I don\'t watch over it as I should\\n:)\\n\\nI should probably sum up the latest state of what was running before I decided\\nto go for a merciless wipe. So here it is:\\n\\n- local Gitea instance, just in case and out of habit\\n- Wireguard connection for easy administration\\n- Certbot & nginx; nginx is probably the biggest piece of work as it also\\n provides reverse proxy for mikrotik router and Ubiquiti AP provided by ISP\\n- CUPS server that has joined the journey once the HP printer was too big of\\n a pain in the :peach: to handle via USB\\n- DDNS service, cause there\'s public, but dynamic IP from ISP\\n\\n## Choosing the next distro\\n\\nI had the switch in mind for some time, but I couldn\'t decide on the\\ndistribution\u2026 In the ideal world, I\'d just slap CentOS Stream on it, **but**\\nthere\'s no Raspberry \u201csupport\u201d for CentOS[^3]. So the other choices were plain\\nDebian and something else from the RHEL-family which could be either Fedora[^4],\\nAlmaLinux or Rocky Linux.\\n\\nI should admit that I\'m not a big Debian fan :smile: Even though _12 bookworm_\\nis relatively on the same terms as anything that tries to match RHEL9, it still\\nfeels weird. That might be caused by the fact that I\'ve switched RPM-based\\ndistributions a long time ago (including screwing around with archLinux and\\n_Jean Tux_[^5]) and never looked back (except for the desktop with NVIDIA GPU\\nthat\'s pain in the :peach: and only Ubuntu runs reasonably\u2026 well).\\n\\nWearing the _red fedora_ also ruled out the Rocky Linux :slightly*smiling_face:\\nas I don\'t endorse nor support their \\\\_way of operation*\\n\\nSo AlmaLinux it is!\\n\\n## Installing AlmaLinux 9\\n\\nI\'m going with AlmaLinux 9.4 on Raspberry Pi 3B. Opened the AlmaLinux\'s wiki and\\nfirst thing I got slapped by is\\n\\n> original Raspberry Pi 3 (without \\"+\\" models) are not supported\\n\\nGREAT! I took the risk, installed it. And it didn\'t boot :grin: It turns out\\nthat the WiFi kernel module caused a kernel panic on the boot. From some people\\non Reddit I found that it caused some issues, **but** worked, so I\'ve just\\ndecided to pop the SD card back in a PC and deny the module from loading. Voil\xe0!\\nIt boots!\\n\\n## Setting up the \u201clocal server\u201d\\n\\n:::caution Public disclaimer\\n\\nI suck as admin\u2026\\n\\n:::\\n\\nBoth the Raspberry and my VPS are maintained in the _caveman-style_ :smile: And\\nthat\'s why I\'ve decided to start with the less painful one (the Raspberry) to\\nwrite the Ansible playbooks for :)\\n\\nI have already managed to migrate my dotfiles and \u201cbootstrap\u201d to be run via\\nAnsible, so I\'ve just proceeded to extend that and also reorganize it a bit,\\ncause the roles grew in size :eyes:\\n\\nAnd I have to admit that I\'ve been mostly successful. Let\'s delve into details!\\n\\n### SELinux\\n\\nYeah\u2026 that\'s something that hasn\'t been running on the openSUSE and I totally\\nforgot that hardening the SSHD config (including port change) requires notifying\\nSELinux about the port change :) Of course I managed to cut myself off :smile:\\n\\n### Certbot\\n\\nCertbot was the service I feared the most, as there is no reasonable way to\\nautomate this. You need to run it manually at least the first time. But in the\\nend, it was quite OK.\\n\\n### Cockpit\\n\\nOne downside of _caveman-style_ administration is the fact that you forget about\\nthe tweaking you do. Reverse proxy breaks Cockpit by default. I was reading\\nthrough the documentation, but haven\'t managed to find the part that mentioned\\nthe specific settings I had to change. When I was about to open the PR with\\nproposed changes, I noticed that it was in a different chapter :man_facepalming:\\n\\n### CUPS\\n\\nCups went rather smoothly\u2026 except for the fact that it doesn\'t work on the one\\nand only Ubuntu desktop and there are no logs with reason why it fails to add\\nthe printer :slightly_smiling_face:\\n\\nAdditionally installing the HP printer via `hp-setup` is very interesting\\nexperience\u2026 I would\'ve never expected the CLI to have a progress bar that opens\\nup at 0% and then just switches into _terms & conditions_\u2026 Yes, that progress\\nbar stayed at 0% even though it was downloading a PPD file **and progressing**.\\n\\n### DDNS\\n\\nI had smallish issue with deciding how to run the DDNS service. I went with\\ndropping my own buggy script and had to choose a DDNS client. Found _inadyn_\\n(that isn\'t built at all for Fedora and family) and _ddclient_. The _ddclient_\\nhad some not very nice feedback, and the version that introduced the Cloudflare\\nsupport I need, was not included, so I dropped that. _inadyn_ is not packaged,\\nso I\'ve set it up as systemd timer spawning a container :)\\n\\n## Summary\\n\\nOverall I\'ve had a very pleasant experience setting up the AlmaLinux on the\\nRaspberry. Even though I took a gamble with the officially unsupported model of\\nRPi, it works. And it also seems to be filling the purpose it has!\\n\\n[^1]:\\n AFAIK there was some issue with dependencies, so it is available on\\n Tumbleweed and also in the latest Leap 15.6\\n\\n[^2]:\\n By default uses _wicked_ and even when running it on desktop via\\n _NetworkManager_ I\'ve hit some inconsistencies with DNS, but\u2026 DNS **is** the\\n Devil, right? :grin:\\n\\n[^3]: And neither RHEL to be fair ;)\\n[^4]:\\n 6-month release cycle goes against the idea to have the least amount of\\n updates as possible\u2026 and on top of that I think that we can safely agree on\\n the fact that Fedora feels like _archLinux with extra steps_\\n\\n[^5]: Gentoo\u2026"},{"id":"/2024/06/19/devconf-2024","metadata":{"permalink":"/blog/2024/06/19/devconf-2024","editUrl":"https://github.com/mfocko/blog/tree/main/blog/2024-06-19-devconf-2024.md","source":"@site/blog/2024-06-19-devconf-2024.md","title":"DevConf.cz 2024","description":"Sharing my experience on DevConf.cz 2024.\\n","date":"2024-06-19T00:00:00.000Z","formattedDate":"June 19, 2024","tags":[{"label":"\ud83c\udfed","permalink":"/blog/tags/\ud83c\udfed"},{"label":"red-hat","permalink":"/blog/tags/red-hat"},{"label":"fedora","permalink":"/blog/tags/fedora"},{"label":"devconf","permalink":"/blog/tags/devconf"},{"label":"conferences","permalink":"/blog/tags/conferences"}],"readingTime":5.36,"hasTruncateMarker":true,"authors":[{"name":"Matej Focko","email":"me+blog@mfocko.xyz","title":"a.k.a. exhausted DevConf attendee","url":"https://gitlab.com/mfocko","imageURL":"https://github.com/mfocko.png","key":"mf"}],"frontMatter":{"title":"DevConf.cz 2024","description":"Sharing my experience on DevConf.cz 2024.\\n","date":"2024-06-19T00:00:00.000Z","authors":[{"key":"mf","title":"a.k.a. exhausted DevConf attendee"}],"tags":["\ud83c\udfed","red-hat","fedora","devconf","conferences"]},"unlisted":false,"prevItem":{"title":"Raspberry Alma","permalink":"/blog/2024/07/20/raspberry-alma"},"nextItem":{"title":"LTS distributions","permalink":"/blog/2024/02/07/lts-distros"}},"content":"I\'d like to share my experience and views on some of the talks that I\'ve\\nattended on the DevConf.cz 2024.\\n\\n\x3c!--truncate--\x3e\\n\\n## Day 1\\n\\nLet\'s start with the first day which was Thursday this year as opposed to the\\nprevious years when the conference started on Friday and finished on Sunday.\\n\\nLet\'s start with the _[keynote]_. The keynote wasn\'t very interesting, at some of\\nthe slides actually felt like advertisement for other talks on the topic of the\\nAI\u2026\\n\\nNext talk about _[event-driven Ansible]_ was way more interesting. It allows you\\nto run Ansible playbooks after provisioning hosts, or on certain events, such as\\ndiscovered vulnerabilities. On one hand it feels like a very nice thing, but on\\nthe other one I can\'t help but to think how you need to write the playbooks, so\\nthat they are generic enough. One more example that\'s been given comes from the\\npossibility to react to tickets, e.g., outages and this feels like something\\nthat could be abused to cause DoS.\\n\\nAfterwards we\'ve seen two lightning talks, one about\\n_[choosing the right OpenShift size]_ which was a pretty quick, but listed all\\nof the possible ways you can deploy OpenShift in detail. This lightning talk\\nwas followed by the first AI (lightning) talk I\'ve attended about\\n_[rapid prototyping]_ of the open-source AI models.\\n\\nAs someone who\'s involved in the automation of the RPM packaging and testing, of\\ncourse, we had to attend _[Learning from Nix]_. Nix has a very intriguing\\nconcept which is pretty powerful, but painful at the same time. This can be\\nsummed up pretty nicely by [Tsoding] who got asked about some tips & tricks for\\nsomeone who wants to try out NixOS:\\n\\n> Just don\'t.\\n\\nAnd now we\'re moving into a section where everything revolves about the Packit\\nTeam :)\\n\\nFirst talk about _[changelogs]_ was an interactive session that was (probably)\\nmeant to share different approaches we take to handle this rather convoluted\\ntopic that involves changelogs on both upstream and also on downstream with no\\nrules[^1].\\n\\n![changelogs](https://i.imgur.com/YHstMAt.jpg)\\n\\nNext one was about _[static analysis]_ done by [OpenScanHub]. I like the idea of\\nrunning the static analysis that can uncover nasty bugs (as it has been even\\nshowed in the talk) at the same time as they are introduced. I gotta admit that\\nafter seeing the UI of the [deployed OpenScanHub] on the Fedora Infra, I couldn\'t\\nhelp but to think about the [United States Graphics Company] :smile: The UI is\\nto the point, no fancy annoying shit, you get what you need, it\'s hard to get\\nlost. **Just simplicity.** Best kind of UI/UX in my opinion.\\n\\nAfter the OpenScanHub talk we\'re getting to talks that were taken in a totally\\ndifferent direction from the usual talks you\'re used to :wink: First one was\\ngiven title of _[\u201cIndiana Jones and obsoleted projects\u201d]_ by [Mirek]. He talked\\nabout projects that got obsoleted, but started with projects that had no\\nrelation to IT field at all. I\'d mark this talk as a _stand up_ without any\\nhesitation.\\n\\nAnd finally we will wrap up the first day with the talk where speakers spoke the\\nleast\u2026 _[\u201cLet the users speak!\u201d]_ that involved users of both Packit and\\nTesting Farm who spoke about their use case and benefits they gained from using\\nboth services in a symbiosis.\\n\\n## Day 2\\n\\nOn the second day I\'ve attended less talks to not burn myself out :) I\'ve\\nstarted with an AI-related talk with title _[\u201cAI: Open source will save us!\u201d]_,\\neven though this talk has been improvised, as the speakers from the schedule\\ncouldn\'t have attended, it provided a nice overview what [InstructLab] can do\\nand how can you \u201cfeed\u201d the relevant info into the language models by yourself.\\n\\nAfter that I attended a _\u201ccoffee enthusiasts Meetup\u201d_ which was very nice and,\\nof course, an organized chaos :wink:\\n\\nBefore attending the social event I wrapped up the second day with a lightning\\ntalk about _[recent updates in Toolbx]_. I\'ve used both [toolbx] and\\n[distrobox], so it\'s nice to see the improvements in progress and also that both\\nprojects are well and lively.\\n\\n## Day 3\\n\\nOn the third day I\'ve attended only in the afternoon. \u201cStarted\u201d my day with\\na discussion _[\u201cLeadership: Where people skills meet programmers\u201d]_ which was\\nvery nice for gaining an insight into how developer, manager and QE lead roles\\noverlap.\\n\\nThat talk has been followed up by a talk about [role rotation] in our Packit\\nTeam. I would say it is a nice \u201cupgrade\u201d to the agile process which allows you\\nto not create a single point of failure in the mundane and repetitive processes\\nwithin your team.\\n\\nAnd this day has been finished off with a talk about [shifting left] in Podman.\\nIt\'s nice to see how other teams utilize our Packit Service and also the\\nservices we rely on, such as [Copr] or [Testing Farm]. With the help of Cockpit\\ntests they can catch breaking changes early on, or even bugs that have been\\nintroduced and break usage of the dependent projects.\\n\\n![shifting left](https://i.imgur.com/bp6FxT9.jpg)\\n\\n## Picks from the Packit Team\\n\\nOn the Tuesday, during our Packit stand up, I have managed to abuse my\\nKanban Lead role to collect some of the talks that each of us would recommend:\\n\\n- [Rapid Prototyping] with Open Source AI Models\\n- Do you like your [changelogs]?\\n- OpenScanHub - [Static Analysis] of a Linux Distribution\\n- Creating a [Language Server] for RPM Spec Files\\n- Containers and Kubernetes Made Easy: A 15-minute dive into [Podman Desktop]\\n- [\u201cLeadership: Where people skills meet programmers\u201d]\\n\\n## Wrap up\\n\\nI have to admit that these 3 days have been pretty exhaustive, including\\ninformation overload :smile: but at the same time it was really nice to meet\\nwith the colleagues and at least some of our users who are not based in Brno.\\n\\n[^1]: except for the Fedora\'s downstream ;)\\n\\n[keynote]: https://pretalx.com/devconf-cz-2024/talk/AD3HWR/\\n[event-driven ansible]: https://pretalx.com/devconf-cz-2024/talk/3UKGLB/\\n[choosing the right openshift size]: https://pretalx.com/devconf-cz-2024/talk/KSDRWL/\\n[rapid prototyping]: https://pretalx.com/devconf-cz-2024/talk/H9QFLM/\\n[learning from nix]: https://pretalx.com/devconf-cz-2024/talk/NNKT3F/\\n[tsoding]: https://twitch.tv/tsoding\\n[changelogs]: https://pretalx.com/devconf-cz-2024/talk/ECU7QS/\\n[static analysis]: https://pretalx.com/devconf-cz-2024/talk/7C38GJ/\\n[openscanhub]: https://openscanhub.dev/\\n[deployed openscanhub]: https://openscanhub.fedoraproject.org/\\n[united states graphics company]: https://x.com/usgraphics\\n[\u201cindiana jones and obsoleted projects\u201d]: https://pretalx.com/devconf-cz-2024/talk/X8SYDG/\\n[mirek]: https://rodina-sucha.cz/@mirek\\n[\u201clet the users speak!\u201d]: https://pretalx.com/devconf-cz-2024/talk/BDMWF3/\\n[\u201cai: open source will save us!\u201d]: https://pretalx.com/devconf-cz-2024/talk/QSF9QQ/\\n[instructlab]: https://github.com/instructlab/instructlab\\n[recent updates in toolbx]: https://pretalx.com/devconf-cz-2024/talk/SXWE7K/\\n[toolbx]: https://containertoolbx.org/\\n[distrobox]: https://distrobox.it/\\n[\u201cleadership: where people skills meet programmers\u201d]: https://pretalx.com/devconf-cz-2024/talk/8PARM8/\\n[role rotation]: https://pretalx.com/devconf-cz-2024/talk/8T88MT/\\n[shifting left]: https://pretalx.com/devconf-cz-2024/talk/WVNJZS/\\n[copr]: https://copr.fedorainfracloud.org/\\n[testing farm]: https://docs.testing-farm.io/Testing%20Farm/0.1/index.html\\n[language server]: https://pretalx.com/devconf-cz-2024/talk/RXKMKA/\\n[podman desktop]: https://pretalx.com/devconf-cz-2024/talk/HKWP7V/"},{"id":"/2024/02/07/lts-distros","metadata":{"permalink":"/blog/2024/02/07/lts-distros","editUrl":"https://github.com/mfocko/blog/tree/main/blog/2024-02-07-lts-distros.md","source":"@site/blog/2024-02-07-lts-distros.md","title":"LTS distributions","description":"Shower thoughts on the LTS Linux distributions.\\n","date":"2024-02-07T00:00:00.000Z","formattedDate":"February 7, 2024","tags":[{"label":"lts","permalink":"/blog/tags/lts"},{"label":"linux distributions","permalink":"/blog/tags/linux-distributions"},{"label":"support","permalink":"/blog/tags/support"},{"label":"paywall","permalink":"/blog/tags/paywall"}],"readingTime":14.515,"hasTruncateMarker":true,"authors":[{"name":"Matej Focko","email":"me+blog@mfocko.xyz","title":"a.k.a. small Fedora maintainer","url":"https://gitlab.com/mfocko","imageURL":"https://github.com/mfocko.png","key":"mf"}],"frontMatter":{"title":"LTS distributions","description":"Shower thoughts on the LTS Linux distributions.\\n","date":"2024-02-07T00:00:00.000Z","authors":[{"key":"mf","title":"a.k.a. small Fedora maintainer"}],"tags":["lts","linux distributions","support","paywall"],"hide_table_of_contents":false},"unlisted":false,"prevItem":{"title":"DevConf.cz 2024","permalink":"/blog/2024/06/19/devconf-2024"},"nextItem":{"title":"Mixed feelings on Rust","permalink":"/blog/2024/01/28/rust-opinion"}},"content":"Linux distributions are a common choice for running the servers. There\'s a wide\\nvariety of distributions, but on the servers majority is made by only a few.\\n\\nSome corporations also profit from the support of the \u201cbig\u201d distributions. Let\'s\\ndive into the pros, cons and peculiarities of such _business_.\\n\\nThis post is inspired/triggered by the following Mastodon post:\\n[![Mastodon post about Ubuntu Pro](https://i.imgur.com/mh5RAlV.png)](https://hackers.town/@antijingoist/111864760073049505)\\n\\n\x3c!--truncate--\x3e\\n\\n:::warning Disclaimer\\n\\nYou may take my opinion with a grain of salt, since I\'m affiliated with Red Hat,\\nbut at the same time I\'ve also seen the other side of the fence, so I know how\\nit works from the perspective of the provider/maintainer.\\n\\n:::\\n\\n:::tip\\n\\nIf you are not very oriented in the matters of Linux distributions and\\nmaintaining of packages, I suggest looking at the [glossary](#glossary) at the\\nend to have a better grasp of the terms that are used throughout the post.\\n\\n:::\\n\\n## Point of linux distributions\\n\\nFirst thing I\'d like to point out is the point of the Linux distributions. What\\nbenefit do they provide? And why there are so many of them\u2026\\n\\nAs it has been brought up many times by the _rms_[^1], Linux by itself is not\\nenough, it\'s just the kernel that does the underlying work. We need more\\nsoftware to utilize the hardware. That\'s the gap that Linux distributions bridge\\nby providing the Linux and much more other software that we need.\\n\\nEach distribution is unique in its own way. Some prefer different ways of\\nhandling the software (like Gentoo that allows you to compile it yourself) and\\nothers stable releases of software (like Debian).\\n\\nIn the end it mostly boils down to the packaging. I, as a user, want to do\\nsomething like\\n\\n```\\n$ sudo dnf5 install firefox\\n```\\n\\nand not bother about anything else. I don\'t want to open browser to look the\\nthing up, download it and then click mindlessly 500\xd7 \u201cNext\u201d. I just want to run\\none command and when the maintainers decide it\'s time to move on, another one to\\nupgrade the software to the newer version.\\n\\nOf course, for some use cases you want to minimize the latter. And even make\\nsure that it\'s safe to do it when you need to. You don\'t want to break your\\nproduction deployment just because someone decided it\'s time to push something\\nout.\\n\\nThat\'s when the _maintainers_ come in. They take upon themselves the\\nresponsibility of maintaining the packages. If you\'ve ever used the Debian, you\\nknow very well how _old_ the software is, but that\'s what you might need for\\nyour servers.\\n\\n## Pain of packaging\\n\\nPackaging software _is not_ cost-free. You may as well have 80 % of packages\\nthat don\'t need much care and it\'s rather easy to push them forward, but those\\nremaining, which are complicated and raise issues regularly, will make it up and\\ntake a lot of time and also pain.\\n\\nLibraries are the most common example that might not need much work to be done.\\nOn the other hand, Linux kernel itself is a rather complicated machinery that\\nis patched **a lot** and its build process is not simple either.\\n\\nEven if you consider just those _easily-maintainble_ packages, the process can\\nbe tedious, boring and overall time consuming.\\n\\n:::tip Shameless RHEL-based ecosystem plug\\n\\n[Packit] can help tremendously with the _easily-maintainable_ packages, since it\\n**can** be automated.\\n\\n:::\\n\\n### Packaging whole ecosystems\\n\\nNow it\'s time to talk about whole ecosystems that have some kind of a packaging\\nby themselves. Yes, I mean Python (with its continuous stream of different\\npackage managers), Rust, Go, etc.\\n\\nWhole point of packaging is to have some form of _gating_. In other words, you\\nwant some kind of _quality control_ when pushing changes into the Linux distros.\\n\\nIf you want to package some tool (or even library) from the aforementioned\\necosystems, you need to package all of the dependencies to make sure something\\ndoesn\'t get updated in the meantime (and also that you can safely reproduce the\\nbuilds, if need be).\\n\\nI\'ve tried to package some utilities for EPEL both in Rust and Go. Dependencies\\nform a DAG[^2] and in case of Rust, it\'s _very_ similar to the way `npm` does\\nits packaging.\\n\\n:::danger Spoiler alert\\n\\nYou get a lot of dependencies. And since it\'s a tree of dependencies, there may\\nbe **a lot** of them.\\n\\n:::\\n\\nI have no clue how do the Rust maintainers operate, but I\'m tipping my fedora in\\ntheir direction, since it must be a _pain in the ass_.\\n\\n## Paid distributions\\n\\nYou can find few Linux distributions that are \u201cpaid\u201d. I\'m very well aware of the\\nfact I\'ve used quotes around the word, cause it\'s not that easy and not even\\nsame for all of the distributions that involve some kind of a payment.\\n\\nOne of the first non-free distributions I\'ve come into contact was _[Zorin OS]_\\nwhich basically tries to be the best _transition_ solution when moving away from\\nthe Windows or macOS. If you have a look at the _perks_ of its _Pro_ version\\nthat\'s paid, you may as well decide they are rather questionable\u2026\\n\\nIt\'s time to move into the _Ubuntu Pro_, _RHEL_ and _SLE_ territory. What\'s the\\npoint of those? They definitely offer different kind of, let\'s say,\\n_non-free experience_.\\n\\nWith those you are paying mainly for the support and bug/security patches.\\n\\n:::tip Fun fact\\n\\nThere\'s no mention of any kind of support on the Zorin page\u2026 Apart from the fact\\nthat _you are supporting_ the Zorin development.\\n\\n:::\\n\\n## Repository structure\\n\\nAs I have mentioned above, the three _services_[^3] I mentioned are providing\\nsupport with regards to bugs and security vulnerabilites. Therefore it makes\\nsense to have some kind of a process in place when you\'re pushing changes\\n(either updates, patches or _security_ patches) to the distribution. And yes,\\nthese processes are _in place_.\\n\\nIf you think about the amount of packages that is present in the community\\ndistributions like _archLinux_ (14,830 packages) or _Fedora_ (74,309 packages),\\nit is safe to come to a conclusion that _there\'s no way_ to support all of them.\\n\\n:::tip archLinux\\n\\nIt may seem that archLinux contains rather small set of packages, but one of the\\n_killer features_ of archLinux lies in the AUR (archLinux User Repository) where\\nyou can find additional **93,283** packages.\\n\\n:::\\n\\nThat\'s why the Linux distributions have some structure to their repositories\\nthat contain packages. The way you go around this is rather simple, you choose\\nsome set of _critical_ packages that you guarantee support for (like Linux\\nkernel, openSSL, etc.) and maintain those with all the QA processes in place.\\n\\n:::warning Unpopular opinion\\n\\nThis is also one of the reasons why I\'m quite against packaging anything and\\neverything into the Linux distribution. In my opinion it is impossible to\\n**properly** maintain **huge** set of packages and enforce some kind of\\n**quality control**.\\n\\n:::\\n\\n### Ubuntu\\n\\nUbuntu has pretty granular structure of their repositories, namely:\\n\\n- `main` containing the \u201ccore\u201d of the Ubuntu that is maintained by the Canonical,\\n- `universe` containing literally the \u201cuniverse\u201d, packages that everyone likes,\\n but they\'re not crucial, this repo is maintained mostly by the community,\\n- `multiverse` containing packages with some license or copyright issues, and\\n- `restricted` containing _proprietary_ packages like nvidia drivers and such.\\n\\nBy briefly checking my Ubuntu 23.10 installation, here are stats of packages in\\ntheir respective repositories:\\n\\n- `main` with 6,128 packages,\\n- `universe` with 63,380 packages,\\n- `multiverse` with 997 packages, and finally\\n- `restricted` with 784 packages.\\n\\nAs you can see, if we sum them up, they are relatively similar to the Fedora\\nnumbers.\\n\\n### CentOS\\n\\nCentOS on the other hand has a bit simpler structure with BaseOS for the base\\nand AppStream for additional packages:\\n\\n- `baseos` with 1,058 packages,\\n- `appstream` with 5,646 packages, and\\n- `extras-common` with 42 packages.\\n\\nOverall they make up the similar number as the Ubuntu\'s `main` repository. And\\nyou can also notice that there are no additional repositories.\\n\\n:::tip\\n\\nThere\'s also a CRB (CodeReady Builder) repository with dev packages like headers\\nand such.\\n\\nAnd you can also enable EPEL (Extra Packages for Enterprise Linux) which is\\ncommunity-supported and provides another 19,903 packages.\\n\\n:::\\n\\n## Ubuntu Pro\\n\\nNow it\'s time to get back to the Ubuntu Pro. There are multiple points that need\\nto be taken in account to be either positive or negative about it\u2026\\n\\nWe can start with the way Ubuntu is released and maintained. Ubuntu has regular\\n6-month release cycle and biannual LTS release. Releases are normally supported\\nfor 9 months with the exception of the LTS releases being supported for 5 years.\\n\\nIf you check out the _[Ubuntu Pro]_ website, you can find the following\\nstatement:\\n\\n> **Ubuntu Pro**\\n>\\n> The most comprehensive subscription for open-source software security\\n>\\n> 30-day trial for enterprises. Always free for personal use.\\n\\n:::tip Personal use\\n\\nUbuntu Pro for _personal use_ consists of 5 installations and in case of the\\ncommunity _ambassadors_ 50.\\n\\n:::\\n\\nOverall if you try to find what is included in the Ubuntu Pro:\\n\\n- high and critical patches,\\n- 10 years of maintenance, and\\n- (optional) 24/7 enterprise-grade support.\\n\\nIf we get back to the screenshot all the way at the beginning of the post:\\n[![Mastodon post about Ubuntu Pro](https://i.imgur.com/mh5RAlV.png)](https://hackers.town/@antijingoist/111864760073049505)\\n\\nand try to look up to which repository the packages mentioned in the screenshot\\nbelong, we will find out that they belong to `universe` repository which is\\nmaintained by the community. Not to mention nature of the packages: multimedia.\\n\\nYou may think about this as a scam, but considering repository consisting of 70k\\npackages, it is not an easy task to do. And with LTS releases we\'re talking\\nabout 5+ years of support.\\n\\n:::info Fedora\\n\\nTry to compare this state to Fedora. It also has a 6-month release cycle, but\\nthere are no LTS releases and each release is supported only for a year.\\n\\n:::\\n\\nCommon strategy, at this point, is to pull out the _open-source_. Yes, we are\\nstill dealing with the open-source, but keep in mind that you\'re trying to patch\\nsome issue in a version that\'s 5 years old, upstream definitely doesn\'t care\\nanymore[^4], the development didn\'t stop 5 years ago, it\'s going on and fixing\\nthis issue in a release from 5 years is not the same as fixing it in the current\\nrelease. At this point, if you are paying for such support, you are actually\\npaying for someone to do _software archaeology_ which **can be** _non-trivial_\\nto do.\\n\\nIn the case of Ubuntu Pro we\'re talking about community support and best-effort\\nsupport by Canonical for the paying customers. And that makes sense to me,\\nrunning LTS distro for 5+ years on a desktop seems like an odd choice, even\\nwith the help of _[podman]_ and _[distrobox]_ or _[toolbx]_ that allow us to use\\nstable or LTS distro as a base and containerized development environments on top\\nof that.\\n\\n## RHEL ecosystem\\n\\nRHEL ecosystem is much more complicated in this matter. However it\'s very\\nsimilar to the way SUSE operates with few exceptions.\\n\\nYou can see a flow diagram here:\\n\\n```mermaid\\nflowchart LR;\\n U[upstream] --\x3e FR[Fedora Rawhide];\\n FR --\x3e F[Fedora release];\\n F --\x3e C[CentOS Stream];\\n C --\x3e R[RHEL];\\n```\\n\\nKey things to take and not to take from the flow diagram:\\n\\n- getting from one upstream to its respective downstream is not as simple as the\\n presence of an arrow and it\'s not the same process for all of them\\n- lengths of the arrows are not proportional, specifically:\\n - Fedora Rawhide is _supposed to_ consume updates as soon as possible,\\n - depending on the decision of the maintainer they can, but _don\'t have to_ be\\n included in the currently supported Fedora releases (you can take [Emacs] as\\n an example of such package), but Rawhide eventually becomes the next Fedora\\n release,\\n - CentOS Stream gets branched off a specific Fedora release, and then\\n - ultimately CentOS Stream becomes the next **minor** release of RHEL.\\n- this diagram is simplified by **a lot**\\n\\n:::tip SUSE flow for comparison\\n\\nI\'ll also include a SUSE flow, so you can compare:\\n\\n```mermaid\\nflowchart LR;\\n U[upstream] --\x3e T[openSUSE Tumbleweed];\\n T --\x3e L[openSUSE Leap];\\n L --\x3e S[SUSE Linux Enterprise];\\n S --\x3e L;\\n```\\n\\nYou can notice, as opposed to the RHEL ecosystem, some changes are being\\nbackported to the openSUSE Leap.\\n\\nHowever this is subject to change as there is a new [ALP] project arising which\\nis, more than likely, going to replace the Leap.\\n\\n:::\\n\\n### Change in the model\\n\\nThe flow I\'ve shown above is in effect since late \u201820 and early \u201821. I hope you\\ncan see that it is quite similar to the way SUSE operates too. Before late \u201820\\nthe flow was following:\\n\\n```mermaid\\nflowchart LR;\\n U[upstream] --\x3e FR[Fedora Rawhide];\\n FR --\x3e F[Fedora release];\\n F --\x3e R[RHEL];\\n R --- C[CentOS];\\n```\\n\\nCentOS was the last distribution in that \u201cchain\u201d. This provides some benefits\\nand some negatives.\\n\\n#### Before the change\\n\\nFrom the point of a developer, unless you have some kind of an early access to\\nRHEL, you don\'t see the changes until they land and are already released. This\\nimpairs your ability to test and verify your software before shipping it to your\\nclients that use RHEL.\\n\\nFrom the point of a user, there is one positive, you basically get \u201cfree RHEL\u201d\\nwithout the support. This also allowed you to report bugs against the RHEL,\\nsince they were 1:1 distros (minus the branding and support). So you\'d\\ntechnically get RHEL free of charge.\\n\\nBenefit of such project, except for the cost, is questionable. The main issue,\\nwhich actually became even more apparent after changing the flow, is someone\\nelse repackaging your own product and selling it again.\\n\\n#### After the change\\n\\nFirst of all, the current flow counters the issue mentioned above. You can test\\nyour projects against the _next minor RHEL release_. CentOS Stream is free, so\\nyou can freely incorporate it into your CI pipelines.\\n\\n:::tip Shameless plug pt. 2\\n\\nAgain, [Packit] can help you on upstream to verify that you\'re not breaking your\\nRPM builds and on top of that you can also use [Testing Farm] to run tests on a\\nspecific Fedora or CentOS Stream releases.\\n\\n> Green tests may not be green everywhere and catching such issues as soon as\\n> possible costs much less than catching them further down the chain.\\n\\n:::\\n\\nThere are many people thinking that RHEL has become closed-source. It is not.\\nThe development happens _out in the open_, it\'s more open that it was before.\\nHowever with the cost of not getting the exact same thing for free. You can get\\nthe next minor RHEL, not the same that\'s normally paid for. [Packit] is an\\nexample of a service that is deployed on the CentOS 9 Stream and even used to be\\ndeployed on Fedora, but the regular 6-month release cycle caused some minor\\nissues here and there.\\n\\n_Production-ready_ is something that heavily depends on the context\u2026\\n\\n:::tip Free \u201cclones\u201d\\n\\nAfter this change so-called _free \u201cclones\u201d_ emerged. I have to admit that in\\ncase of _[AlmaLinux]_ I can see some benefits e.g., pushing for live images and\\nsupport of various desktop environments, Raspberry Pi support or even WSL images\\nbeing present in the M$ Store and easy to install.\\n\\n:::\\n\\n## Open-source and paid support\\n\\nOverall I don\'t think that paying for the support of 5 years old _non-critical_\\npackages is going against the open-source. It is a non-trivial work that, in\\nmajority of cases, cannot be included in the upstream, therefore the benefit is\\nreapt only by the paying customers. I have to admit that in the case of the\\nUbuntu Pro it may seem a bit weird (hiding patches behind the paywall). However\\nwe\'re still talking about rather big set of packages that will affect a minority\\nof server workloads, if any.\\n\\n## Glossary\\n\\n- _rolling release_ - continuously released without \u201csignificant milestones\u201d\\n\\n :::tip\\n\\n As an example of rolling distribution you can take archLinux, openSUSE\\n Tumbleweed, Fedora Rawhide, or even CentOS 9 Stream.\\n\\n As en example of **not** rolling distribution you can take Ubuntu, openSUSE\\n Leap or Fedora.\\n\\n :::\\n\\n- _bleeding edge_ - contains the latest versions as they are released on the\\n upstream\\n\\n :::tip\\n\\n As an example you can take archLinux, openSUSE Tumbleweed or Fedora Rawhide.\\n You can also notice how common it is to combine _rolling release_ with\\n _bleeding edge_.\\n\\n :::\\n\\n- _upstream_ & _downstream_\\n\\n You\'re most likely to meet these terms in the meaning of upstream being the\\n project itself and downstream being the packaging of said project in some\\n distribution.\\n\\n However this can also apply to distributions like _openSUSE Tumbleweed_ with\\n _openSUSE Leap_, _Fedora_ with _CentOS Stream_, or even _CentOS Stream_ with\\n _RHEL_. This basically means that the packages/software is being released into\\n the upstream (Tumbleweed, Fedora, or even CentOS) and then after being tested\\n is taken further down into their respective downstreams (Leap, CentOS, RHEL).\\n\\n[almalinux]: https://almalinux.org/\\n[alp]: https://susealp.io/\\n[distrobox]: https://distrobox.it/\\n[emacs]: https://src.fedoraproject.org/rpms/emacs/\\n[packit]: https://packit.dev/\\n[podman]: https://podman.io/\\n[testing farm]: https://docs.testing-farm.io/Testing%20Farm/0.1/index.html\\n[toolbx]: https://containertoolbx.org/\\n[ubuntu pro]: https://ubuntu.com/pro/\\n[zorin os]: https://zorin.com/os/pro/\\n\\n[^1]: Richard Stallman\\n[^2]: directed acyclic graph\\n[^3]:\\n Ubuntu Pro is technically a service whereas the RHEL and SLE are distros\\n with the support included.\\n\\n[^4]:\\n There are upstream projects that keep LTS branches, such as Linux kernel,\\n but even in the case of the kernel itself, they\'re planning on ending it,\\n since the cost outweighs the benefits at this point."},{"id":"/2024/01/28/rust-opinion","metadata":{"permalink":"/blog/2024/01/28/rust-opinion","editUrl":"https://github.com/mfocko/blog/tree/main/blog/2024-01-28-rust-opinion.md","source":"@site/blog/2024-01-28-rust-opinion.md","title":"Mixed feelings on Rust","description":"Discussing my mixed feelings about the Rust language.\\n","date":"2024-01-28T00:00:00.000Z","formattedDate":"January 28, 2024","tags":[{"label":"rust","permalink":"/blog/tags/rust"},{"label":"memory safety","permalink":"/blog/tags/memory-safety"},{"label":"cult","permalink":"/blog/tags/cult"},{"label":"hype","permalink":"/blog/tags/hype"}],"readingTime":15.395,"hasTruncateMarker":true,"authors":[{"name":"Matej Focko","email":"me+blog@mfocko.xyz","title":"a.k.a. passionate language hater","url":"https://gitlab.com/mfocko","imageURL":"https://github.com/mfocko.png","key":"mf"}],"frontMatter":{"title":"Mixed feelings on Rust","description":"Discussing my mixed feelings about the Rust language.\\n","date":"2024-01-28T00:00:00.000Z","authors":[{"key":"mf","title":"a.k.a. passionate language hater"}],"tags":["rust","memory safety","cult","hype"],"hide_table_of_contents":false},"unlisted":false,"prevItem":{"title":"LTS distributions","permalink":"/blog/2024/02/07/lts-distros"},"nextItem":{"title":"How can Copr help with broken dependencies","permalink":"/blog/2023/08/02/copr"}},"content":"Rust has become a rather popular language these days. I\'ve managed to get my\\nhands dirty with it during _[Advent of Code]_ \u201822 and partially \u201823. I\'ve also\\nused it for few rounds of _[Codeforces]_ and I have to try very hard to maintain\\nsome variety of languages for LeetCode challenges along with the Rust. I\'ll\\ndisclaim up front that I won\'t be only positive, since this post is a result of\\nmultiple discussions about Rust and I stand by\\n_\u201cAll that glitters is not gold\u201d_, so if you can\'t stand your favorite language\\nbeing criticized in any way, don\'t even proceed. :wink:\\n\\n\x3c!--truncate--\x3e\\n\\n## Memory safety\\n\\nI\'ll start by kicking the biggest benefit of the language, the memory safety.\\nLet\'s be honest here, majority of the checks rely on the static analysis, cause\\nyou can\'t do anything else during the compile-time, right? Therefore we can\\nbasically say that we are relying on the compiler to \u201csolve\u201d all of our issues.\\n\\n:::danger\\n\\nI\'m not doubting the fact that compiler can prevent **a lot** of the memory\\nerrors, I\'m just saying it\'s not realistic to cover **everything**.\\n\\n:::\\n\\n### Compiler\\n\\nI guess we can safely[^2] agree on the fact that we 100% rely on the compiler to\\n_have our back_. Is the compiler bug-free? I doubt it. This is not meant in an\\noffensive way to the Rust compiler developers, but we need to be realistic here.\\nIt\'s a compiler, even older and larger projects like _gcc_ or _llvm_ can\'t avoid\\nbugs to appear.\\n\\nWhen I was trying out Rust for some of the LeetCode challenges I\'ve stumbled\\nupon the following warning:\\n![Example of a compiler bug](https://i.imgur.com/NfPLF6o.png)\\n\\n:::danger [Issue](https://github.com/rust-lang/rust/issues/59159)\\n\\nThe issue here comes from the fact that we have 2 simultaneous references to the\\nsame memory (one is mutable and one immutable). If you cannot think of any way\\nthis can break, I\'ll give you a rather simple example from C++ where this could\\ncause an issue.\\n\\nImagine a function that has some complex object and also calls a coroutine which\\nutilizes read-only reference to that object. When the coroutine suspends, the\\ncaller can modify the object. This can break the integrity of data read by the\\ncoroutine.\\n\\n- Yes, this **can** cause a memory error.\\n- Yes, this **hasn\'t** been handled until someone noticed it.\\n\\nFixing this bug is not backwards compatible, cause you\'re covering a case that\\nhasn\'t been covered before.\\n\\n:::\\n\\n### Enforcing the safety\\n\\nOne of the ways Rust enforces the safety is by restricting what you can do, like\\nthe example above. Aforementioned issue _can_ happen, but **doesn\'t have to**.\\nRule of the thumb in the Rust compiler is to _\u201cblock\u201d_ anything that can be an\\nissue, static analysis can\'t do much more, it cannot decide whether it\'s safe to\\ndo it or not.\\n\\nSatisfying the Rust compiler is sometimes a brutal pain in the ass, because you\\ncannot do things like you\'re used to, you need to work around them _somehow_.\\n\\n:::tip\\n\\nKey difference between Rust and C or C++ lies in the fact that Rust chooses to\\n_ban_ all \u201cpotentially offensive\u201d actions, C and C++ _relies_ on **you** to be\\nsure it\'s safe to do.\\n\\n![C++ v. Rust](https://i.imgur.com/0vbkYPp.png)\\n\\n:::\\n\\n### Consequences\\n\\nWhere are we heading with this approach of \u201cif it compiles, it runs\u201d though?\\nIn this aspect I have a rather similar opinion as with regards to the ChatGPT\\nand its derivatives.\\n\\nIf you teach people to 100% depend on the compiler, they will do it, cause it\'s\\n_easy_. All you need to do is make the compiler _shut up_[^3]. Giving up the\\n_intellectual masturbation_ about the memory safety will make you lose your edge\\nover the time. When we get to the point of everyone being in the mindset\\nmentioned above, who\'s going to maintain the compiler? This is the place where\\nyou **need to** think about the memory safety and furthermore in a much more\\ngeneral way than in your own projects, because it is the thing that everyone\\n_blindly believes in_ in the end.\\n\\nI\'m not saying that everyone should give up Rust and think about their memory\\nmanagement and potential memory issues. I\'m just saying that going the easy way\\nwill make people _dull_ and they should think about it anyways, that\'s how the\\nissue above has been discovered. If everyone walked past and didn\'t think about\\nit, no one would discover this issue till it bit them hard.\\n\\n:::tip Standard library\\n\\nEven the standard library is littered with `unsafe` blocks that are prefixed\\nwith comments in style:\\n\\n```rs\\n// SAFETY: \u2026\\n```\\n\\nThe fact that the _casual_ Rust dev doesn\'t have to think much about safety,\\ncause the compiler has their back, doesn\'t mean that the Rust compiler dev\\ndoesn\'t either.\\n\\nI gotta admit that I adopted this concept in other languages (even in Python),\\ncause you can encounter situations where it doesn\'t have to be clear _why_ you\\ncan do _what_ you\'re doing.\\n\\n:::\\n\\n## Development & design\\n\\nDevelopment of Rust is\u2026 very fast. One positive is that they\'re trying to be as\\nbackward compatible as possible at least by verifying against all the published\\ncrates in the process. Of course, you cannot be backward compatible about fixing\\nthe bugs that have been found, but such is life.\\n\\n### Fast development cycle\\n\\nOne of the negatives of the fast development cycle is the fact that they\'re\\nusing the latest features already in the next release of the Rust. Yes, it is\\nsomething that you can use for verifying and testing your own changes, but at\\nthe same time it places a requirement of the latest release to compile the next\\none.\\n\\n:::tip\\n\\nIf you check `gcc` for example, they have a requirement of minimal version of\\ncompiler that you need for the build. Though gcc\'s requirement is not so _needy_\\nas the Rust one.\\n\\n:::\\n\\nOne of the other negatives is the introduction of bugs. If you\'re pushing\\nchanges, somewhat mindlessly, at such a fast pace, it is inevitable to introduce\\na bunch bugs in the process. Checking the GitHub issue tracker with\\n\\n```\\nis:issue is:open label:C-bug label:T-compiler\\n```\\n\\nyields **2,224** open issues at the time of writing this post.\\n\\n### RFCs\\n\\nYou can find **a lot** of RFCs for the Rust. Some of them are more questionable\\nthan the others. Fun thing is that a lot of them make it to the nightly builds,\\nso they can be tested and polished off. Even the questionable ones\u2026 I\'ll leave\\nfew examples for a better understanding.\\n\\nOne of such features is the `do yeet` expression:\\n\\n```rust\\n#![feature(yeet_expr)]\\n\\nfn foo() -> Result {\\n do yeet 4;\\n}\\nassert_eq!(foo(), Err(4));\\n\\nfn bar() -> Option {\\n do yeet;\\n}\\nassert_eq!(bar(), None);\\n```\\n\\nIt allows you to \u201cyeet\u201d the errors out of the functions that return `Result` or\\n`Option`.\\n\\n[One](https://github.com/rust-lang/rfcs/pull/3503) of the more recent ones is\\nthe ability to include Cargo manifests into the sources, so you can do something\\nlike:\\n\\n```rust\\n#!/usr/bin/env cargo\\n---\\n[dependencies]\\nclap = { version = \\"4.2\\", features = [\\"derive\\"] }\\n---\\n\\nuse clap::Parser;\\n\\n#[derive(Parser, Debug)]\\n#[clap(version)]\\nstruct Args {\\n #[clap(short, long, help = \\"Path to config\\")]\\n config: Option,\\n}\\n\\nfn main() {\\n let args = Args::parse();\\n println!(\\"{:?}\\", args);\\n}\\n```\\n\\nI would say you can get almost anything into the language\u2026\\n\\n## Community and hype train\\n\\nRust community is a rather unique thing. A lot of people will hate me for this,\\nbut I can\'t help, but to compare them to _militant vegans_. I\'ll go through some\\nof the things related to it, so I can support my opinion at least.\\n\\n_Rust is the best language._ It is not. There is no best language, each has its\\nown positives and negatives, you need to choose the language that\'s **the most**\\n**suitable for your use case**. There are areas where Rust excels, though I have\\nto admit it\'s very close to being a universal hammer regardless of how suitable\\nit is. There is a very steep learning curve to it, beginnings in Rust are very\\npainful.\\n\\n_Rewrite everything in Rust._ Just no. There are multiple feedbacks on doing\\nrewrites, it is very common to fix _N_ bugs with a rewrite while introducing\\n_N + 1_ other bugs in the process. It doesn\'t solve anything unless there are\\nsome strong reasons to go with it. Majority of such suggested rewrites don\'t\\nhave those reasons though.\\n\\n_Language \u2039x\u203a is bad, though in Rust\u2026_ Cherry-picking one specific pain point of\\none language and reflecting how it is better in other language can go both ways.\\nFor example it is rather easy to pick the limitations imposed by Rust compiler\\nand show how it\'s possible in other languages :man_shrugging:\\n\\nI don\'t mind any of those opinions, you\'re free to have them, as long as you\\ndon\'t rub them in my face which is not the usual case\u2026 This experience makes it\\njust worse for me, part of this post may be also influenced by this fact.\\n\\n### Rust in Linux\\n\\n:::warning[caution]\\n\\nAs someone who has seen the way Linux kernel is built in the RHEL ecosystem, how\\ncomplex the whole thing is and how much resources you need to proceed, I have\\nvery strong opinions on this topic.\\n\\n:::\\n\\nIt took years of work to even \u201cincorporate\u201d Rust into the Linux codebase, just\\nto get the \u201cHello World!\u201d. I don\'t have anything against the idea of writing\\ndrivers in the Rust, I bet it can catch a lot of common mistakes, but still\\nintroducing Rust to the kernel is another step to enlarge the monster.\\n\\nI have to admit though that the _Apple GPU_ driver for Linux written in Rust is\\nquite impressive. Apart from that there are not so many benefits, yet\u2026\\n\\n## Packaging\\n\\nI\'ll divide the packaging into the packaging of the language itself and the\\nprograms written in Rust.\\n\\nLet\'s start with the `cargo` itself though. Package managers of the languages\\nusually get a lot of hate (you can take `npm` or `pip` as examples[^1]). If\\nyou\'ve ever tried out Rust, I bet you already know where I\'m going with this.\\nYes, I mean the compilation times, or even Cargo downloading _whole_ index of\\ncrates just so you can update that one dependency (and 3 millions of indirect\\ndeps). When I was doing AoC \u201822 in Rust, I\'ve set up `sccache` right away on the\\nfirst day.\\n\\nLet\'s move to the packaging of the Rust itself, it\'s tedious. Rust has a very\\nfast development cycle and doesn\'t even try to make the builds backward\\ncompatible. If there is a new release of Rust, there is a very high chance that\\nyou cannot build that release with anything other than **the latest** Rust\\nrelease. If you have ever touched the packaging, you know that this is something\\nthat can cause a lot of problems, cause you need the second-to-latest version to\\ncompile the latest version, don\'t forget that this applies inductively\u2026 People\\nrunning _Gentoo_ could tell you a lot about this.\\n\\n:::info\\n\\nCompiling the compilers takes usually more time than compiling the kernel\\nitself\u2026\\n\\n:::\\n\\nI cannot speak about packaging of Rust programs in other than RHEL-based\\ndistros, though I can speak about RHEL ecosystem. Fedora packaging guidelines\\nspecify that you need to build each and every dependency of the program\\nseparately. I wanted to try out _AlmaLinux_ and install Alacritty there and I\\nfailed miserably. The solution that worked, consisted of ignoring the packaging\\nguidelines, running `cargo build` and consuming the binaries afterwards.\\nDependencies of the Rust programs are of a similar nature as JS dependencies.\\n\\n> I\'m tipping my fedora[^2] in the general direction of the maintainers of Rust\\n> packages in RHEL ecosystem. I wouldn\'t be able to do this without losing my\\n> sanity.\\n\\n## Likes\\n\\nIf you\'ve come all the way here and you\'re a Rustacean, I believe I\'ve managed\\nto get your blood boiling, so it\'s time to finish this off by stuff I like about\\nRust. I doubt I will be able to cover everything, but I can try at least. You\\nhave to admit it\'s much easier to remember the bad stuff as opposed to the good.\\n:wink:\\n\\n### Workflow and toolchain\\n\\nI prefered using Rust for the _Advent of Code_ and _Codeforces_ as it provides\\na rather easy way to test the solutions before running them with the challenge\\ninput (or test runner). I can give an example from the _Advent of Code_:\\n\\n```rust\\nuse aoc_2023::*;\\n\\ntype Output1 = i32;\\ntype Output2 = Output1;\\n\\nstruct DayXX {}\\nimpl Solution for DayXX {\\n fn new>(pathname: P) -> Self {\\n let lines: Vec = file_to_lines(pathname);\\n\\n todo!()\\n }\\n\\n fn part_1(&mut self) -> Output1 {\\n todo!()\\n }\\n\\n fn part_2(&mut self) -> Output2 {\\n todo!()\\n }\\n}\\n\\nfn main() -> Result<()> {\\n DayXX::main()\\n}\\n\\ntest_sample!(day_XX, DayXX, 42, 69);\\n```\\n\\nThis was the skeleton I\'ve used and the macro at the end is my own creation that\\nexpands to:\\n\\n```rust\\n#[cfg(test)]\\nmod day_XX {\\n use super::*;\\n\\n #[test]\\n fn part_1() {\\n let path = DayXX::get_sample(1);\\n let mut day = DayXX::new(path);\\n assert_eq!(day.part_1(), 42);\\n }\\n\\n #[test]\\n fn part_2() {\\n let path = DayXX::get_sample(2);\\n let mut day = DayXX::new(path);\\n assert_eq!(day.part_2(), 69);\\n }\\n}\\n```\\n\\nWhen you\'re solving the problem, all you need to do is switch between\\n`cargo test` and `cargo run` to check the answer to either sample or the\\nchallenge input itself.\\n\\nIntroduce [bacon] and it gets even better. Bacon is a CLI tool that wraps around\\nthe `cargo` and allows you to check, run, lint or run tests on each file save.\\nIt\'s a very pleasant thing for a so-called _compiler-assisted_ development.\\n\\nSpeaking of linting from within the bacon, you cannot leave out the [clippy].\\nNot only it can whip your ass because of errors, but it can also produce a lot\\nof helpful suggestions, for example passing slices by borrow instead of\\nborrowing the `Vec` itself when you don\'t need it.\\n\\n### Standard library\\n\\nThere\'s **a lot** included in the standard library. It almost feels like you\\nhave all you need[^4]. I like placeholders (like `todo!()`, `unreachable!()`,\\n`unimplemented!()`) to the extent of\\n[implementing](/cpp/exceptions-and-raii/placeholders) them as exceptions in C++.\\n\\nYou can find almost anything. Though you can also hit some very weird issues\\nwith some of the nuances of the type system.\\n\\n### `unsafe`\\n\\nThis might be something that people like to avoid as much as possible. However I\\nthink that forming a habit of commenting posibly unsafe operations in **any**\\nlanguage is a good habit, as I\'ve mentioned above. You should be able to argue\\nwhy you can do something safely, even if the compiler is not kicking your ass\\nbecause of it.\\n\\nExcerpt of such comment from work:\\n\\n```py\\n# SAFETY: Taking first package instead of specific package should be\\n# safe, since we have put a requirement on \xbbone\xab \u2039upstream_project_url\u203a\\n# per Packit config, i.e. even if we\'re dealing with a monorepo, there\\n# is only \xbbone\xab upstream. If there is one upstream, there is only one\\n# set of GPG keys that can be allowed.\\nreturn self.downstream_config.packages[\\n self.downstream_config._first_package\\n].allowed_gpg_keys\\n```\\n\\n### Traits\\n\\nOne of the other things I like are the traits. They are more restrictive than\\ntemplates or concepts in C++, but they\'re doing their job pretty good. If you\\nare building library and require multiple traits to be satisfied it means a lot\\nof copy-paste, but that\'s soon to be fixed by the [trait aliases].\\n\\n:::tip Comparing to other languages\\n\\nOn Wikipedia I\'ve seen trait being defined as a more restrictive type class as\\nyou may know it from the Haskell for example. C++ isn\'t behind either with its\\n_constraints and concepts_. I would say that we can order them in the following\\norder based on the complexity they can express:\\n\\n```\\nRust\'s trait < Haskell\'s type class < C++\'s concept\\n```\\n\\n:::\\n\\nYou can also hit some issues, like me when trying to support conversions between\\nunderlying numeric types of a 2D vectors or support for using an operator from\\nboth sides (I couldn\'t get `c * u` to work in the same way as `u * c` because\\nthe first one requires you to implement the trait of a built-in type).\\n\\n:::warning Implementation\\n\\nImplementing traits lies in\\n\\n```rust\\nimpl SomeTrait for SomeStruct {\\n // implementation goes here\\n}\\n```\\n\\nOne of the things I **would love to** see is being able to define the helper\\nfunctions within the same block. As of now, the only things allowed are the ones\\nthat are required by the trait, which in the end results in a randomly lying\\nfunctions around (or in a implementation of the structure itself). I don\'t like\\nthis mess at all\u2026\\n\\n:::\\n\\n### Influence of functional paradigm\\n\\nYou can see a big influence of the functional paradigm. Not only in iterators,\\nbut also in the other parts of the language. For example I prefer `Option` or\\n`Result` to `null`s and exceptions. Pattern matching together with\\ncompiler both enforces handling of the errors and rather user-friendly way of\\ndoing it.\\n\\nNot to mention `.and_then()` and such. However spending most of the time with\\nthe AoC you get pretty annoyed of the repetitive `.unwrap()` during parsing,\\nsince you are guaranteed correct input.\\n\\n### Macros\\n\\nMacros are a very strong pro of the Rust. And no, we\'re not going to talk about\\nthe procedural macros\u2026\\n\\nAs I\'ve shown above I\'ve managed to \u201ctame\u201d a lot of copy-paste in the tests for\\nthe AoC by utilizing a macro that generated a very basic template for the tests.\\n\\nAs I have mentioned the traits above, I cannot forget to give props to `derive`\\nmacro that allows you to \u201cdeduce\u201d the default implementation. It is very helpful\\nfor a tedious tasks like implementing `Debug` (for printing out the structures)\\nor comparisons, though with the comparisons you need to be careful about the\\ndefault implementation, it has already bitten me once or twice.\\n\\n## Summary\\n\\nOverall there are many things about the Rust I like and would love to see them\\nimplemented in other languages. However there are also many things I don\'t like.\\nNothing is **exclusively** black and white.\\n\\n[advent of code]: https://adventofcode.com\\n[bacon]: https://dystroy.org/bacon/\\n[clippy]: https://github.com/rust-lang/rust-clippy\\n[codeforces]: https://codeforces.com\\n[trait aliases]: https://github.com/rust-lang/rfcs/blob/master/text/1733-trait-alias.md\\n\\n[^1]:\\n not to even mention multiple different packaging standards Python has, which\\n is borderline https://xkcd.com/927/\\n\\n[^2]: pun intended\\n[^3]: It\'s not that easy with the Rust compiler, but OK\u2026\\n[^4]:\\n unlike Python where there\'s whole universe in the language itself, yet there\\n are essential things not present\u2026"},{"id":"/2023/08/02/copr","metadata":{"permalink":"/blog/2023/08/02/copr","editUrl":"https://github.com/mfocko/blog/tree/main/blog/2023-08-02-copr.md","source":"@site/blog/2023-08-02-copr.md","title":"How can Copr help with broken dependencies","description":"Copr comes to save you when maintainer doesn\'t care.","date":"2023-08-02T00:00:00.000Z","formattedDate":"August 2, 2023","tags":[{"label":"\ud83c\udfed","permalink":"/blog/tags/\ud83c\udfed"},{"label":"red-hat","permalink":"/blog/tags/red-hat"},{"label":"copr","permalink":"/blog/tags/copr"},{"label":"admin","permalink":"/blog/tags/admin"},{"label":"vps","permalink":"/blog/tags/vps"}],"readingTime":3.44,"hasTruncateMarker":true,"authors":[{"name":"Matej Focko","email":"me+blog@mfocko.xyz","title":"a.k.a. your opinionated admin","url":"https://gitlab.com/mfocko","imageURL":"https://github.com/mfocko.png","key":"mf"}],"frontMatter":{"title":"How can Copr help with broken dependencies","description":"Copr comes to save you when maintainer doesn\'t care.","date":"2023-08-02T00:00:00.000Z","authors":[{"key":"mf","title":"a.k.a. your opinionated admin"}],"tags":["\ud83c\udfed","red-hat","copr","admin","vps"]},"unlisted":false,"prevItem":{"title":"Mixed feelings on Rust","permalink":"/blog/2024/01/28/rust-opinion"},"nextItem":{"title":"4th week of Advent of Code \'22 in Rust","permalink":"/blog/aoc-2022/4th-week"}},"content":"When you decide to run Fedora on your VPS, you might get screwed over by using\\nrandom repositories\u2026\\n\\n\x3c!--truncate--\x3e\\n\\nWhen I \u201creserved\u201d my VPS[^1] back in June \'20, I slapped Fedora on it without\\nthinking. I bet 99% of people would say that I\'m crazy for doing such thing[^2],\\n**BUT** I\'ve been using Fedora on my PCs for some time already and it felt very\\nstable and natural to just use, even for VPS.\\n\\nOne of the first things I\'ve done was setting up a mail server. You may guess\\nwhat\'s the fun part about having a mail server\u2026 Yes, it\'s all the spam you\\nreceive and only then you realize how much \u201ccrap\u201d gets filtered on free mail\\nservices. To battle this problem I chose to use\\n[rspamd](https://github.com/rspamd/rspamd) that had CentOS support, but someone\\nhad a [Copr](https://copr.fedorainfracloud.org/) repository that I used to\\ninstall it.\\n\\n## How does Copr repositories work?\\n\\nIf you have ever used Ubuntu, you might be familiar with the concept since it is\\nvery close to [PPAs](https://help.ubuntu.com/community/PPA).\\n\\ntl;dr of the whole process consists of\\n\\n1. enabling the Copr repository, and\\n2. installing the desired package.\\n\\nSo in shell you would do\\n\\n```\\n# dnf copr enable \u2039copr-repository\u203a\\n# dnf install \u2039package-from-the-repository\u203a\\n```\\n\\nAnd\u2026 that\'s it! Nothing else needed! Simple, right? And literally same process\\nas you would do for the PPA.\\n\\n:::tip AUR\\n\\nOn the other hand, if you are familiar with the archLinux, you definitely know\\nAUR and what it can do for you. Copr repository is pretty similar, but the\\npackages are prebuilt in Copr and Copr repositories can carry the required\\ndependencies for said packages, which simplifies the distribution, and can even\\nhelp with installing singular packages (when you just need the dependency, not\\neverything).\\n\\n:::\\n\\n## My issue\\n\\nNow you might wonder how would I use it on my VPS. It\'s rather simple, once in\\n6 months a new Fedora release comes out. And you need to upgrade to newer\\nrelease\u2026 You don\'t need to do it right away and for such setup it probably isn\'t\\neven recommended.\\n\\n:::tip\\n\\nFedora releases are supported for a year, i.e. they live 6 months till the next\\nrelease and then another 6 months till another release.\\n\\nSome people prefer to run one version \u201cbehind\u201d. If you ever decide to run it on\\nyour home server or in a similar setup, it might be a pretty good idea to\\nfollow. I\'m using the \u201clatest greatest\u201d, cause why not :smile:\\n\\nOne way or another, you still need to bump the release every six months, unless\\nyou\'d bump 2 releases at once every year, which would be a decision, since, at\\nleast I, cannot see any benefits in it\u2026 You don\'t go for \u201cstability\u201d, cause once\\na year you switch to the latest release and then, before you bump, you use one\\nyear old software, so you\'re not even using the latest.\\n\\n:::\\n\\nFast-forward 2 years in the future, new Fedora release came out (October \'22)\\nand I was doing an upgrade. Dependencies of the rspamd have been updated and\\nrspamd builds in Copr have failed and no one fixed it. Cool, so now I can\\nupgrade, but can either ignore the dependencies or uninstall the rspamd\u2026\\n\\n## How can Copr help?\\n\\nI have managed to find\\n[specfile](https://github.com/rspamd/rspamd/blob/master/rpm/rspamd.spec) for the\\nrspamd package that they use for CentOS. There were some files apart from the\\nspecfile, so I had to make an SRPM locally and then\u2026 I just uploaded the SRPM\\nto the Copr to\\n[build](https://copr.fedorainfracloud.org/coprs/mfocko/rspamd/build/5046567/)\\nan RPM.\\n\\nI have switched the previous Copr repository for rspamd with my own and happily\\nproceeded with the upgrade.\\n\\n## Conclusion\\n\\nCopr is heavily used for testing builds on the upstream with\\n[Packit](https://packit.dev). However, as you can see, it is possible to use it\\n**very well** for packaging your own stuff and avoiding issues (such as the one\\nI have described above), if need be.\\n\\n[^1]: [vpsFree.cz](https://vpsfree.cz)\\n[^2]:\\n Even though I\'ve been running archLinux on some Raspberry Pi\'s and also\\n on one of my \u201chome servers\u201d, before getting the VPS. You could say I like\\n to live on the edge\u2026"},{"id":"aoc-2022/4th-week","metadata":{"permalink":"/blog/aoc-2022/4th-week","editUrl":"https://github.com/mfocko/blog/tree/main/blog/aoc-2022/04-week-4.md","source":"@site/blog/aoc-2022/04-week-4.md","title":"4th week of Advent of Code \'22 in Rust","description":"Surviving fourth week in Rust.","date":"2023-07-07T15:14:00.000Z","formattedDate":"July 7, 2023","tags":[{"label":"advent-of-code","permalink":"/blog/tags/advent-of-code"},{"label":"advent-of-code-2022","permalink":"/blog/tags/advent-of-code-2022"},{"label":"rust","permalink":"/blog/tags/rust"}],"readingTime":15.315,"hasTruncateMarker":true,"authors":[{"name":"Matej Focko","email":"me+blog@mfocko.xyz","title":"a.k.a. @mf","url":"https://gitlab.com/mfocko","imageURL":"https://github.com/mfocko.png","key":"mf"}],"frontMatter":{"title":"4th week of Advent of Code \'22 in Rust","description":"Surviving fourth week in Rust.","date":"2023-07-07T15:14","slug":"aoc-2022/4th-week","authors":"mf","tags":["advent-of-code","advent-of-code-2022","rust"],"hide_table_of_contents":false},"unlisted":false,"prevItem":{"title":"How can Copr help with broken dependencies","permalink":"/blog/2023/08/02/copr"},"nextItem":{"title":"3rd week of Advent of Code \'22 in Rust","permalink":"/blog/aoc-2022/3rd-week"}},"content":"Let\'s go through the fourth week of [_Advent of Code_] in Rust.\\n\\n\x3c!--truncate--\x3e\\n\\n## [Day 22: Monkey Map](https://adventofcode.com/2022/day/22)\\n\\n:::info tl;dr\\n\\nSimulating a movement on a 2D map with given instructions. Map becomes a cube in\\nthe 2nd part\u2026\\n\\n:::\\n\\n:::danger Rant\\n\\nThis was the most obnoxious problem of this year\u2026 and a lot of Rust issues have\\nbeen hit.\\n\\n:::\\n\\n### Solution\\n\\nIt seems like a very simple problem to solve, but with very obnoxious changes in\\nthe 2nd part and also it\'s relatively hard to decompose \xbbproperly\xab.\\n\\n#### Column iterator\\n\\nIn the first part of the problem it was needed to know the boundaries of each\\nrow and column, since I stored them in `Vec>` and padded with spaces\\nto ensure I have a rectangular 2D \u201carray\u201d. However when you wanted to go through\\neach row and column to determine the boundaries, it was very easy to do for the\\nrows (cause each row is a `Vec` element), but not for the columns, since they\\nspan multiple rows.\\n\\nFor this use case I have implemented my own _column iterator_:\\n\\n```rust\\npub struct ColumnIterator<\'a, T> {\\n map: &\'a [Vec],\\n column: usize,\\n\\n i: usize,\\n}\\n\\nimpl<\'a, T> ColumnIterator<\'a, T> {\\n pub fn new(map: &\'a [Vec], column: usize) -> ColumnIterator<\'a, T> {\\n Self { map, column, i: 0 }\\n }\\n}\\n\\nimpl<\'a, T> Iterator for ColumnIterator<\'a, T> {\\n type Item = &\'a T;\\n\\n fn next(&mut self) -> Option {\\n if self.i >= self.map.len() {\\n return None;\\n }\\n\\n self.i += 1;\\n Some(&self.map[self.i - 1][self.column])\\n }\\n}\\n```\\n\\nGiven this piece of an iterator, it is very easy to factor out the common\\nfunctionality between the rows and columns into:\\n\\n```rust\\nlet mut find_boundaries = |constructor: fn(usize) -> Orientation,\\n iterator: &mut dyn Iterator,\\n upper_bound,\\n i| {\\n let mut first_non_empty = iterator.enumerate().skip_while(|&(_, &c)| c == \' \');\\n let start = first_non_empty.next().unwrap().0 as isize;\\n\\n let mut last_non_empty = first_non_empty.skip_while(|&(_, &c)| c != \' \');\\n let end = last_non_empty.next().unwrap_or((upper_bound, &\'_\')).0 as isize;\\n\\n boundaries.insert(constructor(i), start..end);\\n};\\n```\\n\\nAnd then use it as such:\\n\\n```rust\\n// construct all horizontal boundaries\\n(0..map.len()).for_each(|row| {\\n find_boundaries(\\n Orientation::horizontal,\\n &mut map[row].iter(),\\n map[row].len(),\\n row,\\n );\\n});\\n\\n// construct all vertical boundaries\\n(0..map[0].len()).for_each(|col| {\\n find_boundaries(\\n Orientation::vertical,\\n &mut ColumnIterator::new(&map, col),\\n map.len(),\\n col,\\n );\\n});\\n```\\n\\n#### Walking around the map\\n\\nOnce the 2nd part got introduced, you start to think about a way how not to\\ncopy-paste a lot of stuff (I haven\'t avoided it anyways\u2026). In this problem, I\'ve\\nchosen to introduce a trait (i.e. _interface_) for 2D and 3D walker.\\n\\n```rust\\ntrait Wrap: Clone {\\n type State;\\n\\n // simulation\\n fn is_blocked(&self) -> bool;\\n fn step(&mut self, steps: isize);\\n fn turn_left(&mut self);\\n fn turn_right(&mut self);\\n\\n // movement\\n fn next(&self) -> (Self::State, Direction);\\n\\n // final answer\\n fn answer(&self) -> Output;\\n}\\n```\\n\\nEach walker maintains its own state and also provides the functions that are\\nused during the simulation. The \u201cpromised\u201d methods are separated into:\\n\\n- _simulation_-related: that are used during the simulation from the `.fold()`\\n- _movement_-related: just a one method that holds most of the logic differences\\n between 2D and 3D\\n- _final answer_: which extracts the _proof of solution_ from the\\n implementation-specific walker\\n\\nBoth 2D and 3D versions borrow the original input and therefore you must\\nannotate the lifetime of it:\\n\\n```rust\\nstruct Wrap2D<\'a> {\\n input: &\'a Input,\\n position: Position,\\n direction: Direction,\\n}\\nimpl<\'a> Wrap2D<\'a> {\\n fn new(input: &\'a Input) -> Wrap2D<\'a> {\\n// \u2026\\n```\\n\\n#### Problems\\n\\nI have used a lot of closures for this problem and once I introduced a parameter\\nthat was of unknown type (apart from the fact it implements a specific trait), I\\ngot suggested a \u201cfix\u201d for the compilation error that resulted in something that\\nwas not possible to parse, cause it, more than likely, violated the grammar.\\n\\nIn a similar fashion, I have been suggested changes that led to a code that\\ndidn\'t make sense by just looking at it (there was no need to try the changes),\\nfor example one suggested change in the closure parameter caused disapperance of\\nthe parameter name. :smile:\\n\\n#### Clippy\\n\\nI have to admit that Clippy was rather helpful here, I\'ll include two examples\\nof rather smart suggestions.\\n\\nWhen writing the parsing for this problem, the first thing I have spotted on the\\n`char` was the `.is_digit()` function that takes a radix as a parameter. Clippy\\nnoticed that I use `radix = 10` and suggested switching to `.is_ascii_digit()`\\nthat does exactly the same thing:\\n\\n```diff\\n- .take_while(|c| c.is_digit(10))\\n+ .take_while(|c| c.is_ascii_digit())\\n```\\n\\nAnother useful suggestion appeared when working with the iterators and I wanted\\nto get the $n$-th element from it. You know the `.skip()`, you know the\\n`.next()`, just \u201cslap\u201d them together and we\'re done for :grin: Well, I got\\nsuggested to use `.nth()` that does exactly the combination of the two mentioned\\nmethods on iterators:\\n\\n```diff\\n- match it.clone().skip(skip).next().unwrap() {\\n+ match it.clone().nth(skip).unwrap() {\\n```\\n\\n## [Day 23: Unstable Diffusion](https://adventofcode.com/2022/day/23)\\n\\n:::info tl;dr\\n\\nSimulating movement of elves around with a set of specific rules.\\n\\n:::\\n\\n### Solution\\n\\nThere\'s not much to mention since it\'s just a cellular automaton simulation\\n(even though the AoC rules for cellular automatons usually get out of hand\\n:wink:).\\n\\nAlthough I had a need to determine boundaries of the elves\' positions and ended\\nup with a nasty DRY violation. Knowing that you you\'re looking for maximum and\\nminimum that are, of course, exactly the same except for initial values and\\ncomparators, it looks like a rather simple fix, but typing in Rust is something\\nelse, right? In the end I settled for a function that computes both boundaries\\nwithout any duplication while using a closure:\\n\\n```rust\\nfn get_bounds(positions: &Input) -> (Vector2D, Vector2D) {\\n let f = |init, cmp: &dyn Fn(isize, isize) -> isize| {\\n positions\\n .iter()\\n .fold(Vector2D::new(init, init), |acc, elf| {\\n Vector2D::new(cmp(acc.x(), elf.x()), cmp(acc.y(), elf.y()))\\n })\\n };\\n\\n (f(isize::MAX, &min::), f(isize::MIN, &max::))\\n}\\n```\\n\\nThis function returns a pair of 2D vectors that represent opposite points of the\\nbounding rectangle of all elves.\\n\\nYou might ask why would we need a closure and the answer is that `positions`\\ncannot be captured from within the nested function, only via closure. One more\\nfun fact on top of that is the type of the comparator\\n\\n```rust\\n&dyn Fn(isize, isize) -> isize\\n```\\n\\nOnce we remove the `dyn` keyword, compiler yells at us and also includes a way\\nhow to get a more thorough explanation of the error by running\\n\\n```shell\\n$ rustc --explain E0782\\n```\\n\\nwhich shows us\\n\\n> Trait objects must include the `dyn` keyword.\\n>\\n> Erroneous code example:\\n>\\n> ```\\n> trait Foo {}\\n> fn test(arg: Box) {} // error!\\n> ```\\n>\\n> Trait objects are a way to call methods on types that are not known until\\n> runtime but conform to some trait.\\n>\\n> Trait objects should be formed with `Box`, but in the code above\\n> `dyn` is left off.\\n>\\n> This makes it harder to see that `arg` is a trait object and not a\\n> simply a heap allocated type called `Foo`.\\n>\\n> To fix this issue, add `dyn` before the trait name.\\n>\\n> ```\\n> trait Foo {}\\n> fn test(arg: Box) {} // ok!\\n> ```\\n>\\n> This used to be allowed before edition 2021, but is now an error.\\n\\n:::danger Rant\\n\\nNot all of the explanations are helpful though, in some cases they might be even\\nmore confusing than helpful, since they address _very simple_ use cases.\\n\\nAs you can see, even in this case there are two sides to the explanations:\\n\\n- it explains why you need to use `dyn`, but\\n- it still mentions that trait objects need to be heap-allocated via `Box`\\n that, as you can see in my snippet, **does not** apply here :smile: IMO it\'s\\n caused by the fact that we are borrowing it and therefore we don\'t need to\\n care about the size or whereabouts of it.\\n\\n:::\\n\\n:::info C++ parallel\\n\\nIf you dive into the explanation above, you can notice that the `Box`\\npattern is very helpful for using types that are not known during compile-time.\\nYou would use a very similar approach in C++ when parsing some data structure\\nfrom input (let\'s say JSON for example).\\n\\nOn the other hand, in this case, it doesn\'t really make much sense, cause you\\ncan clearly see that the types **are known** during the compile-time, which in\\nC++ could be easily resolved by templating the helper function.\\n\\n:::\\n\\n## [Day 24: Blizzard Basin](https://adventofcode.com/2022/day/24)\\n\\n:::info tl;dr\\n\\nNavigating your way through a basin with series of blizzards that move around\\nyou as you move.\\n\\n:::\\n\\n:::warning[caution]\\n\\nIt\'s second to last day and I went \u201c_bonkers_\u201d on the Rust :smile: Proceed to\\nread _Solution_ part on your own risk.\\n\\n:::\\n\\n### Solution\\n\\nYou are given a map with blizzards all over the place and you\'re supposed to\\nfind the minimum time it requires you to walk through the basin without getting\\nin any of the blizzards.\\n\\n#### Breakdown\\n\\nRelatively simple, yet a bit annoying, approach can be taken. It\'s technically\\na shortest-path algorithm implementation with some relaxation restrictions and\\nbeing able to stay on one position for some time, so each _vertex_ of the graph\\nis determined by the position on the map and the _timestamp_. I have chosen to\\nuse `Vector3D`, since `x` and `y` attributes can be used for the position\\nand, well, let\'s use `z` for a timestamp, cause why not, right? :wink:\\n\\n#### Evaluating the blizzards\\n\\n:::warning[caution]\\n\\nI think that this is the most perverted abuse of the traits in the whole 4 weeks\\nof AoC in Rust\u2026\\n\\n:::\\n\\nThe blizzards move along their respective directions in time and loop around in\\ntheir respective row/column. Each vertex holds position **and** time, so we can\\n_just_ index the basin with the vertex itself, right? Yes, we can :smiling_imp:\\n\\n:::tip Fun fact\\n\\nWhile writing this part, I\'ve recognized unnecessary verbosity in the code and\\ncleaned it up a bit. The changed version is shown here and the original was just\\nmore verbose.\\n\\n:::\\n\\nI\'ll skip the boring parts of checking bounds and entry/exit of the basin :wink:\\nWe can easily calculate positions of the blizzards using a modular arithmetics:\\n\\n```rust\\nimpl Index for Basin {\\n type Output = char;\\n\\n fn index(&self, index: Position) -> &Self::Output {\\n // \u2039skipped boring parts\u203a\\n\\n // We need to account for the loops of the blizzards\\n let width = self.cols - 2;\\n let height = self.rows - 2;\\n\\n let blizzard_origin = |size, d, t, i| ((i - 1 + size + d * (t % size)) % size + 1) as usize;\\n [\\n (\\n index.y() as usize,\\n blizzard_origin(width, -1, index.z(), index.x()),\\n \'>\',\\n ),\\n (\\n index.y() as usize,\\n blizzard_origin(width, 1, index.z(), index.x()),\\n \'<\',\\n ),\\n (\\n blizzard_origin(height, -1, index.z(), index.y()),\\n index.x() as usize,\\n \'v\',\\n ),\\n (\\n blizzard_origin(height, 1, index.z(), index.y()),\\n index.x() as usize,\\n \'^\',\\n ),\\n ]\\n .iter()\\n .find_map(|&(y, x, direction)| {\\n if self.map[y][x] == direction {\\n Some(&self.map[y][x])\\n } else {\\n None\\n }\\n })\\n .unwrap_or(&\'.\')\\n }\\n}\\n```\\n\\nAs you can see, there is an expression for calculating the original position and\\nit\'s used multiple times, so why not take it out to a lambda, right? :wink:\\n\\nI couldn\'t get the `rustfmt` to format the `for`-loop nicely, so I\'ve just\\ndecided to go with iterating over an elements of a slice. I have used, once\\nagain, a combination of two functions (`find_map` in this case) to do 2 things\\nat once and at the end, if we haven\'t found any blizzard, we just return the\\nempty space.\\n\\nI think it\'s a very _nice_ (and naughty) way how to use the `Index` trait, don\'t\\nyou think?\\n\\n#### Shortest-path algorithm\\n\\nFor the shortest path you can choose and adjust any of the common shortest-path\\nalgorithms, in my case, I have decided to use [_A\\\\*_] instead of Dijkstra\'s\\nalgorithm, since it better reflects the _cost_ function.\\n\\n:::info Comparison of costs\\n\\nWith the Dijkstra\'s algorithm I would proceed with the `time` attribute used as\\na priority for the queue.\\n\\nWhereas with the _A\\\\*_, I have chosen to use both time and Manhattan distance\\nthat promotes vertices closer to the exit **and** with a minimum time taken.\\n\\n:::\\n\\nCost function is, of course, a closure :wink:\\n\\n```rust\\nlet cost = |p: Position| p.z() as usize + exit.y().abs_diff(p.y()) + exit.x().abs_diff(p.x());\\n```\\n\\nAnd also for checking the possible moves from the current vertex, I have\\nimplemented, yet another, closure that yields an iterator with the next moves:\\n\\n```rust\\nlet next_positions = |p| {\\n [(0, 0, 1), (0, -1, 1), (0, 1, 1), (-1, 0, 1), (1, 0, 1)]\\n .iter()\\n .filter_map(move |&(x, y, t)| {\\n let next_p = p + Vector3D::new(x, y, t);\\n\\n if basin[next_p] == \'.\' {\\n Some(next_p)\\n } else {\\n None\\n }\\n })\\n};\\n```\\n\\n#### Min-heap\\n\\nIn this case I had a need to use the priority queue taking the elements with the\\nlowest cost as the prioritized ones. Rust only offers you the [`BinaryHeap`] and\\nthat is a max-heap. One of the ways how to achieve a min-heap is to put the\\nelements in wrapped in a [`Reverse`] (as is even showed in the linked [docs of\\nthe `BinaryHeap`]). However the wrapping affects the type of the heap and also\\npopping the most prioritized elements yields values wrapped in the `Reverse`.\\n\\nFor this purpose I have just taken the max-heap and wrapped it as a whole in a\\nseparate structure providing just the desired methods:\\n\\n```rust\\nuse std::cmp::{Ord, Reverse};\\nuse std::collections::BinaryHeap;\\n\\npub struct MinHeap {\\n heap: BinaryHeap>,\\n}\\n\\nimpl MinHeap {\\n pub fn new() -> MinHeap {\\n MinHeap {\\n heap: BinaryHeap::new(),\\n }\\n }\\n\\n pub fn push(&mut self, item: T) {\\n self.heap.push(Reverse(item))\\n }\\n\\n pub fn pop(&mut self) -> Option {\\n self.heap.pop().map(|Reverse(x)| x)\\n }\\n}\\n\\nimpl Default for MinHeap {\\n fn default() -> Self {\\n Self::new()\\n }\\n}\\n```\\n\\nRest is just the algorithm implementation which is not that interesting.\\n\\n## [Day 25: Full of Hot Air](https://adventofcode.com/2022/day/25)\\n\\n:::info tl;dr\\n\\nPlaying around with a numbers in a _special_ base.\\n\\n:::\\n\\nGetting flashbacks to the _IB111 Foundations of Programming_\u2026 Very nice \u201cproblem\u201d\\nwith a rather easy solution, as the last day always seems to be.\\n\\n### Solution\\n\\nImplementing 2 functions, converting from the _SNAFU base_ and back to the _SNAFU_\\n_base_ representation. Let\'s do a bit more though! I have implemented two functions:\\n\\n- `from_snafu`\\n- `to_snafu`\\n\\nNow it is apparent that all I do is number to string and string to number. Hmm\u2026\\nthat sounds familiar, doesn\'t it? Let\'s introduce a structure for the SNAFU numbers\\nand implement the traits that we need.\\n\\nLet\'s start with a structure:\\n\\n```rust\\n#[derive(Debug, PartialEq, Eq, PartialOrd, Ord)]\\nstruct SNAFU {\\n value: i64,\\n}\\n```\\n\\n#### Converting from `&str`\\n\\nWe will start by implementing the `FromStr` trait that will help us parse our input.\\nThis is rather simple, I can just take the `from_snafu` function, copy-paste it\\ninto the `from_str` method and the number I get will be wrapped in `Result` and\\n`SNAFU` structure.\\n\\n#### Converting to `String`\\n\\nThis is more fun. In some cases you need to implement only one trait and others\\nare automatically implemented using that one trait. In our case, if you look in\\nthe documentation, you can see that `ToString` trait is automatically implemented\\nfor any type that implements `Display` trait.\\n\\nLet\'s implement the `Display` trait then. We should be able to use the `to_snafu`\\nfunction and just take the `self.value` from the `SNAFU` structure.\\n\\nAnd for the convenience of tests, we can also implement a rather simple `From`\\ntrait for the `SNAFU`.\\n\\n#### Adjusting the code\\n\\nAfter those changes we need to adjust the code and tests.\\n\\nParsing of the input is very easy, before we have used the lines, now we parse\\neverything:\\n\\n```diff\\n fn parse_input>(pathname: P) -> Input {\\n- file_to_lines(pathname)\\n+ file_to_structs(pathname)\\n }\\n```\\n\\nPart 1 needs to be adjusted a bit too:\\n\\n```diff\\n fn part_1(input: &Input) -> Output {\\n- to_snafu(input.iter().map(|s| from_snafu(s)).sum())\\n+ SNAFU::from(input.iter().map(|s| s.value).sum::()).to_string()\\n }\\n```\\n\\nYou can also see that it simplifies the meaning a bit and it is more explicit than\\nthe previous versions.\\n\\nAnd for the tests:\\n\\n```diff\\n #[test]\\n fn test_from() {\\n- for (n, s) in EXAMPLES.iter() {\\n- assert_eq!(from_snafu(s), *n);\\n+ for (&n, s) in EXAMPLES.iter() {\\n+ assert_eq!(s.parse::().unwrap().value, n);\\n }\\n }\\n\\n #[test]\\n fn test_to() {\\n- for (n, s) in EXAMPLES.iter() {\\n- assert_eq!(to_snafu(*n), s.to_string());\\n+ for (&n, s) in EXAMPLES.iter() {\\n+ assert_eq!(SNAFU::from(n).to_string(), s.to_string());\\n }\\n```\\n\\n## Summary\\n\\nLet\'s wrap the whole thing up! Keeping in mind both AoC and the Rust\u2026\\n\\n![Finished advent calendar :smile:](/img/blog/aoc-2022/04-week-4/calendar.png)\\n\\n### Advent of Code\\n\\nThis year was quite fun, even though most of the solutions and posts came in\\nlater on (_cough_ in \'23 _cough_). Day 22 was the most obnoxious one\u2026 And also\\nit feels like I used priority queues and tree data structures **a lot** :eyes:\\n\\n### with Rust\\n\\nI must admit that a lot of compiler warnings and errors were very useful. Even\\nthough I still found some instances where they didn\'t help at all or cause even\\nworse issues than I had. Compilation times have been addressed with the caching.\\n\\nBuilding my first tree data structure in Rust has been a very \u201cinteresting\u201d\\njourney. Being able to write a more generic BFS algorithm that allows you to not\\nduplicate code while still mantaining the desired functionality contributes to\\na very readable code.\\n\\nI am definitely much more aware of the basic things that bloated Python is\\nmissing, yet Rust has them\u2026\\n\\nUsing explicit types and writing down placeholder functions with `todo!()`\\nmacros is very pleasant, since it allows you to easily navigate the type system\\nduring the development when you don\'t even need to be sure how are you going to\\nput the smaller pieces together.\\n\\nI have used a plethora of traits and also implemented some of them to either be\\nidiomatic, or exploit the syntactic sugar they offer. Deriving the default trait\\nimplementation is also very helpful in a lot of cases, e.g. debugging output,\\ncopying, equality comparison, etc.\\n\\nI confess to touching more \u201ccursed\u201d parts of the Rust, such as macros to\\ndeclutter the copy-paste for tests or writing my own structures that need to\\ncarry a lifetime for their own fields.\\n\\ntl;dr Relatively pleasant language until you hit brick wall :wink:\\n\\n---\\n\\nSee you next year! Maybe in Rust, maybe not :upside_down_face:\\n\\n[_advent of code_]: https://adventofcode.com\\n[_a\\\\*_]: https://en.wikipedia.org/wiki/A*_search_algorithm\\n[`binaryheap`]: https://doc.rust-lang.org/std/collections/struct.BinaryHeap.html\\n[`reverse`]: https://doc.rust-lang.org/std/cmp/struct.Reverse.html\\n[docs of the `binaryheap`]: https://doc.rust-lang.org/std/collections/struct.BinaryHeap.html#min-heap"},{"id":"aoc-2022/3rd-week","metadata":{"permalink":"/blog/aoc-2022/3rd-week","editUrl":"https://github.com/mfocko/blog/tree/main/blog/aoc-2022/03-week-3.md","source":"@site/blog/aoc-2022/03-week-3.md","title":"3rd week of Advent of Code \'22 in Rust","description":"Surviving third week in Rust.","date":"2023-07-06T21:00:00.000Z","formattedDate":"July 6, 2023","tags":[{"label":"advent-of-code","permalink":"/blog/tags/advent-of-code"},{"label":"advent-of-code-2022","permalink":"/blog/tags/advent-of-code-2022"},{"label":"rust","permalink":"/blog/tags/rust"}],"readingTime":11.57,"hasTruncateMarker":true,"authors":[{"name":"Matej Focko","email":"me+blog@mfocko.xyz","title":"a.k.a. @mf","url":"https://gitlab.com/mfocko","imageURL":"https://github.com/mfocko.png","key":"mf"}],"frontMatter":{"title":"3rd week of Advent of Code \'22 in Rust","description":"Surviving third week in Rust.","date":"2023-07-06T21:00","slug":"aoc-2022/3rd-week","authors":"mf","tags":["advent-of-code","advent-of-code-2022","rust"],"hide_table_of_contents":false},"unlisted":false,"prevItem":{"title":"4th week of Advent of Code \'22 in Rust","permalink":"/blog/aoc-2022/4th-week"},"nextItem":{"title":"Sort the matrix diagonally","permalink":"/blog/leetcode/sort-diagonally"}},"content":"Let\'s go through the third week of [_Advent of Code_] in Rust.\\n\\n\x3c!--truncate--\x3e\\n\\n## [Day 15: Beacon Exclusion Zone](https://adventofcode.com/2022/day/15)\\n\\n:::info tl;dr\\n\\nTriangulating a distress beacon based on the information from the sensors.\\n\\n:::\\n\\n### Solution\\n\\nRelatively easy thing to implement, no major Rust issues hit.\\n\\n## [Day 16: Proboscidea Volcanium](https://adventofcode.com/2022/day/16)\\n\\n:::info tl;dr\\n\\nFinding a max flow in a graph given some time constraints.\\n\\n:::\\n\\n### Solution\\n\\nI have used some interesting things to implement this and make it easier for me.\\n\\n#### Indexing in graph\\n\\nI have come across a situation where I needed to keep more information regarding\\nthe graph\u2026 In that case you can, of course, create a structure and keep it in,\\nbut once you have multiple members in the structure it gets harder to work with\\nsince you need to address the fields in the structure. When you work with graph,\\nyou frequently need to access the vertices and in this case it felt a lot easier\\nto implement the indexing in a graph, rather than explicitly access the\\nunderlying data structure.\\n\\nHere you can see a rather short snippet from the solution that allows you to\\n\u201cindex\u201d the graph:\\n\\n```rust\\nimpl Index<&str> for Graph {\\n type Output = Vertex;\\n\\n fn index(&self, index: &str) -> &Self::Output {\\n &self.g[index]\\n }\\n}\\n```\\n\\n#### Cartesian product\\n\\nDuring the implementation I had to utilize Floyd-Warshall algorithm for finding\\nthe shortest path between pairs of vertices and utilized the `iproduct!` macro\\nfrom the [`itertools`]. It is a very useful higher-order function that allows\\nyou to keep the nesting of the loops at a minimum level while still maintaining\\nthe same functionality.\\n\\n#### \u201cImplementing\u201d an iterator\\n\\nFor the second part, you get to split the work between 2 actors. That way you\\ncan achieve higher efficiency of the whole process that you\'re planning, but it\\nalso makes it harder to evaluate algorithmically, since you need to check the\\ndifferent ways the work can be split.\\n\\nBeing affected by _functional programming brain damage_:tm:, I have chosen to\\ndo this part by function that returns an iterator over the possible ways:\\n\\n```rust\\nfn pairings(\\n valves: &BTreeSet,\\n) -> impl Iterator, BTreeSet)> + \'_ {\\n let mapping = valves.iter().collect_vec();\\n\\n let max_mask = 1 << (valves.len() - 1);\\n\\n (0..max_mask).map(move |mask| {\\n let mut elephant = BTreeSet::new();\\n let mut human = BTreeSet::new();\\n\\n for (i, &v) in mapping.iter().enumerate() {\\n if (mask & (1 << i)) == 0 {\\n human.insert(v.clone());\\n } else {\\n elephant.insert(v.clone());\\n }\\n }\\n\\n (human, elephant)\\n })\\n}\\n```\\n\\n## [Day 17: Pyroclastic Flow](https://adventofcode.com/2022/day/17)\\n\\n:::info tl;dr\\n\\nSimulating an autonomous Tetris where pieces get affected by a series of jets of\\nhot gas.\\n\\n:::\\n\\n### Solution\\n\\nSimilarly to the previous day I have created some iterators :smile:\\n\\n#### Collision detection\\n\\nOnce you need to check for collisions it is very helpful to be able to just\\niterate through the positions that can actually collide with the wall or other\\npiece.\\n\\nTo get the desired behaviour, you can just compose few smaller functions:\\n\\n```rust\\nfn occupied(shape: &[Vec]) -> impl Iterator + \'_ {\\n shape.iter().enumerate().flat_map(|(y, row)| {\\n row.iter().enumerate().filter_map(move |(x, c)| {\\n if c == &\'#\' {\\n Some(Vector2D::new(x as isize, y as isize))\\n } else {\\n None\\n }\\n })\\n })\\n}\\n```\\n\\nIn the end, we get relative positions which we can adjust later when given the\\nspecific positions from iterator. You can see some interesting parts in this:\\n\\n- `.enumerate()` allows us to get both the indices (coordinates) and the line\\n or, later on, the character itself,\\n- `.flat_map()` flattens the iterator, i.e. when we return another iterator,\\n they just get chained instead of iterating over iterators (which sounds pretty\\n disturbing, doesn\'t it?),\\n- and finally `.filter_map()` which is pretty similar to the \u201cbasic\u201d `.map()`\\n with a one, key, difference that it expects the items of an iterator to be\\n mapped to an `Option` from which it ignores nothing (as in `None` :wink:)\\n and also unwraps the values from `Some(\u2026)`.\\n\\n#### Infinite iterator\\n\\nIn the solution we cycle through both Tetris-like shapes that fall down and the\\njets that move our pieces around. Initially I have implemented my own infinite\\niterator that just yields the indices. It is a very simple, yet powerful, piece\\nof code:\\n\\n```rust\\nstruct InfiniteIndex {\\n size: usize,\\n i: usize,\\n}\\n\\nimpl InfiniteIndex {\\n fn new(size: usize) -> InfiniteIndex {\\n InfiniteIndex { size, i: size - 1 }\\n }\\n}\\n\\nimpl Iterator for InfiniteIndex {\\n type Item = usize;\\n\\n fn next(&mut self) -> Option {\\n self.i = (self.i + 1) % self.size;\\n Some(self.i)\\n }\\n}\\n```\\n\\nHowever when I\'m looking at the code now, it doesn\'t really make much sense\u2026\\nGuess what, we can use a built-in function that is implemented on iterators for\\nthat! The function is called `.cycle()`\\n\\nOn the other hand, I am not going to switch to that function, since it would\\nintroduce an another myriad of issues caused by the fact that I create iterators\\nright away in the constructor of my structure and the iterators would borrow\\nboth the jets and shapes which would introduce a lifetime dependency into the\\nstructure.\\n\\n## [Day 18: Boiling Boulders](https://adventofcode.com/2022/day/18)\\n\\n:::info tl;dr\\n\\nLet\'s compute a surface area of some obsidian approximated via coordinates of\\ncubes.\\n\\n:::\\n\\n### Solution\\n\\nThis day is kinda interesting, because it shows how easily you can complicate the\\nproblem and also how much can you screw yourself over with the optimization and\\n\u201csmart\u201d approach.\\n\\nFor the first part you need to find the surface area of an obsidian that is\\napproximated by cubes. Now, that is a very easy thing to do, just keep the track\\nof already added cubes, and check if the newly added cube touches any face of any\\nother cube. Simple, and with a `BTreeSet` relatively efficient way to do it.\\n\\nHowever the second part lets you on a secret that there may be some surface area\\nfrom the \u201cinside\u201d too and you want to know only the one from the outside of the\\nobsidian. I have seen some solutions later, but if you check your data, you might\\nnotice that the bounding box of all the cubes isn\'t that big at all. Therefore I\\nchose to pre-construct the box beforehand, fill in the cubes and then just run a\\nBFS turning all the lava on the outside into the air. Now you just need to check\\ncubes and count how many of their faces touch the air.\\n\\n## [Day 19: Not Enough Minerals](https://adventofcode.com/2022/day/19)\\n\\n:::info tl;dr\\n\\nFinding out the best strategy for building robots to collect geodes.\\n\\n:::\\n\\n### Solution\\n\\nNot much interesting stuff to mention apart from the suggestion to never believe\\nthat the default implementation given by `derive` macro is what you want, it\\ndoesn\'t have to be. :smile:\\n\\n## [Day 20: Grove Positioning System](https://adventofcode.com/2022/day/20)\\n\\n:::info tl;dr\\n\\nShuffling around the _circular linked list_ to find the coordinates.\\n\\n:::\\n\\nNow, small rant for this day is in place. They\'ve never mentioned that coordinates\\ncan repeat and therefore the values are non-unique. This is something that did\\nnot happen in the given sample, but was present in the user input. It took \xbba lot\xab\\nto realize that this is the issue.\\n\\n### Solution\\n\\nI have tried implementing a circular linked list for this\u2026 and I have failed\\nmiserably. To be fair, I still have no clue why. It was \u201cfun\u201d to play around with\\nthe `Rc>`. In the end I failed on _wrong answer_. I have also encountered\\na rather interesting issue with `.borrow_mut()` method being used on `Rc>`.\\n\\n#### `.borrow_mut()`\\n\\nConsider the following snippet of the code (taken from the documentation):\\n\\n```rust\\nuse std::cell::{RefCell, RefMut};\\nuse std::collections::HashMap;\\nuse std::rc::Rc;\\n// use std::borrow::BorrowMut;\\n\\nfn main() {\\n let shared_map: Rc> = Rc::new(RefCell::new(HashMap::new()));\\n // Create a new block to limit the scope of the dynamic borrow\\n {\\n let mut map: RefMut<_> = shared_map.borrow_mut();\\n map.insert(\\"africa\\", 92388);\\n map.insert(\\"kyoto\\", 11837);\\n map.insert(\\"piccadilly\\", 11826);\\n map.insert(\\"marbles\\", 38);\\n }\\n\\n // Note that if we had not let the previous borrow of the cache fall out\\n // of scope then the subsequent borrow would cause a dynamic thread panic.\\n // This is the major hazard of using `RefCell`.\\n let total: i32 = shared_map.borrow().values().sum();\\n println!(\\"{total}\\");\\n}\\n```\\n\\nWe allocate a hash map on the heap and then in the inner block, we borrow it as\\na mutable reference, so that we can use it.\\n\\n:::note\\n\\nIt is a very primitive example for `Rc>` and mutable borrow.\\n\\n:::\\n\\nIf you uncomment the 4th line with `use std::borrow::BorrowMut;`, you cannot\\ncompile the code anymore, because of\\n\\n```\\n Compiling playground v0.0.1 (/playground)\\nerror[E0308]: mismatched types\\n --\x3e src/main.rs:10:34\\n |\\n10 | let mut map: RefMut<_> = shared_map.borrow_mut();\\n | --------- ^^^^^^^^^^^^^^^^^^^^^^^ expected struct `RefMut`, found mutable reference\\n | |\\n | expected due to this\\n |\\n = note: expected struct `RefMut<\'_, _>`\\n found mutable reference `&mut Rc>>`\\n\\nerror[E0599]: no method named `insert` found for struct `RefMut<\'_, _>` in the current scope\\n --\x3e src/main.rs:11:13\\n |\\n11 | map.insert(\\"africa\\", 92388);\\n | ^^^^^^ method not found in `RefMut<\'_, _>`\\n\\nerror[E0599]: no method named `insert` found for struct `RefMut<\'_, _>` in the current scope\\n --\x3e src/main.rs:12:13\\n |\\n12 | map.insert(\\"kyoto\\", 11837);\\n | ^^^^^^ method not found in `RefMut<\'_, _>`\\n\\nerror[E0599]: no method named `insert` found for struct `RefMut<\'_, _>` in the current scope\\n --\x3e src/main.rs:13:13\\n |\\n13 | map.insert(\\"piccadilly\\", 11826);\\n | ^^^^^^ method not found in `RefMut<\'_, _>`\\n\\nerror[E0599]: no method named `insert` found for struct `RefMut<\'_, _>` in the current scope\\n --\x3e src/main.rs:14:13\\n |\\n14 | map.insert(\\"marbles\\", 38);\\n | ^^^^^^ method not found in `RefMut<\'_, _>`\\n\\nSome errors have detailed explanations: E0308, E0599.\\nFor more information about an error, try `rustc --explain E0308`.\\nerror: could not compile `playground` due to 5 previous errors\\n```\\n\\nIt might seem **a bit** ridiculous. However, I got to a point where the compiler\\nsuggested `use std::borrow::BorrowMut;` and it resulted in breaking parts of the\\ncode that worked previously. I think it may be a good idea to go over what is\\nhappening here.\\n\\n##### `.borrow_mut()` on `Rc>`\\n\\nLet\'s consider a variable `x` of type `Rc>`. What happens when you\\ncall `.borrow_mut()` on it? We can look at the `Rc` type, and\u2026 hang on! There is\\nneither `.borrow_mut()` method or `BorrowMut` trait implemented. How can we do it\\nthen?\\n\\nLet\'s go further and we can see that `RefCell` implements a `.borrow_mut()`\\nmethod. OK, but how can we call it on the `Rc`? Easily! `Rc` implements\\n`Deref` and therefore you can call methods on `Rc` objects as if they were\\n`T` objects. If we read on _`Deref` coercion_, we can see the following:\\n\\n> If `T` implements `Deref`, \u2026:\\n>\\n> - \u2026\\n> - `T` implicitly implements all the (immutable) methods of the type `U`.\\n\\nWhat is the requirement for the `.borrow_mut()` on `RefCell`? Well, it needs\\n`&self`, so the `Deref` implements the `.borrow_mut()` for the `Rc>`.\\n\\n##### `BorrowMut` trait\\n\\nI have not been able to find a lot on this trait. My guess is that it provides a\\nmethod instead of a syntactic sugar (`&mut x`) for the mutable borrow. And also\\nit provides default implementations for the types:\\n\\n```rust\\nimpl BorrowMut for String\\n\\nimpl BorrowMut for &mut T\\nwhere\\n T: ?Sized,\\n\\nimpl BorrowMut for T\\nwhere\\n T: ?Sized,\\n\\nimpl BorrowMut<[T]> for Vec\\nwhere\\n A: Allocator,\\n\\nimpl BorrowMut for Box\\nwhere\\n A: Allocator,\\n T: ?Sized,\\n\\nimpl BorrowMut<[T]> for [T; N]\\n```\\n\\n##### Conflict\\n\\nNow the question is why did it break the code\u2026 My first take was that the type\\n`Rc>` has some _specialized_ implementation of the `.borrow_mut()` and\\nthe `use` overrides it with the default, which is true **in a sense**. However\\nthere is no _specialized_ implementation. Let\'s have a look at the trait and the\\ntype signature on the `RefCell`:\\n\\n```rust\\n// trait\\npub trait BorrowMut: Borrow\\nwhere\\n Borrowed: ?Sized,\\n{\\n fn borrow_mut(&mut self) -> &mut Borrowed;\\n}\\n\\n// \u2039RefCell.borrow_mut()\u203a type signature\\npub fn borrow_mut(&self) -> RefMut<\'_, T>\\n```\\n\\nI think that we can definitely agree on the fact that `RefMut<\'_, T>` is not the\\n`RefCell`.\\n\\n**In my opinion**, `RefCell` implements a **separate** `.borrow_mut()` rather\\nthan implementing the interface, because it **cannot** satisfy the type requirements\\nof the trait.\\n\\n:::warning[caution]\\n\\nI wonder how are we expected to deal with this conflict, if and when, we need\\nboth the `.borrow_mut()` of the trait and `.borrow_mut()` of the `RefCell`.\\n\\n:::\\n\\n:::tip Fun fact\\n\\nI was suggested by the compiler to do `use std::borrow::BorrowMut;` and break the\\ncode.\\n\\nSo much for the _almighty_ and _helpful_ compiler\u2026\\n\\n:::\\n\\n## [Day 21: Monkey Math](https://adventofcode.com/2022/day/21)\\n\\n:::info tl;dr\\n\\nComputing an expression tree and then also finding ideal value for a node.\\n\\n:::\\n\\n### Solution\\n\\nRelatively simple, until you get to the 2nd part where you start to practice\\na lot of the copy-paste. I have managed to sneak some perverted stuff in there\\nthough :) Let\'s go through the details.\\n\\n#### `Default` trait\\n\\nFor the first time and twice I had a need to have a default value for my types,\\nenumerations in this case. Rust offers a very nice trait[^1] that is described\\nas:\\n\\n> A trait for giving a type a useful default value.\\n\\nI guess it sums it up nicely. The more interesting part about this is the fact\\nthat you can use the _macro machinery_ to save yourself some typing. If you have\\nenumeration of which the default value doesn\'t bear any parameter, you can just\\ndo[^2]:\\n\\n```rust\\n#[derive(Default)]\\nenum Color {\\n #[default]\\n White,\\n Gray,\\n Black,\\n}\\n```\\n\\n#### Abusing negation\\n\\nIf you want to use a _unary minus_ operator on your own type, you can implement\\na `Neg` trait[^3]. I was dealing with a binary tree and needed a way how to look\\nat the other side, so I have just implemented the negation for flipping between\\nleft and right :smile:\\n\\n[^1]: [`Default`](https://doc.rust-lang.org/std/default/trait.Default.html) docs\\n[^2]: Pardon my example from the graph algorithms ;)\\n[^3]: [`Neg`](https://doc.rust-lang.org/std/ops/trait.Neg.html) docs\\n\\n[_advent of code_]: https://adventofcode.com\\n[`itertools`]: https://crates.io/crates/itertools\\n[this reddit post and the comment]: https://www.reddit.com/r/adventofcode/comments/zb98pn/comment/iyq0ono"},{"id":"leetcode/sort-diagonally","metadata":{"permalink":"/blog/leetcode/sort-diagonally","editUrl":"https://github.com/mfocko/blog/tree/main/blog/leetcode/sort-matrix-diagonally.md","source":"@site/blog/leetcode/sort-matrix-diagonally.md","title":"Sort the matrix diagonally","description":"Compiler assisted development.","date":"2023-03-04T23:15:00.000Z","formattedDate":"March 4, 2023","tags":[{"label":"cpp","permalink":"/blog/tags/cpp"},{"label":"leetcode","permalink":"/blog/tags/leetcode"},{"label":"iterators","permalink":"/blog/tags/iterators"}],"readingTime":16.99,"hasTruncateMarker":true,"authors":[{"name":"Matej Focko","email":"me+blog@mfocko.xyz","title":"a.k.a. @mf","url":"https://gitlab.com/mfocko","imageURL":"https://github.com/mfocko.png","key":"mf"}],"frontMatter":{"title":"Sort the matrix diagonally","description":"Compiler assisted development.","date":"2023-03-04T23:15","slug":"leetcode/sort-diagonally","authors":"mf","tags":["cpp","leetcode","iterators"],"hide_table_of_contents":false},"unlisted":false,"prevItem":{"title":"3rd week of Advent of Code \'22 in Rust","permalink":"/blog/aoc-2022/3rd-week"},"nextItem":{"title":"2nd week of Advent of Code \'22 in Rust","permalink":"/blog/aoc-2022/2nd-week"}},"content":"Let\'s try to solve one of the LeetCode challenges in easy and hard mode at the\\nsame time.\\n\\n\x3c!--truncate--\x3e\\n\\n- Link to the problem: https://leetcode.com/problems/sort-the-matrix-diagonally/\\n\\n## Problem description\\n\\nA **matrix diagonal** is a diagonal line of cells starting from some cell in\\neither the topmost row or leftmost column and going in the bottom-right direction\\nuntil reaching the matrix\'s end. For example, the **matrix diagonal** starting\\nfrom `mat[2][0]`, where `mat` is a `6 x 3` matrix, includes cells `mat[2][0]`,\\n`mat[3][1]`, and `mat[4][2]`.\\n\\nGiven an `m x n` matrix `mat` of integers, sort each matrix diagonal in ascending\\norder and return the resulting matrix.\\n\\n### Example\\n\\n![Image describing the problem](https://assets.leetcode.com/uploads/2020/01/21/1482_example_1_2.png)\\n\\n## Skeleton and initial adjustments\\n\\nWe are given the following skeleton for the C++ and the given challenge:\\n\\n```cpp\\nclass Solution {\\npublic:\\n vector> diagonalSort(vector>& mat) {\\n\\n }\\n};\\n```\\n\\nThe task is to sort the passed matrix diagonally and then return it. First of all,\\nI don\'t like to solve this in a web browser, so we\'ll need to adjust it accordingly\\nfor running it locally. We\'ll start by including the `vector` header and using\\nfully-qualified namespaces[^1] and also adding few tests:\\n\\n```cpp\\n#include \\n#include \\n\\nusing matrix = std::vector>;\\n\\nclass Solution {\\npublic:\\n matrix diagonalSort(matrix& mat)\\n {\\n }\\n};\\n\\nstatic void test_case_1()\\n{\\n // Input: mat = [[3,3,1,1],[2,2,1,2],[1,1,1,2]]\\n // Output: [[1,1,1,1],[1,2,2,2],[1,2,3,3]]\\n\\n Solution s;\\n assert((s.diagonalSort(std::vector { std::vector { 3, 3, 1, 1 },\\n std::vector { 2, 2, 1, 2 },\\n std::vector { 1, 1, 1, 2 } })\\n == std::vector { std::vector { 1, 1, 1, 1 },\\n std::vector { 1, 2, 2, 2 },\\n std::vector { 1, 2, 3, 3 } }));\\n}\\n\\nstatic void test_case_2()\\n{\\n // Input: mat =\\n // [[11,25,66,1,69,7],[23,55,17,45,15,52],[75,31,36,44,58,8],[22,27,33,25,68,4],[84,28,14,11,5,50]]\\n // Output:\\n // [[5,17,4,1,52,7],[11,11,25,45,8,69],[14,23,25,44,58,15],[22,27,31,36,50,66],[84,28,75,33,55,68]]\\n\\n Solution s;\\n assert((s.diagonalSort(std::vector { std::vector { 11, 25, 66, 1, 69, 7 },\\n std::vector { 23, 55, 17, 45, 15, 52 },\\n std::vector { 75, 31, 36, 44, 58, 8 },\\n std::vector { 22, 27, 33, 25, 68, 4 },\\n std::vector { 84, 28, 14, 11, 5, 50 } })\\n == std::vector { std::vector { 5, 17, 4, 1, 52, 7 },\\n std::vector { 11, 11, 25, 45, 8, 69 },\\n std::vector { 14, 23, 25, 44, 58, 15 },\\n std::vector { 22, 27, 31, 36, 50, 66 },\\n std::vector { 84, 28, 75, 33, 55, 68 } }));\\n}\\n\\nint main()\\n{\\n test_case_1();\\n test_case_2();\\n\\n return 0;\\n}\\n```\\n\\nWe need to return the matrix, but we\'re given a reference to the input matrix. We\\ncan easily abuse the C++ here and just switch the reference to value, this way\\nthe matrix will be copied when passed to the function, we can sort the copy and\\njust return it back. And we also get yelled by the compiler for the fact that the\\nmethod doesn\'t return anything yet, so to make it \u201cshut up\u201d we will just return\\nthe input for now:\\n\\n```diff\\n- matrix diagonalSort(matrix& mat)\\n+ matrix diagonalSort(matrix mat)\\n {\\n+ return mat;\\n }\\n```\\n\\nNow, we get the copy and we\'re good to go.\\n\\n## Na\xefve solution\\n\\nAs you may know, C++ offers a plethora of functions that can be used to your\\nadvantage, given that you know how to \u201cbend\u201d the data structures accordingly.\\n\\nWhat does that mean for us? Well, we have an `std::sort`, we can use it, right?\\nLet\'s have a look at it:\\n\\n```cpp\\ntemplate< class RandomIt >\\nvoid sort( RandomIt first, RandomIt last );\\n```\\n\\nThis overload is more than we need. What does it do? It just sorts the elements\\nin the range `[first, last)` using `operator<` on them. We can\'t sort the whole\\nmatrix using this, but\u2026 we can sort just \xbbone\xab diagonal without doing much work\\non our end.\\n\\nWhat is the `RandomIt` type though? If we look more into the documentation, we\\ncan easily find the requirements for it and also learn that it\'s a _random access_\\n_iterator_ and allows swapping its values at the same time.\\n\\n:::tip Random access iterator\\n\\nWhat is the _random access iterator_ though? We can find it in a documentation\\nand see the following description:\\n\\n> A **LegacyRandomAccessIterator** is a [LegacyBidirectionalIterator](https://en.cppreference.com/w/cpp/named_req/BidirectionalIterator)\\n> that can be moved to point to any element in constant time.\\n\\nAfter that we can see all the requirements for it being listed. I don\'t feel like\\nreading them right now, so we will just use it and see where the compilation blows\\nup, i.e. \u201c_compiler-assisted development_\u201d[^2] if you will ;)\\n\\n:::\\n\\nNow we know that we can use `std::sort` to sort the diagonal itself, but we also\\nneed to get the diagonals somehow. I\'m rather lazy, so I\'ll just delegate it to\\nsomeone else[^3]. And that way we get\\n\\n```cpp\\nmatrix diagonalSort(matrix mat)\\n{\\n // we iterate over the diagonals\\n for (auto d : diagonals(mat)) {\\n // and we sort each diagonal\\n std::sort(d.begin(), d.end());\\n }\\n\\n // we take the matrix by copy, so we can sort in-situ and return the copy\\n // that we sorted\\n return mat;\\n}\\n```\\n\\nThis solution looks very simple, doesn\'t it? Well, cause it is.\\nLet\'s try compiling it:\\n\\n```\\nmatrix-sort.cpp:11:23: error: use of undeclared identifier \'diagonals\' [clang-diagnostic-error]\\n for (auto d : diagonals(mat)) {\\n ^\\nFound compiler error(s).\\nmake: *** [makefile:14: tidy] Error 1\\n```\\n\\nOK, seems about right. We haven\'t implemented the `diagonals` yet. And based on\\nwhat we\'ve written so far, we need a function or a class `diagonals` that will\\ngive us the diagonals we need.\\n\\n## Implementing the `diagonals`\\n\\nCool, so we need the function that will let us go through each and every diagonal\\nin our matrix. We use the _for-range_ loop, so whatever we get back from the\\n`diagonals` must support `.begin()` and `.end()`. Since I am a masochist, we will\\ndo such functionality for a matrix of any type, not just the `int` from the challenge.\\n\\nAs I said, we need to be able to\\n\\n- construct the object\\n- get the beginning\\n- get the end (the \u201csentinel\u201d)\\n\\n```cpp\\ntemplate \\nclass diagonals {\\n using matrix_t = std::vector>;\\n\\n matrix_t& _matrix;\\n\\npublic:\\n diagonals(matrix_t& m)\\n : _matrix(m)\\n {\\n }\\n diagonals_iter begin()\\n {\\n /* TODO */\\n }\\n diagonals_iter end()\\n {\\n /* TODO */\\n }\\n};\\n```\\n\\nNow we have a `diagonals` that we can use to go through the diagonals. We haven\'t\\nimplemented the core of it yet. Let\'s go through what we have for now.\\n\\nWe have a templated class with templated `T` that is used as a placeholder for any\\ntype we would store in the matrix. Because I\'m lazy, I have defined the `matrix_t`\\ntype that is a \u201cshortcut\u201d for `std::vector>`, so I don\'t have to\\ntype it out all the time. Of course, we need to store the matrix, we are given,\\nas a private attribute. And then just have the constructor and the 2 methods we\\nneed for the _for-range_.\\n\\n### Iterating over diagonals\\n\\nNow that we have an object that will allow us to iterate through the diagonals,\\nwe need to implement the iterating itself. We need to go through all of them, so\\nwe have multiple options how to do so. I have decided to start from the \u201cmain\u201d\\ndiagonal that starts at `(0, 0)` index and then proceed with the diagonals starting\\nin the first row, followed by the rest of the diagonals in the first column.\\n\\nWe need to be able to tell that we\'ve iterated through all of them, and also we\\nneed to know which diagonal is next. For that purpose we will pass the indices\\nof the first cell on the diagonal. That way we can always tell how to move forward.\\n\\nWe will start by updating the `begin` and `end` to reflect our choice accordingly.\\n\\n```cpp\\ndiagonals_iter begin() { return diagonals_iter { _matrix, 0, 0 }; }\\ndiagonals_iter end() { return diagonals_iter { _matrix, 0, _matrix.size() }; }\\n```\\n\\nFor the `begin` we return the first diagonal that starts at `(0, 0)`. And because\\nwe have decided to do the diagonals in the first column at the end, the first\\ndiagonal that is not a valid one is the one at `(0, height)`. Apart from the\\nindices, we also need to pass reference to the matrix itself.\\n\\n:::note\\n\\nYou may have noticed that we also include the diagonals that have length 1,\\nspecifically the ones at `(0, height - 1)` and `(width - 1, 0)`. We are implementing\\nan iterator that **should not** care about the way it\'s being used. Therefore, we\\ndon\'t care about the fact they don\'t need to be sorted.\\n\\n:::\\n\\nCool, let\'s leave the iterator itself to someone else, right?[^4]\\n\\n### Implementing the iterator over diagonals\\n\\nWe can start with a simple skeleton based on the information that we pass from\\nthe `diagonals`. Also to utilize the `matrix_t` and also contain implementation\\ndetails hidden away, we will put this code into the `diagonals` class.\\n\\n```cpp\\nclass diagonals_iter {\\n matrix_t& m;\\n std::size_t x;\\n std::size_t y;\\n\\npublic:\\n diagonals_iter(matrix_t& matrix, std::size_t x, std::size_t y)\\n : m(matrix)\\n , x(x)\\n , y(y)\\n {\\n }\\n};\\n```\\n\\nIn this case we will be implementing a \u201csimple\u201d forward iterator, so we don\'t\\nneed to implement a lot. Notably it will be:\\n\\n- inequality operator (we need to know when we reach the end and have nothing to\\n iterate over)\\n- preincrementation operator (we need to be able to move around the iterable)\\n- dereference operator (we need to be able to retrieve the objects we iterate\\n over)\\n\\n```cpp\\nclass diagonals_iter {\\n matrix_t& m;\\n std::size_t x;\\n std::size_t y;\\n\\npublic:\\n diagonals_iter(matrix_t& matrix, std::size_t x, std::size_t y)\\n : m(matrix)\\n , x(x)\\n , y(y)\\n {\\n }\\n\\n bool operator!=(const diagonals_iter& rhs) const\\n {\\n // iterators are not equal if they reference different matrices, or\\n // their positions differ\\n return m != rhs.m || x != rhs.x || y != rhs.y;\\n }\\n\\n diagonals_iter& operator++()\\n {\\n if (y != 0) {\\n // iterating through diagonals down the first column\\n y++;\\n return *this;\\n }\\n\\n // iterating the diagonals along the first row\\n x++;\\n if (x == m.front().size()) {\\n // switching to diagonals in the first column\\n x = 0;\\n y++;\\n }\\n\\n return *this;\\n }\\n\\n diagonal operator*() const { return diagonal { m, x, y }; }\\n};\\n```\\n\\nLet\'s go one-by-one. Inequality operator is rather simple, just compare iterator\'s\\nattributes field-by-field. If you think about it, checking inequality of two 2D\\nvectors may be a bit inefficient, therefore, we can swap around and check it as\\na last thing.\\n\\n```diff\\n- return m != rhs.m || x != rhs.x || y != rhs.y;\\n+ return x != rhs.x || y != rhs.y || m != rhs.m;\\n```\\n\\nPreincrementation is where the magic happens. If you have a better look, you can\\nsee two branches of this operation:\\n\\n1. When `y != 0` (we\'re iterating over the diagonals in the first column)\\n In this case, we just bump the row and we\'re done.\\n2. When `y == 0` (we\'re iterating over the diagonals in the first row)\\n In this case, we bump the column and check if we haven\'t gotten out of bounds,\\n i.e. the end of the first row. If we get out of the bounds, we\'re continuing\\n with the second diagonal in the first column.\\n\\nDereferencing the iterator must \u201cyield\u201d something. In our case it will be the\\ndiagonal that we want to sort. For sorting we need just the iterators that can\\nmove around said diagonal. The simplest thing, we can do, is to delegate it to\\nsomething else. In our case it will be a class called `diagonal`.\\n\\n## Implementing the `diagonal` itself\\n\\nAfter implementing the iterator over diagonals, we know that all we need to describe\\na diagonal is the matrix itself and the \u201cstart\u201d of the diagonal (row and column).\\nAnd we also know that the diagonal must provide some iterators for the `std::sort`\\nfunction. We can start with the following skeleton:\\n\\n```cpp\\ntemplate \\nclass diagonal {\\n using matrix_t = std::vector>;\\n\\n matrix_t& matrix;\\n std::size_t x;\\n std::size_t y;\\n\\npublic:\\n diagonal(matrix_t& matrix, std::size_t x, std::size_t y)\\n : matrix(matrix)\\n , x(x)\\n , y(y)\\n {\\n }\\n\\n diagonal_iter begin() const { return diagonal_iter { matrix, x, y }; }\\n\\n diagonal_iter end() const\\n {\\n auto max_x = matrix[y].size();\\n auto max_y = matrix.size();\\n\\n // we need to find the distance in which we get out of bounds (either in\\n // column or row)\\n auto steps = std::min(max_x - x, max_y - y);\\n\\n return diagonal_iter { matrix, x + steps, y + steps };\\n }\\n};\\n```\\n\\nInitialization is rather simple, we just \u201ckeep\u201d the stuff we get, `begin` is the\\nsimplest, we just delegate.\\n\\nIn case of the `end`, it gets more complicated. We need to know where is the \u201cend\u201d\\nof the diagonal. Since `end` should point to the first element \u201cafter\u201d the iterable,\\nwe know that it\'s the first position of the iterator where either `y` becomes\\n`matrix.size()` or `x` becomes `matrix[y].size()`. Also we are moving along diagonal,\\nduh, therefore we can deduce the first \u201cposition\u201d afterwards by minimal amount of\\nsteps to get out of the any column or row, hence `std::min(max_x - x, max_y - y)`.\\nFinal position is then computed simply by adding the steps to the beginning of\\nthe diagonal.\\n\\nNow we just need to finish the iterator for the diagonal itself and we\'re done.\\n\\n### Implementing `diagonal_iter`\\n\\nThis part is the hardest from all we need to do. It\'s because of the requirements\\nof the `std::sort` that requires us to implement a _random access iterator_. I have\\nbriefly described it above, and \u201cin a nutshell\u201d it means that we need to implement\\nan iterator that can move in constant time along the diagonal in any amount of\\nsteps.\\n\\nLet\'s go through all of the functionality that our iterator needs to support to\\nbe used in `std::sort`. We need the usual operations like:\\n\\n- equality/inequality\\n- incrementation\\n- dereferencing\\n\\nWe will also add all the types that our iterator uses with the category of the\\niterator, i.e. what interface it supports:\\n\\n```cpp\\nclass diagonal_iter {\\n // we need to keep reference to the matrix itself\\n matrix_t& m;\\n\\n // we need to be able to tell our current position\\n std::size_t x;\\n std::size_t y;\\n\\npublic:\\n using difference_type = std::ptrdiff_t;\\n using value_type = T;\\n using pointer = T*;\\n using reference = T&;\\n using iterator_category = std::random_access_iterator_tag;\\n\\n diagonal_iter(matrix_t& matrix,\\n std::size_t x,\\n std::size_t y)\\n : m(matrix)\\n , x(x)\\n , y(y)\\n {\\n }\\n\\n bool operator==(const diagonal_iter& rhs) const\\n {\\n return x == rhs.x && y == rhs.y && m == rhs.m;\\n }\\n\\n diagonal_iter& operator++()\\n {\\n // we are moving along the diagonal, so we increment both \u2039x\u203a and \u2039y\u203a at\\n // the same time\\n x++;\\n y++;\\n return *this;\\n }\\n\\n reference operator*() const { return m[y][x]; }\\n};\\n```\\n\\nThis is pretty similar to the previous iterator, but now we need to implement the\\nremaining requirements of the _random access iterator_. Let\'s see what those are:\\n\\n- decrementation - cause we need to be able to move backwards too, since _random _\\n _access iterator_ extends the interface of _bidirectional iterator_\\n- moving the iterator in either direction by steps given as an integer\\n- being able to tell the distance between two iterators\\n- define an ordering on the iterators\\n\\nLet\'s fill them in:\\n\\n```cpp\\nclass diagonal_iter {\\n // we need to keep reference to the matrix itself\\n matrix_t& m;\\n\\n // we need to be able to tell our current position\\n std::size_t x;\\n std::size_t y;\\n\\npublic:\\n using difference_type = std::ptrdiff_t;\\n using value_type = T;\\n using pointer = T*;\\n using reference = T&;\\n using iterator_category = std::random_access_iterator_tag;\\n\\n diagonal_iter(matrix_t& matrix,\\n std::size_t x,\\n std::size_t y)\\n : m(matrix)\\n , x(x)\\n , y(y)\\n {\\n }\\n\\n bool operator==(const diagonal_iter& rhs) const\\n {\\n return x == rhs.x && y == rhs.y && m == rhs.m;\\n }\\n\\n diagonal_iter& operator++()\\n {\\n // we are moving along the diagonal, so we increment both \u2039x\u203a and \u2039y\u203a at\\n // the same time\\n x++;\\n y++;\\n return *this;\\n }\\n\\n reference operator*() const { return m[y][x]; }\\n\\n // exactly opposite to the incrementation\\n diagonal_iter operator--()\\n {\\n x--;\\n y--;\\n return *this;\\n }\\n\\n // moving \u2039n\u203a steps back is same as calling decrementation \u2039n\u203a-times, so we\\n // can just return a new iterator and subtract \u2039n\u203a from both coordinates in\\n // the matrix\\n diagonal_iter operator-(difference_type n) const\\n {\\n return diagonal_iter { m, x - n, y - n };\\n }\\n\\n // here we assume that we are given two iterators on the same diagonal\\n difference_type operator-(const diagonal_iter& rhs) const\\n {\\n assert(m == rhs.m);\\n return x - rhs.x;\\n }\\n\\n // counterpart of moving \u2039n\u203a steps backwards\\n diagonal_iter operator+(difference_type n) const\\n {\\n return diagonal_iter { m, x + n, y + n };\\n }\\n\\n // we compare the coordinates, and also assume that those 2 iterators are\\n // lying on the same diagonal\\n bool operator<(const diagonal_iter& rhs) const\\n {\\n assert(m == rhs.m);\\n return x < rhs.x && y < rhs.y;\\n }\\n};\\n```\\n\\nAt this point we could probably try and compile it, right? If we do so, we will\\nget yelled at by a compiler for the following reasons:\\n\\n```\\n/usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/bits/stl_algo.h:1792:11: error: object of type \'diagonal::diagonal_iter\' cannot be assigned because its copy assignment operator is implicitly deleted [clang-diagnostic-error]\\n __last = __next;\\n ^\\n/usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/bits/stl_algo.h:1817:11: note: in instantiation of function template specialization \'std::__unguarded_linear_insert::diagonal_iter, __gnu_cxx::__ops::_Val_less_iter>\' requested here\\n std::__unguarded_linear_insert(__i,\\n ^\\n/usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/bits/stl_algo.h:1849:9: note: in instantiation of function template specialization \'std::__insertion_sort::diagonal_iter, __gnu_cxx::__ops::_Iter_less_iter>\' requested here\\n std::__insertion_sort(__first, __first + int(_S_threshold), __comp);\\n ^\\n/usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/bits/stl_algo.h:1940:9: note: in instantiation of function template specialization \'std::__final_insertion_sort::diagonal_iter, __gnu_cxx::__ops::_Iter_less_iter>\' requested here\\n std::__final_insertion_sort(__first, __last, __comp);\\n ^\\n/usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/bits/stl_algo.h:4820:12: note: in instantiation of function template specialization \'std::__sort::diagonal_iter, __gnu_cxx::__ops::_Iter_less_iter>\' requested here\\n std::__sort(__first, __last, __gnu_cxx::__ops::__iter_less_iter());\\n ^\\nmatrix-sort.cpp:161:18: note: in instantiation of function template specialization \'std::sort::diagonal_iter>\' requested here\\n std::sort(d.begin(), d.end());\\n ^\\nmatrix-sort.cpp:17:19: note: copy assignment operator of \'diagonal_iter\' is implicitly deleted because field \'m\' is of reference type \'diagonal::matrix_t &\' (aka \'vector> &\')\\n matrix_t& m;\\n ^\\n/usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/bits/stl_algo.h:1830:2: error: no matching function for call to \'__unguarded_linear_insert\' [clang-diagnostic-error]\\n std::__unguarded_linear_insert(__i,\\n ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\\n/usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/bits/stl_algo.h:1850:9: note: in instantiation of function template specialization \'std::__unguarded_insertion_sort::diagonal_iter, __gnu_cxx::__ops::_Iter_less_iter>\' requested here\\n std::__unguarded_insertion_sort(__first + int(_S_threshold), __last,\\n ^\\n/usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/bits/stl_algo.h:1940:9: note: in instantiation of function template specialization \'std::__final_insertion_sort::diagonal_iter, __gnu_cxx::__ops::_Iter_less_iter>\' requested here\\n std::__final_insertion_sort(__first, __last, __comp);\\n ^\\n/usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/bits/stl_algo.h:4820:12: note: in instantiation of function template specialization \'std::__sort::diagonal_iter, __gnu_cxx::__ops::_Iter_less_iter>\' requested here\\n std::__sort(__first, __last, __gnu_cxx::__ops::__iter_less_iter());\\n ^\\nmatrix-sort.cpp:161:18: note: in instantiation of function template specialization \'std::sort::diagonal_iter>\' requested here\\n std::sort(d.begin(), d.end());\\n ^\\n/usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/bits/stl_algo.h:1782:5: note: candidate template ignored: substitution failure [with _RandomAccessIterator = diagonal::diagonal_iter, _Compare = __gnu_cxx::__ops::_Val_less_iter]\\n __unguarded_linear_insert(_RandomAccessIterator __last,\\n ^\\n/usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/bits/stl_algo.h:1923:11: error: object of type \'diagonal::diagonal_iter\' cannot be assigned because its copy assignment operator is implicitly deleted [clang-diagnostic-error]\\n __last = __cut;\\n ^\\n/usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/bits/stl_algo.h:1937:9: note: in instantiation of function template specialization \'std::__introsort_loop::diagonal_iter, long, __gnu_cxx::__ops::_Iter_less_iter>\' requested here\\n std::__introsort_loop(__first, __last,\\n ^\\n/usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/bits/stl_algo.h:4820:12: note: in instantiation of function template specialization \'std::__sort::diagonal_iter, __gnu_cxx::__ops::_Iter_less_iter>\' requested here\\n std::__sort(__first, __last, __gnu_cxx::__ops::__iter_less_iter());\\n ^\\nmatrix-sort.cpp:161:18: note: in instantiation of function template specialization \'std::sort::diagonal_iter>\' requested here\\n std::sort(d.begin(), d.end());\\n ^\\nmatrix-sort.cpp:17:19: note: copy assignment operator of \'diagonal_iter\' is implicitly deleted because field \'m\' is of reference type \'diagonal::matrix_t &\' (aka \'vector> &\')\\n matrix_t& m;\\n ^\\n```\\n\\nThat\'s a lot of noise, isn\'t it? Let\'s focus on the important parts:\\n\\n```\\n/usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/bits/stl_algo.h:1792:11: error: object of type \'diagonal::diagonal_iter\' cannot be assigned because its copy assignment operator is implicitly deleted [clang-diagnostic-error]\\n\u2026\\nmatrix-sort.cpp:17:19: note: copy assignment operator of \'diagonal_iter\' is implicitly deleted because field \'m\' is of reference type \'diagonal::matrix_t &\' (aka \'vector> &\')\\n matrix_t& m;\\n ^\\n```\\n\\nAh! We have a reference in our iterator, and this prevents us from having a copy\\nassignment operator (that is used \u201csomewhere\u201d in the sorting algorithm). Well\u2026\\nLet\'s just wrap it!\\n\\n```diff\\n# we need to keep a different type than reference\\n- matrix_t& m;\\n+ std::reference_wrapper m;\\n\\n# in comparison we need to get the reference out of the wrapper first\\n- return x == rhs.x && y == rhs.y && m == rhs.m;\\n+ return x == rhs.x && y == rhs.y && m.get() == rhs.m.get();\\n\\n# same when we return a reference to the \u201ccell\u201d in the matrix\\n- reference operator*() const { return m[y][x]; }\\n+ reference operator*() const { return m.get()[y][x]; }\\n\\n# and finally in the assertions that we set for the \u201cdistance\u201d and \u201cless than\u201d\\n- assert(m == rhs.m);\\n+ assert(m.get() == rhs.m.get());\\n```\\n\\nWe\'re done now! We have written an iterator over diagonals for a 2D `vector`. You can have a look at the final result [here](pathname:///files/blog/leetcode/sort-matrix-diagonally/matrix-sort.cpp).\\n\\n[^1]: just because I\'m used to it and don\'t care about your opinion ;)\\n[^2]: exercise at your own risk\\n[^3]: me in 5 minutes in fact, but don\'t make me scared\\n[^4]: me in the next section\u2026"},{"id":"aoc-2022/2nd-week","metadata":{"permalink":"/blog/aoc-2022/2nd-week","editUrl":"https://github.com/mfocko/blog/tree/main/blog/aoc-2022/02-week-2.md","source":"@site/blog/aoc-2022/02-week-2.md","title":"2nd week of Advent of Code \'22 in Rust","description":"Surviving second week in Rust.","date":"2022-12-25T23:15:00.000Z","formattedDate":"December 25, 2022","tags":[{"label":"advent-of-code","permalink":"/blog/tags/advent-of-code"},{"label":"advent-of-code-2022","permalink":"/blog/tags/advent-of-code-2022"},{"label":"rust","permalink":"/blog/tags/rust"}],"readingTime":20.875,"hasTruncateMarker":true,"authors":[{"name":"Matej Focko","email":"me+blog@mfocko.xyz","title":"a.k.a. @mf","url":"https://gitlab.com/mfocko","imageURL":"https://github.com/mfocko.png","key":"mf"}],"frontMatter":{"title":"2nd week of Advent of Code \'22 in Rust","description":"Surviving second week in Rust.","date":"2022-12-25T23:15","slug":"aoc-2022/2nd-week","authors":"mf","tags":["advent-of-code","advent-of-code-2022","rust"],"hide_table_of_contents":false},"unlisted":false,"prevItem":{"title":"Sort the matrix diagonally","permalink":"/blog/leetcode/sort-diagonally"},"nextItem":{"title":"1st week of Advent of Code \'22 in Rust","permalink":"/blog/aoc-2022/1st-week"}},"content":"Let\'s go through the second week of [_Advent of Code_] in Rust.\\n\\n\x3c!--truncate--\x3e\\n\\n## [Day 8: Treetop Tree House](https://adventofcode.com/2022/day/8)\\n\\n:::info tl;dr\\n\\nWe get a forest and we want to know how many trees are visible from the outside.\\nApart from that we want to find the best view.\\n\\n:::\\n\\nNothing interesting. We are moving around 2D map though. And indexing can get a\\nbit painful when doing so, let\'s refactor it a bit ;) During the preparation for\\nthe AoC, I have written `Vector2D` and now it\'s time to extend it with indexing\\nof `Vec` of `Vec`s. In my solution I was manipulating with indices in the following\\nway:\\n\\n- swapping them\\n- checking whether they are correct indices for the `Vec>`\\n- indexing `Vec>` with them\\n\\n:::warning[caution]\\n\\nI\'m getting familiar with Rust and starting to \u201cabuse\u201d it\u2026 While doing so, I\'m\\nalso uncovering some \u201cfeatures\u201d that I don\'t really like. Therefore I will mark\\nall of my rants with _thicc_ **\xab\u21af\xbb** mark and will try to \u201clock\u201d them into their\\nown \u201cbox of hell\u201d.\\n\\n:::\\n\\n#### Swapping indices\\n\\nRelatively simple implementation, just take the values, swap them and return new\\nvector.\\n\\n```rust\\nimpl Vector2D {\\n pub fn swap(&self) -> Self {\\n Self {\\n x: self.y,\\n y: self.x,\\n }\\n }\\n}\\n```\\n\\nPretty straight-forward implementation, but let\'s talk about the `T: Copy`. We\\nneed to use it, since we are returning a **new** vector, with swapped **values**.\\nIf we had values that cannot be copied, the only thing we could do, would be a\\nvector of references (and it would also introduce a lifetime, to which we\'ll get\\nlater on). This is pretty similar with the operations on sets from the first week.\\n\\n#### Indexing `Vec`\\n\\nI will start with the indexing, cause bound-checking is a bit more\u2026 complicated\\nthan I would like to.\\n\\n```rust\\npub fn index<\'a, T, U>(v: &\'a [Vec], idx: &Vector2D) -> &\'a U\\nwhere\\n usize: TryFrom,\\n >::Error: Debug,\\n T: Copy,\\n{\\n let (x, y): (usize, usize) = (idx.x.try_into().unwrap(), idx.y.try_into().unwrap());\\n &v[y][x]\\n}\\n```\\n\\nLet\'s talk about this mess\u2026 Body of the function is probably the most easy part\\nand should not be hard to understand, we just take the `x` and `y` and convert\\nthem both to `usize` type that can be used later on for indexing.\\n\\nThe type signature of the function is where the fun is at :wink: We are trying\\nto convert unknown type to `usize`, so we must bound the `T` as a type that can\\nbe converted to `usize`, that\'s how we got `usize: TryFrom` which basically\\nsays that `usize` must implement `TryFrom` trait and therefore allows us to\\nconvert the indices to actual `usize` indices. Using `.unwrap()` also forces us\\nto bound the error that can occur when converting `T` into `usize`, that\'s how\\nwe get `>::Error: Debug` which loosely means\\n\\n> error during conversion of `T` into `usize` must implement `Debug`,\\n> i.e. can be printed in some way or other\\n\\n`T: Copy` is required by `.try_into()` which takes `T` by-value.\\n\\nAnd now we are left only with the first line of the definition.\\n\\n:::note\\n\\nSkilled Rustaceans might notice that this implementation is rather flaky and can\\nbreak in multiple places at once. I\'ll get back to it\u2026\\n\\n:::\\n\\nLet\'s split it in multiple parts:\\n\\n- `v: &\'a [Vec]` represents the 2D `Vec`, we are indexing, `Vec` implements\\n `Slice` trait and _clippy_ recommends using `&[T]` to `&Vec`, exact details\\n are unknown to me\\n- `idx: &Vector2D` represents the _indices_ which we use, we take them by\\n reference to avoid an unnecessary copy\\n- `-> &\'a U` means that we are returning a _reference_ to some value of type `U`.\\n Now the question is what does the `\'a` mean, we can also see it as a generic\\n type declared along `T` and `U`. And the answer is _relatively_ simple, `\'a`\\n represents a _lifetime_. We take the `v` by a reference and return a reference,\\n borrow checker validates all of the _borrows_ (or references), so we need to\\n specify that our returned value has _the same lifetime_ as the vector we have\\n taken by a reference, i.e. returned reference must live at least as long as the\\n `v`. This way we can \u201cbe sure\u201d that the returned reference is valid.\\n\\n##### Issues\\n\\nFirst issue that our implementation has is the fact that we cannot get a mutable\\nreference out of that function. This could be easily resolved by introducing new\\nfunction, e.g. `index_mut`. Which I have actually done while writing this part:\\n\\n```rust\\npub fn index_mut<\'a, T, U>(v: &\'a mut [Vec], idx: &Vector2D) -> &\'a mut U\\nwhere\\n usize: TryFrom,\\n >::Error: Debug,\\n T: Copy,\\n{\\n let (x, y): (usize, usize) = (idx.x.try_into().unwrap(), idx.y.try_into().unwrap());\\n &mut v[y][x]\\n}\\n```\\n\\n:::warning **\xab\u21af\xbb** Why can\'t we use one function?\\n\\nWhen we consider a `Vec`, we don\'t need to consider containers as `T`, Rust\\nimplements indexing as traits `Index` and `IndexMut` that do the dirty work\\nbehind syntactic sugar of `container[idx]`.\\n\\nHowever, implementing of traits is not allowed for _external_ types, i.e. types\\nthat you haven\'t defined yourself. This means that you can implement indexing\\nover containers that you have implemented yourself, but you cannot use your own\\ntypes for indexing \u201cbuilt-in\u201d types.\\n\\nAnother part of this rabbit hole is trait `SliceIndex` that is of a relevance\\nbecause of\\n\\n```rust\\nimpl Index for [T]\\nwhere\\n I: SliceIndex<[T]>\\n\\nimpl Index for Vec\\nwhere\\n I: SliceIndex<[T]>,\\n A: Allocator\\n\\nimpl Index for [T; N]\\nwhere\\n [T]: Index\\n```\\n\\nIn other words, if your type implements `SliceIndex` trait, it can be used\\nfor indexing. As of now, this trait has all of its required methods experimental\\nand is marked as `unsafe`.\\n\\n:::\\n\\nAnother problem is a requirement for indexing either `[Vec]` or `Vec>`.\\nThis requirement could be countered by removing inner type `Vec` and constraining\\nit by a trait `Index` (or `IndexMut` respectively) in a following way\\n\\n```rust\\npub fn index<\'a, C, T>(v: &\'a [C], idx: &Vector2D) -> &\'a C::Output\\nwhere\\n usize: TryFrom,\\n >::Error: Debug,\\n T: Copy,\\n C: Index\\n{\\n let (x, y): (usize, usize) = (idx.x.try_into().unwrap(), idx.y.try_into().unwrap());\\n &v[y][x]\\n}\\n```\\n\\nGiven this, we can also give a more meaningful typename for indexing type, such\\nas `I`.\\n\\n#### Checking bounds\\n\\nNow we can get to the boundary checks, it is very similar, but a more\u2026 dirty.\\nFirst approach that came up was to convert the indices in `Vector2D` to `usize`,\\nbut when you add the indices up, e.g. when checking the neighbors, you can end\\nup with negative values which, unlike in C++, causes an error (instead of underflow\\nthat you can use to your advantage; you can easily guess how).\\n\\nSo how can we approach this then? Well\u2026 we will convert the bounds instead of\\nthe indices and that lead us to:\\n\\n```rust\\npub fn in_range(v: &[Vec], idx: &Vector2D) -> bool\\nwhere\\n usize: TryInto,\\n >::Error: Debug,\\n T: PartialOrd + Copy,\\n{\\n idx.y >= 0.try_into().unwrap()\\n && idx.y < v.len().try_into().unwrap()\\n && idx.x >= 0.try_into().unwrap()\\n && idx.x\\n < v[TryInto::::try_into(idx.y).unwrap()]\\n .len()\\n .try_into()\\n .unwrap()\\n}\\n```\\n\\nYou can tell that it\'s definitely a shitty code. Let\'s improve it now! We will\\nget back to the original idea, but do it better. We know that we cannot convert\\nnegative values into `usize`, **but** we also know that conversion like that\\nreturns a `Result` which we can use to our advantage.\\n\\n```rust\\npub fn in_range(v: &[Vec], idx: &Vector2D) -> bool\\nwhere\\n T: Copy,\\n usize: TryFrom,\\n{\\n usize::try_from(idx.y)\\n .and_then(|y| usize::try_from(idx.x).map(|x| y < v.len() && x < v[y].len()))\\n .unwrap_or(false)\\n}\\n```\\n\\n`Result` is a type similar to `Either` in Haskell and it allows us to chain\\nmultiple operations on correct results or propagate the original error without\\ndoing anything. Let\'s dissect it one-by-one.\\n\\n`try_from` is a method implemented in `TryFrom` trait, that allows you to convert\\ntypes and either successfully convert them or fail (with a reasonable error). This\\nmethod returns `Result`.\\n\\nWe call `and_then` on that _result_, let\'s have a look at the type signature of\\n`and_then`, IMO it explains more than enough:\\n\\n```rust\\npub fn and_then(self, op: F) -> Result\\nwhere\\n F: FnOnce(T) -> Result\\n```\\n\\nOK\u2026 So it takes the result and a function and returns another result with\\ndifferent value and different error. However we can see that the function, which\\nrepresents an operation on a result, takes just the value, i.e. it doesn\'t care\\nabout any previous error. To make it short:\\n\\n> `and_then` allows us to run an operation, which can fail, on the correct result\\n\\nWe parsed a `y` index and now we try to convert the `x` index with `try_from`\\nagain, but on that result we use `map` rather than `and_then`, why would that be?\\n\\n```rust\\npub fn map(self, op: F) -> Result\\nwhere\\n F: FnOnce(T) -> U\\n```\\n\\nHuh\u2026 `map` performs an operation that **cannot** fail. And finally we use\\n`unwrap_or` which takes the value from result, or in case of an error returns the\\ndefault that we define.\\n\\nHow does this work then? If `y` is negative, the conversion fails and the error\\npropagates all the way to `unwrap_or`, if `y` can be a correct `usize` value, then\\nwe do the same with `x`. If `x` is negative, we propagate the error as with `y`,\\nand if it\'s not, then we check whether it exceeds the higher bounds or not.\\n\\n### Solution\\n\\nRelatively simple, you just need follow the rules and not get too smart, otherwise\\nit will get back at you.\\n\\n## [Day 9: Rope Bridge](https://adventofcode.com/2022/day/9)\\n\\n:::info tl;dr\\n\\nWe get a rope with knots and we want to track how many different positions are\\nvisited with the rope\'s tail.\\n\\n:::\\n\\nBy this day, I have come to a conclusion that current skeleton for each day\\ngenerates a lot of boilerplate. And even though it can be easily copied, it\'s\\njust a waste of space and unnecessary code. Let\'s \u201csimplify\u201d this (on one end\\nwhile creating monster on the other end). I\'ve gone through what we need in the\\npreparations for the AoC. Let\'s sum up our requirements:\\n\\n- parsing\\n- part 1 & 2\\n- running on sample / input\\n- tests\\n\\nParsing and implementation of both parts is code that changes each day and we\\ncannot do anything about it. However running and testing can be simplified!\\n\\nLet\'s introduce and export a new module `solution` that will take care of all of\\nthis. We will start by introducing a trait for each day.\\n\\n```rust\\npub trait Solution {\\n fn parse_input>(pathname: P) -> Input;\\n\\n fn part_1(input: &Input) -> Output;\\n fn part_2(input: &Input) -> Output;\\n}\\n```\\n\\nThis does a lot of work for us already, we have defined a trait and for each day\\nwe will create a structure representing a specific day. That structure will also\\nimplement the `Solution` trait.\\n\\nNow we need to get rid of the boilerplate, we can\'t get rid of the `main` function,\\nbut we can at least move out the functionality.\\n\\n```rust\\nfn run(type_of_input: &str) -> Result<()>\\nwhere\\n Self: Sized,\\n{\\n tracing_subscriber::fmt()\\n .with_env_filter(EnvFilter::from_default_env())\\n .with_target(false)\\n .with_file(true)\\n .with_line_number(true)\\n .without_time()\\n .compact()\\n .init();\\n color_eyre::install()?;\\n\\n let input = Self::parse_input(format!(\\"{}s/{}.txt\\", type_of_input, Self::day()));\\n\\n info!(\\"Part 1: {}\\", Self::part_1(&input));\\n info!(\\"Part 2: {}\\", Self::part_2(&input));\\n\\n Ok(())\\n}\\n\\nfn main() -> Result<()>\\nwhere\\n Self: Sized,\\n{\\n Self::run(\\"input\\")\\n}\\n```\\n\\nThis is all part of the `Solution` trait, which can implement methods while being\\ndependent on what is provided by the implementing types. In this case, we just\\nneed to bound the `Output` type to implement `Display` that is necessary for the\\n`info!` and format string there.\\n\\nNow we can get to first of the nasty things we are going to do\u2026 And it is the\\n`day()` method that you can see being used when constructing path to the input\\nfile. That method will generate a name of the file, e.g. `day01` and we know that\\nwe can _somehow_ deduce it from the structure name, given we name it reasonably.\\n\\n```rust\\nfn day() -> String {\\n let mut day = String::from(type_name::().split(\\"::\\").next().unwrap());\\n day.make_ascii_lowercase();\\n\\n day.to_string()\\n}\\n```\\n\\n:::warning `type_name`\\n\\nThis feature is still experimental and considered to be internal, it is not\\nadvised to use it any production code.\\n\\n:::\\n\\nAnd now we can get to the nastiest stuff :weary: We will **generate** the tests!\\n\\nWe want to be able to generate tests for sample input in a following way:\\n\\n```rust\\ntest_sample!(day_01, Day01, 42, 69);\\n```\\n\\nThere\'s not much we can do, so we will write a macro to generate the tests for us.\\n\\n```rust\\n#[macro_export]\\nmacro_rules! test_sample {\\n ($mod_name:ident, $day_struct:tt, $part_1:expr, $part_2:expr) => {\\n #[cfg(test)]\\n mod $mod_name {\\n use super::*;\\n\\n #[test]\\n fn test_part_1() {\\n let sample =\\n $day_struct::parse_input(&format!(\\"samples/{}.txt\\", $day_struct::day()));\\n assert_eq!($day_struct::part_1(&sample), $part_1);\\n }\\n\\n #[test]\\n fn test_part_2() {\\n let sample =\\n $day_struct::parse_input(&format!(\\"samples/{}.txt\\", $day_struct::day()));\\n assert_eq!($day_struct::part_2(&sample), $part_2);\\n }\\n }\\n };\\n}\\n```\\n\\nWe have used it in a similar way as macros in C/C++, one of the things that we\\ncan use to our advantage is defining \u201ctype\u201d of the parameters for the macro. All\\nparameters have their name prefixed with `$` sign and you can define various \u201cforms\u201d\\nof your macro. Let\'s go through it!\\n\\nWe have following parameters:\\n\\n- `$mod_name` which represents the name for the module with tests, it is typed\\n with `ident` which means that we want a valid identifier to be passed in.\\n- `$day_struct` represents the structure that will be used for tests, it is typed\\n with `tt` which represents a _token tree_, in our case it is a type.\\n- `$part_X` represents the expected output for the `X`th part and is of type `expr`\\n which literally means an _expression_.\\n\\nApart from that we need to use `#[macro_export]` to mark the macro as exported\\nfor usage outside of the module. Now our skeleton looks like:\\n\\n```rust\\nuse aoc_2022::*;\\n\\ntype Input = String;\\ntype Output = String;\\n\\nstruct DayXX;\\nimpl Solution for DayXX {\\n fn parse_input>(pathname: P) -> Input {\\n file_to_string(pathname)\\n }\\n\\n fn part_1(input: &Input) -> Output {\\n todo!()\\n }\\n\\n fn part_2(input: &Input) -> Output {\\n todo!()\\n }\\n}\\n\\nfn main() -> Result<()> {\\n // DayXX::run(\\"sample\\")\\n DayXX::main()\\n}\\n\\n// test_sample!(day_XX, DayXX, , );\\n```\\n\\n### Solution\\n\\nNot much to talk about, it is relatively easy to simulate.\\n\\n## [Day 10: Cathode-Ray Tube](https://adventofcode.com/2022/day/10)\\n\\n:::info tl;dr\\n\\nEmulating basic arithmetic operations on a CPU and drawing on CRT based on the\\nCPU\'s accumulator.\\n\\n:::\\n\\nIn this day I have discovered an issue with my design of the `Solution` trait.\\nAnd the issue is caused by different types of `Output` for the part 1 and part 2.\\n\\nProblem is relatively simple and consists of simulating a CPU, I have approached\\nit in a following way:\\n\\n```rust\\nfn evaluate_instructions(instructions: &[Instruction], mut out: Output) -> Output {\\n instructions\\n .iter()\\n .fold(State::new(), |state, instruction| {\\n state.execute(instruction, &mut out)\\n });\\n\\n out\\n}\\n```\\n\\nWe just take the instructions, we have some state of the CPU and we execute the\\ninstructions one-by-one. Perfect usage of the `fold` (or `reduce` as you may know\\nit from other languages).\\n\\nYou can also see that we have an `Output` type, so the question is how can we fix\\nthat problem. And the answer is very simple and _functional_. Rust allows you to\\nhave an `enumeration` that can _bear_ some other values apart from the type itself.\\n\\n:::tip\\n\\nWe could\'ve seen something like this with the `Result` type that can be\\ndefined as\\n\\n```rust\\nenum Result {\\n Ok(T),\\n Err(E)\\n}\\n```\\n\\n###### What does that mean though?\\n\\nWhen we have an `Ok` value, it has the result itself, and when we get an `Err`\\nvalue, it has the error. This also allows us to handle _results_ in a rather\\npretty way:\\n\\n```rust\\nmatch do_something(x) {\\n Ok(y) => {\\n println!(\\"SUCCESS: {}\\", y);\\n },\\n Err(y) => {\\n eprintln!(\\"ERROR: {}\\", y);\\n }\\n}\\n```\\n\\n:::\\n\\nMy solution has a following outline:\\n\\n```rust\\nfn execute(&self, i: &Instruction, output: &mut Output) -> State {\\n // execute the instruction\\n\\n // collect results if necessary\\n match output {\\n Output::Part1(x) => self.execute_part_1(y, x),\\n Output::Part2(x) => self.execute_part_2(y, x),\\n }\\n\\n // return the obtained state\\n new_state\\n}\\n```\\n\\nYou might think that it\'s a perfectly reasonable thing to do. Yes, **but** notice\\nthat the `match` statement doesn\'t _collect_ the changes in any way and also we\\npass `output` by `&mut`, so it is shared across each _iteration_ of the `fold`.\\n\\nThe dirty and ingenious thing is that `x`s are passed by `&mut` too and therefore\\nthey are directly modified by the helper functions. To sum it up and let it sit\\n\\n> We are **collecting** the result **into** an **enumeration** that is **shared**\\n> across **all** iterations of `fold`.\\n\\n### Solution\\n\\nSimilar to _Day 9_, but there are some technical details that can get you.\\n\\n## [Day 11: Monkey in the Middle](https://adventofcode.com/2022/day/11)\\n\\n:::info tl;dr\\n\\nSimulation of monkeys throwing stuff around and measuring your stress levels\\nwhile your stuff is being passed around.\\n\\n:::\\n\\nI think I decided to use regular expressions here for the first time, cause\\nparsing the input was a pain.\\n\\nAlso I didn\'t expect to implement Euclidean algorithm in Rust\u2026\\n\\n### Solution\\n\\nAgain, we\'re just running a simulation. Though I must admit it was very easy to\\nmake a small technical mistakes that could affect the final results very late.\\n\\n## [Day 12: Hill Climbing Algorithm](https://adventofcode.com/2022/day/12)\\n\\n:::info tl;dr\\n\\nFinding shortest path up the hill and also shortest path down to the ground while\\nalso rolling down the hill\u2026\\n\\n:::\\n\\nAs I have said in the _tl;dr_, we are looking for the shortest path, but the start\\nand goal differ for the part 1 and 2. So I have decided to refactor my solution\\nto a BFS algorithm that takes necessary parameters via functions:\\n\\n```rust\\nfn bfs(\\n graph: &[Vec], start: &Position, has_edge: F, is_target: G\\n) -> Option\\nwhere\\n F: Fn(&[Vec], &Position, &Position) -> bool,\\n G: Fn(&[Vec], &Position) -> bool\\n```\\n\\nWe pass the initial vertex from the caller and everything else is left to the BFS\\nalgorithm, based on the `has_edge` and `is_target` functions.\\n\\nThis was easy! And that is not very usual in Rust once you want to pass around\\nfunctions. :eyes:\\n\\n### Solution\\n\\nLooking for the shortest path\u2026 Must be Dijkstra, right? **Nope!** Half of the\\nReddit got jebaited though. In all fairness, nothing stops you from implementing\\nthe Dijkstra\'s algorithm for finding the shortest path, **but** if you know that\\nall connected vertices are in a unit (actually $d = 1$) distance from each other,\\nthen you know that running Dijkstra is equivalent to running BFS, only with worse\\ntime complexity, because of the priority heap instead of the queue.\\n\\n## [Day 13: Distress Signal](https://adventofcode.com/2022/day/13)\\n\\n:::info tl;dr\\n\\nProcessing packets with structured data from the distress signal.\\n\\n:::\\n\\nYou can implement a lot of traits if you want to. It is _imperative_ to implement\\nordering on the packets. I had a typo, so I also proceeded to implement a `Display`\\ntrait for debugging purposes:\\n\\n```rust\\nimpl Display for Packet {\\n fn fmt(&self, f: &mut std::fmt::Formatter<\'_>) -> std::fmt::Result {\\n match self {\\n Packet::Integer(x) => write!(f, \\"{x}\\"),\\n Packet::List(lst) => write!(f, \\"[{}]\\", lst.iter().map(|p| format!(\\"{p}\\")).join(\\",\\")),\\n }\\n }\\n}\\n```\\n\\n### Solution\\n\\nA lot of technical details\u2026 Parsing is nasty too\u2026\\n\\n## [Day 14: Regolith Reservoir](https://adventofcode.com/2022/day/14)\\n\\n:::info tl;dr\\n\\nLet\'s simulate falling sand grain-by-grain.\\n\\n:::\\n\\nAgain, both parts are relatively similar with minimal changes, so it is a good\\nidea to refactor it a bit. Similar approach to the [BFS above]. Also this is the\\nfirst day where I ran into efficiency issues and had to redo my solution to speed\\nit up just a bit.\\n\\n### Solution\\n\\nTedious.\\n\\n## Post Mortem\\n\\n### Indexing\\n\\nI was asked about the indexing after publishing the blog. And truly it is rather\\ncomplicated topic, especially after releasing `SliceIndex` trait. I couldn\'t\\nleave it be, so I tried to implement the `Index` and `IndexMut` trait.\\n\\n:::note\\n\\nI have also mentioned that the `SliceIndex` trait is `unsafe`, but truth be told,\\nonly _unsafe_ part are the 2 methods that are named `*unchecked*`. Anyways, I will\\nbe implementing the `Index*` traits for now, rather than the `SliceIndex`.\\n\\n:::\\n\\nIt\'s relatively straightforward\u2026\\n\\n```rust\\nimpl Index> for [C]\\nwhere\\n I: Copy + TryInto,\\n >::Error: Debug,\\n C: Index,\\n{\\n type Output = C::Output;\\n\\n fn index(&self, index: Vector2D) -> &Self::Output {\\n let (x, y): (usize, usize) =\\n (index.x.try_into().unwrap(), index.y.try_into().unwrap());\\n &self[y][x]\\n }\\n}\\n\\nimpl IndexMut> for [C]\\nwhere\\n I: Copy + TryInto,\\n >::Error: Debug,\\n C: IndexMut,\\n{\\n fn index_mut(&mut self, index: Vector2D) -> &mut Self::Output {\\n let (x, y): (usize, usize) =\\n (index.x.try_into().unwrap(), index.y.try_into().unwrap());\\n &mut self[y][x]\\n }\\n}\\n```\\n\\nWe can see a lot of similarities to the implementation of `index` and `index_mut`\\nfunctions. In the end, they are 1:1, just wrapped in the trait that provides a\\nsyntax sugar for `container[idx]`.\\n\\n:::note\\n\\nI have also switched from using the `TryFrom` to `TryInto` trait, since it better\\nmatches what we are using, the `.try_into` rather than `usize::try_from`.\\n\\nAlso implementing `TryFrom` automatically provides you with a `TryInto` trait,\\nsince it is relatively easy to implement. Just compare the following:\\n\\n```rust\\npub trait TryFrom: Sized {\\n type Error;\\n\\n fn try_from(value: T) -> Result;\\n}\\n\\npub trait TryInto: Sized {\\n type Error;\\n\\n fn try_into(self) -> Result;\\n}\\n```\\n\\n:::\\n\\nOK, so we have our trait implemented, we should be able to use `container[index]`,\\nright? Yes\u2026 but actually no :frowning:\\n\\n```\\nerror[E0277]: the type `[std::vec::Vec]` cannot be indexed by `aoc_2022::Vector2D`\\n --\x3e src/bin/day08.rs:26:18\\n |\\n26 | if trees[pos] > tallest {\\n | ^^^ slice indices are of type `usize` or ranges of `usize`\\n |\\n = help: the trait `std::slice::SliceIndex<[std::vec::Vec]>` is not implemented for `aoc_2022::Vector2D`\\n = note: required for `std::vec::Vec>` to implement `std::ops::Index>`\\n\\nerror[E0277]: the type `[std::vec::Vec]` cannot be indexed by `aoc_2022::Vector2D`\\n --\x3e src/bin/day08.rs:30:28\\n |\\n30 | max(tallest, trees[pos])\\n | ^^^ slice indices are of type `usize` or ranges of `usize`\\n |\\n = help: the trait `std::slice::SliceIndex<[std::vec::Vec]>` is not implemented for `aoc_2022::Vector2D`\\n = note: required for `std::vec::Vec>` to implement `std::ops::Index>`\\n\\nerror[E0277]: the type `[std::vec::Vec]` cannot be indexed by `aoc_2022::Vector2D`\\n --\x3e src/bin/day08.rs:52:28\\n |\\n52 | let max_height = trees[position];\\n | ^^^^^^^^ slice indices are of type `usize` or ranges of `usize`\\n |\\n = help: the trait `std::slice::SliceIndex<[std::vec::Vec]>` is not implemented for `aoc_2022::Vector2D`\\n = note: required for `std::vec::Vec>` to implement `std::ops::Index>`\\n```\\n\\nWhy? We have it implemented for the slices (`[C]`), why doesn\'t it work? Well,\\nthe fun part consists of the fact that in other place, where we were using it,\\nwe were passing the `&[Vec]`, but this is coming from a helper functions that\\ntake `&Vec>` instead. And\u2026 we don\'t implement `Index` and `IndexMut` for\\nthose. Just for the slices. \ud83e\udd2f _What are we going to do about it?_\\n\\nWe can either start copy-pasting or be smarter about it\u2026 I choose to be smarter,\\nso let\'s implement a macro! The only difference across the implementations are\\nthe types of the outer containers. Implementation doesn\'t differ **at all**!\\n\\nImplementing the macro can be done in a following way:\\n\\n```rust\\nmacro_rules! generate_indices {\\n ($container:ty) => {\\n impl Index> for $container\\n where\\n I: Copy + TryInto,\\n >::Error: Debug,\\n C: Index,\\n {\\n type Output = C::Output;\\n\\n fn index(&self, index: Vector2D) -> &Self::Output {\\n let (x, y): (usize, usize) =\\n (index.x.try_into().unwrap(), index.y.try_into().unwrap());\\n &self[y][x]\\n }\\n }\\n\\n impl IndexMut> for $container\\n where\\n I: Copy + TryInto,\\n >::Error: Debug,\\n C: IndexMut,\\n {\\n fn index_mut(&mut self, index: Vector2D) -> &mut Self::Output {\\n let (x, y): (usize, usize) =\\n (index.x.try_into().unwrap(), index.y.try_into().unwrap());\\n &mut self[y][x]\\n }\\n }\\n };\\n}\\n```\\n\\nAnd now we can simply do\\n\\n```rust\\ngenerate_indices!(VecDeque);\\ngenerate_indices!([C]);\\ngenerate_indices!(Vec);\\n// generate_indices!([C; N], const N: usize);\\n```\\n\\nThe last type (I took the inspiration from the implementations of the `Index` and\\n`IndexMut` traits) is a bit problematic, because of the `const N: usize` part,\\nwhich I haven\'t managed to be able to parse. And that\'s how I got rid of the error.\\n\\n:::note\\n\\nIf I were to use 2D-indexing over `[C; N]` slices, I\'d probably just go with the\\ncopy-paste, cause the cost of this \u201cmonstrosity\u201d outweighs the benefits of no DRY.\\n\\n:::\\n\\n#### Cause of the problem\\n\\nThis issue is relatively funny. If you don\'t use any type aliases, just the raw\\ntypes, you\'ll get suggested certain changes by the _clippy_. For example if you\\nconsider the following piece of code\\n\\n```rust\\nfn get_sum(nums: &Vec) -> i32 {\\n nums.iter().sum()\\n}\\n\\nfn main() {\\n let nums = vec![1, 2, 3];\\n println!(\\"Sum: {}\\", get_sum(&nums));\\n}\\n```\\n\\nand you run _clippy_ on it, you will get\\n\\n```\\nChecking playground v0.0.1 (/playground)\\nwarning: writing `&Vec` instead of `&[_]` involves a new object where a slice will do\\n --\x3e src/main.rs:1:18\\n |\\n1 | fn get_sum(nums: &Vec) -> i32 {\\n | ^^^^^^^^^ help: change this to: `&[i32]`\\n |\\n = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#ptr_arg\\n = note: `#[warn(clippy::ptr_arg)]` on by default\\n\\nwarning: `playground` (bin \\"playground\\") generated 1 warning\\n Finished dev [unoptimized + debuginfo] target(s) in 0.61s\\n```\\n\\nHowever, if you introduce a type alias, such as\\n\\n```rust\\ntype Numbers = Vec;\\n```\\n\\nThen _clippy_ won\'t say anything, cause there is literally nothing to suggest.\\nHowever the outcome is not the same\u2026\\n\\n[_advent of code_]: https://adventofcode.com\\n[bfs above]: #day-12-hill-climbing-algorithm"},{"id":"aoc-2022/1st-week","metadata":{"permalink":"/blog/aoc-2022/1st-week","editUrl":"https://github.com/mfocko/blog/tree/main/blog/aoc-2022/01-week-1.md","source":"@site/blog/aoc-2022/01-week-1.md","title":"1st week of Advent of Code \'22 in Rust","description":"Surviving first week in Rust.","date":"2022-12-15T01:15:00.000Z","formattedDate":"December 15, 2022","tags":[{"label":"advent-of-code","permalink":"/blog/tags/advent-of-code"},{"label":"advent-of-code-2022","permalink":"/blog/tags/advent-of-code-2022"},{"label":"rust","permalink":"/blog/tags/rust"}],"readingTime":12.4,"hasTruncateMarker":true,"authors":[{"name":"Matej Focko","email":"me+blog@mfocko.xyz","title":"a.k.a. @mf","url":"https://gitlab.com/mfocko","imageURL":"https://github.com/mfocko.png","key":"mf"}],"frontMatter":{"title":"1st week of Advent of Code \'22 in Rust","description":"Surviving first week in Rust.","date":"2022-12-15T01:15","slug":"aoc-2022/1st-week","authors":"mf","tags":["advent-of-code","advent-of-code-2022","rust"],"hide_table_of_contents":false},"unlisted":false,"prevItem":{"title":"2nd week of Advent of Code \'22 in Rust","permalink":"/blog/aoc-2022/2nd-week"},"nextItem":{"title":"Advent of Code \'22 in Rust","permalink":"/blog/aoc-2022/intro"}},"content":"Let\'s go through the first week of [_Advent of Code_] in Rust.\\n\\n\x3c!--truncate--\x3e\\n\\n:::note\\n\\nIf you wish to have a look at the solutions, you can follow them on my [GitLab].\\nMore specifically in the [`/src/bin/`].\\n\\n:::\\n\\nI will try to summarize my experience with using Rust for the AoC. Trying it out\\nages ago, I believe it will be _pain and suffering_, but we will see. For each\\nday I will also try to give a tl;dr of the problem, so that you can better imagine\\nthe relation to my woes or :+1: moments.\\n\\n## [Day 1: Calorie Counting](https://adventofcode.com/2022/day/1)\\n\\n:::info tl;dr\\n\\nAs the name suggests, we get the calories of the food contained in the elves\\nbackpacks and we want to choose the elf that has the most food ;)\\n\\n:::\\n\\n> Wakey wakey!\\n\\nProgramming in Rust at 6am definitely hits. I\'ve also forgotten to mention how I\\nhandle samples. With each puzzle you usually get a sample input and expected\\noutput. You can use them to verify that your solution works, or usually doesn\'t.\\n\\nAt first I\'ve decided to put asserts into my `main`, something like\\n\\n```rust\\nassert_eq!(part_1(&sample), 24000);\\ninfo!(\\"Part 1: {}\\", part_1(&input));\\n\\nassert_eq!(part_2(&sample), 45000);\\ninfo!(\\"Part 2: {}\\", part_2(&input));\\n```\\n\\nHowever, once you get further, the sample input may take some time to run itself.\\nSo in the end, I have decided to turn them into unit tests:\\n\\n```rust\\n#[cfg(test)]\\nmod tests {\\n use super::*;\\n\\n #[test]\\n fn test_part_1() {\\n let sample = parse_input(\\"samples/day01.txt\\");\\n assert_eq!(part_1(&sample), 24000);\\n }\\n\\n #[test]\\n fn test_part_2() {\\n let sample = parse_input(\\"samples/day01.txt\\");\\n assert_eq!(part_2(&sample), 45000);\\n }\\n}\\n```\\n\\nAnd later on I have noticed, it\'s hard to tell the difference between the days,\\nso I further renamed the `mod` from generic `tests` to reflect the days.\\n\\nAlso after finishing the first day puzzle, I have installed an [`sccache`] to\\ncache the builds, so that the build time is lower, cause it was kinda unbearable.\\n\\n### Solution\\n\\nWell, it\'s a pretty simple problem. You just take the input, sum the calories and\\nfind the biggest one. However, if we try to generalize to more than the biggest\\none, the fun appears. We have few options:\\n\\n- keep all the calories, sort them, take what we need\\n- keep all the calories and use max heap\\n- use min heap and maintain at most N calories that we need\\n\\n## [Day 2: Rock Paper Scissors](https://adventofcode.com/2022/day/2)\\n\\n:::info tl;dr\\n\\nYou want to know what score did you achieve while playing _Rock Paper Scissors_.\\nAnd then you want to be strategic about it.\\n\\n:::\\n\\nApart from the technical details of the puzzle, it went relatively smooth.\\n\\n### Solution\\n\\nI took relatively na\xefve approach and then tried to simplify it.\\n\\n## [Day 3: Rucksack Reorganization](https://adventofcode.com/2022/day/3)\\n\\n:::info tl;dr\\n\\nLet\'s go reorganize elves\' backpacks! Each backpacks has 2 compartments and you\\nwant to find the common item among those compartments. Each of them has priority,\\nyou care only about the sum.\\n\\n:::\\n\\nThis is the day where I started to fight the compiler and neither of us decided\\nto give up. Let\'s dive into it \\\\o/\\n\\n:::tip Fun fact\\n\\nFighting the compiler took me 30 minutes.\\n\\n:::\\n\\nWe need to find a common item among 2 collections, that\'s an easy task, right?\\nWe can construct 2 sets and find an intersection:\\n\\n```rust\\nlet top: HashSet = [1, 2, 3].iter().collect();\\nlet bottom: HashSet = [3, 4, 5].iter().collect();\\n```\\n\\nNow, the first issue that we encounter is caused by the fact that we are using\\na slice (the `[\u2026]`), iterator of that returns **references** to the numbers.\\nAnd we get immediately yelled at by the compiler, because the numbers are discarded\\nafter running the `.collect`. To fix this, we can use `.into_iter`:\\n\\n```rust\\nlet top: HashSet = [1, 2, 3].into_iter().collect();\\nlet bottom: HashSet = [3, 4, 5].into_iter().collect();\\n```\\n\\nThis way the numbers will get copied instead of referenced. OK, let\'s find the\\nintersection of those 2 collections:\\n\\n```rust\\nprintln!(\\"Common elements: {:?}\\", top.intersection(&bottom));\\n```\\n\\n```\\nCommon elements: [3]\\n```\\n\\n:::warning[caution]\\n\\nNotice that we need to do `&bottom`. It explicitly specifies that `.intersection`\\n**borrows** the `bottom`, i.e. takes an immutable reference to it.\\n\\n:::\\n\\nThat\'s what we want, right? Looks like it! \\\\o/\\n\\nNext part wants us to find the common element among all of the backpacks. OK, so\\nthat should be fairly easy, we have an intersection and we want to find intersection\\nover all of them.\\n\\nLet\'s have a look at the type of the `.intersection`\\n\\n```rust\\npub fn intersection<\'a>(\\n\xa0\xa0\xa0\xa0&\'a self,\\n\xa0\xa0\xa0\xa0other: &\'a HashSet\\n) -> Intersection<\'a, T, S>\\n```\\n\\nOK\u2026 Huh\u2026 But we have an example there!\\n\\n```rust\\nlet intersection: HashSet<_> = a.intersection(&b).collect();\\n```\\n\\nCool, that\'s all we need.\\n\\n```rust\\nlet top: HashSet = [1, 2, 3, 4].into_iter().collect();\\nlet bottom: HashSet = [3, 4, 5, 6].into_iter().collect();\\nlet top_2: HashSet = [2, 3, 4, 5, 6].into_iter().collect();\\nlet bottom_2: HashSet = [4, 5, 6].into_iter().collect();\\n\\nlet intersection: HashSet<_> = top.intersection(&bottom).collect();\\nprintln!(\\"Intersection: {:?}\\", intersection);\\n```\\n\\n```\\nIntersection: {3, 4}\\n```\\n\\nCool, so let\'s do the intersection with the `top_2`:\\n\\n```rust\\nlet top: HashSet = [1, 2, 3, 4].into_iter().collect();\\nlet bottom: HashSet = [3, 4, 5, 6].into_iter().collect();\\nlet top_2: HashSet = [2, 3, 4, 5, 6].into_iter().collect();\\nlet bottom_2: HashSet = [4, 5, 6].into_iter().collect();\\n\\nlet intersection: HashSet<_> = top.intersection(&bottom).collect();\\nlet intersection: HashSet<_> = intersection.intersection(&top_2).collect();\\nprintln!(\\"Intersection: {:?}\\", intersection);\\n```\\n\\nAnd we get yelled at by the compiler:\\n\\n```\\nerror[E0308]: mismatched types\\n --\x3e src/main.rs:10:58\\n |\\n10 | let intersection: HashSet<_> = intersection.intersection(&top_2).collect();\\n | ------------ ^^^^^^ expected `&i32`, found `i32`\\n | |\\n | arguments to this function are incorrect\\n |\\n = note: expected reference `&HashSet<&i32>`\\n found reference `&HashSet`\\n```\\n\\n/o\\\\ What the hell is going on here? Well, the funny thing is, that this operation\\ndoesn\'t return the elements themselves, but the references to them and when we pass\\nthe third set, it has just the values themselves, without any references.\\n\\n:::tip\\n\\nIt may seem as a very weird decision, but in fact it makes some sense\u2026 It allows\\nyou to do intersection of items that may not be possible to copy. Overall this is\\na \u201ctax\u201d for having a borrow checker ~~drilling your ass~~ having your back and\\nmaking sure you\'re not doing something naughty that may cause an **undefined**\\n**behavior**.\\n\\n:::\\n\\nTo resolve this we need to get an iterator that **clones** the elements:\\n\\n```rust\\nlet top: HashSet = [1, 2, 3, 4].into_iter().collect();\\nlet bottom: HashSet = [3, 4, 5, 6].into_iter().collect();\\nlet top_2: HashSet = [2, 3, 4, 5, 6].into_iter().collect();\\nlet bottom_2: HashSet = [4, 5, 6].into_iter().collect();\\n\\nlet intersection: HashSet<_> = top.intersection(&bottom).cloned().collect();\\nlet intersection: HashSet<_> = intersection.intersection(&top_2).cloned().collect();\\nlet intersection: HashSet<_> = intersection.intersection(&bottom_2).cloned().collect();\\nprintln!(\\"Intersection: {:?}\\", intersection);\\n```\\n\\n```\\nIntersection: {4}\\n```\\n\\n### Solution\\n\\nThe approach is pretty simple, if you omit the _1on1 with the compiler_. You just\\nhave some fun with the set operations :)\\n\\n## [Day 4: Camp Cleanup](https://adventofcode.com/2022/day/4)\\n\\n:::info tl;dr\\n\\nElves are cleaning up the camp and they got overlapping sections to clean up.\\nFind how many overlap and can take the day off.\\n\\n:::\\n\\n[`RangeInclusive`] is your friend not an enemy :)\\n\\n### Solution\\n\\nRelatively easy, you just need to parse the input and know what you want. Rust\'s\\n`RangeInclusive` type helped a lot, cause it took care of all abstractions.\\n\\n## [Day 5: Supply Stacks](https://adventofcode.com/2022/day/5)\\n\\n:::info tl;dr\\n\\nLet\'s play with stacks of crates.\\n\\n:::\\n\\nVery easy problem with very annoying input. You can judge yourself:\\n\\n```\\n [D]\\n[N] [C]\\n[Z] [M] [P]\\n 1 2 3\\n\\nmove 1 from 2 to 1\\nmove 3 from 1 to 3\\nmove 2 from 2 to 1\\nmove 1 from 1 to 2\\n```\\n\\nGood luck transforming that into something reasonable :)\\n\\n:::tip Fun fact\\n\\nTook me 40 minutes to parse this reasonably, including fighting the compiler.\\n\\n:::\\n\\n### Solution\\n\\nFor the initial solution I went with a manual solution (as in _I have done all_\\n_the work_. Later on I have decided to explore the `std` and interface of the\\n`std::vec::Vec` and found [`split_off`] which takes an index and splits (duh)\\nthe vector:\\n\\n```rust\\nlet mut vec = vec![1, 2, 3];\\nlet vec2 = vec.split_off(1);\\nassert_eq!(vec, [1]);\\nassert_eq!(vec2, [2, 3]);\\n```\\n\\nThis helped me simplify my solution a lot and also get rid of some _edge cases_.\\n\\n## [Day 6: Tuning Trouble](https://adventofcode.com/2022/day/6)\\n\\n:::info tl;dr\\n\\nFinding start of the message in a very weird protocol. Start of the message is\\ndenoted by $N$ unique consecutive characters.\\n\\n:::\\n\\n### Solution\\n\\nA lot of different approaches, knowing that we are dealing with input consisting\\nsolely of ASCII letters, I bit the bullet and went with sliding window and\\nconstructing sets from that window, checking if the set is as big as the window.\\n\\nOne possible optimization could consist of keeping a bit-vector (i.e. `usize`\\nvariable) of encountered characters and updating it as we go. However this has\\na different issue and that is removal of the characters from the left side of the\\nwindow. We don\'t know if the same character is not included later on.\\n\\nOther option is to do similar thing, but keeping the frequencies of the letters,\\nand again knowing we have only ASCII letters we can optimize by having a vector\\nof 26 elements that keeps count for each lowercase letter.\\n\\n## [Day 7: No Space Left On Device](https://adventofcode.com/2022/day/7)\\n\\n:::info tl;dr\\n\\nLet\'s simulate [`du`] to get some stats about our file system and then pinpoint\\ndirectories that take a lot of space and should be deleted.\\n\\n:::\\n\\n> I was waiting for this moment, and yet it got me!\\n> _imagine me swearing for hours_\\n\\n### Solution\\n\\nWe need to \u201c_build_\u201d a file system from the input that is given in a following form:\\n\\n```\\n$ cd /\\n$ ls\\ndir a\\n14848514 b.txt\\n8504156 c.dat\\ndir d\\n$ cd a\\n$ ls\\ndir e\\n29116 f\\n2557 g\\n62596 h.lst\\n$ cd e\\n$ ls\\n584 i\\n$ cd ..\\n$ cd ..\\n$ cd d\\n$ ls\\n4060174 j\\n8033020 d.log\\n5626152 d.ext\\n7214296 k\\n```\\n\\nThere are few ways in which you can achieve this and also you can assume some\\npreconditions, but why would we do that, right? :)\\n\\nYou can \u201cslap\u201d this in either [`HashMap`] or [`BTreeMap`] and call it a day.\\nAnd that would be boring\u2026\\n\\n:::tip\\n\\n`BTreeMap` is quite fitting for this, don\'t you think?\\n\\n:::\\n\\nI always wanted to try allocation on heap in Rust, so I chose to implement a tree.\\nI fought with the `Box` for some time and was losing\u2026\\n\\nThen I looked up some implementations of trees or linked lists and decided to try\\n`Rc>`. And I got my _ass whopped_ by the compiler once again. /o\\\\\\n\\n:::tip\\n\\n`Box` represents a dynamically allocated memory on heap. It is a single pointer,\\nyou can imagine this as `std::unique_ptr` in C++.\\n\\n`Rc` represents a dynamically allocated memory on heap. On top of that it is\\n_reference counted_ (that\'s what the `Rc` stands for). You can imagine this as\\n`std::shared_ptr` in C++.\\n\\nNow the fun stuff. Neither of them lets you **mutate** the contents of the memory.\\n\\n`Cell` allows you to mutate the memory. Can be used reasonably with types that\\ncan be copied, because the memory safety is guaranteed by copying the contents\\nwhen there is more than one **mutable** reference to the memory.\\n\\n`RefCell` is similar to the `Cell`, but the borrowing rules (how many mutable\\nreferences are present) are checked dynamically.\\n\\nSo in the end, if you want something like `std::shared_ptr` in Rust, you want\\nto have `Rc>`.\\n\\n:::\\n\\nSo, how are we going to represent the file system then? We will use an enumeration,\\nhehe, which is an algebraic data type that can store some stuff in itself :weary:\\n\\n```rust\\ntype FileHandle = Rc>;\\n\\n#[derive(Debug)]\\nenum AocFile {\\n File(usize),\\n Directory(BTreeMap),\\n}\\n```\\n\\nLet\'s go over it! `FileHandle` represents dynamically allocated `AocFile`, not\\nmuch to discuss. What does the `#[derive(Debug)]` do though? It lets us to print\\nout the value of that enumeration, it\'s derived, so it\'s not as good as if we had\\nimplemented it ourselves, but it\'s good enough for debugging, hence the name.\\n\\nNow to the fun part! `AocFile` value can be represented in two ways:\\n\\n- `File(usize)`, e.g. `AocFile::File(123)` and we can pattern match it, if we\\n need to\\n- `Directory(BTreeMap)` will represent the directory and will\\n contain map matching the name of the files (or directories) within to their\\n respective file handles\\n\\nI will omit the details about constructing this file system, cause there are a lot\\nof technicalities introduced by the nature of the input. However if you are\\ninterested, you can have a look at my solution.\\n\\nWe need to find small enough directories and also find the smallest directory that\\nwill free enough space. Now the question is, how could we do that. And there are\\nmultiple ways I will describe.\\n\\nI have chosen to implement [_tree catamorphism_] :weary:. It is basically a fold\\nover a tree data structure. We descent down into the leaves and propagate computed\\nresults all the way to the root. You can also notice that this approach is very\\nsimilar to _dynamic programming_, we find overlapping sections of the computation\\nand try to minimize the additional work (in this case: we need to know sizes of\\nour descendants, but we have already been there).\\n\\nAnother approach that has been suggested to me few days later is running DFS on\\nthe graph. And, funnily enough, we would still need to combine what we found in\\nthe branches where we descent. So in the end, it would work very similarly to my\\nsolution.\\n\\nOne of the more exotic options would be precomputing the required information at\\nthe same time as parsing. That could be done by adding additional fields to the\\nnodes which would allow storing such information and updating it as we construct\\nthe file system.\\n\\n## Post Mortem\\n\\nThings that have been brought up in the discussion later on.\\n\\n### `Rc` vs `Rc>`\\n\\nIt has been brought up that I have a contradicting statement regarding the\\ndynamically allocated memory. Specifically:\\n\\n- You can imagine `Rc` as an `std::shared_ptr` (in C++)\\n- When you want an equivalent of `std::shared_ptr`, you want to use\\n `Rc>`\\n\\nNow, in Rust it is a bit more complicated, because the type that represents the\\n\u201cshared pointer\u201d is `Rc`. What `RefCell` does is making sure that there is\\nonly one \u201cowner\u201d of a mutable reference at a time (and dynamically, as opposed\\nto the `Cell`).\\n\\nTherefore to be precise and correct about the equivalents of `std::shared_ptr`\\nin Rust, we can say that\\n\\n- `Rc` is an equivalent of a `const std::shared_ptr`,\\n- and `Rc>` is an equivalent of a `std::shared_ptr`.\\n\\nYou can easily see that they only differ in the mutability. (And even that is not\\nas simple as it seems, because there is also `Cell`)\\n\\n[_advent of code_]: https://adventofcode.com\\n[gitlab]: https://gitlab.com/mfocko/advent-of-code-2022\\n[`/src/bin/`]: https://gitlab.com/mfocko/advent-of-code-2022/-/tree/main/src/bin\\n[`sccache`]: https://github.com/mozilla/sccache\\n[`rangeinclusive`]: https://doc.rust-lang.org/std/ops/struct.RangeInclusive.html\\n[`split_off`]: https://doc.rust-lang.org/std/vec/struct.Vec.html#method.split_off\\n[`du`]: https://www.man7.org/linux/man-pages/man1/du.1.html\\n[`hashmap`]: https://doc.rust-lang.org/std/collections/struct.HashMap.html\\n[`btreemap`]: https://doc.rust-lang.org/std/collections/struct.BTreeMap.html\\n[_tree catamorphism_]: https://en.wikipedia.org/wiki/Catamorphism#Tree_fold"},{"id":"aoc-2022/intro","metadata":{"permalink":"/blog/aoc-2022/intro","editUrl":"https://github.com/mfocko/blog/tree/main/blog/aoc-2022/00-intro.md","source":"@site/blog/aoc-2022/00-intro.md","title":"Advent of Code \'22 in Rust","description":"Preparing for Advent of Code \'22.","date":"2022-12-14T21:45:00.000Z","formattedDate":"December 14, 2022","tags":[{"label":"advent-of-code","permalink":"/blog/tags/advent-of-code"},{"label":"advent-of-code-2022","permalink":"/blog/tags/advent-of-code-2022"},{"label":"rust","permalink":"/blog/tags/rust"}],"readingTime":8.665,"hasTruncateMarker":true,"authors":[{"name":"Matej Focko","email":"me+blog@mfocko.xyz","title":"a.k.a. @mf","url":"https://gitlab.com/mfocko","imageURL":"https://github.com/mfocko.png","key":"mf"}],"frontMatter":{"title":"Advent of Code \'22 in Rust","description":"Preparing for Advent of Code \'22.","date":"2022-12-14T21:45","slug":"aoc-2022/intro","authors":"mf","tags":["advent-of-code","advent-of-code-2022","rust"],"hide_table_of_contents":false},"unlisted":false,"prevItem":{"title":"1st week of Advent of Code \'22 in Rust","permalink":"/blog/aoc-2022/1st-week"}},"content":"Let\'s talk about the preparations for this year\'s [_Advent of Code_].\\n\\n\x3c!--truncate--\x3e\\n\\n## Choosing a language\\n\\nWhen choosing a language for AoC, you usually want a language that gives you a\\nquick feedback which allows you to iterate quickly to the solution of the puzzle.\\nOne of the most common choices is Python, many people also use JavaScript or Ruby.\\n\\nGiven the competitive nature of the AoC and popularity among competitive programming,\\nC++ might be also a very good choice. Only if you are familiar with it, I guess\u2026\\n\\nIf you want a challenge, you might also choose to rotate the languages each day.\\nThough I prefer to use only one language.\\n\\nFor this year I have been deciding between _Rust_, _C++_ and _Pascal_ or _Ada_.\\n\\nI have tried Rust last year and have survived with it for 3 days and then gave\\nup and switched to _Kotlin_, which was pretty good given it is \u201cJava undercover\u201d.\\nI pretty much like the ideas behind Rust, I am not sure about the whole cult and\\nimplementation of those ideas though. After some years with C/C++, I would say\\nthat Rust feels _too safe_ for my taste and tries to \u201c_punish me_\u201d even for the\\nmost trivial things.\\n\\nC++ is a very robust, but also comes with a wide variety of options providing you\\nthe ability to shoot yourself in the leg. I have tried to solve few days of previous\\nAdvent of Code events, it was _relatively easy_ to solve the problems in C++, given\\nthat I do not admit writing my own iterator for `enumerate`\u2026\\n\\nPascal or Ada were meme choices :) Ada is heavily inspired by Pascal and has a\\npretty nice standard library that offers enough to be able to quickly solve some\\nproblems in it. However the toolkit is questionable :/\\n\\n## Choosing libraries\\n\\n## Preparations for Rust\\n\\nAll of the sources, later on including solutions, can be found at my\\n[GitLab].\\n\\n### Toolkit\\n\\nSince we are using Rust, we are going to use a [Cargo] and more than likely VSCode\\nwith [`rust-analyzer`]. Because of my choice of libraries, we will also introduce\\na `.envrc` file that can be used by [`direnv`], which allows you to set specific\\nenvironment variables when you enter a directory. In our case, we will use\\n\\n```bash\\n# to show nice backtrace when using the color-eyre\\nexport RUST_BACKTRACE=1\\n\\n# to catch logs generated by tracing\\nexport RUST_LOG=trace\\n```\\n\\nAnd for the one of the most obnoxious things ever, we will use a script to download\\nthe inputs instead of \u201c_clicking, opening and copying to a file_\u201d[^1]. There is\\nno need to be _fancy_, so we will adjust Python script by Martin[^2].\\n\\n```py\\n#!/usr/bin/env python3\\n\\nimport datetime\\nimport yaml\\nimport requests\\nimport sys\\n\\n\\ndef load_config():\\n with open(\\"env.yaml\\", \\"r\\") as f:\\n js = yaml.load(f, Loader=yaml.Loader)\\n return js[\\"session\\"], js[\\"year\\"]\\n\\n\\ndef get_input(session, year, day):\\n return requests.get(\\n f\\"https://adventofcode.com/{year}/day/{day}/input\\",\\n cookies={\\"session\\": session},\\n headers={\\n \\"User-Agent\\": \\"{repo} by {mail}\\".format(\\n repo=\\"gitlab.com/mfocko/advent-of-code-2022\\",\\n mail=\\"me@mfocko.xyz\\",\\n )\\n },\\n ).content.decode(\\"utf-8\\")\\n\\n\\ndef main():\\n day = datetime.datetime.now().day\\n if len(sys.argv) == 2:\\n day = sys.argv[1]\\n\\n session, year = load_config()\\n problem_input = get_input(session, year, day)\\n\\n with open(f\\"./inputs/day{day:>02}.txt\\", \\"w\\") as f:\\n f.write(problem_input)\\n\\n\\nif __name__ == \\"__main__\\":\\n main()\\n```\\n\\nIf the script is called without any arguments, it will deduce the day from the\\nsystem, so we do not need to change the day every morning. It also requires a\\nconfiguration file:\\n\\n```yaml\\n# env.yaml\\nsession: \u2039your session cookie\u203a\\nyear: 2022\\n```\\n\\n### Libraries\\n\\nLooking at the list of the libraries, I have chosen \u201ca lot\u201d of them. Let\'s walk\\nthrough each of them.\\n\\n[`tracing`] and [`tracing-subscriber`] are the crates that can be used for tracing\\nand logging of your Rust programs, there are also other crates that can help you\\nwith providing backtrace to the Sentry in case you have deployed your application\\nsomewhere and you want to watch over it. In our use case we will just utilize the\\nmacros for debugging in the terminal.\\n\\n[`thiserror`], [`anyhow`] and [`color-eyre`] are used for error reporting.\\n`thiserror` is a very good choice for libraries, cause it extends the `Error`\\nfrom the `std` and allows you to create more convenient error types. Next is\\n`anyhow` which kinda builds on top of the `thiserror` and provides you with simpler\\nerror handling in binaries[^3]. And finally we have `color-eyre` which, as I found\\nout later, is a colorful (_wink wink_) extension of `eyre` which is fork of `anyhow`\\nwhile supporting customized reports.\\n\\nIn the end I have decided to remove `thiserror` and `anyhow`, since first one is\\nsuitable for libraries and the latter was basically fully replaced by `{color-,}eyre`.\\n\\n[`regex`] and [`lazy_static`] are a very good and also, I hope, self-explanatory\\ncombination. `lazy_static` allows you to have static variables that must be initialized\\nduring runtime.\\n\\n[`itertools`] provides some nice extensions to the iterators from the `std`.\\n\\n### My own \u201clibrary\u201d\\n\\nWhen creating the crate for this year\'s Advent of Code, I have chosen a library\\ntype. Even though standard library is huge, some things might not be included and\\nalso we can follow _KISS_. I have 2 modules that my \u201clibrary\u201d exports, one for\\nparsing and one for 2D vector (that gets used quite often during Advent of Code).\\n\\nKey part is, of course, processing the input and my library exports following\\nfunctions that get used a lot:\\n\\n```rust\\n/// Reads file to the string.\\npub fn file_to_string>(pathname: P) -> String;\\n\\n/// Reads file and returns it as a vector of characters.\\npub fn file_to_chars>(pathname: P) -> Vec;\\n\\n/// Reads file and returns a vector of parsed structures. Expects each structure\\n/// on its own line in the file. And `T` needs to implement `FromStr` trait.\\npub fn file_to_structs, T: FromStr>(pathname: P) -> Vec\\nwhere\\n ::Err: Debug;\\n\\n/// Converts iterator over strings to a vector of parsed structures. `T` needs\\n/// to implement `FromStr` trait and its error must derive `Debug` trait.\\npub fn strings_to_structs(\\n iter: impl Iterator\\n) -> Vec\\nwhere\\n ::Err: std::fmt::Debug,\\n U: Deref;\\n\\n/// Reads file and returns it as a vector of its lines.\\npub fn file_to_lines>(pathname: P) -> Vec;\\n```\\n\\nAs for the vector, I went with a rather simple implementation that allows only\\naddition of the vectors for now and accessing the elements via functions `x()`\\nand `y()`. Also the vector is generic, so we can use it with any numeric type we\\nneed.\\n\\n### Skeleton\\n\\nWe can also prepare a template to quickly bootstrap each of the days. We know\\nthat each puzzle has 2 parts, which means that we can start with 2 functions that\\nwill solve them.\\n\\n```rust\\nfn part1(input: &Input) -> Output {\\n todo!()\\n}\\n\\nfn part2(input: &Input) -> Output {\\n todo!()\\n}\\n```\\n\\nBoth functions take reference to the input and return some output (in majority\\nof puzzles, it is the same type). `todo!()` can be used as a nice placeholder,\\nit also causes a panic when reached and we could also provide some string with\\nan explanation, e.g. `todo!(\\"part 1\\")`. We have not given functions a specific\\ntype and to avoid as much copy-paste as possible, we will introduce type aliases.\\n\\n```rust\\ntype Input = String;\\ntype Output = i32;\\n```\\n\\n:::tip\\n\\nThis allows us to quickly adjust the types only in one place without the need to\\ndo _regex-replace_ or replace them manually.\\n\\n:::\\n\\nFor each day we get a personalized input that is provided as a text file. Almost\\nall the time, we would like to get some structured type out of that input, and\\ntherefore it makes sense to introduce a new function that will provide the parsing\\nof the input.\\n\\n```rust\\nfn parse_input(path: &str) -> Input {\\n todo!()\\n}\\n```\\n\\nThis \u201cparser\u201d will take a path to the file, just in case we would like to run the\\nsample instead of input.\\n\\nOK, so now we can write a `main` function that will take all of the pieces and\\nrun them.\\n\\n```rust\\nfn main() {\\n let input = parse_input(\\"inputs/dayXX.txt\\");\\n\\n println!(\\"Part 1: {}\\", part_1(&input));\\n println!(\\"Part 2: {}\\", part_2(&input));\\n}\\n```\\n\\nThis would definitely do :) But we have installed a few libraries and we want to\\nuse them. In this part we are going to utilize _[`tracing`]_ (for tracing, duh\u2026)\\nand _[`color-eyre`]_ (for better error reporting, e.g. from parsing).\\n\\n```rust\\nfn main() -> Result<()> {\\n tracing_subscriber::fmt()\\n .with_env_filter(EnvFilter::from_default_env())\\n .with_target(false)\\n .with_file(true)\\n .with_line_number(true)\\n .without_time()\\n .compact()\\n .init();\\n color_eyre::install()?;\\n\\n let input = parse_input(\\"inputs/dayXX.txt\\");\\n\\n info!(\\"Part 1: {}\\", part_1(&input));\\n info!(\\"Part 2: {}\\", part_2(&input));\\n\\n Ok(())\\n}\\n```\\n\\nThe first statement will set up tracing and configure it to print out the logs to\\nterminal, based on the environment variable. We also change the formatting a bit,\\nsince we do not need all the _fancy_ features of the logger. Pure initialization\\nwould get us logs like this:\\n\\n```\\n2022-12-11T19:53:19.975343Z INFO day01: Part 1: 0\\n```\\n\\nHowever after running that command, we will get the following:\\n\\n```\\n INFO src/bin/day01.rs:35: Part 1: 0\\n```\\n\\nAnd the `color_eyre::install()?` is quite straightforward. We just initialize the\\nerror reporting by _color eyre_.\\n\\n:::warning[caution]\\n\\nNotice that we had to add `Ok(())` to the end of the function and adjust the\\nreturn type of the `main` to `Result<()>`. It is caused by the _color eyre_ that\\ncan be installed only once and therefore it can fail, that is how we got the `?`\\nat the end of the `::install` which _unwraps_ the **\xbbresult\xab** of the installation.\\n\\n:::\\n\\nOverall we will get to a template like this:\\n\\n```rust\\nuse aoc_2022::*;\\n\\nuse color_eyre::eyre::Result;\\nuse tracing::info;\\nuse tracing_subscriber::EnvFilter;\\n\\ntype Input = String;\\ntype Output = i32;\\n\\nfn parse_input(path: &str) -> Input {\\n todo!()\\n}\\n\\nfn part1(input: &Input) -> Output {\\n todo!()\\n}\\n\\nfn part2(input: &Input) -> Output {\\n todo!()\\n}\\n\\nfn main() -> Result<()> {\\n tracing_subscriber::fmt()\\n .with_env_filter(EnvFilter::from_default_env())\\n .with_target(false)\\n .with_file(true)\\n .with_line_number(true)\\n .without_time()\\n .compact()\\n .init();\\n color_eyre::install()?;\\n\\n let input = parse_input(\\"inputs/dayXX.txt\\");\\n\\n info!(\\"Part 1: {}\\", part_1(&input));\\n info!(\\"Part 2: {}\\", part_2(&input));\\n\\n Ok(())\\n}\\n```\\n\\n[^1]:\\n Copy-pasting might be a relaxing thing to do, but you can also discover\\n nasty stuff about your PC. See [this Reddit post and the comment].\\n\\n[^2]: [GitHub profile](https://github.com/martinjonas)\\n[^3]:\\n Even though you can use it even for libraries, but handling errors from\\n libraries using `anyhow` is nasty\u2026 You will be the stinky one ;)\\n\\n[_advent of code_]: https://adventofcode.com\\n[gitlab]: https://gitlab.com/mfocko/advent-of-code-2022\\n[cargo]: https://doc.rust-lang.org/cargo/\\n[`rust-analyzer`]: https://rust-analyzer.github.io/\\n[`direnv`]: https://direnv.net/\\n[`tracing`]: https://crates.io/crates/tracing\\n[`tracing-subscriber`]: https://crates.io/crates/tracing-subscriber\\n[`thiserror`]: https://crates.io/crates/thiserror\\n[`anyhow`]: https://crates.io/crates/anyhow\\n[`color-eyre`]: https://crates.io/crates/color-eyre\\n[`regex`]: https://crates.io/crates/regex\\n[`lazy_static`]: https://crates.io/crates/lazy_static\\n[`itertools`]: https://crates.io/crates/itertools\\n[this reddit post and the comment]: https://www.reddit.com/r/adventofcode/comments/zb98pn/comment/iyq0ono"}]}')}}]); \ No newline at end of file diff --git a/assets/js/51efb406.0bebd8d7.js b/assets/js/51efb406.0bebd8d7.js deleted file mode 100644 index a1c3e87..0000000 --- a/assets/js/51efb406.0bebd8d7.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkfi=self.webpackChunkfi||[]).push([[4223],{66933:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>l,contentTitle:()=>s,default:()=>c,frontMatter:()=>r,metadata:()=>i,toc:()=>p});var a=n(85893),o=n(11151);const r={title:"Raspberry Alma",description:"My experience with running \u201cgaming\u201d desktop on Linux.\n",date:new Date("2024-07-20T00:00:00.000Z"),authors:[{key:"mf",title:"a.k.a. useless admin or \u201cSir Tweak-a-Lot\u201d"}],tags:["raspberry-pi","opensuse","almalinux","ansible","self-hosting"]},s=void 0,i={permalink:"/blog/2024/07/20/raspberry-alma",editUrl:"https://github.com/mfocko/blog/tree/main/blog/2024-07-20-raspberry-alma.md",source:"@site/blog/2024-07-20-raspberry-alma.md",title:"Raspberry Alma",description:"My experience with running \u201cgaming\u201d desktop on Linux.\n",date:"2024-07-20T00:00:00.000Z",formattedDate:"July 20, 2024",tags:[{label:"raspberry-pi",permalink:"/blog/tags/raspberry-pi"},{label:"opensuse",permalink:"/blog/tags/opensuse"},{label:"almalinux",permalink:"/blog/tags/almalinux"},{label:"ansible",permalink:"/blog/tags/ansible"},{label:"self-hosting",permalink:"/blog/tags/self-hosting"}],readingTime:5.945,hasTruncateMarker:!0,authors:[{name:"Matej Focko",email:"me+blog@mfocko.xyz",title:"a.k.a. useless admin or \u201cSir Tweak-a-Lot\u201d",url:"https://gitlab.com/mfocko",imageURL:"https://github.com/mfocko.png",key:"mf"}],frontMatter:{title:"Raspberry Alma",description:"My experience with running \u201cgaming\u201d desktop on Linux.\n",date:"2024-07-20T00:00:00.000Z",authors:[{key:"mf",title:"a.k.a. useless admin or \u201cSir Tweak-a-Lot\u201d"}],tags:["raspberry-pi","opensuse","almalinux","ansible","self-hosting"]},unlisted:!1,nextItem:{title:"DevConf.cz 2024",permalink:"/blog/2024/06/19/devconf-2024"}},l={authorsImageUrls:[void 0]},p=[];function m(e){const t={p:"p",...(0,o.a)(),...e.components};return(0,a.jsx)(t.p,{children:"Every now and then I get angry at something not working on the Raspberry and so\nI decide to swap the OSs. Now it's time for something new and not expected."})}function c(e={}){const{wrapper:t}={...(0,o.a)(),...e.components};return t?(0,a.jsx)(t,{...e,children:(0,a.jsx)(m,{...e})}):m(e)}},11151:(e,t,n)=>{n.d(t,{Z:()=>i,a:()=>s});var a=n(67294);const o={},r=a.createContext(o);function s(e){const t=a.useContext(r);return a.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function i(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:s(e.components),a.createElement(r.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/51efb406.13dca2b5.js b/assets/js/51efb406.13dca2b5.js new file mode 100644 index 0000000..417dae5 --- /dev/null +++ b/assets/js/51efb406.13dca2b5.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkfi=self.webpackChunkfi||[]).push([[4223],{66933:(e,t,a)=>{a.r(t),a.d(t,{assets:()=>l,contentTitle:()=>s,default:()=>c,frontMatter:()=>r,metadata:()=>i,toc:()=>m});var n=a(85893),o=a(11151);const r={title:"Raspberry Alma",description:"Finally migrating to a stable distro on Raspberry\u2026\n",date:new Date("2024-07-20T00:00:00.000Z"),authors:[{key:"mf",title:"a.k.a. useless admin or \u201cSir Tweak-a-Lot\u201d"}],tags:["raspberry-pi","opensuse","almalinux","ansible","self-hosting"]},s=void 0,i={permalink:"/blog/2024/07/20/raspberry-alma",editUrl:"https://github.com/mfocko/blog/tree/main/blog/2024-07-20-raspberry-alma.md",source:"@site/blog/2024-07-20-raspberry-alma.md",title:"Raspberry Alma",description:"Finally migrating to a stable distro on Raspberry\u2026\n",date:"2024-07-20T00:00:00.000Z",formattedDate:"July 20, 2024",tags:[{label:"raspberry-pi",permalink:"/blog/tags/raspberry-pi"},{label:"opensuse",permalink:"/blog/tags/opensuse"},{label:"almalinux",permalink:"/blog/tags/almalinux"},{label:"ansible",permalink:"/blog/tags/ansible"},{label:"self-hosting",permalink:"/blog/tags/self-hosting"}],readingTime:5.945,hasTruncateMarker:!0,authors:[{name:"Matej Focko",email:"me+blog@mfocko.xyz",title:"a.k.a. useless admin or \u201cSir Tweak-a-Lot\u201d",url:"https://gitlab.com/mfocko",imageURL:"https://github.com/mfocko.png",key:"mf"}],frontMatter:{title:"Raspberry Alma",description:"Finally migrating to a stable distro on Raspberry\u2026\n",date:"2024-07-20T00:00:00.000Z",authors:[{key:"mf",title:"a.k.a. useless admin or \u201cSir Tweak-a-Lot\u201d"}],tags:["raspberry-pi","opensuse","almalinux","ansible","self-hosting"]},unlisted:!1,nextItem:{title:"DevConf.cz 2024",permalink:"/blog/2024/06/19/devconf-2024"}},l={authorsImageUrls:[void 0]},m=[];function p(e){const t={p:"p",...(0,o.a)(),...e.components};return(0,n.jsx)(t.p,{children:"Every now and then I get angry at something not working on the Raspberry and so\nI decide to swap the OSs. Now it's time for something new and not expected."})}function c(e={}){const{wrapper:t}={...(0,o.a)(),...e.components};return t?(0,n.jsx)(t,{...e,children:(0,n.jsx)(p,{...e})}):p(e)}},11151:(e,t,a)=>{a.d(t,{Z:()=>i,a:()=>s});var n=a(67294);const o={},r=n.createContext(o);function s(e){const t=n.useContext(r);return n.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function i(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:s(e.components),n.createElement(r.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/595c7293.c6b27c6e.js b/assets/js/595c7293.61144ad0.js similarity index 99% rename from assets/js/595c7293.c6b27c6e.js rename to assets/js/595c7293.61144ad0.js index bc998db..2bcb1b2 100644 --- a/assets/js/595c7293.c6b27c6e.js +++ b/assets/js/595c7293.61144ad0.js @@ -1 +1 @@ -"use strict";(self.webpackChunkfi=self.webpackChunkfi||[]).push([[5634],{58396:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>a,contentTitle:()=>o,default:()=>h,frontMatter:()=>r,metadata:()=>c,toc:()=>l});var i=t(85893),s=t(11151);const r={id:"seminar-08",title:"8th seminar",description:"Manipulating with files only char-by-char and a magic tree.\n"},o="8th seminar bonus assignment",c={id:"bonuses/seminar-08",title:"8th seminar",description:"Manipulating with files only char-by-char and a magic tree.\n",source:"@site/c/bonuses/08.md",sourceDirName:"bonuses",slug:"/bonuses/seminar-08",permalink:"/c/bonuses/seminar-08",draft:!1,unlisted:!1,editUrl:"https://github.com/mfocko/blog/tree/main/c/bonuses/08.md",tags:[],version:"current",lastUpdatedAt:1721511622,formattedLastUpdatedAt:"Jul 20, 2024",frontMatter:{id:"seminar-08",title:"8th seminar",description:"Manipulating with files only char-by-char and a magic tree.\n"},sidebar:"autogeneratedBar",previous:{title:"5th and 6th seminar",permalink:"/c/bonuses/seminar-05-06"},next:{title:"10th seminar",permalink:"/c/bonuses/seminar-10"}},a={},l=[{value:"Introduction",id:"introduction",level:2},{value:"Warning",id:"warning",level:2},{value:"Testing",id:"testing",level:2},{value:"Task no. 1: Counting (0.75 K\u20a1)",id:"task-no-1-counting-075-k",level:2},{value:"Requirements",id:"requirements",level:3},{value:"Bonus part (0.75 K\u20a1)",id:"bonus-part-075-k",level:3},{value:"Task no. 2: Weird trees (1 K\u20a1)",id:"task-no-2-weird-trees-1-k",level:2},{value:"Submitting",id:"submitting",level:2}];function d(e){const n={a:"a",blockquote:"blockquote",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",hr:"hr",img:"img",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,s.a)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.h1,{id:"8th-seminar-bonus-assignment",children:"8th seminar bonus assignment"}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.a,{href:"pathname:///files/c/bonuses/08.tar.gz",children:"Source"})}),"\n",(0,i.jsx)(n.h2,{id:"introduction",children:"Introduction"}),"\n",(0,i.jsx)(n.p,{children:"In this bonus you can implement two tasks, one of them has a bonus part with generic\nsolution."}),"\n",(0,i.jsx)(n.p,{children:"One is focused on counting ananas or in case of generic version any substring in\nthe file, but with a restriction on the function you use."}),"\n",(0,i.jsx)(n.p,{children:"Other one has a more algorithmic spirit."}),"\n",(0,i.jsx)(n.p,{children:"For this bonus you can get at maximum 2.5 K\u20a1."}),"\n",(0,i.jsx)(n.h2,{id:"warning",children:"Warning"}),"\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.strong,{children:"DO NOT COMMIT test data"})," to your own git repository, since the tests include\nfiles that exceed 10MB by themselves. Even if they are on separate branch, they\ntake up the space."]}),"\n",(0,i.jsx)(n.h2,{id:"testing",children:"Testing"}),"\n",(0,i.jsxs)(n.p,{children:["For testing you are provided with python script (requires ",(0,i.jsx)(n.code,{children:"click"})," to be installed:\n",(0,i.jsx)(n.code,{children:"pip3 install --user click"}),") and ",(0,i.jsx)(n.code,{children:"Makefile"})," that provides following targets:"]}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"check-counting"})," - runs the ",(0,i.jsx)(n.code,{children:"counting"})," tests"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"check-counting-bonus"})," - runs the ",(0,i.jsx)(n.code,{children:"counting"})," tests with bonus implemented"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"check"})," - runs both ",(0,i.jsx)(n.code,{children:"counting"})," and ",(0,i.jsx)(n.code,{children:"counting-bonus"})," tests"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"clean"})," - removes output files from the test runs"]}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"task-no-1-counting-075-k",children:"Task no. 1: Counting (0.75 K\u20a1)"}),"\n",(0,i.jsx)(n.p,{children:"Your first task is to make smallish program that counts occurences of specific\n(or given) word from file and writes the number to other file."}),"\n",(0,i.jsx)(n.p,{children:"Usage of the program is:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"Usage: ./counting [string-to-be-counted]\n"})}),"\n",(0,i.jsx)(n.p,{children:"Arguments that are passed to the program represent:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:""})," - path to the file where we count the words"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:""})," - path to the file where we output the count"]}),"\n",(0,i.jsxs)(n.li,{children:["(optional argument) ",(0,i.jsx)(n.code,{children:"[string-to-be-counted]"})," - in case you implement bonus,\notherwise we default to word ",(0,i.jsx)(n.code,{children:"ananas"})," ;)"]}),"\n"]}),"\n",(0,i.jsx)(n.p,{children:"In skeleton you are given 3 empty, but documented, functions to implement."}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"count_anything"})," - function accepts input file and substring to be counted in\nthe file, returns the count."]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"count_ananas"})," - same as ",(0,i.jsx)(n.code,{children:"count_anything"}),", but specialized for ananases, the\ndefault implementation from the skeleton expects you to implement ",(0,i.jsx)(n.code,{children:"count_anything"}),"\nand therefore it just calls the other function."]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"write_number"})," - function that writes the number to the file, why would you\nneed the function is explained later :)"]}),"\n"]}),"\n",(0,i.jsx)(n.h3,{id:"requirements",children:"Requirements"}),"\n",(0,i.jsxs)(n.p,{children:["For manipulation with the files you are only allowed to use ",(0,i.jsx)(n.code,{children:"fopen"}),", ",(0,i.jsx)(n.code,{children:"fclose"}),",\n",(0,i.jsx)(n.code,{children:"fgetc"})," and ",(0,i.jsx)(n.code,{children:"fputc"}),". Functions like ",(0,i.jsx)(n.code,{children:"fprintf"})," (except for ",(0,i.jsx)(n.code,{children:"stderr"})," or logging) and\n",(0,i.jsx)(n.code,{children:"fscanf"})," are ",(0,i.jsx)(n.strong,{children:"forbidden"}),"."]}),"\n",(0,i.jsx)(n.p,{children:"In case you struggle and want to use one of those functions, the solution will be\npenalized by 50% of points."}),"\n",(0,i.jsx)(n.h3,{id:"bonus-part-075-k",children:"Bonus part (0.75 K\u20a1)"}),"\n",(0,i.jsxs)(n.p,{children:["Bonus part of this assignment is to implement ",(0,i.jsx)(n.code,{children:"count_anything"})," rather than ",(0,i.jsx)(n.code,{children:"count_ananas"}),"."]}),"\n",(0,i.jsxs)(n.blockquote,{children:["\n",(0,i.jsx)(n.p,{children:"Smaller hint: This task does not need dynamic allocation :) You just need one\ngood helper function and the right idea ;)"}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"task-no-2-weird-trees-1-k",children:"Task no. 2: Weird trees (1 K\u20a1)"}),"\n",(0,i.jsxs)(n.p,{children:["In this task we are crossing our paths with ",(0,i.jsx)(n.em,{children:"algorithms and data structures"}),".\nYour task is to write a program that constructs tree from the file that is given\nas an argument and pretty-prints it."]}),"\n",(0,i.jsxs)(n.p,{children:["Input file consists of lines, that include ",(0,i.jsx)(n.code,{children:"key"})," and ",(0,i.jsx)(n.code,{children:"rank"})," in form ",(0,i.jsx)(n.code,{children:"key;rank"}),"\nor ",(0,i.jsx)(n.code,{children:"nil"}),". Why would we have ",(0,i.jsx)(n.code,{children:"nil"})," in a file? The file represents pre-order iteration\nthrough the tree. Leaves never have rank different than 0, so you can safely assume\n2 non-existing ",(0,i.jsx)(n.code,{children:"nil"}),"s in the input after you read such node ;)"]}),"\n",(0,i.jsxs)("table",{children:[(0,i.jsxs)("tr",{children:[(0,i.jsx)("th",{children:"Example input file"}),(0,i.jsx)("th",{children:"Tree it represents"})]}),(0,i.jsxs)("tr",{children:[(0,i.jsx)("td",{children:(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"8;4\n5;3\n3;2\n2;1\n1;0\nnil\n4;0\n7;1\n6;0\nnil\n11;2\n10;1\n9;0\nnil\n12;0\n"})})}),(0,i.jsx)("td",{children:(0,i.jsx)(n.p,{children:(0,i.jsx)(n.img,{alt:"tree",src:t(30073).Z+"",width:"633",height:"684"})})})]})]}),"\n",(0,i.jsxs)(n.p,{children:["In this task you are only provided with different trees in the ",(0,i.jsx)(n.code,{children:"test-trees"})," directory.\nImplementation and format of the pretty-print is totally up to you. :)"]}),"\n",(0,i.jsx)(n.p,{children:"Example of mine for the tree above:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"8 (rank = 4)\n+-- 5 (rank = 3)\n| +-- 3 (rank = 2)\n| | +-- 2 (rank = 1)\n| | | +-- 1 (rank = 0)\n| | +-- 4 (rank = 0)\n| +-- 7 (rank = 1)\n| +-- 6 (rank = 0)\n+-- 11 (rank = 2)\n +-- 10 (rank = 1)\n | +-- 9 (rank = 0)\n +-- 12 (rank = 0)\n"})}),"\n",(0,i.jsxs)(n.blockquote,{children:["\n",(0,i.jsx)(n.p,{children:"Can you find out what are those trees? :)"}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"submitting",children:"Submitting"}),"\n",(0,i.jsx)(n.p,{children:"In case you have any questions, feel free to reach out to me."}),"\n",(0,i.jsx)(n.hr,{})]})}function h(e={}){const{wrapper:n}={...(0,s.a)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(d,{...e})}):d(e)}},30073:(e,n,t)=>{t.d(n,{Z:()=>i});const i=t.p+"assets/images/tree-c9e37f87f9095c00fad33ea034485ce6.png"},11151:(e,n,t)=>{t.d(n,{Z:()=>c,a:()=>o});var i=t(67294);const s={},r=i.createContext(s);function o(e){const n=i.useContext(r);return i.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function c(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:o(e.components),i.createElement(r.Provider,{value:n},e.children)}}}]); \ No newline at end of file +"use strict";(self.webpackChunkfi=self.webpackChunkfi||[]).push([[5634],{58396:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>a,contentTitle:()=>o,default:()=>h,frontMatter:()=>r,metadata:()=>c,toc:()=>l});var i=t(85893),s=t(11151);const r={id:"seminar-08",title:"8th seminar",description:"Manipulating with files only char-by-char and a magic tree.\n"},o="8th seminar bonus assignment",c={id:"bonuses/seminar-08",title:"8th seminar",description:"Manipulating with files only char-by-char and a magic tree.\n",source:"@site/c/bonuses/08.md",sourceDirName:"bonuses",slug:"/bonuses/seminar-08",permalink:"/c/bonuses/seminar-08",draft:!1,unlisted:!1,editUrl:"https://github.com/mfocko/blog/tree/main/c/bonuses/08.md",tags:[],version:"current",lastUpdatedAt:1721512130,formattedLastUpdatedAt:"Jul 20, 2024",frontMatter:{id:"seminar-08",title:"8th seminar",description:"Manipulating with files only char-by-char and a magic tree.\n"},sidebar:"autogeneratedBar",previous:{title:"5th and 6th seminar",permalink:"/c/bonuses/seminar-05-06"},next:{title:"10th seminar",permalink:"/c/bonuses/seminar-10"}},a={},l=[{value:"Introduction",id:"introduction",level:2},{value:"Warning",id:"warning",level:2},{value:"Testing",id:"testing",level:2},{value:"Task no. 1: Counting (0.75 K\u20a1)",id:"task-no-1-counting-075-k",level:2},{value:"Requirements",id:"requirements",level:3},{value:"Bonus part (0.75 K\u20a1)",id:"bonus-part-075-k",level:3},{value:"Task no. 2: Weird trees (1 K\u20a1)",id:"task-no-2-weird-trees-1-k",level:2},{value:"Submitting",id:"submitting",level:2}];function d(e){const n={a:"a",blockquote:"blockquote",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",hr:"hr",img:"img",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,s.a)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.h1,{id:"8th-seminar-bonus-assignment",children:"8th seminar bonus assignment"}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.a,{href:"pathname:///files/c/bonuses/08.tar.gz",children:"Source"})}),"\n",(0,i.jsx)(n.h2,{id:"introduction",children:"Introduction"}),"\n",(0,i.jsx)(n.p,{children:"In this bonus you can implement two tasks, one of them has a bonus part with generic\nsolution."}),"\n",(0,i.jsx)(n.p,{children:"One is focused on counting ananas or in case of generic version any substring in\nthe file, but with a restriction on the function you use."}),"\n",(0,i.jsx)(n.p,{children:"Other one has a more algorithmic spirit."}),"\n",(0,i.jsx)(n.p,{children:"For this bonus you can get at maximum 2.5 K\u20a1."}),"\n",(0,i.jsx)(n.h2,{id:"warning",children:"Warning"}),"\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.strong,{children:"DO NOT COMMIT test data"})," to your own git repository, since the tests include\nfiles that exceed 10MB by themselves. Even if they are on separate branch, they\ntake up the space."]}),"\n",(0,i.jsx)(n.h2,{id:"testing",children:"Testing"}),"\n",(0,i.jsxs)(n.p,{children:["For testing you are provided with python script (requires ",(0,i.jsx)(n.code,{children:"click"})," to be installed:\n",(0,i.jsx)(n.code,{children:"pip3 install --user click"}),") and ",(0,i.jsx)(n.code,{children:"Makefile"})," that provides following targets:"]}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"check-counting"})," - runs the ",(0,i.jsx)(n.code,{children:"counting"})," tests"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"check-counting-bonus"})," - runs the ",(0,i.jsx)(n.code,{children:"counting"})," tests with bonus implemented"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"check"})," - runs both ",(0,i.jsx)(n.code,{children:"counting"})," and ",(0,i.jsx)(n.code,{children:"counting-bonus"})," tests"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"clean"})," - removes output files from the test runs"]}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"task-no-1-counting-075-k",children:"Task no. 1: Counting (0.75 K\u20a1)"}),"\n",(0,i.jsx)(n.p,{children:"Your first task is to make smallish program that counts occurences of specific\n(or given) word from file and writes the number to other file."}),"\n",(0,i.jsx)(n.p,{children:"Usage of the program is:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"Usage: ./counting [string-to-be-counted]\n"})}),"\n",(0,i.jsx)(n.p,{children:"Arguments that are passed to the program represent:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:""})," - path to the file where we count the words"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:""})," - path to the file where we output the count"]}),"\n",(0,i.jsxs)(n.li,{children:["(optional argument) ",(0,i.jsx)(n.code,{children:"[string-to-be-counted]"})," - in case you implement bonus,\notherwise we default to word ",(0,i.jsx)(n.code,{children:"ananas"})," ;)"]}),"\n"]}),"\n",(0,i.jsx)(n.p,{children:"In skeleton you are given 3 empty, but documented, functions to implement."}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"count_anything"})," - function accepts input file and substring to be counted in\nthe file, returns the count."]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"count_ananas"})," - same as ",(0,i.jsx)(n.code,{children:"count_anything"}),", but specialized for ananases, the\ndefault implementation from the skeleton expects you to implement ",(0,i.jsx)(n.code,{children:"count_anything"}),"\nand therefore it just calls the other function."]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"write_number"})," - function that writes the number to the file, why would you\nneed the function is explained later :)"]}),"\n"]}),"\n",(0,i.jsx)(n.h3,{id:"requirements",children:"Requirements"}),"\n",(0,i.jsxs)(n.p,{children:["For manipulation with the files you are only allowed to use ",(0,i.jsx)(n.code,{children:"fopen"}),", ",(0,i.jsx)(n.code,{children:"fclose"}),",\n",(0,i.jsx)(n.code,{children:"fgetc"})," and ",(0,i.jsx)(n.code,{children:"fputc"}),". Functions like ",(0,i.jsx)(n.code,{children:"fprintf"})," (except for ",(0,i.jsx)(n.code,{children:"stderr"})," or logging) and\n",(0,i.jsx)(n.code,{children:"fscanf"})," are ",(0,i.jsx)(n.strong,{children:"forbidden"}),"."]}),"\n",(0,i.jsx)(n.p,{children:"In case you struggle and want to use one of those functions, the solution will be\npenalized by 50% of points."}),"\n",(0,i.jsx)(n.h3,{id:"bonus-part-075-k",children:"Bonus part (0.75 K\u20a1)"}),"\n",(0,i.jsxs)(n.p,{children:["Bonus part of this assignment is to implement ",(0,i.jsx)(n.code,{children:"count_anything"})," rather than ",(0,i.jsx)(n.code,{children:"count_ananas"}),"."]}),"\n",(0,i.jsxs)(n.blockquote,{children:["\n",(0,i.jsx)(n.p,{children:"Smaller hint: This task does not need dynamic allocation :) You just need one\ngood helper function and the right idea ;)"}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"task-no-2-weird-trees-1-k",children:"Task no. 2: Weird trees (1 K\u20a1)"}),"\n",(0,i.jsxs)(n.p,{children:["In this task we are crossing our paths with ",(0,i.jsx)(n.em,{children:"algorithms and data structures"}),".\nYour task is to write a program that constructs tree from the file that is given\nas an argument and pretty-prints it."]}),"\n",(0,i.jsxs)(n.p,{children:["Input file consists of lines, that include ",(0,i.jsx)(n.code,{children:"key"})," and ",(0,i.jsx)(n.code,{children:"rank"})," in form ",(0,i.jsx)(n.code,{children:"key;rank"}),"\nor ",(0,i.jsx)(n.code,{children:"nil"}),". Why would we have ",(0,i.jsx)(n.code,{children:"nil"})," in a file? The file represents pre-order iteration\nthrough the tree. Leaves never have rank different than 0, so you can safely assume\n2 non-existing ",(0,i.jsx)(n.code,{children:"nil"}),"s in the input after you read such node ;)"]}),"\n",(0,i.jsxs)("table",{children:[(0,i.jsxs)("tr",{children:[(0,i.jsx)("th",{children:"Example input file"}),(0,i.jsx)("th",{children:"Tree it represents"})]}),(0,i.jsxs)("tr",{children:[(0,i.jsx)("td",{children:(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"8;4\n5;3\n3;2\n2;1\n1;0\nnil\n4;0\n7;1\n6;0\nnil\n11;2\n10;1\n9;0\nnil\n12;0\n"})})}),(0,i.jsx)("td",{children:(0,i.jsx)(n.p,{children:(0,i.jsx)(n.img,{alt:"tree",src:t(30073).Z+"",width:"633",height:"684"})})})]})]}),"\n",(0,i.jsxs)(n.p,{children:["In this task you are only provided with different trees in the ",(0,i.jsx)(n.code,{children:"test-trees"})," directory.\nImplementation and format of the pretty-print is totally up to you. :)"]}),"\n",(0,i.jsx)(n.p,{children:"Example of mine for the tree above:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"8 (rank = 4)\n+-- 5 (rank = 3)\n| +-- 3 (rank = 2)\n| | +-- 2 (rank = 1)\n| | | +-- 1 (rank = 0)\n| | +-- 4 (rank = 0)\n| +-- 7 (rank = 1)\n| +-- 6 (rank = 0)\n+-- 11 (rank = 2)\n +-- 10 (rank = 1)\n | +-- 9 (rank = 0)\n +-- 12 (rank = 0)\n"})}),"\n",(0,i.jsxs)(n.blockquote,{children:["\n",(0,i.jsx)(n.p,{children:"Can you find out what are those trees? :)"}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"submitting",children:"Submitting"}),"\n",(0,i.jsx)(n.p,{children:"In case you have any questions, feel free to reach out to me."}),"\n",(0,i.jsx)(n.hr,{})]})}function h(e={}){const{wrapper:n}={...(0,s.a)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(d,{...e})}):d(e)}},30073:(e,n,t)=>{t.d(n,{Z:()=>i});const i=t.p+"assets/images/tree-c9e37f87f9095c00fad33ea034485ce6.png"},11151:(e,n,t)=>{t.d(n,{Z:()=>c,a:()=>o});var i=t(67294);const s={},r=i.createContext(s);function o(e){const n=i.useContext(r);return i.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function c(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:o(e.components),i.createElement(r.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/7052c0bc.9f968677.js b/assets/js/7052c0bc.e0cffc16.js similarity index 95% rename from assets/js/7052c0bc.9f968677.js rename to assets/js/7052c0bc.e0cffc16.js index a914619..76c15e9 100644 --- a/assets/js/7052c0bc.9f968677.js +++ b/assets/js/7052c0bc.e0cffc16.js @@ -1 +1 @@ -"use strict";(self.webpackChunkfi=self.webpackChunkfi||[]).push([[9731],{42286:(t,e,n)=>{n.r(e),n.d(e,{assets:()=>a,contentTitle:()=>c,default:()=>d,frontMatter:()=>i,metadata:()=>s,toc:()=>p});var o=n(85893),r=n(11151);const i={id:"cpp-intro",title:"Introduction",slug:"/"},c=void 0,s={id:"cpp-intro",title:"Introduction",description:"",source:"@site/cpp/00-intro.md",sourceDirName:".",slug:"/",permalink:"/cpp/",draft:!1,unlisted:!1,editUrl:"https://github.com/mfocko/blog/tree/main/cpp/00-intro.md",tags:[],version:"current",lastUpdatedAt:1721511622,formattedLastUpdatedAt:"Jul 20, 2024",sidebarPosition:0,frontMatter:{id:"cpp-intro",title:"Introduction",slug:"/"},sidebar:"autogeneratedBar",next:{title:"Exceptions and RAII",permalink:"/cpp/category/exceptions-and-raii"}},a={},p=[];function u(t){return(0,o.jsx)(o.Fragment,{})}function d(t={}){const{wrapper:e}={...(0,r.a)(),...t.components};return e?(0,o.jsx)(e,{...t,children:(0,o.jsx)(u,{...t})}):u()}},11151:(t,e,n)=>{n.d(e,{Z:()=>s,a:()=>c});var o=n(67294);const r={},i=o.createContext(r);function c(t){const e=o.useContext(i);return o.useMemo((function(){return"function"==typeof t?t(e):{...e,...t}}),[e,t])}function s(t){let e;return e=t.disableParentContext?"function"==typeof t.components?t.components(r):t.components||r:c(t.components),o.createElement(i.Provider,{value:e},t.children)}}}]); \ No newline at end of file +"use strict";(self.webpackChunkfi=self.webpackChunkfi||[]).push([[9731],{42286:(t,e,n)=>{n.r(e),n.d(e,{assets:()=>a,contentTitle:()=>c,default:()=>d,frontMatter:()=>i,metadata:()=>s,toc:()=>p});var o=n(85893),r=n(11151);const i={id:"cpp-intro",title:"Introduction",slug:"/"},c=void 0,s={id:"cpp-intro",title:"Introduction",description:"",source:"@site/cpp/00-intro.md",sourceDirName:".",slug:"/",permalink:"/cpp/",draft:!1,unlisted:!1,editUrl:"https://github.com/mfocko/blog/tree/main/cpp/00-intro.md",tags:[],version:"current",lastUpdatedAt:1721512130,formattedLastUpdatedAt:"Jul 20, 2024",sidebarPosition:0,frontMatter:{id:"cpp-intro",title:"Introduction",slug:"/"},sidebar:"autogeneratedBar",next:{title:"Exceptions and RAII",permalink:"/cpp/category/exceptions-and-raii"}},a={},p=[];function u(t){return(0,o.jsx)(o.Fragment,{})}function d(t={}){const{wrapper:e}={...(0,r.a)(),...t.components};return e?(0,o.jsx)(e,{...t,children:(0,o.jsx)(u,{...t})}):u()}},11151:(t,e,n)=>{n.d(e,{Z:()=>s,a:()=>c});var o=n(67294);const r={},i=o.createContext(r);function c(t){const e=o.useContext(i);return o.useMemo((function(){return"function"==typeof t?t(e):{...e,...t}}),[e,t])}function s(t){let e;return e=t.disableParentContext?"function"==typeof t.components?t.components(r):t.components||r:c(t.components),o.createElement(i.Provider,{value:e},t.children)}}}]); \ No newline at end of file diff --git a/assets/js/794ef108.5cea6ebe.js b/assets/js/794ef108.03844d61.js similarity index 95% rename from assets/js/794ef108.5cea6ebe.js rename to assets/js/794ef108.03844d61.js index 348db9e..d02f542 100644 --- a/assets/js/794ef108.5cea6ebe.js +++ b/assets/js/794ef108.03844d61.js @@ -1 +1 @@ -"use strict";(self.webpackChunkfi=self.webpackChunkfi||[]).push([[3803],{86427:(t,e,n)=>{n.r(e),n.d(e,{assets:()=>a,contentTitle:()=>s,default:()=>l,frontMatter:()=>i,metadata:()=>c,toc:()=>u});var o=n(85893),r=n(11151);const i={id:"c-intro",title:"Introduction",slug:"/"},s=void 0,c={id:"c-intro",title:"Introduction",description:"",source:"@site/c/00-intro.md",sourceDirName:".",slug:"/",permalink:"/c/",draft:!1,unlisted:!1,editUrl:"https://github.com/mfocko/blog/tree/main/c/00-intro.md",tags:[],version:"current",lastUpdatedAt:1721511622,formattedLastUpdatedAt:"Jul 20, 2024",sidebarPosition:0,frontMatter:{id:"c-intro",title:"Introduction",slug:"/"},sidebar:"autogeneratedBar",next:{title:"Bonuses",permalink:"/c/category/bonuses"}},a={},u=[];function d(t){return(0,o.jsx)(o.Fragment,{})}function l(t={}){const{wrapper:e}={...(0,r.a)(),...t.components};return e?(0,o.jsx)(e,{...t,children:(0,o.jsx)(d,{...t})}):d()}},11151:(t,e,n)=>{n.d(e,{Z:()=>c,a:()=>s});var o=n(67294);const r={},i=o.createContext(r);function s(t){const e=o.useContext(i);return o.useMemo((function(){return"function"==typeof t?t(e):{...e,...t}}),[e,t])}function c(t){let e;return e=t.disableParentContext?"function"==typeof t.components?t.components(r):t.components||r:s(t.components),o.createElement(i.Provider,{value:e},t.children)}}}]); \ No newline at end of file +"use strict";(self.webpackChunkfi=self.webpackChunkfi||[]).push([[3803],{86427:(t,e,n)=>{n.r(e),n.d(e,{assets:()=>a,contentTitle:()=>s,default:()=>l,frontMatter:()=>i,metadata:()=>c,toc:()=>u});var o=n(85893),r=n(11151);const i={id:"c-intro",title:"Introduction",slug:"/"},s=void 0,c={id:"c-intro",title:"Introduction",description:"",source:"@site/c/00-intro.md",sourceDirName:".",slug:"/",permalink:"/c/",draft:!1,unlisted:!1,editUrl:"https://github.com/mfocko/blog/tree/main/c/00-intro.md",tags:[],version:"current",lastUpdatedAt:1721512130,formattedLastUpdatedAt:"Jul 20, 2024",sidebarPosition:0,frontMatter:{id:"c-intro",title:"Introduction",slug:"/"},sidebar:"autogeneratedBar",next:{title:"Bonuses",permalink:"/c/category/bonuses"}},a={},u=[];function d(t){return(0,o.jsx)(o.Fragment,{})}function l(t={}){const{wrapper:e}={...(0,r.a)(),...t.components};return e?(0,o.jsx)(e,{...t,children:(0,o.jsx)(d,{...t})}):d()}},11151:(t,e,n)=>{n.d(e,{Z:()=>c,a:()=>s});var o=n(67294);const r={},i=o.createContext(r);function s(t){const e=o.useContext(i);return o.useMemo((function(){return"function"==typeof t?t(e):{...e,...t}}),[e,t])}function c(t){let e;return e=t.disableParentContext?"function"==typeof t.components?t.components(r):t.components||r:s(t.components),o.createElement(i.Provider,{value:e},t.children)}}}]); \ No newline at end of file diff --git a/assets/js/84d1e0d8.2a9a4a49.js b/assets/js/84d1e0d8.377dd43e.js similarity index 97% rename from assets/js/84d1e0d8.2a9a4a49.js rename to assets/js/84d1e0d8.377dd43e.js index 9f63a30..afc325a 100644 --- a/assets/js/84d1e0d8.2a9a4a49.js +++ b/assets/js/84d1e0d8.377dd43e.js @@ -1 +1 @@ -"use strict";(self.webpackChunkfi=self.webpackChunkfi||[]).push([[1885],{49713:(t,e,n)=>{n.r(e),n.d(e,{assets:()=>c,contentTitle:()=>i,default:()=>u,frontMatter:()=>r,metadata:()=>a,toc:()=>d});var o=n(85893),s=n(11151);const r={id:"algorithms-intro",title:"Introduction",slug:"/"},i=void 0,a={id:"algorithms-intro",title:"Introduction",description:"In this part you can find \u201crandom\u201d additional materials I have written over the",source:"@site/algorithms/00-intro.md",sourceDirName:".",slug:"/",permalink:"/algorithms/",draft:!1,unlisted:!1,editUrl:"https://github.com/mfocko/blog/tree/main/algorithms/00-intro.md",tags:[],version:"current",lastUpdatedAt:1721511622,formattedLastUpdatedAt:"Jul 20, 2024",sidebarPosition:0,frontMatter:{id:"algorithms-intro",title:"Introduction",slug:"/"},sidebar:"autogeneratedBar",next:{title:"Algorithms and Correctness",permalink:"/algorithms/category/algorithms-and-correctness"}},c={},d=[];function l(t){const e={a:"a",em:"em",p:"p",...(0,s.a)(),...t.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsxs)(e.p,{children:["In this part you can find \u201crandom\u201d additional materials I have written over the\ncourse of teaching ",(0,o.jsx)(e.em,{children:"Algorithms and data structures I"}),"."]}),"\n",(0,o.jsx)(e.p,{children:"It is a various mix of stuff that may have been produced as a follow-up on some\nquestion asked at the seminar or spontanously."}),"\n",(0,o.jsxs)(e.p,{children:["If you have some ideas for posts, please do not hesitate to submit them as issues\nin the linked ",(0,o.jsx)(e.a,{href:"https://gitlab.fi.muni.cz/xfocko/kb/issues",children:"GitLab"}),"."]})]})}function u(t={}){const{wrapper:e}={...(0,s.a)(),...t.components};return e?(0,o.jsx)(e,{...t,children:(0,o.jsx)(l,{...t})}):l(t)}},11151:(t,e,n)=>{n.d(e,{Z:()=>a,a:()=>i});var o=n(67294);const s={},r=o.createContext(s);function i(t){const e=o.useContext(r);return o.useMemo((function(){return"function"==typeof t?t(e):{...e,...t}}),[e,t])}function a(t){let e;return e=t.disableParentContext?"function"==typeof t.components?t.components(s):t.components||s:i(t.components),o.createElement(r.Provider,{value:e},t.children)}}}]); \ No newline at end of file +"use strict";(self.webpackChunkfi=self.webpackChunkfi||[]).push([[1885],{49713:(t,e,n)=>{n.r(e),n.d(e,{assets:()=>c,contentTitle:()=>i,default:()=>u,frontMatter:()=>r,metadata:()=>a,toc:()=>d});var o=n(85893),s=n(11151);const r={id:"algorithms-intro",title:"Introduction",slug:"/"},i=void 0,a={id:"algorithms-intro",title:"Introduction",description:"In this part you can find \u201crandom\u201d additional materials I have written over the",source:"@site/algorithms/00-intro.md",sourceDirName:".",slug:"/",permalink:"/algorithms/",draft:!1,unlisted:!1,editUrl:"https://github.com/mfocko/blog/tree/main/algorithms/00-intro.md",tags:[],version:"current",lastUpdatedAt:1721512130,formattedLastUpdatedAt:"Jul 20, 2024",sidebarPosition:0,frontMatter:{id:"algorithms-intro",title:"Introduction",slug:"/"},sidebar:"autogeneratedBar",next:{title:"Algorithms and Correctness",permalink:"/algorithms/category/algorithms-and-correctness"}},c={},d=[];function l(t){const e={a:"a",em:"em",p:"p",...(0,s.a)(),...t.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsxs)(e.p,{children:["In this part you can find \u201crandom\u201d additional materials I have written over the\ncourse of teaching ",(0,o.jsx)(e.em,{children:"Algorithms and data structures I"}),"."]}),"\n",(0,o.jsx)(e.p,{children:"It is a various mix of stuff that may have been produced as a follow-up on some\nquestion asked at the seminar or spontanously."}),"\n",(0,o.jsxs)(e.p,{children:["If you have some ideas for posts, please do not hesitate to submit them as issues\nin the linked ",(0,o.jsx)(e.a,{href:"https://gitlab.fi.muni.cz/xfocko/kb/issues",children:"GitLab"}),"."]})]})}function u(t={}){const{wrapper:e}={...(0,s.a)(),...t.components};return e?(0,o.jsx)(e,{...t,children:(0,o.jsx)(l,{...t})}):l(t)}},11151:(t,e,n)=>{n.d(e,{Z:()=>a,a:()=>i});var o=n(67294);const s={},r=o.createContext(s);function i(t){const e=o.useContext(r);return o.useMemo((function(){return"function"==typeof t?t(e):{...e,...t}}),[e,t])}function a(t){let e;return e=t.disableParentContext?"function"==typeof t.components?t.components(s):t.components||s:i(t.components),o.createElement(r.Provider,{value:e},t.children)}}}]); \ No newline at end of file diff --git a/assets/js/a9167e8d.ebc51550.js b/assets/js/a9167e8d.ebc51550.js new file mode 100644 index 0000000..08d26e0 --- /dev/null +++ b/assets/js/a9167e8d.ebc51550.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkfi=self.webpackChunkfi||[]).push([[6074],{53742:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>l,contentTitle:()=>o,default:()=>c,frontMatter:()=>s,metadata:()=>r,toc:()=>d});var a=t(85893),i=t(11151);const s={title:"Raspberry Alma",description:"Finally migrating to a stable distro on Raspberry\u2026\n",date:new Date("2024-07-20T00:00:00.000Z"),authors:[{key:"mf",title:"a.k.a. useless admin or \u201cSir Tweak-a-Lot\u201d"}],tags:["raspberry-pi","opensuse","almalinux","ansible","self-hosting"]},o=void 0,r={permalink:"/blog/2024/07/20/raspberry-alma",editUrl:"https://github.com/mfocko/blog/tree/main/blog/2024-07-20-raspberry-alma.md",source:"@site/blog/2024-07-20-raspberry-alma.md",title:"Raspberry Alma",description:"Finally migrating to a stable distro on Raspberry\u2026\n",date:"2024-07-20T00:00:00.000Z",formattedDate:"July 20, 2024",tags:[{label:"raspberry-pi",permalink:"/blog/tags/raspberry-pi"},{label:"opensuse",permalink:"/blog/tags/opensuse"},{label:"almalinux",permalink:"/blog/tags/almalinux"},{label:"ansible",permalink:"/blog/tags/ansible"},{label:"self-hosting",permalink:"/blog/tags/self-hosting"}],readingTime:5.945,hasTruncateMarker:!0,authors:[{name:"Matej Focko",email:"me+blog@mfocko.xyz",title:"a.k.a. useless admin or \u201cSir Tweak-a-Lot\u201d",url:"https://gitlab.com/mfocko",imageURL:"https://github.com/mfocko.png",key:"mf"}],frontMatter:{title:"Raspberry Alma",description:"Finally migrating to a stable distro on Raspberry\u2026\n",date:"2024-07-20T00:00:00.000Z",authors:[{key:"mf",title:"a.k.a. useless admin or \u201cSir Tweak-a-Lot\u201d"}],tags:["raspberry-pi","opensuse","almalinux","ansible","self-hosting"]},unlisted:!1,nextItem:{title:"DevConf.cz 2024",permalink:"/blog/2024/06/19/devconf-2024"}},l={authorsImageUrls:[void 0]},d=[{value:"Purpose and past",id:"purpose-and-past",level:2},{value:"Choosing the next distro",id:"choosing-the-next-distro",level:2},{value:"Installing AlmaLinux 9",id:"installing-almalinux-9",level:2},{value:"Setting up the \u201clocal server\u201d",id:"setting-up-the-local-server",level:2},{value:"SELinux",id:"selinux",level:3},{value:"Certbot",id:"certbot",level:3},{value:"Cockpit",id:"cockpit",level:3},{value:"CUPS",id:"cups",level:3},{value:"DDNS",id:"ddns",level:3},{value:"Summary",id:"summary",level:2}];function h(e){const n={a:"a",admonition:"admonition",blockquote:"blockquote",code:"code",em:"em",h2:"h2",h3:"h3",li:"li",ol:"ol",p:"p",section:"section",strong:"strong",sup:"sup",ul:"ul",...(0,i.a)(),...e.components};return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(n.p,{children:"Every now and then I get angry at something not working on the Raspberry and so\nI decide to swap the OSs. Now it's time for something new and not expected."}),"\n",(0,a.jsx)(n.h2,{id:"purpose-and-past",children:"Purpose and past"}),"\n",(0,a.jsx)(n.p,{children:"After I've subscribed a VPS at vpsfree.cz for myself, I got an opportunity to\ndrop using an old laptop for running a local \u201cserver\u201d. At that point all I've\nhad was self-hosted Gitea, some aliases on nginx and that was all. Out with the\nold laptop and let's begin experimenting with the Raspberry, right?"}),"\n",(0,a.jsxs)(n.p,{children:["The first OS that got on the Raspberry was ",(0,a.jsx)(n.em,{children:"archLinux"})," (BTW\u2026). I've been using\nit for a long time and had the best experience with. I haven't hit any issues,\nbut at the same time, you need to keep in mind we're running it off the SD card\nand they are known to get worn out quickly, especially if you write ",(0,a.jsx)(n.strong,{children:"a lot"}),"\nwhich\u2026 guess what, is quite common with rolling and bleeding-edge distribution\n","\ud83d\ude04"," And the worst part is keeping up with the updates."]}),"\n",(0,a.jsxs)(n.p,{children:["And that's how I migrated to openSUSE Leap :) I've been using openSUSE for at\nleast 4 years during the high school and a bit more before and after\u2026 openSUSE\nis very user-friendly (YaST is amazing) distribution and honestly just works.\nHowever the cost lies in Cockpit not being available",(0,a.jsx)(n.sup,{children:(0,a.jsx)(n.a,{href:"#user-content-fn-1-930d69",id:"user-content-fnref-1-930d69","data-footnote-ref":!0,"aria-describedby":"footnote-label",children:"1"})})," and some weird design\ndecision, e.g., networking stack is very fragile",(0,a.jsx)(n.sup,{children:(0,a.jsx)(n.a,{href:"#user-content-fn-2-930d69",id:"user-content-fnref-2-930d69","data-footnote-ref":!0,"aria-describedby":"footnote-label",children:"2"})}),"."]}),"\n",(0,a.jsx)(n.p,{children:"And I've got finished in the recent weeks with some issues during updates, but\nthose can be, of course, blamed on me, cause I don't watch over it as I should\n:)"}),"\n",(0,a.jsx)(n.p,{children:"I should probably sum up the latest state of what was running before I decided\nto go for a merciless wipe. So here it is:"}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsx)(n.li,{children:"local Gitea instance, just in case and out of habit"}),"\n",(0,a.jsx)(n.li,{children:"Wireguard connection for easy administration"}),"\n",(0,a.jsx)(n.li,{children:"Certbot & nginx; nginx is probably the biggest piece of work as it also\nprovides reverse proxy for mikrotik router and Ubiquiti AP provided by ISP"}),"\n",(0,a.jsxs)(n.li,{children:["CUPS server that has joined the journey once the HP printer was too big of\na pain in the ","\ud83c\udf51"," to handle via USB"]}),"\n",(0,a.jsx)(n.li,{children:"DDNS service, cause there's public, but dynamic IP from ISP"}),"\n"]}),"\n",(0,a.jsx)(n.h2,{id:"choosing-the-next-distro",children:"Choosing the next distro"}),"\n",(0,a.jsxs)(n.p,{children:["I had the switch in mind for some time, but I couldn't decide on the\ndistribution\u2026 In the ideal world, I'd just slap CentOS Stream on it, ",(0,a.jsx)(n.strong,{children:"but"}),"\nthere's no Raspberry \u201csupport\u201d for CentOS",(0,a.jsx)(n.sup,{children:(0,a.jsx)(n.a,{href:"#user-content-fn-3-930d69",id:"user-content-fnref-3-930d69","data-footnote-ref":!0,"aria-describedby":"footnote-label",children:"3"})}),". So the other choices were plain\nDebian and something else from the RHEL-family which could be either Fedora",(0,a.jsx)(n.sup,{children:(0,a.jsx)(n.a,{href:"#user-content-fn-4-930d69",id:"user-content-fnref-4-930d69","data-footnote-ref":!0,"aria-describedby":"footnote-label",children:"4"})}),",\nAlmaLinux or Rocky Linux."]}),"\n",(0,a.jsxs)(n.p,{children:["I should admit that I'm not a big Debian fan ","\ud83d\ude04"," Even though ",(0,a.jsx)(n.em,{children:"12 bookworm"}),"\nis relatively on the same terms as anything that tries to match RHEL9, it still\nfeels weird. That might be caused by the fact that I've switched RPM-based\ndistributions a long time ago (including screwing around with archLinux and\n",(0,a.jsx)(n.em,{children:"Jean Tux"}),(0,a.jsx)(n.sup,{children:(0,a.jsx)(n.a,{href:"#user-content-fn-5-930d69",id:"user-content-fnref-5-930d69","data-footnote-ref":!0,"aria-describedby":"footnote-label",children:"5"})}),") and never looked back (except for the desktop with NVIDIA GPU\nthat's pain in the ","\ud83c\udf51"," and only Ubuntu runs reasonably\u2026 well)."]}),"\n",(0,a.jsxs)(n.p,{children:["Wearing the ",(0,a.jsx)(n.em,{children:"red fedora"})," also ruled out the Rocky Linux ",":slightly",(0,a.jsx)(n.em,{children:"smiling_face:\nas I don't endorse nor support their _way of operation"})]}),"\n",(0,a.jsx)(n.p,{children:"So AlmaLinux it is!"}),"\n",(0,a.jsx)(n.h2,{id:"installing-almalinux-9",children:"Installing AlmaLinux 9"}),"\n",(0,a.jsx)(n.p,{children:"I'm going with AlmaLinux 9.4 on Raspberry Pi 3B. Opened the AlmaLinux's wiki and\nfirst thing I got slapped by is"}),"\n",(0,a.jsxs)(n.blockquote,{children:["\n",(0,a.jsx)(n.p,{children:'original Raspberry Pi 3 (without "+" models) are not supported'}),"\n"]}),"\n",(0,a.jsxs)(n.p,{children:["GREAT! I took the risk, installed it. And it didn't boot ","\ud83d\ude01"," It turns out\nthat the WiFi kernel module caused a kernel panic on the boot. From some people\non Reddit I found that it caused some issues, ",(0,a.jsx)(n.strong,{children:"but"})," worked, so I've just\ndecided to pop the SD card back in a PC and deny the module from loading. Voil\xe0!\nIt boots!"]}),"\n",(0,a.jsx)(n.h2,{id:"setting-up-the-local-server",children:"Setting up the \u201clocal server\u201d"}),"\n",(0,a.jsx)(n.admonition,{title:"Public disclaimer",type:"caution",children:(0,a.jsx)(n.p,{children:"I suck as admin\u2026"})}),"\n",(0,a.jsxs)(n.p,{children:["Both the Raspberry and my VPS are maintained in the ",(0,a.jsx)(n.em,{children:"caveman-style"})," ","\ud83d\ude04"," And\nthat's why I've decided to start with the less painful one (the Raspberry) to\nwrite the Ansible playbooks for :)"]}),"\n",(0,a.jsxs)(n.p,{children:["I have already managed to migrate my dotfiles and \u201cbootstrap\u201d to be run via\nAnsible, so I've just proceeded to extend that and also reorganize it a bit,\ncause the roles grew in size ","\ud83d\udc40"]}),"\n",(0,a.jsx)(n.p,{children:"And I have to admit that I've been mostly successful. Let's delve into details!"}),"\n",(0,a.jsx)(n.h3,{id:"selinux",children:"SELinux"}),"\n",(0,a.jsxs)(n.p,{children:["Yeah\u2026 that's something that hasn't been running on the openSUSE and I totally\nforgot that hardening the SSHD config (including port change) requires notifying\nSELinux about the port change :) Of course I managed to cut myself off ","\ud83d\ude04"]}),"\n",(0,a.jsx)(n.h3,{id:"certbot",children:"Certbot"}),"\n",(0,a.jsx)(n.p,{children:"Certbot was the service I feared the most, as there is no reasonable way to\nautomate this. You need to run it manually at least the first time. But in the\nend, it was quite OK."}),"\n",(0,a.jsx)(n.h3,{id:"cockpit",children:"Cockpit"}),"\n",(0,a.jsxs)(n.p,{children:["One downside of ",(0,a.jsx)(n.em,{children:"caveman-style"})," administration is the fact that you forget about\nthe tweaking you do. Reverse proxy breaks Cockpit by default. I was reading\nthrough the documentation, but haven't managed to find the part that mentioned\nthe specific settings I had to change. When I was about to open the PR with\nproposed changes, I noticed that it was in a different chapter ","\ud83e\udd26\u200d\u2642\ufe0f"]}),"\n",(0,a.jsx)(n.h3,{id:"cups",children:"CUPS"}),"\n",(0,a.jsxs)(n.p,{children:["Cups went rather smoothly\u2026 except for the fact that it doesn't work on the one\nand only Ubuntu desktop and there are no logs with reason why it fails to add\nthe printer ","\ud83d\ude42"]}),"\n",(0,a.jsxs)(n.p,{children:["Additionally installing the HP printer via ",(0,a.jsx)(n.code,{children:"hp-setup"})," is very interesting\nexperience\u2026 I would've never expected the CLI to have a progress bar that opens\nup at 0% and then just switches into ",(0,a.jsx)(n.em,{children:"terms & conditions"}),"\u2026 Yes, that progress\nbar stayed at 0% even though it was downloading a PPD file ",(0,a.jsx)(n.strong,{children:"and progressing"}),"."]}),"\n",(0,a.jsx)(n.h3,{id:"ddns",children:"DDNS"}),"\n",(0,a.jsxs)(n.p,{children:["I had smallish issue with deciding how to run the DDNS service. I went with\ndropping my own buggy script and had to choose a DDNS client. Found ",(0,a.jsx)(n.em,{children:"inadyn"}),"\n(that isn't built at all for Fedora and family) and ",(0,a.jsx)(n.em,{children:"ddclient"}),". The ",(0,a.jsx)(n.em,{children:"ddclient"}),"\nhad some not very nice feedback, and the version that introduced the Cloudflare\nsupport I need, was not included, so I dropped that. ",(0,a.jsx)(n.em,{children:"inadyn"})," is not packaged,\nso I've set it up as systemd timer spawning a container :)"]}),"\n",(0,a.jsx)(n.h2,{id:"summary",children:"Summary"}),"\n",(0,a.jsx)(n.p,{children:"Overall I've had a very pleasant experience setting up the AlmaLinux on the\nRaspberry. Even though I took a gamble with the officially unsupported model of\nRPi, it works. And it also seems to be filling the purpose it has!"}),"\n",(0,a.jsxs)(n.section,{"data-footnotes":!0,className:"footnotes",children:[(0,a.jsx)(n.h2,{className:"sr-only",id:"footnote-label",children:"Footnotes"}),"\n",(0,a.jsxs)(n.ol,{children:["\n",(0,a.jsxs)(n.li,{id:"user-content-fn-1-930d69",children:["\n",(0,a.jsxs)(n.p,{children:["AFAIK there was some issue with dependencies, so it is available on\nTumbleweed and also in the latest Leap 15.6 ",(0,a.jsx)(n.a,{href:"#user-content-fnref-1-930d69","data-footnote-backref":"","aria-label":"Back to reference 1",className:"data-footnote-backref",children:"\u21a9"})]}),"\n"]}),"\n",(0,a.jsxs)(n.li,{id:"user-content-fn-2-930d69",children:["\n",(0,a.jsxs)(n.p,{children:["By default uses ",(0,a.jsx)(n.em,{children:"wicked"})," and even when running it on desktop via\n",(0,a.jsx)(n.em,{children:"NetworkManager"})," I've hit some inconsistencies with DNS, but\u2026 DNS ",(0,a.jsx)(n.strong,{children:"is"})," the\nDevil, right? ","\ud83d\ude01 ",(0,a.jsx)(n.a,{href:"#user-content-fnref-2-930d69","data-footnote-backref":"","aria-label":"Back to reference 2",className:"data-footnote-backref",children:"\u21a9"})]}),"\n"]}),"\n",(0,a.jsxs)(n.li,{id:"user-content-fn-3-930d69",children:["\n",(0,a.jsxs)(n.p,{children:["And neither RHEL to be fair ;) ",(0,a.jsx)(n.a,{href:"#user-content-fnref-3-930d69","data-footnote-backref":"","aria-label":"Back to reference 3",className:"data-footnote-backref",children:"\u21a9"})]}),"\n"]}),"\n",(0,a.jsxs)(n.li,{id:"user-content-fn-4-930d69",children:["\n",(0,a.jsxs)(n.p,{children:["6-month release cycle goes against the idea to have the least amount of\nupdates as possible\u2026 and on top of that I think that we can safely agree on\nthe fact that Fedora feels like ",(0,a.jsx)(n.em,{children:"archLinux with extra steps"})," ",(0,a.jsx)(n.a,{href:"#user-content-fnref-4-930d69","data-footnote-backref":"","aria-label":"Back to reference 4",className:"data-footnote-backref",children:"\u21a9"})]}),"\n"]}),"\n",(0,a.jsxs)(n.li,{id:"user-content-fn-5-930d69",children:["\n",(0,a.jsxs)(n.p,{children:["Gentoo\u2026 ",(0,a.jsx)(n.a,{href:"#user-content-fnref-5-930d69","data-footnote-backref":"","aria-label":"Back to reference 5",className:"data-footnote-backref",children:"\u21a9"})]}),"\n"]}),"\n"]}),"\n"]})]})}function c(e={}){const{wrapper:n}={...(0,i.a)(),...e.components};return n?(0,a.jsx)(n,{...e,children:(0,a.jsx)(h,{...e})}):h(e)}},11151:(e,n,t)=>{t.d(n,{Z:()=>r,a:()=>o});var a=t(67294);const i={},s=a.createContext(i);function o(e){const n=a.useContext(s);return a.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function r(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:o(e.components),a.createElement(s.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/a9167e8d.fed08b8c.js b/assets/js/a9167e8d.fed08b8c.js deleted file mode 100644 index 9def116..0000000 --- a/assets/js/a9167e8d.fed08b8c.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkfi=self.webpackChunkfi||[]).push([[6074],{53742:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>d,contentTitle:()=>o,default:()=>c,frontMatter:()=>s,metadata:()=>r,toc:()=>l});var i=t(85893),a=t(11151);const s={title:"Raspberry Alma",description:"My experience with running \u201cgaming\u201d desktop on Linux.\n",date:new Date("2024-07-20T00:00:00.000Z"),authors:[{key:"mf",title:"a.k.a. useless admin or \u201cSir Tweak-a-Lot\u201d"}],tags:["raspberry-pi","opensuse","almalinux","ansible","self-hosting"]},o=void 0,r={permalink:"/blog/2024/07/20/raspberry-alma",editUrl:"https://github.com/mfocko/blog/tree/main/blog/2024-07-20-raspberry-alma.md",source:"@site/blog/2024-07-20-raspberry-alma.md",title:"Raspberry Alma",description:"My experience with running \u201cgaming\u201d desktop on Linux.\n",date:"2024-07-20T00:00:00.000Z",formattedDate:"July 20, 2024",tags:[{label:"raspberry-pi",permalink:"/blog/tags/raspberry-pi"},{label:"opensuse",permalink:"/blog/tags/opensuse"},{label:"almalinux",permalink:"/blog/tags/almalinux"},{label:"ansible",permalink:"/blog/tags/ansible"},{label:"self-hosting",permalink:"/blog/tags/self-hosting"}],readingTime:5.945,hasTruncateMarker:!0,authors:[{name:"Matej Focko",email:"me+blog@mfocko.xyz",title:"a.k.a. useless admin or \u201cSir Tweak-a-Lot\u201d",url:"https://gitlab.com/mfocko",imageURL:"https://github.com/mfocko.png",key:"mf"}],frontMatter:{title:"Raspberry Alma",description:"My experience with running \u201cgaming\u201d desktop on Linux.\n",date:"2024-07-20T00:00:00.000Z",authors:[{key:"mf",title:"a.k.a. useless admin or \u201cSir Tweak-a-Lot\u201d"}],tags:["raspberry-pi","opensuse","almalinux","ansible","self-hosting"]},unlisted:!1,nextItem:{title:"DevConf.cz 2024",permalink:"/blog/2024/06/19/devconf-2024"}},d={authorsImageUrls:[void 0]},l=[{value:"Purpose and past",id:"purpose-and-past",level:2},{value:"Choosing the next distro",id:"choosing-the-next-distro",level:2},{value:"Installing AlmaLinux 9",id:"installing-almalinux-9",level:2},{value:"Setting up the \u201clocal server\u201d",id:"setting-up-the-local-server",level:2},{value:"SELinux",id:"selinux",level:3},{value:"Certbot",id:"certbot",level:3},{value:"Cockpit",id:"cockpit",level:3},{value:"CUPS",id:"cups",level:3},{value:"DDNS",id:"ddns",level:3},{value:"Summary",id:"summary",level:2}];function h(e){const n={a:"a",admonition:"admonition",blockquote:"blockquote",code:"code",em:"em",h2:"h2",h3:"h3",li:"li",ol:"ol",p:"p",section:"section",strong:"strong",sup:"sup",ul:"ul",...(0,a.a)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.p,{children:"Every now and then I get angry at something not working on the Raspberry and so\nI decide to swap the OSs. Now it's time for something new and not expected."}),"\n",(0,i.jsx)(n.h2,{id:"purpose-and-past",children:"Purpose and past"}),"\n",(0,i.jsx)(n.p,{children:"After I've subscribed a VPS at vpsfree.cz for myself, I got an opportunity to\ndrop using an old laptop for running a local \u201cserver\u201d. At that point all I've\nhad was self-hosted Gitea, some aliases on nginx and that was all. Out with the\nold laptop and let's begin experimenting with the Raspberry, right?"}),"\n",(0,i.jsxs)(n.p,{children:["The first OS that got on the Raspberry was ",(0,i.jsx)(n.em,{children:"archLinux"})," (BTW\u2026). I've been using\nit for a long time and had the best experience with. I haven't hit any issues,\nbut at the same time, you need to keep in mind we're running it off the SD card\nand they are known to get worn out quickly, especially if you write ",(0,i.jsx)(n.strong,{children:"a lot"}),"\nwhich\u2026 guess what, is quite common with rolling and bleeding-edge distribution\n","\ud83d\ude04"," And the worst part is keeping up with the updates."]}),"\n",(0,i.jsxs)(n.p,{children:["And that's how I migrated to openSUSE Leap :) I've been using openSUSE for at\nleast 4 years during the high school and a bit more before and after\u2026 openSUSE\nis very user-friendly (YaST is amazing) distribution and honestly just works.\nHowever the cost lies in Cockpit not being available",(0,i.jsx)(n.sup,{children:(0,i.jsx)(n.a,{href:"#user-content-fn-1-930d69",id:"user-content-fnref-1-930d69","data-footnote-ref":!0,"aria-describedby":"footnote-label",children:"1"})})," and some weird design\ndecision, e.g., networking stack is very fragile",(0,i.jsx)(n.sup,{children:(0,i.jsx)(n.a,{href:"#user-content-fn-2-930d69",id:"user-content-fnref-2-930d69","data-footnote-ref":!0,"aria-describedby":"footnote-label",children:"2"})}),"."]}),"\n",(0,i.jsx)(n.p,{children:"And I've got finished in the recent weeks with some issues during updates, but\nthose can be, of course, blamed on me, cause I don't watch over it as I should\n:)"}),"\n",(0,i.jsx)(n.p,{children:"I should probably sum up the latest state of what was running before I decided\nto go for a merciless wipe. So here it is:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"local Gitea instance, just in case and out of habit"}),"\n",(0,i.jsx)(n.li,{children:"Wireguard connection for easy administration"}),"\n",(0,i.jsx)(n.li,{children:"Certbot & nginx; nginx is probably the biggest piece of work as it also\nprovides reverse proxy for mikrotik router and Ubiquiti AP provided by ISP"}),"\n",(0,i.jsxs)(n.li,{children:["CUPS server that has joined the journey once the HP printer was too big of\na pain in the ","\ud83c\udf51"," to handle via USB"]}),"\n",(0,i.jsx)(n.li,{children:"DDNS service, cause there's public, but dynamic IP from ISP"}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"choosing-the-next-distro",children:"Choosing the next distro"}),"\n",(0,i.jsxs)(n.p,{children:["I had the switch in mind for some time, but I couldn't decide on the\ndistribution\u2026 In the ideal world, I'd just slap CentOS Stream on it, ",(0,i.jsx)(n.strong,{children:"but"}),"\nthere's no Raspberry \u201csupport\u201d for CentOS",(0,i.jsx)(n.sup,{children:(0,i.jsx)(n.a,{href:"#user-content-fn-3-930d69",id:"user-content-fnref-3-930d69","data-footnote-ref":!0,"aria-describedby":"footnote-label",children:"3"})}),". So the other choices were plain\nDebian and something else from the RHEL-family which could be either Fedora",(0,i.jsx)(n.sup,{children:(0,i.jsx)(n.a,{href:"#user-content-fn-4-930d69",id:"user-content-fnref-4-930d69","data-footnote-ref":!0,"aria-describedby":"footnote-label",children:"4"})}),",\nAlmaLinux or Rocky Linux."]}),"\n",(0,i.jsxs)(n.p,{children:["I should admit that I'm not a big Debian fan ","\ud83d\ude04"," Even though ",(0,i.jsx)(n.em,{children:"12 bookworm"}),"\nis relatively on the same terms as anything that tries to match RHEL9, it still\nfeels weird. That might be caused by the fact that I've switched RPM-based\ndistributions a long time ago (including screwing around with archLinux and\n",(0,i.jsx)(n.em,{children:"Jean Tux"}),(0,i.jsx)(n.sup,{children:(0,i.jsx)(n.a,{href:"#user-content-fn-5-930d69",id:"user-content-fnref-5-930d69","data-footnote-ref":!0,"aria-describedby":"footnote-label",children:"5"})}),") and never looked back (except for the desktop with NVIDIA GPU\nthat's pain in the ","\ud83c\udf51"," and only Ubuntu runs reasonably\u2026 well)."]}),"\n",(0,i.jsxs)(n.p,{children:["Wearing the ",(0,i.jsx)(n.em,{children:"red fedora"})," also ruled out the Rocky Linux ",":slightly",(0,i.jsx)(n.em,{children:"smiling_face:\nas I don't endorse nor support their _way of operation"})]}),"\n",(0,i.jsx)(n.p,{children:"So AlmaLinux it is!"}),"\n",(0,i.jsx)(n.h2,{id:"installing-almalinux-9",children:"Installing AlmaLinux 9"}),"\n",(0,i.jsx)(n.p,{children:"I'm going with AlmaLinux 9.4 on Raspberry Pi 3B. Opened the AlmaLinux's wiki and\nfirst thing I got slapped by is"}),"\n",(0,i.jsxs)(n.blockquote,{children:["\n",(0,i.jsx)(n.p,{children:'original Raspberry Pi 3 (without "+" models) are not supported'}),"\n"]}),"\n",(0,i.jsxs)(n.p,{children:["GREAT! I took the risk, installed it. And it didn't boot ","\ud83d\ude01"," It turns out\nthat the WiFi kernel module caused a kernel panic on the boot. From some people\non Reddit I found that it caused some issues, ",(0,i.jsx)(n.strong,{children:"but"})," worked, so I've just\ndecided to pop the SD card back in a PC and deny the module from loading. Voil\xe0!\nIt boots!"]}),"\n",(0,i.jsx)(n.h2,{id:"setting-up-the-local-server",children:"Setting up the \u201clocal server\u201d"}),"\n",(0,i.jsx)(n.admonition,{title:"Public disclaimer",type:"caution",children:(0,i.jsx)(n.p,{children:"I suck as admin\u2026"})}),"\n",(0,i.jsxs)(n.p,{children:["Both the Raspberry and my VPS are maintained in the ",(0,i.jsx)(n.em,{children:"caveman-style"})," ","\ud83d\ude04"," And\nthat's why I've decided to start with the less painful one (the Raspberry) to\nwrite the Ansible playbooks for :)"]}),"\n",(0,i.jsxs)(n.p,{children:["I have already managed to migrate my dotfiles and \u201cbootstrap\u201d to be run via\nAnsible, so I've just proceeded to extend that and also reorganize it a bit,\ncause the roles grew in size ","\ud83d\udc40"]}),"\n",(0,i.jsx)(n.p,{children:"And I have to admit that I've been mostly successful. Let's delve into details!"}),"\n",(0,i.jsx)(n.h3,{id:"selinux",children:"SELinux"}),"\n",(0,i.jsxs)(n.p,{children:["Yeah\u2026 that's something that hasn't been running on the openSUSE and I totally\nforgot that hardening the SSHD config (including port change) requires notifying\nSELinux about the port change :) Of course I managed to cut myself off ","\ud83d\ude04"]}),"\n",(0,i.jsx)(n.h3,{id:"certbot",children:"Certbot"}),"\n",(0,i.jsx)(n.p,{children:"Certbot was the service I feared the most, as there is no reasonable way to\nautomate this. You need to run it manually at least the first time. But in the\nend, it was quite OK."}),"\n",(0,i.jsx)(n.h3,{id:"cockpit",children:"Cockpit"}),"\n",(0,i.jsxs)(n.p,{children:["One downside of ",(0,i.jsx)(n.em,{children:"caveman-style"})," administration is the fact that you forget about\nthe tweaking you do. Reverse proxy breaks Cockpit by default. I was reading\nthrough the documentation, but haven't managed to find the part that mentioned\nthe specific settings I had to change. When I was about to open the PR with\nproposed changes, I noticed that it was in a different chapter ","\ud83e\udd26\u200d\u2642\ufe0f"]}),"\n",(0,i.jsx)(n.h3,{id:"cups",children:"CUPS"}),"\n",(0,i.jsxs)(n.p,{children:["Cups went rather smoothly\u2026 except for the fact that it doesn't work on the one\nand only Ubuntu desktop and there are no logs with reason why it fails to add\nthe printer ","\ud83d\ude42"]}),"\n",(0,i.jsxs)(n.p,{children:["Additionally installing the HP printer via ",(0,i.jsx)(n.code,{children:"hp-setup"})," is very interesting\nexperience\u2026 I would've never expected the CLI to have a progress bar that opens\nup at 0% and then just switches into ",(0,i.jsx)(n.em,{children:"terms & conditions"}),"\u2026 Yes, that progress\nbar stayed at 0% even though it was downloading a PPD file ",(0,i.jsx)(n.strong,{children:"and progressing"}),"."]}),"\n",(0,i.jsx)(n.h3,{id:"ddns",children:"DDNS"}),"\n",(0,i.jsxs)(n.p,{children:["I had smallish issue with deciding how to run the DDNS service. I went with\ndropping my own buggy script and had to choose a DDNS client. Found ",(0,i.jsx)(n.em,{children:"inadyn"}),"\n(that isn't built at all for Fedora and family) and ",(0,i.jsx)(n.em,{children:"ddclient"}),". The ",(0,i.jsx)(n.em,{children:"ddclient"}),"\nhad some not very nice feedback, and the version that introduced the Cloudflare\nsupport I need, was not included, so I dropped that. ",(0,i.jsx)(n.em,{children:"inadyn"})," is not packaged,\nso I've set it up as systemd timer spawning a container :)"]}),"\n",(0,i.jsx)(n.h2,{id:"summary",children:"Summary"}),"\n",(0,i.jsx)(n.p,{children:"Overall I've had a very pleasant experience setting up the AlmaLinux on the\nRaspberry. Even though I took a gamble with the officially unsupported model of\nRPi, it works. And it also seems to be filling the purpose it has!"}),"\n",(0,i.jsxs)(n.section,{"data-footnotes":!0,className:"footnotes",children:[(0,i.jsx)(n.h2,{className:"sr-only",id:"footnote-label",children:"Footnotes"}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsxs)(n.li,{id:"user-content-fn-1-930d69",children:["\n",(0,i.jsxs)(n.p,{children:["AFAIK there was some issue with dependencies, so it is available on\nTumbleweed and also in the latest Leap 15.6 ",(0,i.jsx)(n.a,{href:"#user-content-fnref-1-930d69","data-footnote-backref":"","aria-label":"Back to reference 1",className:"data-footnote-backref",children:"\u21a9"})]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{id:"user-content-fn-2-930d69",children:["\n",(0,i.jsxs)(n.p,{children:["By default uses ",(0,i.jsx)(n.em,{children:"wicked"})," and even when running it on desktop via\n",(0,i.jsx)(n.em,{children:"NetworkManager"})," I've hit some inconsistencies with DNS, but\u2026 DNS ",(0,i.jsx)(n.strong,{children:"is"})," the\nDevil, right? ","\ud83d\ude01 ",(0,i.jsx)(n.a,{href:"#user-content-fnref-2-930d69","data-footnote-backref":"","aria-label":"Back to reference 2",className:"data-footnote-backref",children:"\u21a9"})]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{id:"user-content-fn-3-930d69",children:["\n",(0,i.jsxs)(n.p,{children:["And neither RHEL to be fair ;) ",(0,i.jsx)(n.a,{href:"#user-content-fnref-3-930d69","data-footnote-backref":"","aria-label":"Back to reference 3",className:"data-footnote-backref",children:"\u21a9"})]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{id:"user-content-fn-4-930d69",children:["\n",(0,i.jsxs)(n.p,{children:["6-month release cycle goes against the idea to have the least amount of\nupdates as possible\u2026 and on top of that I think that we can safely agree on\nthe fact that Fedora feels like ",(0,i.jsx)(n.em,{children:"archLinux with extra steps"})," ",(0,i.jsx)(n.a,{href:"#user-content-fnref-4-930d69","data-footnote-backref":"","aria-label":"Back to reference 4",className:"data-footnote-backref",children:"\u21a9"})]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{id:"user-content-fn-5-930d69",children:["\n",(0,i.jsxs)(n.p,{children:["Gentoo\u2026 ",(0,i.jsx)(n.a,{href:"#user-content-fnref-5-930d69","data-footnote-backref":"","aria-label":"Back to reference 5",className:"data-footnote-backref",children:"\u21a9"})]}),"\n"]}),"\n"]}),"\n"]})]})}function c(e={}){const{wrapper:n}={...(0,a.a)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(h,{...e})}):h(e)}},11151:(e,n,t)=>{t.d(n,{Z:()=>r,a:()=>o});var i=t(67294);const a={},s=i.createContext(a);function o(e){const n=i.useContext(s);return i.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function r(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:o(e.components),i.createElement(s.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/b1288602.7613202c.js b/assets/js/b1288602.88758f6b.js similarity index 99% rename from assets/js/b1288602.7613202c.js rename to assets/js/b1288602.88758f6b.js index 7b5ea41..42d023c 100644 --- a/assets/js/b1288602.7613202c.js +++ b/assets/js/b1288602.88758f6b.js @@ -1 +1 @@ -"use strict";(self.webpackChunkfi=self.webpackChunkfi||[]).push([[59],{51456:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>c,contentTitle:()=>i,default:()=>d,frontMatter:()=>o,metadata:()=>a,toc:()=>h});var r=t(85893),s=t(11151);const o={title:"Submitting merge requests"},i="Submitting merge requests for review",a={id:"mr",title:"Submitting merge requests",description:"This tutorial aims to show you how to follow basic git workflow and submit changes",source:"@site/c/mr.md",sourceDirName:".",slug:"/mr",permalink:"/c/mr",draft:!1,unlisted:!1,editUrl:"https://github.com/mfocko/blog/tree/main/c/mr.md",tags:[],version:"current",lastUpdatedAt:1721511622,formattedLastUpdatedAt:"Jul 20, 2024",frontMatter:{title:"Submitting merge requests"},sidebar:"autogeneratedBar",previous:{title:"Practice exam C",permalink:"/c/pexam/cams"}},c={},h=[{value:"Tutorial",id:"tutorial",level:2},{value:"Step #1 - Starting from the clean repository",id:"step-1---starting-from-the-clean-repository",level:3},{value:"Step #2 - Create new branch",id:"step-2---create-new-branch",level:3},{value:"Step #3 - Do the assignment",id:"step-3---do-the-assignment",level:3},{value:"Step #4 - Commit and upload the changes to GitLab",id:"step-4---commit-and-upload-the-changes-to-gitlab",level:3},{value:"Step #5 - Creating a merge request manually",id:"step-5---creating-a-merge-request-manually",level:3},{value:"Step #6 - Set assignees",id:"step-6---set-assignees",level:3},{value:"Step #7 - Return to default branch",id:"step-7---return-to-default-branch",level:3}];function l(e){const n={a:"a",blockquote:"blockquote",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",hr:"hr",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",...(0,s.a)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(n.h1,{id:"submitting-merge-requests-for-review",children:"Submitting merge requests for review"}),"\n",(0,r.jsxs)(n.p,{children:["This tutorial aims to show you how to follow basic git workflow and submit changes\nthrough ",(0,r.jsx)(n.em,{children:"Merge Requests"})," for review."]}),"\n",(0,r.jsxs)(n.p,{children:["The rudimentary idea behind aims for changes to be present on a separate branch\nthat is supposedly ",(0,r.jsx)(n.em,{children:"merged"})," into the default branch. Till then changes can be reviewed\non ",(0,r.jsx)(n.em,{children:"Merge Request"})," and additional changes may be made based on the reviews. Once\nthe changes satisfy requirements, the merge request is merged."]}),"\n",(0,r.jsx)(n.h2,{id:"tutorial",children:"Tutorial"}),"\n",(0,r.jsxs)(n.blockquote,{children:["\n",(0,r.jsxs)(n.p,{children:["Use this tutorial only for bonus assignments ",(0,r.jsx)(n.strong,{children:"made by your tutors"})," or in case\nyou need to make up for the absence."]}),"\n"]}),"\n",(0,r.jsx)(n.h3,{id:"step-1---starting-from-the-clean-repository",children:"Step #1 - Starting from the clean repository"}),"\n",(0,r.jsxs)(n.p,{children:["In your repository (either locally or on aisa) type ",(0,r.jsx)(n.code,{children:"git status"})," and check if your\nrepository is clean and you are present on the main branch (",(0,r.jsx)(n.code,{children:"master"}),", ",(0,r.jsx)(n.code,{children:"main"})," or\n",(0,r.jsx)(n.code,{children:"trunk"}),"). If you do not know what your default branch is, it is probably ",(0,r.jsx)(n.code,{children:"master"}),"\nand you should not be on any other branch."]}),"\n",(0,r.jsx)(n.p,{children:"Output of the command should look like this:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{children:"aisa$ git status\nOn branch master # Or main or trunk.\nYour branch is up to date with 'origin/master'.\n\nnothing to commit, working tree clean\n"})}),"\n",(0,r.jsxs)(n.blockquote,{children:["\n",(0,r.jsxs)(n.p,{children:["In case you are on different branch or there are uncommitted changes,\n",(0,r.jsx)(n.strong,{children:"do not continue!!!"})," Clean your repository (commit the changes or discard\nthem), before you continue."]}),"\n"]}),"\n",(0,r.jsx)(n.h3,{id:"step-2---create-new-branch",children:"Step #2 - Create new branch"}),"\n",(0,r.jsx)(n.p,{children:"In your repository write command:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{children:"aisa$ git checkout -b BRANCH\nSwitched to a new branch 'BRANCH'\n"})}),"\n",(0,r.jsxs)(n.p,{children:["Instead of ",(0,r.jsx)(n.code,{children:"BRANCH"})," use some reasonable name for the branch. For example if you\nare working on the seminar from 3rd week, name the branch ",(0,r.jsx)(n.code,{children:"seminar-03"}),"."]}),"\n",(0,r.jsx)(n.h3,{id:"step-3---do-the-assignment",children:"Step #3 - Do the assignment"}),"\n",(0,r.jsx)(n.p,{children:"Download the skeleton for the seminar assignment, extract and program. For example\nif you are working on 3rd seminar, you can do so by:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{children:"aisa$ wget https://www.fi.muni.cz/pb071/seminars/seminar-03/pb071-seminar-03.zip\naisa$ unzip pb071-seminar-03.zip\n# Now you should have directory 'seminar-03'.\naisa$ rm pb071-seminar-03.zip\naisa$ cd seminar-03\n# You can work on the assignment.\n"})}),"\n",(0,r.jsx)(n.h3,{id:"step-4---commit-and-upload-the-changes-to-gitlab",children:"Step #4 - Commit and upload the changes to GitLab"}),"\n",(0,r.jsxs)(n.p,{children:["The same way you ",(0,r.jsx)(n.em,{children:"add"})," and ",(0,r.jsx)(n.em,{children:"commit"})," files for the homework assignments, you do for\nthe seminar."]}),"\n",(0,r.jsxs)(n.p,{children:["Now you can upload the changes to GitLab. ",(0,r.jsx)(n.code,{children:"git push"})," is not enough, since repository\non GitLab does not know your new branch. You can solve this by adding arguments:"]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{children:"aisa$ git push origin BRANCH\n...\nremote: To create a merge request for BRANCH, visit:\nremote: https://gitlab.fi.muni.cz/login/pb071/merge_requests/new?merge_request%5Bsource_branch%5D=BRANCH\n...\n"})}),"\n",(0,r.jsx)(n.p,{children:"In the output you should have a link for creating a merge request. If you see this\nlink, open it and skip next step."}),"\n",(0,r.jsx)(n.h3,{id:"step-5---creating-a-merge-request-manually",children:"Step #5 - Creating a merge request manually"}),"\n",(0,r.jsxs)(n.ol,{children:["\n",(0,r.jsx)(n.li,{children:"Open your repository on GitLab."}),"\n",(0,r.jsxs)(n.li,{children:["On the left panel click on ",(0,r.jsx)(n.em,{children:"Merge Requests"}),"."]}),"\n",(0,r.jsxs)(n.li,{children:["Click on ",(0,r.jsx)(n.em,{children:"New Merge Request"}),"."]}),"\n",(0,r.jsxs)(n.li,{children:["In ",(0,r.jsx)(n.em,{children:"Source branch"})," select ",(0,r.jsx)(n.code,{children:"login/pb071"})," and ",(0,r.jsx)(n.code,{children:"BRANCH"}),", which you created."]}),"\n",(0,r.jsxs)(n.li,{children:["In ",(0,r.jsx)(n.em,{children:"Target branch"})," select ",(0,r.jsx)(n.code,{children:"login/pb071"})," and your default branch you have seen\nin the output of the first command. (most likely ",(0,r.jsx)(n.code,{children:"master"}),")"]}),"\n",(0,r.jsxs)(n.li,{children:["Click on ",(0,r.jsx)(n.em,{children:"Compare branches and continue"}),"."]}),"\n"]}),"\n",(0,r.jsx)(n.h3,{id:"step-6---set-assignees",children:"Step #6 - Set assignees"}),"\n",(0,r.jsxs)(n.p,{children:["On the page that is opened, please check at the top that you are creating merge\nrequest ",(0,r.jsx)(n.strong,{children:"from"})," your new branch ",(0,r.jsx)(n.strong,{children:"to"})," your default branch (one of ",(0,r.jsx)(n.code,{children:"master"}),", ",(0,r.jsx)(n.code,{children:"main"}),"\nor ",(0,r.jsx)(n.code,{children:"trunk"}),")."]}),"\n",(0,r.jsxs)(n.p,{children:["Then in the field ",(0,r.jsx)(n.em,{children:"Assignees"})," set your tutors based on the seminar group. You can\nuse login for a quick look up."]}),"\n",(0,r.jsxs)(n.p,{children:["In the end click on ",(0,r.jsx)(n.em,{children:"Submit merge request"}),"."]}),"\n",(0,r.jsx)(n.h3,{id:"step-7---return-to-default-branch",children:"Step #7 - Return to default branch"}),"\n",(0,r.jsx)(n.p,{children:"Homework assignments can be submitted only from branches specified in the rules\nfor the course. Because of that, before you do anything else, you should switch\nback to your default branch."}),"\n",(0,r.jsxs)(n.p,{children:["First of all, same as in step #1, check that your repository is clean with ",(0,r.jsx)(n.code,{children:"git status"}),".\nFor the sake of safety, do not continue without clean repository. Then with command\n",(0,r.jsx)(n.code,{children:"git checkout BRANCH"})," switch to your default branch ",(0,r.jsx)(n.code,{children:"BRANCH"}),"."]}),"\n",(0,r.jsxs)(n.p,{children:["If you do not know which branch is your default, try ",(0,r.jsx)(n.code,{children:"git branch"})," that outputs all branches in your repository. Default branch is typically ",(0,r.jsx)(n.code,{children:"master"}),", but can\nbe ",(0,r.jsx)(n.code,{children:"main"})," or ",(0,r.jsx)(n.code,{children:"trunk"}),"."]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{children:"aisa$ git status\n# Check if repository is clean\n\n# If you know, what is your default branch, you can skip next command.\naisa$ git branch\n# Find the default branch in the list; should be one of the `master`, `main` or\n# `trunk` and you should not have more than one of those.\n# In case the list clears the terminal and you cannot see shell prompt, you can\n# press `q` to quit the pager.\n\naisa$ git checkout master\n"})}),"\n",(0,r.jsx)(n.hr,{}),"\n",(0,r.jsxs)(n.p,{children:["Adapted from: ",(0,r.jsx)(n.a,{href:"https://www.fi.muni.cz/~xlacko1/pb071/mr.html",children:"https://www.fi.muni.cz/~xlacko1/pb071/mr.html"})]})]})}function d(e={}){const{wrapper:n}={...(0,s.a)(),...e.components};return n?(0,r.jsx)(n,{...e,children:(0,r.jsx)(l,{...e})}):l(e)}},11151:(e,n,t)=>{t.d(n,{Z:()=>a,a:()=>i});var r=t(67294);const s={},o=r.createContext(s);function i(e){const n=r.useContext(o);return r.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:i(e.components),r.createElement(o.Provider,{value:n},e.children)}}}]); \ No newline at end of file +"use strict";(self.webpackChunkfi=self.webpackChunkfi||[]).push([[59],{51456:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>c,contentTitle:()=>i,default:()=>d,frontMatter:()=>o,metadata:()=>a,toc:()=>h});var r=t(85893),s=t(11151);const o={title:"Submitting merge requests"},i="Submitting merge requests for review",a={id:"mr",title:"Submitting merge requests",description:"This tutorial aims to show you how to follow basic git workflow and submit changes",source:"@site/c/mr.md",sourceDirName:".",slug:"/mr",permalink:"/c/mr",draft:!1,unlisted:!1,editUrl:"https://github.com/mfocko/blog/tree/main/c/mr.md",tags:[],version:"current",lastUpdatedAt:1721512130,formattedLastUpdatedAt:"Jul 20, 2024",frontMatter:{title:"Submitting merge requests"},sidebar:"autogeneratedBar",previous:{title:"Practice exam C",permalink:"/c/pexam/cams"}},c={},h=[{value:"Tutorial",id:"tutorial",level:2},{value:"Step #1 - Starting from the clean repository",id:"step-1---starting-from-the-clean-repository",level:3},{value:"Step #2 - Create new branch",id:"step-2---create-new-branch",level:3},{value:"Step #3 - Do the assignment",id:"step-3---do-the-assignment",level:3},{value:"Step #4 - Commit and upload the changes to GitLab",id:"step-4---commit-and-upload-the-changes-to-gitlab",level:3},{value:"Step #5 - Creating a merge request manually",id:"step-5---creating-a-merge-request-manually",level:3},{value:"Step #6 - Set assignees",id:"step-6---set-assignees",level:3},{value:"Step #7 - Return to default branch",id:"step-7---return-to-default-branch",level:3}];function l(e){const n={a:"a",blockquote:"blockquote",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",hr:"hr",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",...(0,s.a)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(n.h1,{id:"submitting-merge-requests-for-review",children:"Submitting merge requests for review"}),"\n",(0,r.jsxs)(n.p,{children:["This tutorial aims to show you how to follow basic git workflow and submit changes\nthrough ",(0,r.jsx)(n.em,{children:"Merge Requests"})," for review."]}),"\n",(0,r.jsxs)(n.p,{children:["The rudimentary idea behind aims for changes to be present on a separate branch\nthat is supposedly ",(0,r.jsx)(n.em,{children:"merged"})," into the default branch. Till then changes can be reviewed\non ",(0,r.jsx)(n.em,{children:"Merge Request"})," and additional changes may be made based on the reviews. Once\nthe changes satisfy requirements, the merge request is merged."]}),"\n",(0,r.jsx)(n.h2,{id:"tutorial",children:"Tutorial"}),"\n",(0,r.jsxs)(n.blockquote,{children:["\n",(0,r.jsxs)(n.p,{children:["Use this tutorial only for bonus assignments ",(0,r.jsx)(n.strong,{children:"made by your tutors"})," or in case\nyou need to make up for the absence."]}),"\n"]}),"\n",(0,r.jsx)(n.h3,{id:"step-1---starting-from-the-clean-repository",children:"Step #1 - Starting from the clean repository"}),"\n",(0,r.jsxs)(n.p,{children:["In your repository (either locally or on aisa) type ",(0,r.jsx)(n.code,{children:"git status"})," and check if your\nrepository is clean and you are present on the main branch (",(0,r.jsx)(n.code,{children:"master"}),", ",(0,r.jsx)(n.code,{children:"main"})," or\n",(0,r.jsx)(n.code,{children:"trunk"}),"). If you do not know what your default branch is, it is probably ",(0,r.jsx)(n.code,{children:"master"}),"\nand you should not be on any other branch."]}),"\n",(0,r.jsx)(n.p,{children:"Output of the command should look like this:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{children:"aisa$ git status\nOn branch master # Or main or trunk.\nYour branch is up to date with 'origin/master'.\n\nnothing to commit, working tree clean\n"})}),"\n",(0,r.jsxs)(n.blockquote,{children:["\n",(0,r.jsxs)(n.p,{children:["In case you are on different branch or there are uncommitted changes,\n",(0,r.jsx)(n.strong,{children:"do not continue!!!"})," Clean your repository (commit the changes or discard\nthem), before you continue."]}),"\n"]}),"\n",(0,r.jsx)(n.h3,{id:"step-2---create-new-branch",children:"Step #2 - Create new branch"}),"\n",(0,r.jsx)(n.p,{children:"In your repository write command:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{children:"aisa$ git checkout -b BRANCH\nSwitched to a new branch 'BRANCH'\n"})}),"\n",(0,r.jsxs)(n.p,{children:["Instead of ",(0,r.jsx)(n.code,{children:"BRANCH"})," use some reasonable name for the branch. For example if you\nare working on the seminar from 3rd week, name the branch ",(0,r.jsx)(n.code,{children:"seminar-03"}),"."]}),"\n",(0,r.jsx)(n.h3,{id:"step-3---do-the-assignment",children:"Step #3 - Do the assignment"}),"\n",(0,r.jsx)(n.p,{children:"Download the skeleton for the seminar assignment, extract and program. For example\nif you are working on 3rd seminar, you can do so by:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{children:"aisa$ wget https://www.fi.muni.cz/pb071/seminars/seminar-03/pb071-seminar-03.zip\naisa$ unzip pb071-seminar-03.zip\n# Now you should have directory 'seminar-03'.\naisa$ rm pb071-seminar-03.zip\naisa$ cd seminar-03\n# You can work on the assignment.\n"})}),"\n",(0,r.jsx)(n.h3,{id:"step-4---commit-and-upload-the-changes-to-gitlab",children:"Step #4 - Commit and upload the changes to GitLab"}),"\n",(0,r.jsxs)(n.p,{children:["The same way you ",(0,r.jsx)(n.em,{children:"add"})," and ",(0,r.jsx)(n.em,{children:"commit"})," files for the homework assignments, you do for\nthe seminar."]}),"\n",(0,r.jsxs)(n.p,{children:["Now you can upload the changes to GitLab. ",(0,r.jsx)(n.code,{children:"git push"})," is not enough, since repository\non GitLab does not know your new branch. You can solve this by adding arguments:"]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{children:"aisa$ git push origin BRANCH\n...\nremote: To create a merge request for BRANCH, visit:\nremote: https://gitlab.fi.muni.cz/login/pb071/merge_requests/new?merge_request%5Bsource_branch%5D=BRANCH\n...\n"})}),"\n",(0,r.jsx)(n.p,{children:"In the output you should have a link for creating a merge request. If you see this\nlink, open it and skip next step."}),"\n",(0,r.jsx)(n.h3,{id:"step-5---creating-a-merge-request-manually",children:"Step #5 - Creating a merge request manually"}),"\n",(0,r.jsxs)(n.ol,{children:["\n",(0,r.jsx)(n.li,{children:"Open your repository on GitLab."}),"\n",(0,r.jsxs)(n.li,{children:["On the left panel click on ",(0,r.jsx)(n.em,{children:"Merge Requests"}),"."]}),"\n",(0,r.jsxs)(n.li,{children:["Click on ",(0,r.jsx)(n.em,{children:"New Merge Request"}),"."]}),"\n",(0,r.jsxs)(n.li,{children:["In ",(0,r.jsx)(n.em,{children:"Source branch"})," select ",(0,r.jsx)(n.code,{children:"login/pb071"})," and ",(0,r.jsx)(n.code,{children:"BRANCH"}),", which you created."]}),"\n",(0,r.jsxs)(n.li,{children:["In ",(0,r.jsx)(n.em,{children:"Target branch"})," select ",(0,r.jsx)(n.code,{children:"login/pb071"})," and your default branch you have seen\nin the output of the first command. (most likely ",(0,r.jsx)(n.code,{children:"master"}),")"]}),"\n",(0,r.jsxs)(n.li,{children:["Click on ",(0,r.jsx)(n.em,{children:"Compare branches and continue"}),"."]}),"\n"]}),"\n",(0,r.jsx)(n.h3,{id:"step-6---set-assignees",children:"Step #6 - Set assignees"}),"\n",(0,r.jsxs)(n.p,{children:["On the page that is opened, please check at the top that you are creating merge\nrequest ",(0,r.jsx)(n.strong,{children:"from"})," your new branch ",(0,r.jsx)(n.strong,{children:"to"})," your default branch (one of ",(0,r.jsx)(n.code,{children:"master"}),", ",(0,r.jsx)(n.code,{children:"main"}),"\nor ",(0,r.jsx)(n.code,{children:"trunk"}),")."]}),"\n",(0,r.jsxs)(n.p,{children:["Then in the field ",(0,r.jsx)(n.em,{children:"Assignees"})," set your tutors based on the seminar group. You can\nuse login for a quick look up."]}),"\n",(0,r.jsxs)(n.p,{children:["In the end click on ",(0,r.jsx)(n.em,{children:"Submit merge request"}),"."]}),"\n",(0,r.jsx)(n.h3,{id:"step-7---return-to-default-branch",children:"Step #7 - Return to default branch"}),"\n",(0,r.jsx)(n.p,{children:"Homework assignments can be submitted only from branches specified in the rules\nfor the course. Because of that, before you do anything else, you should switch\nback to your default branch."}),"\n",(0,r.jsxs)(n.p,{children:["First of all, same as in step #1, check that your repository is clean with ",(0,r.jsx)(n.code,{children:"git status"}),".\nFor the sake of safety, do not continue without clean repository. Then with command\n",(0,r.jsx)(n.code,{children:"git checkout BRANCH"})," switch to your default branch ",(0,r.jsx)(n.code,{children:"BRANCH"}),"."]}),"\n",(0,r.jsxs)(n.p,{children:["If you do not know which branch is your default, try ",(0,r.jsx)(n.code,{children:"git branch"})," that outputs all branches in your repository. Default branch is typically ",(0,r.jsx)(n.code,{children:"master"}),", but can\nbe ",(0,r.jsx)(n.code,{children:"main"})," or ",(0,r.jsx)(n.code,{children:"trunk"}),"."]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{children:"aisa$ git status\n# Check if repository is clean\n\n# If you know, what is your default branch, you can skip next command.\naisa$ git branch\n# Find the default branch in the list; should be one of the `master`, `main` or\n# `trunk` and you should not have more than one of those.\n# In case the list clears the terminal and you cannot see shell prompt, you can\n# press `q` to quit the pager.\n\naisa$ git checkout master\n"})}),"\n",(0,r.jsx)(n.hr,{}),"\n",(0,r.jsxs)(n.p,{children:["Adapted from: ",(0,r.jsx)(n.a,{href:"https://www.fi.muni.cz/~xlacko1/pb071/mr.html",children:"https://www.fi.muni.cz/~xlacko1/pb071/mr.html"})]})]})}function d(e={}){const{wrapper:n}={...(0,s.a)(),...e.components};return n?(0,r.jsx)(n,{...e,children:(0,r.jsx)(l,{...e})}):l(e)}},11151:(e,n,t)=>{t.d(n,{Z:()=>a,a:()=>i});var r=t(67294);const s={},o=r.createContext(s);function i(e){const n=r.useContext(o);return r.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:i(e.components),r.createElement(o.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/d05e838c.f04d4535.js b/assets/js/d05e838c.111e6323.js similarity index 99% rename from assets/js/d05e838c.f04d4535.js rename to assets/js/d05e838c.111e6323.js index b4a9a4e..4bdc74d 100644 --- a/assets/js/d05e838c.f04d4535.js +++ b/assets/js/d05e838c.111e6323.js @@ -1 +1 @@ -"use strict";(self.webpackChunkfi=self.webpackChunkfi||[]).push([[6544],{63004:(e,n,r)=>{r.r(n),r.d(n,{assets:()=>d,contentTitle:()=>c,default:()=>a,frontMatter:()=>i,metadata:()=>o,toc:()=>l});var s=r(85893),t=r(11151);const i={id:"seminar-05-06",title:"5th and 6th seminar",description:"200IQ encryption.\n"},c=void 0,o={id:"bonuses/seminar-05-06",title:"5th and 6th seminar",description:"200IQ encryption.\n",source:"@site/c/bonuses/05-06.md",sourceDirName:"bonuses",slug:"/bonuses/seminar-05-06",permalink:"/c/bonuses/seminar-05-06",draft:!1,unlisted:!1,editUrl:"https://github.com/mfocko/blog/tree/main/c/bonuses/05-06.md",tags:[],version:"current",lastUpdatedAt:1721511622,formattedLastUpdatedAt:"Jul 20, 2024",frontMatter:{id:"seminar-05-06",title:"5th and 6th seminar",description:"200IQ encryption.\n"},sidebar:"autogeneratedBar",previous:{title:"4th seminar",permalink:"/c/bonuses/seminar-04"},next:{title:"8th seminar",permalink:"/c/bonuses/seminar-08"}},d={},l=[{value:"Introduction",id:"introduction",level:2},{value:"Task no. 1: Reverse (0.5 K\u20a1)",id:"task-no-1-reverse-05-k",level:3},{value:"Task no. 2: Vigen\xe8re (0.5 K\u20a1)",id:"task-no-2-vigen\xe8re-05-k",level:3},{value:"Bonus part (0.5 K\u20a1)",id:"bonus-part-05-k",level:4},{value:"Task no. 3: Bit madness (0.5 K\u20a1)",id:"task-no-3-bit-madness-05-k",level:3},{value:"Task no. 4: All combined to BMP (0.5 K\u20a1)",id:"task-no-4-all-combined-to-bmp-05-k",level:3},{value:"Submitting",id:"submitting",level:2}];function h(e){const n={a:"a",code:"code",h2:"h2",h3:"h3",h4:"h4",hr:"hr",li:"li",ol:"ol",p:"p",pre:"pre",ul:"ul",...(0,t.a)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.p,{children:"For this bonus you can get at maximum 2.5 K\u20a1."}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"pathname:///files/c/bonuses/05-06.tar.gz",children:"Source"})}),"\n",(0,s.jsx)(n.h2,{id:"introduction",children:"Introduction"}),"\n",(0,s.jsx)(n.p,{children:"In this bonus you will implement few functions that will be used together for\nimplementing a very special cipher."}),"\n",(0,s.jsx)(n.h3,{id:"task-no-1-reverse-05-k",children:"Task no. 1: Reverse (0.5 K\u20a1)"}),"\n",(0,s.jsxs)(n.p,{children:["Write a function ",(0,s.jsx)(n.code,{children:"char* reverse(const char* text)"})," that returns copy of the input\nstring in reversed order (also uppercase)."]}),"\n",(0,s.jsxs)(n.p,{children:["In case you are given ",(0,s.jsx)(n.code,{children:"NULL"}),", return ",(0,s.jsx)(n.code,{children:"NULL"}),"."]}),"\n",(0,s.jsx)(n.p,{children:"Example (more in tests):"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-c",children:'char* reversed = reverse("Hello world!");\n\nprintf("%s\\n", reversed);\n// "!DLROW OLLEH"\n\nif (reversed != NULL) {\n free(reversed);\n}\n'})}),"\n",(0,s.jsx)(n.h3,{id:"task-no-2-vigen\xe8re-05-k",children:"Task no. 2: Vigen\xe8re (0.5 K\u20a1)"}),"\n",(0,s.jsx)(n.p,{children:"Vigen\xe8re cipher is similar to the Caesar cipher, but you also have a key that is\nused for encrypting (or decrypting)."}),"\n",(0,s.jsx)(n.p,{children:"Your task is to write two functions:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"char* vigenere_encrypt(const char* key, const char* text)"})," for encrypting"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"char* vigenere_decrypt(const char* key, const char* text)"})," for decrypting"]}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"In both of those you should return uppercase characters."}),"\n",(0,s.jsx)(n.p,{children:"Meaning of the parameters you are given:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"key"})," - String that represents key that is used for *crypting. It consists of\none word and can have only characters of the alphabet. Does not matter if they\nare uppercase or lowercase."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"text"})," - String that is to be *crypted."]}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:["Function returns address of the encrypted (or decrypted) string. Or ",(0,s.jsx)(n.code,{children:"NULL"})," in case\nerror occurs."]}),"\n",(0,s.jsx)(n.p,{children:"Example:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-c",children:'char *encrypted = vigenere_encrypt("CoMPuTeR", "Hello world!");\n\nprintf("%s\\n", encrypted);\n// "JSXAI PSINR!"\n\nif (encrypted != NULL) {\n free(encrypted)\n}\n'})}),"\n",(0,s.jsx)(n.h4,{id:"bonus-part-05-k",children:"Bonus part (0.5 K\u20a1)"}),"\n",(0,s.jsx)(n.p,{children:"If you can utilize helper function that would do both encrypting and decrypting,\nyou can gain 0.5 K\u20a1."}),"\n",(0,s.jsxs)(n.p,{children:["Usage of ",(0,s.jsx)(n.code,{children:"true"}),"/",(0,s.jsx)(n.code,{children:"false"})," to decide path in code is prohibited. It leads to merging\nof both functions into one. Point of this part is to discover a way to do this\ngenerically in such way that there are no separate paths for one or the other. One\nfunction with no branching for both of them, parametrization is your friend :)"]}),"\n",(0,s.jsx)(n.h3,{id:"task-no-3-bit-madness-05-k",children:"Task no. 3: Bit madness (0.5 K\u20a1)"}),"\n",(0,s.jsx)(n.p,{children:"This is a state of the art crypto. Please do not share :)"}),"\n",(0,s.jsx)(n.p,{children:"For encrypting:"}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsx)(n.li,{children:"Split the character that is to be encrypted in halves (4 and 4 bits each)."}),"\n",(0,s.jsx)(n.li,{children:"Bits in 1st half are to be split into pairs. Swap bits in those pairs."}),"\n",(0,s.jsxs)(n.li,{children:["Then use the 4 bits that you created in the 2nd step for ",(0,s.jsx)(n.code,{children:"XOR"})," with the other\n4 bits."]}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:["This simple and ingenious principle will be illustrated on the following example.\nString we want to encrypt is ",(0,s.jsx)(n.code,{children:"Hello world!"}),". We need to encrypt each letter separately,\nso we will demonstrate on letter ",(0,s.jsx)(n.code,{children:"H"}),":"]}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["Letter ",(0,s.jsx)(n.code,{children:"H"})," is represented in ASCII as ",(0,s.jsx)(n.code,{children:"72"}),"."]}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"72"})," represented in binary is: ",(0,s.jsx)(n.code,{children:"01001000"}),". So first 4 bits are: ",(0,s.jsx)(n.code,{children:"0100"})," and last\n4 bits are ",(0,s.jsx)(n.code,{children:"1000"}),"."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["First half of bits (",(0,s.jsx)(n.code,{children:"0100"}),") consists of 2 pairs (",(0,s.jsx)(n.code,{children:"01"})," and ",(0,s.jsx)(n.code,{children:"00"}),") which we swap\n(",(0,s.jsx)(n.code,{children:"01 ~> 10"})," and ",(0,s.jsx)(n.code,{children:"00 ~> 00"}),"). That way we get ",(0,s.jsx)(n.code,{children:"1000"}),"."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"That half is used for xor with the other 4 bits:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:" 1000 // second half\nXOR 1000 // first half after 2nd step\n--------\n 0000\n"})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["Now we combine both halves (first one is ",(0,s.jsx)(n.code,{children:"1000"}),", which we got from the 2nd step\nand second one is ",(0,s.jsx)(n.code,{children:"0000"}),", which we got from the 3rd step) and get ",(0,s.jsx)(n.code,{children:"10000000"}),",\nwhich is encrypted character ",(0,s.jsx)(n.code,{children:"H"})," using this method."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"In case of decryption, reverse those steps."}),"\n",(0,s.jsx)(n.p,{children:"Your task is to implement functions:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.code,{children:"unsigned char* bit_encrypt(const char* text)"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.code,{children:"char* bit_decrypt(const unsigned char* text)"})}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"Example:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-c",children:'unsigned char* encrypted = bit_encrypt("Hello world!");\n\nfor (int i = 0; i < 12;i++) {\n printf("%x ", encrypted[i]);\n //80 9c 95 95 96 11 bc 96 b9 95 9d 10\n}\n\nif (encrypted != NULL) {\n free(encrypted);\n}\n'})}),"\n",(0,s.jsx)(n.h3,{id:"task-no-4-all-combined-to-bmp-05-k",children:"Task no. 4: All combined to BMP (0.5 K\u20a1)"}),"\n",(0,s.jsx)(n.p,{children:"Authors of the BMP cipher are non-disclosed :)"}),"\n",(0,s.jsx)(n.p,{children:"Create pair of functions:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.code,{children:"unsigned char* bmp_encrypt(const char* key, const char* text)"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.code,{children:"char* bmp_decrypt(const char* key, const unsigned char* text)"})}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"BMP cipher consists of following steps for encrypting:"}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsx)(n.li,{children:"Reverse the input string"}),"\n",(0,s.jsx)(n.li,{children:"Use Vigenere on the string you got from step #1"}),"\n",(0,s.jsx)(n.li,{children:"Use bit madness on the string you got from step #2"}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"For decrypting, reverse the steps."}),"\n",(0,s.jsx)(n.h2,{id:"submitting",children:"Submitting"}),"\n",(0,s.jsx)(n.p,{children:"In case you have any questions, feel free to reach out to me."}),"\n",(0,s.jsx)(n.hr,{})]})}function a(e={}){const{wrapper:n}={...(0,t.a)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(h,{...e})}):h(e)}},11151:(e,n,r)=>{r.d(n,{Z:()=>o,a:()=>c});var s=r(67294);const t={},i=s.createContext(t);function c(e){const n=s.useContext(i);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function o(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:c(e.components),s.createElement(i.Provider,{value:n},e.children)}}}]); \ No newline at end of file +"use strict";(self.webpackChunkfi=self.webpackChunkfi||[]).push([[6544],{63004:(e,n,r)=>{r.r(n),r.d(n,{assets:()=>d,contentTitle:()=>c,default:()=>a,frontMatter:()=>i,metadata:()=>o,toc:()=>l});var s=r(85893),t=r(11151);const i={id:"seminar-05-06",title:"5th and 6th seminar",description:"200IQ encryption.\n"},c=void 0,o={id:"bonuses/seminar-05-06",title:"5th and 6th seminar",description:"200IQ encryption.\n",source:"@site/c/bonuses/05-06.md",sourceDirName:"bonuses",slug:"/bonuses/seminar-05-06",permalink:"/c/bonuses/seminar-05-06",draft:!1,unlisted:!1,editUrl:"https://github.com/mfocko/blog/tree/main/c/bonuses/05-06.md",tags:[],version:"current",lastUpdatedAt:1721512130,formattedLastUpdatedAt:"Jul 20, 2024",frontMatter:{id:"seminar-05-06",title:"5th and 6th seminar",description:"200IQ encryption.\n"},sidebar:"autogeneratedBar",previous:{title:"4th seminar",permalink:"/c/bonuses/seminar-04"},next:{title:"8th seminar",permalink:"/c/bonuses/seminar-08"}},d={},l=[{value:"Introduction",id:"introduction",level:2},{value:"Task no. 1: Reverse (0.5 K\u20a1)",id:"task-no-1-reverse-05-k",level:3},{value:"Task no. 2: Vigen\xe8re (0.5 K\u20a1)",id:"task-no-2-vigen\xe8re-05-k",level:3},{value:"Bonus part (0.5 K\u20a1)",id:"bonus-part-05-k",level:4},{value:"Task no. 3: Bit madness (0.5 K\u20a1)",id:"task-no-3-bit-madness-05-k",level:3},{value:"Task no. 4: All combined to BMP (0.5 K\u20a1)",id:"task-no-4-all-combined-to-bmp-05-k",level:3},{value:"Submitting",id:"submitting",level:2}];function h(e){const n={a:"a",code:"code",h2:"h2",h3:"h3",h4:"h4",hr:"hr",li:"li",ol:"ol",p:"p",pre:"pre",ul:"ul",...(0,t.a)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.p,{children:"For this bonus you can get at maximum 2.5 K\u20a1."}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"pathname:///files/c/bonuses/05-06.tar.gz",children:"Source"})}),"\n",(0,s.jsx)(n.h2,{id:"introduction",children:"Introduction"}),"\n",(0,s.jsx)(n.p,{children:"In this bonus you will implement few functions that will be used together for\nimplementing a very special cipher."}),"\n",(0,s.jsx)(n.h3,{id:"task-no-1-reverse-05-k",children:"Task no. 1: Reverse (0.5 K\u20a1)"}),"\n",(0,s.jsxs)(n.p,{children:["Write a function ",(0,s.jsx)(n.code,{children:"char* reverse(const char* text)"})," that returns copy of the input\nstring in reversed order (also uppercase)."]}),"\n",(0,s.jsxs)(n.p,{children:["In case you are given ",(0,s.jsx)(n.code,{children:"NULL"}),", return ",(0,s.jsx)(n.code,{children:"NULL"}),"."]}),"\n",(0,s.jsx)(n.p,{children:"Example (more in tests):"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-c",children:'char* reversed = reverse("Hello world!");\n\nprintf("%s\\n", reversed);\n// "!DLROW OLLEH"\n\nif (reversed != NULL) {\n free(reversed);\n}\n'})}),"\n",(0,s.jsx)(n.h3,{id:"task-no-2-vigen\xe8re-05-k",children:"Task no. 2: Vigen\xe8re (0.5 K\u20a1)"}),"\n",(0,s.jsx)(n.p,{children:"Vigen\xe8re cipher is similar to the Caesar cipher, but you also have a key that is\nused for encrypting (or decrypting)."}),"\n",(0,s.jsx)(n.p,{children:"Your task is to write two functions:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"char* vigenere_encrypt(const char* key, const char* text)"})," for encrypting"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"char* vigenere_decrypt(const char* key, const char* text)"})," for decrypting"]}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"In both of those you should return uppercase characters."}),"\n",(0,s.jsx)(n.p,{children:"Meaning of the parameters you are given:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"key"})," - String that represents key that is used for *crypting. It consists of\none word and can have only characters of the alphabet. Does not matter if they\nare uppercase or lowercase."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"text"})," - String that is to be *crypted."]}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:["Function returns address of the encrypted (or decrypted) string. Or ",(0,s.jsx)(n.code,{children:"NULL"})," in case\nerror occurs."]}),"\n",(0,s.jsx)(n.p,{children:"Example:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-c",children:'char *encrypted = vigenere_encrypt("CoMPuTeR", "Hello world!");\n\nprintf("%s\\n", encrypted);\n// "JSXAI PSINR!"\n\nif (encrypted != NULL) {\n free(encrypted)\n}\n'})}),"\n",(0,s.jsx)(n.h4,{id:"bonus-part-05-k",children:"Bonus part (0.5 K\u20a1)"}),"\n",(0,s.jsx)(n.p,{children:"If you can utilize helper function that would do both encrypting and decrypting,\nyou can gain 0.5 K\u20a1."}),"\n",(0,s.jsxs)(n.p,{children:["Usage of ",(0,s.jsx)(n.code,{children:"true"}),"/",(0,s.jsx)(n.code,{children:"false"})," to decide path in code is prohibited. It leads to merging\nof both functions into one. Point of this part is to discover a way to do this\ngenerically in such way that there are no separate paths for one or the other. One\nfunction with no branching for both of them, parametrization is your friend :)"]}),"\n",(0,s.jsx)(n.h3,{id:"task-no-3-bit-madness-05-k",children:"Task no. 3: Bit madness (0.5 K\u20a1)"}),"\n",(0,s.jsx)(n.p,{children:"This is a state of the art crypto. Please do not share :)"}),"\n",(0,s.jsx)(n.p,{children:"For encrypting:"}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsx)(n.li,{children:"Split the character that is to be encrypted in halves (4 and 4 bits each)."}),"\n",(0,s.jsx)(n.li,{children:"Bits in 1st half are to be split into pairs. Swap bits in those pairs."}),"\n",(0,s.jsxs)(n.li,{children:["Then use the 4 bits that you created in the 2nd step for ",(0,s.jsx)(n.code,{children:"XOR"})," with the other\n4 bits."]}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:["This simple and ingenious principle will be illustrated on the following example.\nString we want to encrypt is ",(0,s.jsx)(n.code,{children:"Hello world!"}),". We need to encrypt each letter separately,\nso we will demonstrate on letter ",(0,s.jsx)(n.code,{children:"H"}),":"]}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["Letter ",(0,s.jsx)(n.code,{children:"H"})," is represented in ASCII as ",(0,s.jsx)(n.code,{children:"72"}),"."]}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"72"})," represented in binary is: ",(0,s.jsx)(n.code,{children:"01001000"}),". So first 4 bits are: ",(0,s.jsx)(n.code,{children:"0100"})," and last\n4 bits are ",(0,s.jsx)(n.code,{children:"1000"}),"."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["First half of bits (",(0,s.jsx)(n.code,{children:"0100"}),") consists of 2 pairs (",(0,s.jsx)(n.code,{children:"01"})," and ",(0,s.jsx)(n.code,{children:"00"}),") which we swap\n(",(0,s.jsx)(n.code,{children:"01 ~> 10"})," and ",(0,s.jsx)(n.code,{children:"00 ~> 00"}),"). That way we get ",(0,s.jsx)(n.code,{children:"1000"}),"."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"That half is used for xor with the other 4 bits:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:" 1000 // second half\nXOR 1000 // first half after 2nd step\n--------\n 0000\n"})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["Now we combine both halves (first one is ",(0,s.jsx)(n.code,{children:"1000"}),", which we got from the 2nd step\nand second one is ",(0,s.jsx)(n.code,{children:"0000"}),", which we got from the 3rd step) and get ",(0,s.jsx)(n.code,{children:"10000000"}),",\nwhich is encrypted character ",(0,s.jsx)(n.code,{children:"H"})," using this method."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"In case of decryption, reverse those steps."}),"\n",(0,s.jsx)(n.p,{children:"Your task is to implement functions:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.code,{children:"unsigned char* bit_encrypt(const char* text)"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.code,{children:"char* bit_decrypt(const unsigned char* text)"})}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"Example:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-c",children:'unsigned char* encrypted = bit_encrypt("Hello world!");\n\nfor (int i = 0; i < 12;i++) {\n printf("%x ", encrypted[i]);\n //80 9c 95 95 96 11 bc 96 b9 95 9d 10\n}\n\nif (encrypted != NULL) {\n free(encrypted);\n}\n'})}),"\n",(0,s.jsx)(n.h3,{id:"task-no-4-all-combined-to-bmp-05-k",children:"Task no. 4: All combined to BMP (0.5 K\u20a1)"}),"\n",(0,s.jsx)(n.p,{children:"Authors of the BMP cipher are non-disclosed :)"}),"\n",(0,s.jsx)(n.p,{children:"Create pair of functions:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.code,{children:"unsigned char* bmp_encrypt(const char* key, const char* text)"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.code,{children:"char* bmp_decrypt(const char* key, const unsigned char* text)"})}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"BMP cipher consists of following steps for encrypting:"}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsx)(n.li,{children:"Reverse the input string"}),"\n",(0,s.jsx)(n.li,{children:"Use Vigenere on the string you got from step #1"}),"\n",(0,s.jsx)(n.li,{children:"Use bit madness on the string you got from step #2"}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"For decrypting, reverse the steps."}),"\n",(0,s.jsx)(n.h2,{id:"submitting",children:"Submitting"}),"\n",(0,s.jsx)(n.p,{children:"In case you have any questions, feel free to reach out to me."}),"\n",(0,s.jsx)(n.hr,{})]})}function a(e={}){const{wrapper:n}={...(0,t.a)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(h,{...e})}):h(e)}},11151:(e,n,r)=>{r.d(n,{Z:()=>o,a:()=>c});var s=r(67294);const t={},i=s.createContext(t);function c(e){const n=s.useContext(i);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function o(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:c(e.components),s.createElement(i.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/main.4fda3a57.js b/assets/js/main.b2fc7d7d.js similarity index 99% rename from assets/js/main.4fda3a57.js rename to assets/js/main.b2fc7d7d.js index 5f60b52..8dcfff5 100644 --- a/assets/js/main.4fda3a57.js +++ b/assets/js/main.b2fc7d7d.js @@ -1,2 +1,2 @@ -/*! For license information please see main.4fda3a57.js.LICENSE.txt */ -(self.webpackChunkfi=self.webpackChunkfi||[]).push([[179],{20830:(e,t,n)=>{"use strict";n.d(t,{W:()=>a});var r=n(67294);function a(){return r.createElement("svg",{width:"20",height:"20",className:"DocSearch-Search-Icon",viewBox:"0 0 20 20"},r.createElement("path",{d:"M14.386 14.386l4.0877 4.0877-4.0877-4.0877c-2.9418 2.9419-7.7115 2.9419-10.6533 0-2.9419-2.9418-2.9419-7.7115 0-10.6533 2.9418-2.9419 7.7115-2.9419 10.6533 0 2.9419 2.9418 2.9419 7.7115 0 10.6533z",stroke:"currentColor",fill:"none",fillRule:"evenodd",strokeLinecap:"round",strokeLinejoin:"round"}))}},723:(e,t,n)=>{"use strict";n.d(t,{Z:()=>p});n(67294);var r=n(68356),a=n.n(r),o=n(16887);const i={"0123bc76":[()=>n.e(3734).then(n.t.bind(n,76554,19)),"~docs/algorithms/tag-algorithms-tags-c-e22.json",76554],"0178f9ad":[()=>n.e(9898).then(n.bind(n,35610)),"@site/algorithms/08-rb-trees/2022-04-05-applications.md",35610],"01a85c17":[()=>Promise.all([n.e(532),n.e(4013)]).then(n.bind(n,24524)),"@theme/BlogTagsListPage",24524],"0220f5fc":[()=>n.e(1378).then(n.t.bind(n,85804,19)),"/home/runner/work/blog/blog/.docusaurus/docusaurus-plugin-content-blog/blog/plugin-route-context-module-100.json",85804],"0608d96f":[()=>n.e(7568).then(n.t.bind(n,77158,19)),"~blog/blog/blog-tags-vps-843-list.json",77158],"06c4a8fc":[()=>n.e(2125).then(n.t.bind(n,4697,19)),"~docs/algorithms/tag-algorithms-tags-testing-0c4.json",4697],"0816068a":[()=>n.e(2948).then(n.t.bind(n,17702,19)),"~blog/blog/blog-tags-hype-1ee.json",17702],"087808f1":[()=>n.e(3731).then(n.bind(n,48157)),"@site/algorithms/12-hash-tables/2023-11-28-breaking/index.md",48157],"08dfa3a2":[()=>n.e(2606).then(n.t.bind(n,32412,19)),"~docs/algorithms/tag-algorithms-tags-astar-f6e.json",32412],"0bfe45d5":[()=>n.e(4269).then(n.t.bind(n,13847,19)),"~blog/blog/blog-tags-rust-0c9-list.json",13847],"0c53a0a5":[()=>n.e(9642).then(n.t.bind(n,74073,19)),"~blog/blog/blog-tags-opensuse-436-list.json",74073],"0d8122e4":[()=>n.e(3917).then(n.t.bind(n,92713,19)),"~blog/blog/blog-tags-ansible-2bb.json",92713],"0fcbc6ca":[()=>Promise.all([n.e(532),n.e(1851)]).then(n.bind(n,39900)),"@site/src/pages/talks.tsx",39900],"146d9b84":[()=>n.e(9300).then(n.t.bind(n,96671,19)),"~blog/blog/blog-tags-admin-b05-list.json",96671],"14eb3368":[()=>Promise.all([n.e(532),n.e(9817)]).then(n.bind(n,34228)),"@theme/DocCategoryGeneratedIndexPage",34228],"1535ede8":[()=>n.e(5376).then(n.bind(n,44969)),"@site/c/bonuses/10.md",44969],15966941:[()=>n.e(8326).then(n.bind(n,16721)),"@site/algorithms/12-hash-tables/2023-11-28-breaking/02-mitigations.md",16721],"16cbc838":[()=>n.e(1494).then(n.t.bind(n,98252,19)),"~docs/algorithms/tag-algorithms-tags-iterative-d5b.json",98252],"171c9bb5":[()=>n.e(5329).then(n.t.bind(n,27615,19)),"~blog/blog/blog-tags-devconf-979.json",27615],17896441:[()=>Promise.all([n.e(532),n.e(1325),n.e(7918)]).then(n.bind(n,15154)),"@theme/DocItem",15154],"182b5a8d":[()=>n.e(6048).then(n.bind(n,32582)),"@site/blog/2024-01-28-rust-opinion.md?truncated=true",32582],"19d7c045":[()=>n.e(4637).then(n.t.bind(n,67772,19)),"~blog/blog/blog-tags-advent-of-code-49f.json",67772],"1a2684fd":[()=>n.e(5688).then(n.t.bind(n,99303,19)),"~blog/blog/blog-tags-fedora-bd8.json",99303],"1a4e3797":[()=>Promise.all([n.e(532),n.e(7920)]).then(n.bind(n,39172)),"@theme/SearchPage",39172],"1a606400":[()=>n.e(494).then(n.t.bind(n,82400,19)),"/home/runner/work/blog/blog/.docusaurus/docusaurus-plugin-content-docs/algorithms/plugin-route-context-module-100.json",82400],"1acf65cc":[()=>n.e(8529).then(n.bind(n,34568)),"@site/c/pexam/b-garbage_collect.md",34568],"1cd58e77":[()=>n.e(1547).then(n.bind(n,32090)),"@site/algorithms/04-recursion/2023-08-17-pyramid-slide-down/04-bottom-up-dp.md",32090],"22a175ec":[()=>Promise.all([n.e(532),n.e(6890)]).then(n.bind(n,40707)),"@site/src/pages/contributions.tsx",40707],"24fecc0a":[()=>n.e(3707).then(n.bind(n,69383)),"@site/algorithms/03-time-complexity/2021-03-31-extend.md",69383],"257fa000":[()=>n.e(9595).then(n.t.bind(n,35455,19)),"~blog/blog/blog-tags-cult-e97-list.json",35455],"28d80ff8":[()=>n.e(6435).then(n.t.bind(n,7465,19)),"~docs/algorithms/tag-algorithms-tags-sorting-d73.json",7465],29694455:[()=>n.e(3388).then(n.t.bind(n,39828,19)),"~blog/blog/blog-tags-iterators-977-list.json",39828],"2af5d0a7":[()=>n.e(3979).then(n.t.bind(n,53703,19)),"~docs/algorithms/tag-algorithms-tags-a-star-775.json",53703],"2b89902a":[()=>n.e(6342).then(n.t.bind(n,45443,19)),"~docs/algorithms/tag-algorithms-tags-recursion-1bd.json",45443],"2ca64e35":[()=>n.e(281).then(n.bind(n,99544)),"@site/algorithms/04-recursion/2022-11-29-karel/index.md",99544],"2d2e3e59":[()=>n.e(6689).then(n.bind(n,55268)),"@site/blog/2024-06-19-devconf-2024.md",55268],"2f0fcd8b":[()=>n.e(4695).then(n.t.bind(n,25870,19)),"~blog/blog/blog-tags-raspberry-pi-394.json",25870],"2fcf0558":[()=>n.e(4638).then(n.t.bind(n,69470,19)),"~docs/algorithms/category-algorithms-autogeneratedbar-category-hash-tables-062.json",69470],"3011a4c0":[()=>n.e(7926).then(n.t.bind(n,31670,19)),"~blog/blog/blog-tags-copr-70b-list.json",31670],30814625:[()=>n.e(115).then(n.bind(n,78416)),"@site/algorithms/04-recursion/2022-11-29-karel/2023-12-24-solution.md",78416],"3183a14f":[()=>n.e(8158).then(n.t.bind(n,75865,19)),"~blog/blog/blog-tags-ansible-2bb-list.json",75865],"3238adfd":[()=>n.e(7285).then(n.t.bind(n,16107,19)),"~blog/blog/blog-tags-lts-b6c.json",16107],"33e3c739":[()=>n.e(2389).then(n.t.bind(n,73435,19)),"~blog/blog/blog-tags-opensuse-436.json",73435],"34ab65f4":[()=>n.e(3220).then(n.t.bind(n,28865,19)),"~docs/algorithms/tag-algorithms-tags-postconditions-1f3.json",28865],"34df9f28":[()=>n.e(9977).then(n.t.bind(n,59267,19)),"~blog/blog/blog-tags-paywall-11b.json",59267],"354a7b72":[()=>n.e(9414).then(n.bind(n,46617)),"@site/algorithms/10-graphs/2022-04-30-bfs-tree.md",46617],"3716fece":[()=>n.e(1511).then(n.bind(n,76225)),"@site/blog/2024-06-19-devconf-2024.md?truncated=true",76225],"3720c009":[()=>Promise.all([n.e(532),n.e(3751)]).then(n.bind(n,10727)),"@theme/DocTagsListPage",10727],"377f3aa1":[()=>n.e(1011).then(n.bind(n,7582)),"@site/blog/aoc-2022/02-week-2.md",7582],"3a0bc46c":[()=>n.e(7524).then(n.t.bind(n,80975,19)),"~blog/blog/blog-tags-fedora-bd8-list.json",80975],"3adcbc3a":[()=>n.e(5701).then(n.bind(n,62535)),"@site/algorithms/11-paths/2024-01-01-bf-to-astar/01-bf.md",62535],"3d92ba6e":[()=>n.e(8236).then(n.t.bind(n,77778,19)),"~docs/algorithms/tag-algorithms-tags-dijkstra-48e.json",77778],"3da4b779":[()=>n.e(2177).then(n.bind(n,28737)),"@site/blog/aoc-2022/04-week-4.md",28737],"4200b1a9":[()=>n.e(866).then(n.t.bind(n,24612,19)),"~blog/blog/blog-archive-80c.json",24612],"45c9e308":[()=>n.e(7084).then(n.bind(n,53181)),"@site/cpp/07-exceptions-and-raii/2023-11-24-placeholders.md",53181],"4621632b":[()=>n.e(3519).then(n.t.bind(n,29760,19)),"~blog/blog/blog-tags-cpp-7c7-list.json",29760],"48b268a6":[()=>n.e(1648).then(n.t.bind(n,35067,19)),"~docs/c/category-c-autogeneratedbar-category-bonuses-216.json",35067],"493c0536":[()=>n.e(7292).then(n.bind(n,45594)),"@site/algorithms/11-paths/2024-01-01-bf-to-astar/03-astar.md",45594],"4e546705":[()=>n.e(4327).then(n.t.bind(n,61795,19)),"~docs/c/version-current-metadata-prop-751.json",61795],"4edd2021":[()=>n.e(5975).then(n.t.bind(n,21705,19)),"~blog/blog/blog-tags-cpp-7c7.json",21705],"4f96b16e":[()=>n.e(6306).then(n.bind(n,24693)),"@site/c/pexam/c-cams.md",24693],"4fd4011a":[()=>n.e(565).then(n.t.bind(n,43050,19)),"~blog/blog/blog-tags-lts-b6c-list.json",43050],51624505:[()=>n.e(4394).then(n.bind(n,32609)),"@site/blog/aoc-2022/00-intro.md",32609],"51efb406":[()=>n.e(4223).then(n.bind(n,66933)),"@site/blog/2024-07-20-raspberry-alma.md?truncated=true",66933],"520f8175":[()=>n.e(8058).then(n.t.bind(n,24353,19)),"~docs/algorithms/tag-algorithms-tags-cpp-0d2.json",24353],"52f2a5bf":[()=>n.e(5430).then(n.t.bind(n,61387,19)),"~blog/blog/blog-tags-red-hat-df4.json",61387],"534d4833":[()=>n.e(9771).then(n.bind(n,93019)),"@site/algorithms/02-algorithms-correctness/2021-03-18-postcondition-ambiguity.md",93019],"57ac6224":[()=>n.e(2698).then(n.t.bind(n,35340,19)),"~blog/blog/blog-tags-linux-distributions-991-list.json",35340],"595c7293":[()=>n.e(5634).then(n.bind(n,58396)),"@site/c/bonuses/08.md",58396],"5c15401e":[()=>n.e(9579).then(n.t.bind(n,43761,19)),"~docs/algorithms/tag-algorithms-tags-bellman-ford-731.json",43761],"5ca803d2":[()=>n.e(9173).then(n.t.bind(n,24890,19)),"/home/runner/work/blog/blog/.docusaurus/docusaurus-plugin-content-docs/c/plugin-route-context-module-100.json",24890],"5e91a78c":[()=>n.e(1033).then(n.t.bind(n,82547,19)),"~blog/blog/blog-tags-linux-distributions-991.json",82547],"5e95c892":[()=>n.e(9661).then(n.bind(n,41892)),"@theme/DocsRoot",41892],"5e9f5e1a":[()=>Promise.resolve().then(n.bind(n,36809)),"@generated/docusaurus.config",36809],"62d847b3":[()=>n.e(8520).then(n.t.bind(n,91901,19)),"~blog/blog/blog-tags-advent-of-code-2022-3db-list.json",91901],"66d5ef6c":[()=>n.e(9228).then(n.t.bind(n,4087,19)),"~blog/blog/blog-tags-tags-4c2.json",4087],"686a7a89":[()=>n.e(728).then(n.t.bind(n,77507,19)),"~docs/algorithms/tag-algorithms-tags-graphs-31d.json",77507],"6875c492":[()=>Promise.all([n.e(532),n.e(1325),n.e(130),n.e(8610)]).then(n.bind(n,41714)),"@theme/BlogTagsPostsPage",41714],"698e2076":[()=>n.e(3713).then(n.bind(n,38961)),"@site/algorithms/11-paths/2024-01-01-bf-to-astar/02-dijkstra.md",38961],"6bc697d0":[()=>n.e(5287).then(n.t.bind(n,68529,19)),"/home/runner/work/blog/blog/.docusaurus/docusaurus-plugin-content-docs/cpp/plugin-route-context-module-100.json",68529],"6e3cbca1":[()=>n.e(3276).then(n.t.bind(n,29538,19)),"~docs/algorithms/version-current-metadata-prop-751.json",29538],"7052c0bc":[()=>n.e(9731).then(n.bind(n,42286)),"@site/cpp/00-intro.md",42286],"70a4540f":[()=>n.e(9249).then(n.bind(n,44493)),"@site/algorithms/04-recursion/2023-08-17-pyramid-slide-down/01-naive.md",44493],"75cccf44":[()=>n.e(4256).then(n.bind(n,98215)),"@site/blog/leetcode/sort-matrix-diagonally.md?truncated=true",98215],"765ea78b":[()=>n.e(3039).then(n.t.bind(n,83010,19)),"~blog/blog/blog-tags-\ud83c\udfed-551.json",83010],"769debb9":[()=>n.e(9931).then(n.t.bind(n,33792,19)),"~blog/blog/blog-tags-paywall-11b-list.json",33792],"794ef108":[()=>n.e(3803).then(n.bind(n,86427)),"@site/c/00-intro.md",86427],"7a5bb070":[()=>n.e(4582).then(n.t.bind(n,64863,19)),"~blog/blog/blog-tags-memory-safety-1ae.json",64863],"7bc6fefd":[()=>n.e(8615).then(n.t.bind(n,72257,19)),"~blog/blog/blog-tags-almalinux-c6a-list.json",72257],"7ce7faac":[()=>n.e(6064).then(n.t.bind(n,12884,19)),"~docs/algorithms/tag-algorithms-tags-solution-61b.json",12884],"7e6d325b":[()=>n.e(3184).then(n.t.bind(n,26139,19)),"~docs/cpp/version-current-metadata-prop-751.json",26139],"84d1e0d8":[()=>n.e(1885).then(n.bind(n,49713)),"@site/algorithms/00-intro.md",49713],"86cd1460":[()=>n.e(1235).then(n.t.bind(n,38968,19)),"~blog/blog/blog-tags-leetcode-042.json",38968],"8891732d":[()=>n.e(3306).then(n.t.bind(n,36047,19)),"~blog/blog/blog-page-2-677.json",36047],"8a25f659":[()=>n.e(7728).then(n.bind(n,73212)),"@site/algorithms/04-recursion/2023-08-17-pyramid-slide-down/03-top-down-dp.md",73212],"8b1802c5":[()=>n.e(8480).then(n.t.bind(n,60832,19)),"~blog/blog/blog-tags-advent-of-code-49f-list.json",60832],"8c0e532b":[()=>n.e(822).then(n.t.bind(n,73968,19)),"~blog/blog/blog-tags-vps-843.json",73968],"8d31a880":[()=>n.e(9066).then(n.t.bind(n,72232,19)),"~docs/algorithms/tag-algorithms-tags-python-48f.json",72232],"8e6bb954":[()=>n.e(5775).then(n.t.bind(n,76206,19)),"~docs/algorithms/tag-algorithms-tags-exponential-60a.json",76206],"9287eafd":[()=>n.e(5521).then(n.t.bind(n,90716,19)),"~blog/blog/blog-tags-rust-0c9.json",90716],"933b95b3":[()=>n.e(3887).then(n.t.bind(n,7405,19)),"~docs/algorithms/category-algorithms-autogeneratedbar-category-recursion-257.json",7405],"947341b7":[()=>n.e(1145).then(n.t.bind(n,2897,19)),"~docs/algorithms/tag-algorithms-tags-bfs-69f.json",2897],"95b96bb9":[()=>n.e(3561).then(n.t.bind(n,24577,19)),"~blog/blog/blog-post-list-prop-blog.json",24577],"95f41f0b":[()=>n.e(9385).then(n.bind(n,93195)),"@site/blog/aoc-2022/01-week-1.md?truncated=true",93195],"962da50c":[()=>n.e(2264).then(n.t.bind(n,9705,19)),"~docs/c/category-c-autogeneratedbar-category-practice-exams-e97.json",9705],"976c4f3b":[()=>n.e(4562).then(n.t.bind(n,69019,19)),"~docs/algorithms/tag-algorithms-tags-java-6c3.json",69019],"97a42631":[()=>n.e(1464).then(n.t.bind(n,77343,19)),"~docs/algorithms/tags-list-current-prop-15a.json",77343],"9a3dc578":[()=>n.e(655).then(n.t.bind(n,9916,19)),"~docs/algorithms/tag-algorithms-tags-dynamic-array-5d3.json",9916],"9ad42b04":[()=>n.e(8041).then(n.t.bind(n,41271,19)),"~blog/blog/blog-tags-devconf-979-list.json",41271],"9b91a88c":[()=>n.e(2545).then(n.bind(n,19466)),"@site/algorithms/04-recursion/2023-08-17-pyramid-slide-down/index.md",19466],"9deee4a0":[()=>n.e(1164).then(n.t.bind(n,99947,19)),"~blog/blog/blog-tags-self-hosting-911.json",99947],"9df0e937":[()=>n.e(2210).then(n.t.bind(n,55256,19)),"~docs/algorithms/category-algorithms-autogeneratedbar-category-graphs-2e2.json",55256],"9e4087bc":[()=>n.e(3608).then(n.bind(n,63169)),"@theme/BlogArchivePage",63169],a082abd3:[()=>n.e(8786).then(n.t.bind(n,73276,19)),"~blog/blog/blog-tags-admin-b05.json",73276],a2ba8888:[()=>n.e(8289).then(n.t.bind(n,55941,19)),"~docs/algorithms/tag-algorithms-tags-brute-force-3cb.json",55941],a4c10cf4:[()=>n.e(4382).then(n.t.bind(n,30685,19)),"~docs/algorithms/tag-algorithms-tags-time-complexity-c50.json",30685],a6a48ea2:[()=>n.e(3618).then(n.bind(n,1176)),"@site/blog/aoc-2022/02-week-2.md?truncated=true",1176],a6aa9e1f:[()=>Promise.all([n.e(532),n.e(1325),n.e(130),n.e(3089)]).then(n.bind(n,80046)),"@theme/BlogListPage",80046],a7098721:[()=>n.e(1050).then(n.t.bind(n,26615,19)),"~blog/blog/blog-c06.json",26615],a7bd4aaa:[()=>n.e(8518).then(n.bind(n,8564)),"@theme/DocVersionRoot",8564],a80747a0:[()=>n.e(5824).then(n.t.bind(n,4464,19)),"~blog/blog/blog-tags-advent-of-code-2022-3db.json",4464],a9167e8d:[()=>n.e(6074).then(n.bind(n,53742)),"@site/blog/2024-07-20-raspberry-alma.md",53742],a94703ab:[()=>Promise.all([n.e(532),n.e(4368)]).then(n.bind(n,12674)),"@theme/DocRoot",12674],aa24fd5d:[()=>n.e(7257).then(n.bind(n,90251)),"@site/algorithms/12-hash-tables/2023-11-28-breaking/01-python.md",90251],aa635a28:[()=>n.e(2321).then(n.bind(n,72820)),"@site/blog/2024-02-07-lts-distros.md?truncated=true",72820],ab2721d4:[()=>n.e(7755).then(n.bind(n,53037)),"@site/blog/aoc-2022/04-week-4.md?truncated=true",53037],af8b72a7:[()=>n.e(5658).then(n.bind(n,10507)),"@site/blog/2023-08-02-copr.md?truncated=true",10507],b0291f37:[()=>n.e(6097).then(n.t.bind(n,7085,19)),"/home/runner/work/blog/blog/.docusaurus/docusaurus-theme-search-algolia/default/plugin-route-context-module-100.json",7085],b1288602:[()=>n.e(59).then(n.bind(n,51456)),"@site/c/mr.md",51456],b2538217:[()=>n.e(2152).then(n.t.bind(n,67330,19)),"~blog/blog/blog-tags-almalinux-c6a.json",67330],b25fbc58:[()=>n.e(9197).then(n.t.bind(n,75617,19)),"~blog/blog/blog-tags-\ud83c\udfed-551-list.json",75617],b45dccf0:[()=>n.e(9679).then(n.t.bind(n,58296,19)),"~blog/blog/blog-tags-copr-70b.json",58296],b5a32f14:[()=>n.e(2433).then(n.bind(n,31976)),"@site/blog/2023-08-02-copr.md",31976],b8cbf382:[()=>n.e(7438).then(n.t.bind(n,74632,19)),"~docs/algorithms/tag-algorithms-tags-greedy-02f.json",74632],b9f7f5c4:[()=>n.e(9179).then(n.bind(n,76699)),"@site/cpp/environment.md",76699],bb882650:[()=>n.e(8091).then(n.bind(n,66765)),"@site/blog/aoc-2022/03-week-3.md?truncated=true",66765],bb984793:[()=>n.e(6864).then(n.t.bind(n,82505,19)),"~docs/algorithms/tag-algorithms-tags-karel-df7.json",82505],bc0c9d90:[()=>n.e(354).then(n.bind(n,50476)),"@site/c/bonuses/04.md",50476],bc2d22bc:[()=>n.e(6519).then(n.t.bind(n,70428,19)),"~docs/algorithms/tag-algorithms-tags-bottom-up-dp-4f9.json",70428],c4c4056e:[()=>n.e(635).then(n.bind(n,61381)),"@site/algorithms/11-paths/2024-01-01-bf-to-astar/index.md",61381],c4f5d8e4:[()=>Promise.all([n.e(532),n.e(4195)]).then(n.bind(n,53261)),"@site/src/pages/index.js",53261],c580b66a:[()=>n.e(6573).then(n.t.bind(n,45021,19)),"~docs/algorithms/tag-algorithms-tags-top-down-dp-c2f.json",45021],c90b7ff3:[()=>n.e(3602).then(n.t.bind(n,44960,19)),"~blog/blog/blog-tags-hype-1ee-list.json",44960],ccc49370:[()=>Promise.all([n.e(532),n.e(1325),n.e(130),n.e(6103)]).then(n.bind(n,65203)),"@theme/BlogPostPage",65203],cfa2b263:[()=>n.e(3086).then(n.bind(n,34437)),"@site/blog/leetcode/sort-matrix-diagonally.md",34437],d05e838c:[()=>n.e(6544).then(n.bind(n,63004)),"@site/c/bonuses/05-06.md",63004],d255bd7f:[()=>n.e(6292).then(n.t.bind(n,60341,19)),"~docs/algorithms/tag-algorithms-tags-red-black-trees-c61.json",60341],d309b5b1:[()=>n.e(8908).then(n.t.bind(n,26102,19)),"~docs/algorithms/category-algorithms-autogeneratedbar-category-algorithms-and-correctness-d51.json",26102],d309eaf6:[()=>n.e(6995).then(n.bind(n,54506)),"@site/blog/2024-02-07-lts-distros.md",54506],d4b1e057:[()=>n.e(1492).then(n.t.bind(n,12842,19)),"~docs/algorithms/tag-algorithms-tags-balanced-trees-b3e.json",12842],d57b4369:[()=>n.e(6179).then(n.t.bind(n,52715,19)),"~docs/algorithms/tag-algorithms-tags-csharp-d1d.json",52715],d6308c72:[()=>n.e(8806).then(n.t.bind(n,93012,19)),"~blog/blog/blog-tags-self-hosting-911-list.json",93012],d675395f:[()=>n.e(2741).then(n.t.bind(n,15745,19)),"/home/runner/work/blog/blog/.docusaurus/docusaurus-plugin-content-pages/default/plugin-route-context-module-100.json",15745],d79dd549:[()=>n.e(5169).then(n.t.bind(n,29261,19)),"~blog/blog/blog-tags-red-hat-df4-list.json",29261],d7f7fb17:[()=>n.e(1171).then(n.bind(n,3455)),"@site/blog/aoc-2022/00-intro.md?truncated=true",3455],d8f4410e:[()=>n.e(2997).then(n.t.bind(n,41941,19)),"~docs/algorithms/tag-algorithms-tags-hash-tables-b36.json",41941],dd841e73:[()=>n.e(2482).then(n.t.bind(n,40155,19)),"~docs/algorithms/tag-algorithms-tags-dynamic-programming-3e6.json",40155],ddc7679f:[()=>n.e(569).then(n.bind(n,64322)),"@site/algorithms/10-graphs/2021-05-18-iterative-and-iterators.md",64322],dead8108:[()=>n.e(8807).then(n.bind(n,21431)),"@site/c/bonuses/03.md",21431],decbf9d1:[()=>n.e(2445).then(n.t.bind(n,88876,19)),"~docs/algorithms/category-algorithms-autogeneratedbar-category-asymptotic-notation-and-time-complexity-e0d.json",88876],df078f58:[()=>n.e(7743).then(n.t.bind(n,88298,19)),"~docs/algorithms/category-algorithms-autogeneratedbar-category-paths-in-graphs-202.json",88298],df0885f0:[()=>n.e(4343).then(n.t.bind(n,34175,19)),"~docs/algorithms/tag-algorithms-tags-iterators-13a.json",34175],df203c0f:[()=>Promise.all([n.e(532),n.e(9924)]).then(n.bind(n,40491)),"@theme/DocTagDocListPage",40491],dff2ebad:[()=>n.e(146).then(n.bind(n,42492)),"@site/blog/aoc-2022/01-week-1.md",42492],e0f0fdef:[()=>n.e(8404).then(n.t.bind(n,25240,19)),"~blog/blog/blog-tags-conferences-51c.json",25240],e1717305:[()=>n.e(70).then(n.t.bind(n,96377,19)),"~blog/blog/blog-tags-support-474-list.json",96377],e1d2ae23:[()=>n.e(1475).then(n.t.bind(n,36302,19)),"~docs/algorithms/tag-algorithms-tags-applications-020.json",36302],e31003e9:[()=>n.e(1960).then(n.t.bind(n,81695,19)),"~docs/cpp/category-cpp-autogeneratedbar-category-exceptions-and-raii-6e9.json",81695],e89da83e:[()=>n.e(8757).then(n.t.bind(n,97416,19)),"~blog/blog/blog-tags-leetcode-042-list.json",97416],eba2374c:[()=>n.e(8387).then(n.t.bind(n,47662,19)),"~docs/algorithms/tag-algorithms-tags-backtracking-bb2.json",47662],f44abc07:[()=>n.e(2204).then(n.t.bind(n,39006,19)),"~blog/blog/blog-tags-cult-e97.json",39006],f48be158:[()=>n.e(4064).then(n.bind(n,12326)),"@site/blog/aoc-2022/03-week-3.md",12326],f5445d59:[()=>n.e(6571).then(n.t.bind(n,47705,19)),"~blog/blog/blog-tags-raspberry-pi-394-list.json",47705],f5d65bd1:[()=>n.e(5617).then(n.t.bind(n,66775,19)),"~blog/blog/blog-tags-support-474.json",66775],f7189688:[()=>n.e(4625).then(n.t.bind(n,9843,19)),"~blog/blog/blog-tags-conferences-51c-list.json",9843],f71d1f68:[()=>n.e(6069).then(n.bind(n,13068)),"@site/blog/2024-01-28-rust-opinion.md",13068],f75910c4:[()=>n.e(5934).then(n.bind(n,1910)),"@site/algorithms/04-recursion/2023-08-17-pyramid-slide-down/02-greedy.md",1910],f7d29e9b:[()=>n.e(7959).then(n.t.bind(n,89266,19)),"~blog/blog/blog-tags-memory-safety-1ae-list.json",89266],fb4361d3:[()=>n.e(6327).then(n.t.bind(n,9631,19)),"~docs/algorithms/category-algorithms-autogeneratedbar-category-red-black-trees-d8a.json",9631],ff472cd9:[()=>n.e(8643).then(n.t.bind(n,7122,19)),"~blog/blog/blog-tags-iterators-977.json",7122],ff82dde7:[()=>Promise.all([n.e(532),n.e(8472)]).then(n.bind(n,63935)),"@site/algorithms/08-rb-trees/2023-06-10-rules.md",63935]};var s=n(85893);function l(e){let{error:t,retry:n,pastDelay:r}=e;return t?(0,s.jsxs)("div",{style:{textAlign:"center",color:"#fff",backgroundColor:"#fa383e",borderColor:"#fa383e",borderStyle:"solid",borderRadius:"0.25rem",borderWidth:"1px",boxSizing:"border-box",display:"block",padding:"1rem",flex:"0 0 50%",marginLeft:"25%",marginRight:"25%",marginTop:"5rem",maxWidth:"50%",width:"100%"},children:[(0,s.jsx)("p",{children:String(t)}),(0,s.jsx)("div",{children:(0,s.jsx)("button",{type:"button",onClick:n,children:"Retry"})})]}):r?(0,s.jsx)("div",{style:{display:"flex",justifyContent:"center",alignItems:"center",height:"100vh"},children:(0,s.jsx)("svg",{id:"loader",style:{width:128,height:110,position:"absolute",top:"calc(100vh - 64%)"},viewBox:"0 0 45 45",xmlns:"http://www.w3.org/2000/svg",stroke:"#61dafb",children:(0,s.jsxs)("g",{fill:"none",fillRule:"evenodd",transform:"translate(1 1)",strokeWidth:"2",children:[(0,s.jsxs)("circle",{cx:"22",cy:"22",r:"6",strokeOpacity:"0",children:[(0,s.jsx)("animate",{attributeName:"r",begin:"1.5s",dur:"3s",values:"6;22",calcMode:"linear",repeatCount:"indefinite"}),(0,s.jsx)("animate",{attributeName:"stroke-opacity",begin:"1.5s",dur:"3s",values:"1;0",calcMode:"linear",repeatCount:"indefinite"}),(0,s.jsx)("animate",{attributeName:"stroke-width",begin:"1.5s",dur:"3s",values:"2;0",calcMode:"linear",repeatCount:"indefinite"})]}),(0,s.jsxs)("circle",{cx:"22",cy:"22",r:"6",strokeOpacity:"0",children:[(0,s.jsx)("animate",{attributeName:"r",begin:"3s",dur:"3s",values:"6;22",calcMode:"linear",repeatCount:"indefinite"}),(0,s.jsx)("animate",{attributeName:"stroke-opacity",begin:"3s",dur:"3s",values:"1;0",calcMode:"linear",repeatCount:"indefinite"}),(0,s.jsx)("animate",{attributeName:"stroke-width",begin:"3s",dur:"3s",values:"2;0",calcMode:"linear",repeatCount:"indefinite"})]}),(0,s.jsx)("circle",{cx:"22",cy:"22",r:"8",children:(0,s.jsx)("animate",{attributeName:"r",begin:"0s",dur:"1.5s",values:"6;1;2;3;4;5;6",calcMode:"linear",repeatCount:"indefinite"})})]})})}):null}var c=n(99670),u=n(30226);function d(e,t){if("*"===e)return a()({loading:l,loader:()=>n.e(1772).then(n.bind(n,51772)),modules:["@theme/NotFound"],webpack:()=>[51772],render(e,t){const n=e.default;return(0,s.jsx)(u.z,{value:{plugin:{name:"native",id:"default"}},children:(0,s.jsx)(n,{...t})})}});const r=o[`${e}-${t}`],d={},p=[],f=[],g=(0,c.Z)(r);return Object.entries(g).forEach((e=>{let[t,n]=e;const r=i[n];r&&(d[t]=r[0],p.push(r[1]),f.push(r[2]))})),a().Map({loading:l,loader:d,modules:p,webpack:()=>f,render(t,n){const a=JSON.parse(JSON.stringify(r));Object.entries(t).forEach((t=>{let[n,r]=t;const o=r.default;if(!o)throw new Error(`The page component at ${e} doesn't have a default export. This makes it impossible to render anything. Consider default-exporting a React component.`);"object"!=typeof o&&"function"!=typeof o||Object.keys(r).filter((e=>"default"!==e)).forEach((e=>{o[e]=r[e]}));let i=a;const s=n.split(".");s.slice(0,-1).forEach((e=>{i=i[e]})),i[s[s.length-1]]=o}));const o=a.__comp;delete a.__comp;const i=a.__context;return delete a.__context,(0,s.jsx)(u.z,{value:i,children:(0,s.jsx)(o,{...a,...n})})}})}const p=[{path:"/blog/",component:d("/blog/","27f"),exact:!0},{path:"/blog/2023/08/02/copr/",component:d("/blog/2023/08/02/copr/","69d"),exact:!0},{path:"/blog/2024/01/28/rust-opinion/",component:d("/blog/2024/01/28/rust-opinion/","98d"),exact:!0},{path:"/blog/2024/02/07/lts-distros/",component:d("/blog/2024/02/07/lts-distros/","7f0"),exact:!0},{path:"/blog/2024/06/19/devconf-2024/",component:d("/blog/2024/06/19/devconf-2024/","427"),exact:!0},{path:"/blog/2024/07/20/raspberry-alma/",component:d("/blog/2024/07/20/raspberry-alma/","1c0"),exact:!0},{path:"/blog/aoc-2022/1st-week/",component:d("/blog/aoc-2022/1st-week/","df4"),exact:!0},{path:"/blog/aoc-2022/2nd-week/",component:d("/blog/aoc-2022/2nd-week/","783"),exact:!0},{path:"/blog/aoc-2022/3rd-week/",component:d("/blog/aoc-2022/3rd-week/","7c5"),exact:!0},{path:"/blog/aoc-2022/4th-week/",component:d("/blog/aoc-2022/4th-week/","1ac"),exact:!0},{path:"/blog/aoc-2022/intro/",component:d("/blog/aoc-2022/intro/","ada"),exact:!0},{path:"/blog/archive/",component:d("/blog/archive/","22d"),exact:!0},{path:"/blog/leetcode/sort-diagonally/",component:d("/blog/leetcode/sort-diagonally/","d97"),exact:!0},{path:"/blog/page/2/",component:d("/blog/page/2/","a1d"),exact:!0},{path:"/blog/tags/",component:d("/blog/tags/","f23"),exact:!0},{path:"/blog/tags/\ud83c\udfed/",component:d("/blog/tags/\ud83c\udfed/","381"),exact:!0},{path:"/blog/tags/admin/",component:d("/blog/tags/admin/","d3a"),exact:!0},{path:"/blog/tags/advent-of-code-2022/",component:d("/blog/tags/advent-of-code-2022/","7bd"),exact:!0},{path:"/blog/tags/advent-of-code/",component:d("/blog/tags/advent-of-code/","313"),exact:!0},{path:"/blog/tags/almalinux/",component:d("/blog/tags/almalinux/","ee1"),exact:!0},{path:"/blog/tags/ansible/",component:d("/blog/tags/ansible/","294"),exact:!0},{path:"/blog/tags/conferences/",component:d("/blog/tags/conferences/","77a"),exact:!0},{path:"/blog/tags/copr/",component:d("/blog/tags/copr/","959"),exact:!0},{path:"/blog/tags/cpp/",component:d("/blog/tags/cpp/","770"),exact:!0},{path:"/blog/tags/cult/",component:d("/blog/tags/cult/","73d"),exact:!0},{path:"/blog/tags/devconf/",component:d("/blog/tags/devconf/","602"),exact:!0},{path:"/blog/tags/fedora/",component:d("/blog/tags/fedora/","c8d"),exact:!0},{path:"/blog/tags/hype/",component:d("/blog/tags/hype/","d35"),exact:!0},{path:"/blog/tags/iterators/",component:d("/blog/tags/iterators/","2eb"),exact:!0},{path:"/blog/tags/leetcode/",component:d("/blog/tags/leetcode/","e31"),exact:!0},{path:"/blog/tags/linux-distributions/",component:d("/blog/tags/linux-distributions/","2be"),exact:!0},{path:"/blog/tags/lts/",component:d("/blog/tags/lts/","fa3"),exact:!0},{path:"/blog/tags/memory-safety/",component:d("/blog/tags/memory-safety/","d15"),exact:!0},{path:"/blog/tags/opensuse/",component:d("/blog/tags/opensuse/","0cf"),exact:!0},{path:"/blog/tags/paywall/",component:d("/blog/tags/paywall/","9e7"),exact:!0},{path:"/blog/tags/raspberry-pi/",component:d("/blog/tags/raspberry-pi/","e6a"),exact:!0},{path:"/blog/tags/red-hat/",component:d("/blog/tags/red-hat/","9b4"),exact:!0},{path:"/blog/tags/rust/",component:d("/blog/tags/rust/","bfd"),exact:!0},{path:"/blog/tags/self-hosting/",component:d("/blog/tags/self-hosting/","7ff"),exact:!0},{path:"/blog/tags/support/",component:d("/blog/tags/support/","5f8"),exact:!0},{path:"/blog/tags/vps/",component:d("/blog/tags/vps/","1b8"),exact:!0},{path:"/contributions/",component:d("/contributions/","541"),exact:!0},{path:"/search/",component:d("/search/","c7b"),exact:!0},{path:"/talks/",component:d("/talks/","819"),exact:!0},{path:"/algorithms/",component:d("/algorithms/","c61"),routes:[{path:"/algorithms/",component:d("/algorithms/","b39"),routes:[{path:"/algorithms/tags/",component:d("/algorithms/tags/","bb8"),exact:!0},{path:"/algorithms/tags/a-star/",component:d("/algorithms/tags/a-star/","83e"),exact:!0},{path:"/algorithms/tags/applications/",component:d("/algorithms/tags/applications/","b32"),exact:!0},{path:"/algorithms/tags/astar/",component:d("/algorithms/tags/astar/","08b"),exact:!0},{path:"/algorithms/tags/backtracking/",component:d("/algorithms/tags/backtracking/","e2d"),exact:!0},{path:"/algorithms/tags/balanced-trees/",component:d("/algorithms/tags/balanced-trees/","591"),exact:!0},{path:"/algorithms/tags/bellman-ford/",component:d("/algorithms/tags/bellman-ford/","2bc"),exact:!0},{path:"/algorithms/tags/bfs/",component:d("/algorithms/tags/bfs/","334"),exact:!0},{path:"/algorithms/tags/bottom-up-dp/",component:d("/algorithms/tags/bottom-up-dp/","9e5"),exact:!0},{path:"/algorithms/tags/brute-force/",component:d("/algorithms/tags/brute-force/","99b"),exact:!0},{path:"/algorithms/tags/c/",component:d("/algorithms/tags/c/","cc5"),exact:!0},{path:"/algorithms/tags/cpp/",component:d("/algorithms/tags/cpp/","f5b"),exact:!0},{path:"/algorithms/tags/csharp/",component:d("/algorithms/tags/csharp/","7a9"),exact:!0},{path:"/algorithms/tags/dijkstra/",component:d("/algorithms/tags/dijkstra/","aa8"),exact:!0},{path:"/algorithms/tags/dynamic-array/",component:d("/algorithms/tags/dynamic-array/","00e"),exact:!0},{path:"/algorithms/tags/dynamic-programming/",component:d("/algorithms/tags/dynamic-programming/","f82"),exact:!0},{path:"/algorithms/tags/exponential/",component:d("/algorithms/tags/exponential/","a74"),exact:!0},{path:"/algorithms/tags/graphs/",component:d("/algorithms/tags/graphs/","d5b"),exact:!0},{path:"/algorithms/tags/greedy/",component:d("/algorithms/tags/greedy/","079"),exact:!0},{path:"/algorithms/tags/hash-tables/",component:d("/algorithms/tags/hash-tables/","ae4"),exact:!0},{path:"/algorithms/tags/iterative/",component:d("/algorithms/tags/iterative/","783"),exact:!0},{path:"/algorithms/tags/iterators/",component:d("/algorithms/tags/iterators/","1bc"),exact:!0},{path:"/algorithms/tags/java/",component:d("/algorithms/tags/java/","2b4"),exact:!0},{path:"/algorithms/tags/karel/",component:d("/algorithms/tags/karel/","79f"),exact:!0},{path:"/algorithms/tags/postconditions/",component:d("/algorithms/tags/postconditions/","a27"),exact:!0},{path:"/algorithms/tags/python/",component:d("/algorithms/tags/python/","eb2"),exact:!0},{path:"/algorithms/tags/recursion/",component:d("/algorithms/tags/recursion/","2b0"),exact:!0},{path:"/algorithms/tags/red-black-trees/",component:d("/algorithms/tags/red-black-trees/","9ca"),exact:!0},{path:"/algorithms/tags/solution/",component:d("/algorithms/tags/solution/","fa0"),exact:!0},{path:"/algorithms/tags/sorting/",component:d("/algorithms/tags/sorting/","7ca"),exact:!0},{path:"/algorithms/tags/testing/",component:d("/algorithms/tags/testing/","2af"),exact:!0},{path:"/algorithms/tags/time-complexity/",component:d("/algorithms/tags/time-complexity/","2d3"),exact:!0},{path:"/algorithms/tags/top-down-dp/",component:d("/algorithms/tags/top-down-dp/","779"),exact:!0},{path:"/algorithms/",component:d("/algorithms/","b7c"),routes:[{path:"/algorithms/",component:d("/algorithms/","9b0"),exact:!0,sidebar:"autogeneratedBar"},{path:"/algorithms/algorithms-correctness/postcondition-ambiguity/",component:d("/algorithms/algorithms-correctness/postcondition-ambiguity/","c18"),exact:!0,sidebar:"autogeneratedBar"},{path:"/algorithms/category/algorithms-and-correctness/",component:d("/algorithms/category/algorithms-and-correctness/","ea2"),exact:!0,sidebar:"autogeneratedBar"},{path:"/algorithms/category/asymptotic-notation-and-time-complexity/",component:d("/algorithms/category/asymptotic-notation-and-time-complexity/","fba"),exact:!0,sidebar:"autogeneratedBar"},{path:"/algorithms/category/graphs/",component:d("/algorithms/category/graphs/","a92"),exact:!0,sidebar:"autogeneratedBar"},{path:"/algorithms/category/hash-tables/",component:d("/algorithms/category/hash-tables/","ddd"),exact:!0,sidebar:"autogeneratedBar"},{path:"/algorithms/category/paths-in-graphs/",component:d("/algorithms/category/paths-in-graphs/","7c7"),exact:!0,sidebar:"autogeneratedBar"},{path:"/algorithms/category/recursion/",component:d("/algorithms/category/recursion/","61f"),exact:!0,sidebar:"autogeneratedBar"},{path:"/algorithms/category/red-black-trees/",component:d("/algorithms/category/red-black-trees/","0c0"),exact:!0,sidebar:"autogeneratedBar"},{path:"/algorithms/graphs/bfs-tree/",component:d("/algorithms/graphs/bfs-tree/","2fb"),exact:!0,sidebar:"autogeneratedBar"},{path:"/algorithms/graphs/iterative-and-iterators/",component:d("/algorithms/graphs/iterative-and-iterators/","bfd"),exact:!0,sidebar:"autogeneratedBar"},{path:"/algorithms/hash-tables/breaking/",component:d("/algorithms/hash-tables/breaking/","319"),exact:!0,sidebar:"autogeneratedBar"},{path:"/algorithms/hash-tables/breaking/mitigations/",component:d("/algorithms/hash-tables/breaking/mitigations/","4c2"),exact:!0,sidebar:"autogeneratedBar"},{path:"/algorithms/hash-tables/breaking/python/",component:d("/algorithms/hash-tables/breaking/python/","3d1"),exact:!0,sidebar:"autogeneratedBar"},{path:"/algorithms/paths/bf-to-astar/",component:d("/algorithms/paths/bf-to-astar/","050"),exact:!0,sidebar:"autogeneratedBar"},{path:"/algorithms/paths/bf-to-astar/astar/",component:d("/algorithms/paths/bf-to-astar/astar/","b4d"),exact:!0,sidebar:"autogeneratedBar"},{path:"/algorithms/paths/bf-to-astar/bf/",component:d("/algorithms/paths/bf-to-astar/bf/","e9c"),exact:!0,sidebar:"autogeneratedBar"},{path:"/algorithms/paths/bf-to-astar/dijkstra/",component:d("/algorithms/paths/bf-to-astar/dijkstra/","fe4"),exact:!0,sidebar:"autogeneratedBar"},{path:"/algorithms/rb-trees/applications/",component:d("/algorithms/rb-trees/applications/","46a"),exact:!0,sidebar:"autogeneratedBar"},{path:"/algorithms/rb-trees/rules/",component:d("/algorithms/rb-trees/rules/","21a"),exact:!0,sidebar:"autogeneratedBar"},{path:"/algorithms/recursion/karel/",component:d("/algorithms/recursion/karel/","4cf"),exact:!0,sidebar:"autogeneratedBar"},{path:"/algorithms/recursion/karel/solution/",component:d("/algorithms/recursion/karel/solution/","115"),exact:!0,sidebar:"autogeneratedBar"},{path:"/algorithms/recursion/pyramid-slide-down/",component:d("/algorithms/recursion/pyramid-slide-down/","236"),exact:!0,sidebar:"autogeneratedBar"},{path:"/algorithms/recursion/pyramid-slide-down/bottom-up-dp/",component:d("/algorithms/recursion/pyramid-slide-down/bottom-up-dp/","00d"),exact:!0,sidebar:"autogeneratedBar"},{path:"/algorithms/recursion/pyramid-slide-down/greedy/",component:d("/algorithms/recursion/pyramid-slide-down/greedy/","4bf"),exact:!0,sidebar:"autogeneratedBar"},{path:"/algorithms/recursion/pyramid-slide-down/naive/",component:d("/algorithms/recursion/pyramid-slide-down/naive/","c1b"),exact:!0,sidebar:"autogeneratedBar"},{path:"/algorithms/recursion/pyramid-slide-down/top-down-dp/",component:d("/algorithms/recursion/pyramid-slide-down/top-down-dp/","fe9"),exact:!0,sidebar:"autogeneratedBar"},{path:"/algorithms/time-complexity/extend/",component:d("/algorithms/time-complexity/extend/","250"),exact:!0,sidebar:"autogeneratedBar"}]}]}]},{path:"/c/",component:d("/c/","dae"),routes:[{path:"/c/",component:d("/c/","fc8"),routes:[{path:"/c/",component:d("/c/","1c4"),routes:[{path:"/c/",component:d("/c/","a0f"),exact:!0,sidebar:"autogeneratedBar"},{path:"/c/bonuses/seminar-03/",component:d("/c/bonuses/seminar-03/","aaa"),exact:!0,sidebar:"autogeneratedBar"},{path:"/c/bonuses/seminar-04/",component:d("/c/bonuses/seminar-04/","ffe"),exact:!0,sidebar:"autogeneratedBar"},{path:"/c/bonuses/seminar-05-06/",component:d("/c/bonuses/seminar-05-06/","4cd"),exact:!0,sidebar:"autogeneratedBar"},{path:"/c/bonuses/seminar-08/",component:d("/c/bonuses/seminar-08/","09a"),exact:!0,sidebar:"autogeneratedBar"},{path:"/c/bonuses/seminar-10/",component:d("/c/bonuses/seminar-10/","b9e"),exact:!0,sidebar:"autogeneratedBar"},{path:"/c/category/bonuses/",component:d("/c/category/bonuses/","17e"),exact:!0,sidebar:"autogeneratedBar"},{path:"/c/category/practice-exams/",component:d("/c/category/practice-exams/","009"),exact:!0,sidebar:"autogeneratedBar"},{path:"/c/mr/",component:d("/c/mr/","4c5"),exact:!0,sidebar:"autogeneratedBar"},{path:"/c/pexam/cams/",component:d("/c/pexam/cams/","a10"),exact:!0,sidebar:"autogeneratedBar"},{path:"/c/pexam/garbage_collect/",component:d("/c/pexam/garbage_collect/","44e"),exact:!0,sidebar:"autogeneratedBar"}]}]}]},{path:"/cpp/",component:d("/cpp/","269"),routes:[{path:"/cpp/",component:d("/cpp/","187"),routes:[{path:"/cpp/",component:d("/cpp/","102"),routes:[{path:"/cpp/",component:d("/cpp/","fcd"),exact:!0,sidebar:"autogeneratedBar"},{path:"/cpp/category/exceptions-and-raii/",component:d("/cpp/category/exceptions-and-raii/","cfa"),exact:!0,sidebar:"autogeneratedBar"},{path:"/cpp/environment/",component:d("/cpp/environment/","e0b"),exact:!0,sidebar:"autogeneratedBar"},{path:"/cpp/exceptions-and-raii/placeholders/",component:d("/cpp/exceptions-and-raii/placeholders/","9b3"),exact:!0,sidebar:"autogeneratedBar"}]}]}]},{path:"/",component:d("/","dfb"),exact:!0},{path:"*",component:d("*")}]},98934:(e,t,n)=>{"use strict";n.d(t,{_:()=>o,t:()=>i});var r=n(67294),a=n(85893);const o=r.createContext(!1);function i(e){let{children:t}=e;const[n,i]=(0,r.useState)(!1);return(0,r.useEffect)((()=>{i(!0)}),[]),(0,a.jsx)(o.Provider,{value:n,children:t})}},97221:(e,t,n)=>{"use strict";var r=n(67294),a=n(20745),o=n(73727),i=n(70405),s=n(10412);const l=[n(32497),n(3310),n(18320),n(29268),n(7439)];var c=n(723),u=n(16550),d=n(18790),p=n(85893);function f(e){let{children:t}=e;return(0,p.jsx)(p.Fragment,{children:t})}var g=n(35742),h=n(52263),m=n(44996),b=n(86668),y=n(10833),v=n(94711),w=n(19727),k=n(43320),x=n(18780),S=n(90197);function _(){const{i18n:{currentLocale:e,defaultLocale:t,localeConfigs:n}}=(0,h.Z)(),r=(0,v.l)(),a=n[e].htmlLang,o=e=>e.replace("-","_");return(0,p.jsxs)(g.Z,{children:[Object.entries(n).map((e=>{let[t,{htmlLang:n}]=e;return(0,p.jsx)("link",{rel:"alternate",href:r.createUrl({locale:t,fullyQualified:!0}),hrefLang:n},t)})),(0,p.jsx)("link",{rel:"alternate",href:r.createUrl({locale:t,fullyQualified:!0}),hrefLang:"x-default"}),(0,p.jsx)("meta",{property:"og:locale",content:o(a)}),Object.values(n).filter((e=>a!==e.htmlLang)).map((e=>(0,p.jsx)("meta",{property:"og:locale:alternate",content:o(e.htmlLang)},`meta-og-${e.htmlLang}`)))]})}function E(e){let{permalink:t}=e;const{siteConfig:{url:n}}=(0,h.Z)(),r=function(){const{siteConfig:{url:e,baseUrl:t,trailingSlash:n}}=(0,h.Z)(),{pathname:r}=(0,u.TH)();return e+(0,x.applyTrailingSlash)((0,m.Z)(r),{trailingSlash:n,baseUrl:t})}(),a=t?`${n}${t}`:r;return(0,p.jsxs)(g.Z,{children:[(0,p.jsx)("meta",{property:"og:url",content:a}),(0,p.jsx)("link",{rel:"canonical",href:a})]})}function C(){const{i18n:{currentLocale:e}}=(0,h.Z)(),{metadata:t,image:n}=(0,b.L)();return(0,p.jsxs)(p.Fragment,{children:[(0,p.jsxs)(g.Z,{children:[(0,p.jsx)("meta",{name:"twitter:card",content:"summary_large_image"}),(0,p.jsx)("body",{className:w.h})]}),n&&(0,p.jsx)(y.d,{image:n}),(0,p.jsx)(E,{}),(0,p.jsx)(_,{}),(0,p.jsx)(S.Z,{tag:k.HX,locale:e}),(0,p.jsx)(g.Z,{children:t.map(((e,t)=>(0,p.jsx)("meta",{...e},t)))})]})}const T=new Map;function A(e){if(T.has(e.pathname))return{...e,pathname:T.get(e.pathname)};if((0,d.f)(c.Z,e.pathname).some((e=>{let{route:t}=e;return!0===t.exact})))return T.set(e.pathname,e.pathname),e;const t=e.pathname.trim().replace(/(?:\/index)?\.html$/,"")||"/";return T.set(e.pathname,t),{...e,pathname:t}}var j=n(98934),N=n(58940),L=n(20469);function P(e){for(var t=arguments.length,n=new Array(t>1?t-1:0),r=1;r{const r=t.default?.[e]??t[e];return r?.(...n)}));return()=>a.forEach((e=>e?.()))}const R=function(e){let{children:t,location:n,previousLocation:r}=e;return(0,L.Z)((()=>{r!==n&&(!function(e){let{location:t,previousLocation:n}=e;if(!n)return;const r=t.pathname===n.pathname,a=t.hash===n.hash,o=t.search===n.search;if(r&&a&&!o)return;const{hash:i}=t;if(i){const e=decodeURIComponent(i.substring(1)),t=document.getElementById(e);t?.scrollIntoView()}else window.scrollTo(0,0)}({location:n,previousLocation:r}),P("onRouteDidUpdate",{previousLocation:r,location:n}))}),[r,n]),t};function O(e){const t=Array.from(new Set([e,decodeURI(e)])).map((e=>(0,d.f)(c.Z,e))).flat();return Promise.all(t.map((e=>e.route.component.preload?.())))}class I extends r.Component{previousLocation;routeUpdateCleanupCb;constructor(e){super(e),this.previousLocation=null,this.routeUpdateCleanupCb=s.Z.canUseDOM?P("onRouteUpdate",{previousLocation:null,location:this.props.location}):()=>{},this.state={nextRouteHasLoaded:!0}}shouldComponentUpdate(e,t){if(e.location===this.props.location)return t.nextRouteHasLoaded;const n=e.location;return this.previousLocation=this.props.location,this.setState({nextRouteHasLoaded:!1}),this.routeUpdateCleanupCb=P("onRouteUpdate",{previousLocation:this.previousLocation,location:n}),O(n.pathname).then((()=>{this.routeUpdateCleanupCb(),this.setState({nextRouteHasLoaded:!0})})).catch((e=>{console.warn(e),window.location.reload()})),!1}render(){const{children:e,location:t}=this.props;return(0,p.jsx)(R,{previousLocation:this.previousLocation,location:t,children:(0,p.jsx)(u.AW,{location:t,render:()=>e})})}}const F=I,M="__docusaurus-base-url-issue-banner-container",D="__docusaurus-base-url-issue-banner",B="__docusaurus-base-url-issue-banner-suggestion-container";function z(e){return`\ndocument.addEventListener('DOMContentLoaded', function maybeInsertBanner() {\n var shouldInsert = typeof window['docusaurus'] === 'undefined';\n shouldInsert && insertBanner();\n});\n\nfunction insertBanner() {\n var bannerContainer = document.createElement('div');\n bannerContainer.id = '${M}';\n var bannerHtml = ${JSON.stringify(function(e){return`\n
    \n

    Your Docusaurus site did not load properly.

    \n

    A very common reason is a wrong site baseUrl configuration.

    \n

    Current configured baseUrl = ${e} ${"/"===e?" (default value)":""}

    \n

    We suggest trying baseUrl =

    \n
    \n`}(e)).replace(/{if("undefined"==typeof document)return void n();const r=document.createElement("link");r.setAttribute("rel","prefetch"),r.setAttribute("href",e),r.onload=()=>t(),r.onerror=()=>n();const a=document.getElementsByTagName("head")[0]??document.getElementsByName("script")[0]?.parentNode;a?.appendChild(r)}))}:function(e){return new Promise(((t,n)=>{const r=new XMLHttpRequest;r.open("GET",e,!0),r.withCredentials=!0,r.onload=()=>{200===r.status?t():n()},r.send(null)}))};var Y=n(99670);const Q=new Set,X=new Set,J=()=>navigator.connection?.effectiveType.includes("2g")||navigator.connection?.saveData,ee={prefetch(e){if(!(e=>!J()&&!X.has(e)&&!Q.has(e))(e))return!1;Q.add(e);const t=(0,d.f)(c.Z,e).flatMap((e=>{return t=e.route.path,Object.entries(q).filter((e=>{let[n]=e;return n.replace(/-[^-]+$/,"")===t})).flatMap((e=>{let[,t]=e;return Object.values((0,Y.Z)(t))}));var t}));return Promise.all(t.map((e=>{const t=n.gca(e);return t&&!t.includes("undefined")?K(t).catch((()=>{})):Promise.resolve()})))},preload:e=>!!(e=>!J()&&!X.has(e))(e)&&(X.add(e),O(e))},te=Object.freeze(ee),ne=Boolean(!0);if(s.Z.canUseDOM){window.docusaurus=te;const e=document.getElementById("__docusaurus"),t=(0,p.jsx)(i.B6,{children:(0,p.jsx)(o.VK,{children:(0,p.jsx)(G,{})})}),n=(e,t)=>{console.error("Docusaurus React Root onRecoverableError:",e,t)},s=()=>{if(ne)r.startTransition((()=>{a.hydrateRoot(e,t,{onRecoverableError:n})}));else{const o=a.createRoot(e,{onRecoverableError:n});r.startTransition((()=>{o.render(t)}))}};O(window.location.pathname).then(s)}},58940:(e,t,n)=>{"use strict";n.d(t,{_:()=>d,M:()=>p});var r=n(67294),a=n(36809);const o=JSON.parse('{"docusaurus-plugin-content-docs":{"algorithms":{"path":"/algorithms","versions":[{"name":"current","label":"Next","isLast":true,"path":"/algorithms","mainDocId":"algorithms-intro","docs":[{"id":"algorithms-correctness/postcondition-ambiguity","path":"/algorithms/algorithms-correctness/postcondition-ambiguity","sidebar":"autogeneratedBar"},{"id":"algorithms-intro","path":"/algorithms/","sidebar":"autogeneratedBar"},{"id":"graphs/bfs-tree","path":"/algorithms/graphs/bfs-tree","sidebar":"autogeneratedBar"},{"id":"graphs/iterative-and-iterators","path":"/algorithms/graphs/iterative-and-iterators","sidebar":"autogeneratedBar"},{"id":"hash-tables/2023-11-28-breaking/breaking","path":"/algorithms/hash-tables/breaking","sidebar":"autogeneratedBar"},{"id":"hash-tables/2023-11-28-breaking/mitigations","path":"/algorithms/hash-tables/breaking/mitigations","sidebar":"autogeneratedBar"},{"id":"hash-tables/2023-11-28-breaking/python","path":"/algorithms/hash-tables/breaking/python","sidebar":"autogeneratedBar"},{"id":"paths/2024-01-01-bf-to-astar/astar","path":"/algorithms/paths/bf-to-astar/astar","sidebar":"autogeneratedBar"},{"id":"paths/2024-01-01-bf-to-astar/bf","path":"/algorithms/paths/bf-to-astar/bf","sidebar":"autogeneratedBar"},{"id":"paths/2024-01-01-bf-to-astar/dijkstra","path":"/algorithms/paths/bf-to-astar/dijkstra","sidebar":"autogeneratedBar"},{"id":"paths/2024-01-01-bf-to-astar/index","path":"/algorithms/paths/bf-to-astar","sidebar":"autogeneratedBar"},{"id":"rb-trees/applications","path":"/algorithms/rb-trees/applications","sidebar":"autogeneratedBar"},{"id":"rb-trees/rules","path":"/algorithms/rb-trees/rules","sidebar":"autogeneratedBar"},{"id":"recursion/2022-11-29-karel/karel","path":"/algorithms/recursion/karel","sidebar":"autogeneratedBar"},{"id":"recursion/2022-11-29-karel/solution","path":"/algorithms/recursion/karel/solution","sidebar":"autogeneratedBar"},{"id":"recursion/2023-08-17-pyramid-slide-down/bottom-up-dp","path":"/algorithms/recursion/pyramid-slide-down/bottom-up-dp","sidebar":"autogeneratedBar"},{"id":"recursion/2023-08-17-pyramid-slide-down/greedy","path":"/algorithms/recursion/pyramid-slide-down/greedy","sidebar":"autogeneratedBar"},{"id":"recursion/2023-08-17-pyramid-slide-down/naive","path":"/algorithms/recursion/pyramid-slide-down/naive","sidebar":"autogeneratedBar"},{"id":"recursion/2023-08-17-pyramid-slide-down/pyramid-slide-down","path":"/algorithms/recursion/pyramid-slide-down","sidebar":"autogeneratedBar"},{"id":"recursion/2023-08-17-pyramid-slide-down/top-down-dp","path":"/algorithms/recursion/pyramid-slide-down/top-down-dp","sidebar":"autogeneratedBar"},{"id":"time-complexity/extend","path":"/algorithms/time-complexity/extend","sidebar":"autogeneratedBar"},{"id":"/category/algorithms-and-correctness","path":"/algorithms/category/algorithms-and-correctness","sidebar":"autogeneratedBar"},{"id":"/category/asymptotic-notation-and-time-complexity","path":"/algorithms/category/asymptotic-notation-and-time-complexity","sidebar":"autogeneratedBar"},{"id":"/category/recursion","path":"/algorithms/category/recursion","sidebar":"autogeneratedBar"},{"id":"/category/red-black-trees","path":"/algorithms/category/red-black-trees","sidebar":"autogeneratedBar"},{"id":"/category/graphs","path":"/algorithms/category/graphs","sidebar":"autogeneratedBar"},{"id":"/category/paths-in-graphs","path":"/algorithms/category/paths-in-graphs","sidebar":"autogeneratedBar"},{"id":"/category/hash-tables","path":"/algorithms/category/hash-tables","sidebar":"autogeneratedBar"}],"draftIds":[],"sidebars":{"autogeneratedBar":{"link":{"path":"/algorithms/","label":"algorithms-intro"}}}}],"breadcrumbs":true},"cpp":{"path":"/cpp","versions":[{"name":"current","label":"Next","isLast":true,"path":"/cpp","mainDocId":"cpp-intro","docs":[{"id":"cpp-intro","path":"/cpp/","sidebar":"autogeneratedBar"},{"id":"environment","path":"/cpp/environment","sidebar":"autogeneratedBar"},{"id":"exceptions-and-raii/2023-11-24-placeholders","path":"/cpp/exceptions-and-raii/placeholders","sidebar":"autogeneratedBar"},{"id":"/category/exceptions-and-raii","path":"/cpp/category/exceptions-and-raii","sidebar":"autogeneratedBar"}],"draftIds":[],"sidebars":{"autogeneratedBar":{"link":{"path":"/cpp/","label":"cpp-intro"}}}}],"breadcrumbs":true},"c":{"path":"/c","versions":[{"name":"current","label":"Next","isLast":true,"path":"/c","mainDocId":"c-intro","docs":[{"id":"bonuses/seminar-03","path":"/c/bonuses/seminar-03","sidebar":"autogeneratedBar"},{"id":"bonuses/seminar-04","path":"/c/bonuses/seminar-04","sidebar":"autogeneratedBar"},{"id":"bonuses/seminar-05-06","path":"/c/bonuses/seminar-05-06","sidebar":"autogeneratedBar"},{"id":"bonuses/seminar-08","path":"/c/bonuses/seminar-08","sidebar":"autogeneratedBar"},{"id":"bonuses/seminar-10","path":"/c/bonuses/seminar-10","sidebar":"autogeneratedBar"},{"id":"c-intro","path":"/c/","sidebar":"autogeneratedBar"},{"id":"mr","path":"/c/mr","sidebar":"autogeneratedBar"},{"id":"pexam/b-garbage_collect","path":"/c/pexam/garbage_collect","sidebar":"autogeneratedBar"},{"id":"pexam/c-cams","path":"/c/pexam/cams","sidebar":"autogeneratedBar"},{"id":"/category/bonuses","path":"/c/category/bonuses","sidebar":"autogeneratedBar"},{"id":"/category/practice-exams","path":"/c/category/practice-exams","sidebar":"autogeneratedBar"}],"draftIds":[],"sidebars":{"autogeneratedBar":{"link":{"path":"/c/","label":"c-intro"}}}}],"breadcrumbs":true}}}'),i=JSON.parse('{"defaultLocale":"en","locales":["en"],"path":"i18n","currentLocale":"en","localeConfigs":{"en":{"label":"English","direction":"ltr","htmlLang":"en","calendar":"gregory","path":"en"}}}');var s=n(57529);const l=JSON.parse('{"docusaurusVersion":"3.0.0","siteVersion":"0.0.0","pluginVersions":{"docusaurus-plugin-content-pages":{"type":"package","name":"@docusaurus/plugin-content-pages","version":"3.0.0"},"docusaurus-plugin-sitemap":{"type":"package","name":"@docusaurus/plugin-sitemap","version":"3.0.0"},"docusaurus-theme-classic":{"type":"package","name":"@docusaurus/theme-classic","version":"3.0.0"},"docusaurus-theme-search-algolia":{"type":"package","name":"@docusaurus/theme-search-algolia","version":"3.0.0"},"docusaurus-plugin-content-docs":{"type":"package","name":"@docusaurus/plugin-content-docs","version":"3.0.0"},"docusaurus-plugin-content-blog":{"type":"package","name":"@docusaurus/plugin-content-blog","version":"3.0.0"},"docusaurus-plugin-sass":{"type":"package","name":"docusaurus-plugin-sass","version":"0.2.5"},"docusaurus-plugin-client-redirects":{"type":"package","name":"@docusaurus/plugin-client-redirects","version":"3.0.0"},"docusaurus-theme-mermaid":{"type":"package","name":"@docusaurus/theme-mermaid","version":"3.0.0"}}}');var c=n(85893);const u={siteConfig:a.default,siteMetadata:l,globalData:o,i18n:i,codeTranslations:s},d=r.createContext(u);function p(e){let{children:t}=e;return(0,c.jsx)(d.Provider,{value:u,children:t})}},44763:(e,t,n)=>{"use strict";n.d(t,{Z:()=>f});var r=n(67294),a=n(10412),o=n(35742),i=n(18780),s=n(58207),l=n(85893);function c(e){let{error:t,tryAgain:n}=e;return(0,l.jsxs)("div",{style:{display:"flex",flexDirection:"column",justifyContent:"center",alignItems:"flex-start",minHeight:"100vh",width:"100%",maxWidth:"80ch",fontSize:"20px",margin:"0 auto",padding:"1rem"},children:[(0,l.jsx)("h1",{style:{fontSize:"3rem"},children:"This page crashed"}),(0,l.jsx)("button",{type:"button",onClick:n,style:{margin:"1rem 0",fontSize:"2rem",cursor:"pointer",borderRadius:20,padding:"1rem"},children:"Try again"}),(0,l.jsx)(u,{error:t})]})}function u(e){let{error:t}=e;const n=(0,i.getErrorCausalChain)(t).map((e=>e.message)).join("\n\nCause:\n");return(0,l.jsx)("p",{style:{whiteSpace:"pre-wrap"},children:n})}function d(e){let{error:t,tryAgain:n}=e;return(0,l.jsxs)(f,{fallback:()=>(0,l.jsx)(c,{error:t,tryAgain:n}),children:[(0,l.jsx)(o.Z,{children:(0,l.jsx)("title",{children:"Page Error"})}),(0,l.jsx)(s.Z,{children:(0,l.jsx)(c,{error:t,tryAgain:n})})]})}const p=e=>(0,l.jsx)(d,{...e});class f extends r.Component{constructor(e){super(e),this.state={error:null}}componentDidCatch(e){a.Z.canUseDOM&&this.setState({error:e})}render(){const{children:e}=this.props,{error:t}=this.state;if(t){const e={error:t,tryAgain:()=>this.setState({error:null})};return(this.props.fallback??p)(e)}return e??null}}},10412:(e,t,n)=>{"use strict";n.d(t,{Z:()=>a});const r="undefined"!=typeof window&&"document"in window&&"createElement"in window.document,a={canUseDOM:r,canUseEventListeners:r&&("addEventListener"in window||"attachEvent"in window),canUseIntersectionObserver:r&&"IntersectionObserver"in window,canUseViewport:r&&"screen"in window}},35742:(e,t,n)=>{"use strict";n.d(t,{Z:()=>o});n(67294);var r=n(70405),a=n(85893);function o(e){return(0,a.jsx)(r.ql,{...e})}},39960:(e,t,n)=>{"use strict";n.d(t,{Z:()=>f});var r=n(67294),a=n(73727),o=n(18780),i=n(52263),s=n(13919),l=n(10412),c=n(85893);const u=r.createContext({collectLink:()=>{}});var d=n(44996);function p(e,t){let{isNavLink:n,to:p,href:f,activeClassName:g,isActive:h,"data-noBrokenLinkCheck":m,autoAddBaseUrl:b=!0,...y}=e;const{siteConfig:{trailingSlash:v,baseUrl:w}}=(0,i.Z)(),{withBaseUrl:k}=(0,d.C)(),x=(0,r.useContext)(u),S=(0,r.useRef)(null);(0,r.useImperativeHandle)(t,(()=>S.current));const _=p||f;const E=(0,s.Z)(_),C=_?.replace("pathname://","");let T=void 0!==C?(A=C,b&&(e=>e.startsWith("/"))(A)?k(A):A):void 0;var A;T&&E&&(T=(0,o.applyTrailingSlash)(T,{trailingSlash:v,baseUrl:w}));const j=(0,r.useRef)(!1),N=n?a.OL:a.rU,L=l.Z.canUseIntersectionObserver,P=(0,r.useRef)(),R=()=>{j.current||null==T||(window.docusaurus.preload(T),j.current=!0)};(0,r.useEffect)((()=>(!L&&E&&null!=T&&window.docusaurus.prefetch(T),()=>{L&&P.current&&P.current.disconnect()})),[P,T,L,E]);const O=T?.startsWith("#")??!1,I=!T||!E||O;return I||m||x.collectLink(T),I?(0,c.jsx)("a",{ref:S,href:T,..._&&!E&&{target:"_blank",rel:"noopener noreferrer"},...y}):(0,c.jsx)(N,{...y,onMouseEnter:R,onTouchStart:R,innerRef:e=>{S.current=e,L&&e&&E&&(P.current=new window.IntersectionObserver((t=>{t.forEach((t=>{e===t.target&&(t.isIntersecting||t.intersectionRatio>0)&&(P.current.unobserve(e),P.current.disconnect(),null!=T&&window.docusaurus.prefetch(T))}))})),P.current.observe(e))},to:T,...n&&{isActive:h,activeClassName:g}})}const f=r.forwardRef(p)},95999:(e,t,n)=>{"use strict";n.d(t,{Z:()=>c,I:()=>l});var r=n(67294),a=n(85893);function o(e,t){const n=e.split(/(\{\w+\})/).map(((e,n)=>{if(n%2==1){const n=t?.[e.slice(1,-1)];if(void 0!==n)return n}return e}));return n.some((e=>(0,r.isValidElement)(e)))?n.map(((e,t)=>(0,r.isValidElement)(e)?r.cloneElement(e,{key:t}):e)).filter((e=>""!==e)):n.join("")}var i=n(57529);function s(e){let{id:t,message:n}=e;if(void 0===t&&void 0===n)throw new Error("Docusaurus translation declarations must have at least a translation id or a default translation message");return i[t??n]??n??t}function l(e,t){let{message:n,id:r}=e;return o(s({message:n,id:r}),t)}function c(e){let{children:t,id:n,values:r}=e;if(t&&"string"!=typeof t)throw console.warn("Illegal children",t),new Error("The Docusaurus component only accept simple string values");const i=s({message:t,id:n});return(0,a.jsx)(a.Fragment,{children:o(i,r)})}},29935:(e,t,n)=>{"use strict";n.d(t,{m:()=>r});const r="default"},13919:(e,t,n)=>{"use strict";function r(e){return/^(?:\w*:|\/\/)/.test(e)}function a(e){return void 0!==e&&!r(e)}n.d(t,{Z:()=>a,b:()=>r})},44996:(e,t,n)=>{"use strict";n.d(t,{C:()=>i,Z:()=>s});var r=n(67294),a=n(52263),o=n(13919);function i(){const{siteConfig:{baseUrl:e,url:t}}=(0,a.Z)(),n=(0,r.useCallback)(((n,r)=>function(e,t,n,r){let{forcePrependBaseUrl:a=!1,absolute:i=!1}=void 0===r?{}:r;if(!n||n.startsWith("#")||(0,o.b)(n))return n;if(a)return t+n.replace(/^\//,"");if(n===t.replace(/\/$/,""))return t;const s=n.startsWith(t)?n:t+n.replace(/^\//,"");return i?e+s:s}(t,e,n,r)),[t,e]);return{withBaseUrl:n}}function s(e,t){void 0===t&&(t={});const{withBaseUrl:n}=i();return n(e,t)}},52263:(e,t,n)=>{"use strict";n.d(t,{Z:()=>o});var r=n(67294),a=n(58940);function o(){return(0,r.useContext)(a._)}},72389:(e,t,n)=>{"use strict";n.d(t,{Z:()=>o});var r=n(67294),a=n(98934);function o(){return(0,r.useContext)(a._)}},20469:(e,t,n)=>{"use strict";n.d(t,{Z:()=>a});var r=n(67294);const a=n(10412).Z.canUseDOM?r.useLayoutEffect:r.useEffect},99670:(e,t,n)=>{"use strict";n.d(t,{Z:()=>a});const r=e=>"object"==typeof e&&!!e&&Object.keys(e).length>0;function a(e){const t={};return function e(n,a){Object.entries(n).forEach((n=>{let[o,i]=n;const s=a?`${a}.${o}`:o;r(i)?e(i,s):t[s]=i}))}(e),t}},30226:(e,t,n)=>{"use strict";n.d(t,{_:()=>o,z:()=>i});var r=n(67294),a=n(85893);const o=r.createContext(null);function i(e){let{children:t,value:n}=e;const i=r.useContext(o),s=(0,r.useMemo)((()=>function(e){let{parent:t,value:n}=e;if(!t){if(!n)throw new Error("Unexpected: no Docusaurus route context found");if(!("plugin"in n))throw new Error("Unexpected: Docusaurus topmost route context has no `plugin` attribute");return n}const r={...t.data,...n?.data};return{plugin:t.plugin,data:r}}({parent:i,value:n})),[i,n]);return(0,a.jsx)(o.Provider,{value:s,children:t})}},80143:(e,t,n)=>{"use strict";n.d(t,{Iw:()=>b,gA:()=>f,WS:()=>g,_r:()=>d,Jo:()=>y,zh:()=>p,yW:()=>m,gB:()=>h});var r=n(16550),a=n(52263),o=n(29935);function i(e,t){void 0===t&&(t={});const n=function(){const{globalData:e}=(0,a.Z)();return e}()[e];if(!n&&t.failfast)throw new Error(`Docusaurus plugin global data not found for "${e}" plugin.`);return n}const s=e=>e.versions.find((e=>e.isLast));function l(e,t){const n=s(e);return[...e.versions.filter((e=>e!==n)),n].find((e=>!!(0,r.LX)(t,{path:e.path,exact:!1,strict:!1})))}function c(e,t){const n=l(e,t),a=n?.docs.find((e=>!!(0,r.LX)(t,{path:e.path,exact:!0,strict:!1})));return{activeVersion:n,activeDoc:a,alternateDocVersions:a?function(t){const n={};return e.versions.forEach((e=>{e.docs.forEach((r=>{r.id===t&&(n[e.name]=r)}))})),n}(a.id):{}}}const u={},d=()=>i("docusaurus-plugin-content-docs")??u,p=e=>function(e,t,n){void 0===t&&(t=o.m),void 0===n&&(n={});const r=i(e),a=r?.[t];if(!a&&n.failfast)throw new Error(`Docusaurus plugin global data not found for "${e}" plugin with id "${t}".`);return a}("docusaurus-plugin-content-docs",e,{failfast:!0});function f(e){void 0===e&&(e={});const t=d(),{pathname:n}=(0,r.TH)();return function(e,t,n){void 0===n&&(n={});const a=Object.entries(e).sort(((e,t)=>t[1].path.localeCompare(e[1].path))).find((e=>{let[,n]=e;return!!(0,r.LX)(t,{path:n.path,exact:!1,strict:!1})})),o=a?{pluginId:a[0],pluginData:a[1]}:void 0;if(!o&&n.failfast)throw new Error(`Can't find active docs plugin for "${t}" pathname, while it was expected to be found. Maybe you tried to use a docs feature that can only be used on a docs-related page? Existing docs plugin paths are: ${Object.values(e).map((e=>e.path)).join(", ")}`);return o}(t,n,e)}function g(e){void 0===e&&(e={});const t=f(e),{pathname:n}=(0,r.TH)();if(!t)return;return{activePlugin:t,activeVersion:l(t.pluginData,n)}}function h(e){return p(e).versions}function m(e){const t=p(e);return s(t)}function b(e){const t=p(e),{pathname:n}=(0,r.TH)();return c(t,n)}function y(e){const t=p(e),{pathname:n}=(0,r.TH)();return function(e,t){const n=s(e);return{latestDocSuggestion:c(e,t).alternateDocVersions[n.name],latestVersionSuggestion:n}}(t,n)}},18320:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>o});var r=n(74865),a=n.n(r);a().configure({showSpinner:!1});const o={onRouteUpdate(e){let{location:t,previousLocation:n}=e;if(n&&t.pathname!==n.pathname){const e=window.setTimeout((()=>{a().start()}),200);return()=>window.clearTimeout(e)}},onRouteDidUpdate(){a().done()}}},3310:(e,t,n)=>{"use strict";n.r(t);var r=n(14965),a=n(36809);!function(e){const{themeConfig:{prism:t}}=a.default,{additionalLanguages:r}=t;globalThis.Prism=e,r.forEach((e=>{"php"===e&&n(96854),n(30218)(`./prism-${e}`)})),delete globalThis.Prism}(r.p1)},92503:(e,t,n)=>{"use strict";n.d(t,{Z:()=>c});n(67294);var r=n(86010),a=n(95999),o=n(86668),i=n(39960);const s={anchorWithStickyNavbar:"anchorWithStickyNavbar_LWe7",anchorWithHideOnScrollNavbar:"anchorWithHideOnScrollNavbar_WYt5"};var l=n(85893);function c(e){let{as:t,id:n,...c}=e;const{navbar:{hideOnScroll:u}}=(0,o.L)();if("h1"===t||!n)return(0,l.jsx)(t,{...c,id:void 0});const d=(0,a.I)({id:"theme.common.headingLinkTitle",message:"Direct link to {heading}",description:"Title for link to heading"},{heading:"string"==typeof c.children?c.children:n});return(0,l.jsxs)(t,{...c,className:(0,r.Z)("anchor",u?s.anchorWithHideOnScrollNavbar:s.anchorWithStickyNavbar,c.className),id:n,children:[c.children,(0,l.jsx)(i.Z,{className:"hash-link",to:`#${n}`,"aria-label":d,title:d,children:"\u200b"})]})}},39471:(e,t,n)=>{"use strict";n.d(t,{Z:()=>o});n(67294);const r={iconExternalLink:"iconExternalLink_nPIU"};var a=n(85893);function o(e){let{width:t=13.5,height:n=13.5}=e;return(0,a.jsx)("svg",{width:t,height:n,"aria-hidden":"true",viewBox:"0 0 24 24",className:r.iconExternalLink,children:(0,a.jsx)("path",{fill:"currentColor",d:"M21 13v10h-21v-19h12v2h-10v15h17v-8h2zm3-12h-10.988l4.035 4-6.977 7.07 2.828 2.828 6.977-7.07 4.125 4.172v-11z"})})}},58207:(e,t,n)=>{"use strict";n.d(t,{Z:()=>Tt});var r=n(67294),a=n(86010),o=n(44763),i=n(10833),s=n(16550),l=n(95999),c=n(85936),u=n(85893);const d="__docusaurus_skipToContent_fallback";function p(e){e.setAttribute("tabindex","-1"),e.focus(),e.removeAttribute("tabindex")}function f(){const e=(0,r.useRef)(null),{action:t}=(0,s.k6)(),n=(0,r.useCallback)((e=>{e.preventDefault();const t=document.querySelector("main:first-of-type")??document.getElementById(d);t&&p(t)}),[]);return(0,c.S)((n=>{let{location:r}=n;e.current&&!r.hash&&"PUSH"===t&&p(e.current)})),{containerRef:e,onClick:n}}const g=(0,l.I)({id:"theme.common.skipToMainContent",description:"The skip to content label used for accessibility, allowing to rapidly navigate to main content with keyboard tab/enter navigation",message:"Skip to main content"});function h(e){const t=e.children??g,{containerRef:n,onClick:r}=f();return(0,u.jsx)("div",{ref:n,role:"region","aria-label":g,children:(0,u.jsx)("a",{...e,href:`#${d}`,onClick:r,children:t})})}var m=n(35281),b=n(19727);const y={skipToContent:"skipToContent_fXgn"};function v(){return(0,u.jsx)(h,{className:y.skipToContent})}var w=n(86668),k=n(59689);function x(e){let{width:t=21,height:n=21,color:r="currentColor",strokeWidth:a=1.2,className:o,...i}=e;return(0,u.jsx)("svg",{viewBox:"0 0 15 15",width:t,height:n,...i,children:(0,u.jsx)("g",{stroke:r,strokeWidth:a,children:(0,u.jsx)("path",{d:"M.75.75l13.5 13.5M14.25.75L.75 14.25"})})})}const S={closeButton:"closeButton_CVFx"};function _(e){return(0,u.jsx)("button",{type:"button","aria-label":(0,l.I)({id:"theme.AnnouncementBar.closeButtonAriaLabel",message:"Close",description:"The ARIA label for close button of announcement bar"}),...e,className:(0,a.Z)("clean-btn close",S.closeButton,e.className),children:(0,u.jsx)(x,{width:14,height:14,strokeWidth:3.1})})}const E={content:"content_knG7"};function C(e){const{announcementBar:t}=(0,w.L)(),{content:n}=t;return(0,u.jsx)("div",{...e,className:(0,a.Z)(E.content,e.className),dangerouslySetInnerHTML:{__html:n}})}const T={announcementBar:"announcementBar_mb4j",announcementBarPlaceholder:"announcementBarPlaceholder_vyr4",announcementBarClose:"announcementBarClose_gvF7",announcementBarContent:"announcementBarContent_xLdY"};function A(){const{announcementBar:e}=(0,w.L)(),{isActive:t,close:n}=(0,k.nT)();if(!t)return null;const{backgroundColor:r,textColor:a,isCloseable:o}=e;return(0,u.jsxs)("div",{className:T.announcementBar,style:{backgroundColor:r,color:a},role:"banner",children:[o&&(0,u.jsx)("div",{className:T.announcementBarPlaceholder}),(0,u.jsx)(C,{className:T.announcementBarContent}),o&&(0,u.jsx)(_,{onClick:n,className:T.announcementBarClose})]})}var j=n(93163),N=n(12466);var L=n(902),P=n(13102);const R=r.createContext(null);function O(e){let{children:t}=e;const n=function(){const e=(0,j.e)(),t=(0,P.HY)(),[n,a]=(0,r.useState)(!1),o=null!==t.component,i=(0,L.D9)(o);return(0,r.useEffect)((()=>{o&&!i&&a(!0)}),[o,i]),(0,r.useEffect)((()=>{o?e.shown||a(!0):a(!1)}),[e.shown,o]),(0,r.useMemo)((()=>[n,a]),[n])}();return(0,u.jsx)(R.Provider,{value:n,children:t})}function I(e){if(e.component){const t=e.component;return(0,u.jsx)(t,{...e.props})}}function F(){const e=(0,r.useContext)(R);if(!e)throw new L.i6("NavbarSecondaryMenuDisplayProvider");const[t,n]=e,a=(0,r.useCallback)((()=>n(!1)),[n]),o=(0,P.HY)();return(0,r.useMemo)((()=>({shown:t,hide:a,content:I(o)})),[a,o,t])}function M(e){let{header:t,primaryMenu:n,secondaryMenu:r}=e;const{shown:o}=F();return(0,u.jsxs)("div",{className:"navbar-sidebar",children:[t,(0,u.jsxs)("div",{className:(0,a.Z)("navbar-sidebar__items",{"navbar-sidebar__items--show-secondary":o}),children:[(0,u.jsx)("div",{className:"navbar-sidebar__item menu",children:n}),(0,u.jsx)("div",{className:"navbar-sidebar__item menu",children:r})]})]})}var D=n(92949),B=n(72389);function z(e){return(0,u.jsx)("svg",{viewBox:"0 0 24 24",width:24,height:24,...e,children:(0,u.jsx)("path",{fill:"currentColor",d:"M12,9c1.65,0,3,1.35,3,3s-1.35,3-3,3s-3-1.35-3-3S10.35,9,12,9 M12,7c-2.76,0-5,2.24-5,5s2.24,5,5,5s5-2.24,5-5 S14.76,7,12,7L12,7z M2,13l2,0c0.55,0,1-0.45,1-1s-0.45-1-1-1l-2,0c-0.55,0-1,0.45-1,1S1.45,13,2,13z M20,13l2,0c0.55,0,1-0.45,1-1 s-0.45-1-1-1l-2,0c-0.55,0-1,0.45-1,1S19.45,13,20,13z M11,2v2c0,0.55,0.45,1,1,1s1-0.45,1-1V2c0-0.55-0.45-1-1-1S11,1.45,11,2z M11,20v2c0,0.55,0.45,1,1,1s1-0.45,1-1v-2c0-0.55-0.45-1-1-1C11.45,19,11,19.45,11,20z M5.99,4.58c-0.39-0.39-1.03-0.39-1.41,0 c-0.39,0.39-0.39,1.03,0,1.41l1.06,1.06c0.39,0.39,1.03,0.39,1.41,0s0.39-1.03,0-1.41L5.99,4.58z M18.36,16.95 c-0.39-0.39-1.03-0.39-1.41,0c-0.39,0.39-0.39,1.03,0,1.41l1.06,1.06c0.39,0.39,1.03,0.39,1.41,0c0.39-0.39,0.39-1.03,0-1.41 L18.36,16.95z M19.42,5.99c0.39-0.39,0.39-1.03,0-1.41c-0.39-0.39-1.03-0.39-1.41,0l-1.06,1.06c-0.39,0.39-0.39,1.03,0,1.41 s1.03,0.39,1.41,0L19.42,5.99z M7.05,18.36c0.39-0.39,0.39-1.03,0-1.41c-0.39-0.39-1.03-0.39-1.41,0l-1.06,1.06 c-0.39,0.39-0.39,1.03,0,1.41s1.03,0.39,1.41,0L7.05,18.36z"})})}function $(e){return(0,u.jsx)("svg",{viewBox:"0 0 24 24",width:24,height:24,...e,children:(0,u.jsx)("path",{fill:"currentColor",d:"M9.37,5.51C9.19,6.15,9.1,6.82,9.1,7.5c0,4.08,3.32,7.4,7.4,7.4c0.68,0,1.35-0.09,1.99-0.27C17.45,17.19,14.93,19,12,19 c-3.86,0-7-3.14-7-7C5,9.07,6.81,6.55,9.37,5.51z M12,3c-4.97,0-9,4.03-9,9s4.03,9,9,9s9-4.03,9-9c0-0.46-0.04-0.92-0.1-1.36 c-0.98,1.37-2.58,2.26-4.4,2.26c-2.98,0-5.4-2.42-5.4-5.4c0-1.81,0.89-3.42,2.26-4.4C12.92,3.04,12.46,3,12,3L12,3z"})})}const U={toggle:"toggle_vylO",toggleButton:"toggleButton_gllP",darkToggleIcon:"darkToggleIcon_wfgR",lightToggleIcon:"lightToggleIcon_pyhR",toggleButtonDisabled:"toggleButtonDisabled_aARS"};function Z(e){let{className:t,buttonClassName:n,value:r,onChange:o}=e;const i=(0,B.Z)(),s=(0,l.I)({message:"Switch between dark and light mode (currently {mode})",id:"theme.colorToggle.ariaLabel",description:"The ARIA label for the navbar color mode toggle"},{mode:"dark"===r?(0,l.I)({message:"dark mode",id:"theme.colorToggle.ariaLabel.mode.dark",description:"The name for the dark color mode"}):(0,l.I)({message:"light mode",id:"theme.colorToggle.ariaLabel.mode.light",description:"The name for the light color mode"})});return(0,u.jsx)("div",{className:(0,a.Z)(U.toggle,t),children:(0,u.jsxs)("button",{className:(0,a.Z)("clean-btn",U.toggleButton,!i&&U.toggleButtonDisabled,n),type:"button",onClick:()=>o("dark"===r?"light":"dark"),disabled:!i,title:s,"aria-label":s,"aria-live":"polite",children:[(0,u.jsx)(z,{className:(0,a.Z)(U.toggleIcon,U.lightToggleIcon)}),(0,u.jsx)($,{className:(0,a.Z)(U.toggleIcon,U.darkToggleIcon)})]})})}const H=r.memo(Z),V={darkNavbarColorModeToggle:"darkNavbarColorModeToggle_X3D1"};function W(e){let{className:t}=e;const n=(0,w.L)().navbar.style,r=(0,w.L)().colorMode.disableSwitch,{colorMode:a,setColorMode:o}=(0,D.I)();return r?null:(0,u.jsx)(H,{className:t,buttonClassName:"dark"===n?V.darkNavbarColorModeToggle:void 0,value:a,onChange:o})}var G=n(21327);function q(){return(0,u.jsx)(G.Z,{className:"navbar__brand",imageClassName:"navbar__logo",titleClassName:"navbar__title text--truncate"})}function K(){const e=(0,j.e)();return(0,u.jsx)("button",{type:"button","aria-label":(0,l.I)({id:"theme.docs.sidebar.closeSidebarButtonAriaLabel",message:"Close navigation bar",description:"The ARIA label for close button of mobile sidebar"}),className:"clean-btn navbar-sidebar__close",onClick:()=>e.toggle(),children:(0,u.jsx)(x,{color:"var(--ifm-color-emphasis-600)"})})}function Y(){return(0,u.jsxs)("div",{className:"navbar-sidebar__brand",children:[(0,u.jsx)(q,{}),(0,u.jsx)(W,{className:"margin-right--md"}),(0,u.jsx)(K,{})]})}var Q=n(39960),X=n(44996),J=n(13919),ee=n(98022),te=n(39471);function ne(e){let{activeBasePath:t,activeBaseRegex:n,to:r,href:a,label:o,html:i,isDropdownLink:s,prependBaseUrlToHref:l,...c}=e;const d=(0,X.Z)(r),p=(0,X.Z)(t),f=(0,X.Z)(a,{forcePrependBaseUrl:!0}),g=o&&a&&!(0,J.Z)(a),h=i?{dangerouslySetInnerHTML:{__html:i}}:{children:(0,u.jsxs)(u.Fragment,{children:[o,g&&(0,u.jsx)(te.Z,{...s&&{width:12,height:12}})]})};return a?(0,u.jsx)(Q.Z,{href:l?f:a,...c,...h}):(0,u.jsx)(Q.Z,{to:d,isNavLink:!0,...(t||n)&&{isActive:(e,t)=>n?(0,ee.F)(n,t.pathname):t.pathname.startsWith(p)},...c,...h})}function re(e){let{className:t,isDropdownItem:n=!1,...r}=e;const o=(0,u.jsx)(ne,{className:(0,a.Z)(n?"dropdown__link":"navbar__item navbar__link",t),isDropdownLink:n,...r});return n?(0,u.jsx)("li",{children:o}):o}function ae(e){let{className:t,isDropdownItem:n,...r}=e;return(0,u.jsx)("li",{className:"menu__list-item",children:(0,u.jsx)(ne,{className:(0,a.Z)("menu__link",t),...r})})}function oe(e){let{mobile:t=!1,position:n,...r}=e;const a=t?ae:re;return(0,u.jsx)(a,{...r,activeClassName:r.activeClassName??(t?"menu__link--active":"navbar__link--active")})}var ie=n(86043),se=n(48596),le=n(52263);function ce(e,t){return e.some((e=>function(e,t){return!!(0,se.Mg)(e.to,t)||!!(0,ee.F)(e.activeBaseRegex,t)||!(!e.activeBasePath||!t.startsWith(e.activeBasePath))}(e,t)))}function ue(e){let{items:t,position:n,className:o,onClick:i,...s}=e;const l=(0,r.useRef)(null),[c,d]=(0,r.useState)(!1);return(0,r.useEffect)((()=>{const e=e=>{l.current&&!l.current.contains(e.target)&&d(!1)};return document.addEventListener("mousedown",e),document.addEventListener("touchstart",e),document.addEventListener("focusin",e),()=>{document.removeEventListener("mousedown",e),document.removeEventListener("touchstart",e),document.removeEventListener("focusin",e)}}),[l]),(0,u.jsxs)("div",{ref:l,className:(0,a.Z)("navbar__item","dropdown","dropdown--hoverable",{"dropdown--right":"right"===n,"dropdown--show":c}),children:[(0,u.jsx)(ne,{"aria-haspopup":"true","aria-expanded":c,role:"button",href:s.to?void 0:"#",className:(0,a.Z)("navbar__link",o),...s,onClick:s.to?void 0:e=>e.preventDefault(),onKeyDown:e=>{"Enter"===e.key&&(e.preventDefault(),d(!c))},children:s.children??s.label}),(0,u.jsx)("ul",{className:"dropdown__menu",children:t.map(((e,t)=>(0,r.createElement)(Ze,{isDropdownItem:!0,activeClassName:"dropdown__link--active",...e,key:t})))})]})}function de(e){let{items:t,className:n,position:o,onClick:i,...l}=e;const c=function(){const{siteConfig:{baseUrl:e}}=(0,le.Z)(),{pathname:t}=(0,s.TH)();return t.replace(e,"/")}(),d=ce(t,c),{collapsed:p,toggleCollapsed:f,setCollapsed:g}=(0,ie.u)({initialState:()=>!d});return(0,r.useEffect)((()=>{d&&g(!d)}),[c,d,g]),(0,u.jsxs)("li",{className:(0,a.Z)("menu__list-item",{"menu__list-item--collapsed":p}),children:[(0,u.jsx)(ne,{role:"button",className:(0,a.Z)("menu__link menu__link--sublist menu__link--sublist-caret",n),...l,onClick:e=>{e.preventDefault(),f()},children:l.children??l.label}),(0,u.jsx)(ie.z,{lazy:!0,as:"ul",className:"menu__list",collapsed:p,children:t.map(((e,t)=>(0,r.createElement)(Ze,{mobile:!0,isDropdownItem:!0,onClick:i,activeClassName:"menu__link--active",...e,key:t})))})]})}function pe(e){let{mobile:t=!1,...n}=e;const r=t?de:ue;return(0,u.jsx)(r,{...n})}var fe=n(94711);function ge(e){let{width:t=20,height:n=20,...r}=e;return(0,u.jsx)("svg",{viewBox:"0 0 24 24",width:t,height:n,"aria-hidden":!0,...r,children:(0,u.jsx)("path",{fill:"currentColor",d:"M12.87 15.07l-2.54-2.51.03-.03c1.74-1.94 2.98-4.17 3.71-6.53H17V4h-7V2H8v2H1v1.99h11.17C11.5 7.92 10.44 9.75 9 11.35 8.07 10.32 7.3 9.19 6.69 8h-2c.73 1.63 1.73 3.17 2.98 4.56l-5.09 5.02L4 19l5-5 3.11 3.11.76-2.04zM18.5 10h-2L12 22h2l1.12-3h4.75L21 22h2l-4.5-12zm-2.62 7l1.62-4.33L19.12 17h-3.24z"})})}const he="iconLanguage_nlXk";function me(){return r.createElement("svg",{width:"15",height:"15",className:"DocSearch-Control-Key-Icon"},r.createElement("path",{d:"M4.505 4.496h2M5.505 5.496v5M8.216 4.496l.055 5.993M10 7.5c.333.333.5.667.5 1v2M12.326 4.5v5.996M8.384 4.496c1.674 0 2.116 0 2.116 1.5s-.442 1.5-2.116 1.5M3.205 9.303c-.09.448-.277 1.21-1.241 1.203C1 10.5.5 9.513.5 8V7c0-1.57.5-2.5 1.464-2.494.964.006 1.134.598 1.24 1.342M12.553 10.5h1.953",strokeWidth:"1.2",stroke:"currentColor",fill:"none",strokeLinecap:"square"}))}var be=n(20830),ye=["translations"];function ve(){return ve=Object.assign||function(e){for(var t=1;te.length)&&(t=e.length);for(var n=0,r=new Array(t);n=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var Se="Ctrl";var _e=r.forwardRef((function(e,t){var n=e.translations,a=void 0===n?{}:n,o=xe(e,ye),i=a.buttonText,s=void 0===i?"Search":i,l=a.buttonAriaLabel,c=void 0===l?"Search":l,u=we((0,r.useState)(null),2),d=u[0],p=u[1];return(0,r.useEffect)((function(){"undefined"!=typeof navigator&&(/(Mac|iPhone|iPod|iPad)/i.test(navigator.platform)?p("\u2318"):p(Se))}),[]),r.createElement("button",ve({type:"button",className:"DocSearch DocSearch-Button","aria-label":c},o,{ref:t}),r.createElement("span",{className:"DocSearch-Button-Container"},r.createElement(be.W,null),r.createElement("span",{className:"DocSearch-Button-Placeholder"},s)),r.createElement("span",{className:"DocSearch-Button-Keys"},null!==d&&r.createElement(r.Fragment,null,r.createElement("kbd",{className:"DocSearch-Button-Key"},d===Se?r.createElement(me,null):d),r.createElement("kbd",{className:"DocSearch-Button-Key"},"K"))))})),Ee=n(35742),Ce=n(66177),Te=n(239),Ae=n(43320);var je=n(73935);const Ne={button:{buttonText:(0,l.I)({id:"theme.SearchBar.label",message:"Search",description:"The ARIA label and placeholder for search button"}),buttonAriaLabel:(0,l.I)({id:"theme.SearchBar.label",message:"Search",description:"The ARIA label and placeholder for search button"})},modal:{searchBox:{resetButtonTitle:(0,l.I)({id:"theme.SearchModal.searchBox.resetButtonTitle",message:"Clear the query",description:"The label and ARIA label for search box reset button"}),resetButtonAriaLabel:(0,l.I)({id:"theme.SearchModal.searchBox.resetButtonTitle",message:"Clear the query",description:"The label and ARIA label for search box reset button"}),cancelButtonText:(0,l.I)({id:"theme.SearchModal.searchBox.cancelButtonText",message:"Cancel",description:"The label and ARIA label for search box cancel button"}),cancelButtonAriaLabel:(0,l.I)({id:"theme.SearchModal.searchBox.cancelButtonText",message:"Cancel",description:"The label and ARIA label for search box cancel button"})},startScreen:{recentSearchesTitle:(0,l.I)({id:"theme.SearchModal.startScreen.recentSearchesTitle",message:"Recent",description:"The title for recent searches"}),noRecentSearchesText:(0,l.I)({id:"theme.SearchModal.startScreen.noRecentSearchesText",message:"No recent searches",description:"The text when no recent searches"}),saveRecentSearchButtonTitle:(0,l.I)({id:"theme.SearchModal.startScreen.saveRecentSearchButtonTitle",message:"Save this search",description:"The label for save recent search button"}),removeRecentSearchButtonTitle:(0,l.I)({id:"theme.SearchModal.startScreen.removeRecentSearchButtonTitle",message:"Remove this search from history",description:"The label for remove recent search button"}),favoriteSearchesTitle:(0,l.I)({id:"theme.SearchModal.startScreen.favoriteSearchesTitle",message:"Favorite",description:"The title for favorite searches"}),removeFavoriteSearchButtonTitle:(0,l.I)({id:"theme.SearchModal.startScreen.removeFavoriteSearchButtonTitle",message:"Remove this search from favorites",description:"The label for remove favorite search button"})},errorScreen:{titleText:(0,l.I)({id:"theme.SearchModal.errorScreen.titleText",message:"Unable to fetch results",description:"The title for error screen of search modal"}),helpText:(0,l.I)({id:"theme.SearchModal.errorScreen.helpText",message:"You might want to check your network connection.",description:"The help text for error screen of search modal"})},footer:{selectText:(0,l.I)({id:"theme.SearchModal.footer.selectText",message:"to select",description:"The explanatory text of the action for the enter key"}),selectKeyAriaLabel:(0,l.I)({id:"theme.SearchModal.footer.selectKeyAriaLabel",message:"Enter key",description:"The ARIA label for the Enter key button that makes the selection"}),navigateText:(0,l.I)({id:"theme.SearchModal.footer.navigateText",message:"to navigate",description:"The explanatory text of the action for the Arrow up and Arrow down key"}),navigateUpKeyAriaLabel:(0,l.I)({id:"theme.SearchModal.footer.navigateUpKeyAriaLabel",message:"Arrow up",description:"The ARIA label for the Arrow up key button that makes the navigation"}),navigateDownKeyAriaLabel:(0,l.I)({id:"theme.SearchModal.footer.navigateDownKeyAriaLabel",message:"Arrow down",description:"The ARIA label for the Arrow down key button that makes the navigation"}),closeText:(0,l.I)({id:"theme.SearchModal.footer.closeText",message:"to close",description:"The explanatory text of the action for Escape key"}),closeKeyAriaLabel:(0,l.I)({id:"theme.SearchModal.footer.closeKeyAriaLabel",message:"Escape key",description:"The ARIA label for the Escape key button that close the modal"}),searchByText:(0,l.I)({id:"theme.SearchModal.footer.searchByText",message:"Search by",description:"The text explain that the search is making by Algolia"})},noResultsScreen:{noResultsText:(0,l.I)({id:"theme.SearchModal.noResultsScreen.noResultsText",message:"No results for",description:"The text explains that there are no results for the following search"}),suggestedQueryText:(0,l.I)({id:"theme.SearchModal.noResultsScreen.suggestedQueryText",message:"Try searching for",description:"The text for the suggested query when no results are found for the following search"}),reportMissingResultsText:(0,l.I)({id:"theme.SearchModal.noResultsScreen.reportMissingResultsText",message:"Believe this query should return results?",description:"The text for the question where the user thinks there are missing results"}),reportMissingResultsLinkText:(0,l.I)({id:"theme.SearchModal.noResultsScreen.reportMissingResultsLinkText",message:"Let us know.",description:"The text for the link to report missing results"})}},placeholder:(0,l.I)({id:"theme.SearchModal.placeholder",message:"Search docs",description:"The placeholder of the input of the DocSearch pop-up modal"})};let Le=null;function Pe(e){let{hit:t,children:n}=e;return(0,u.jsx)(Q.Z,{to:t.url,children:n})}function Re(e){let{state:t,onClose:n}=e;const r=(0,Ce.M)();return(0,u.jsx)(Q.Z,{to:r(t.query),onClick:n,children:(0,u.jsx)(l.Z,{id:"theme.SearchBar.seeAll",values:{count:t.context.nbHits},children:"See all {count} results"})})}function Oe(e){let{contextualSearch:t,externalUrlRegex:a,...o}=e;const{siteMetadata:i}=(0,le.Z)(),l=(0,Te.l)(),c=function(){const{locale:e,tags:t}=(0,Ae._q)();return[`language:${e}`,t.map((e=>`docusaurus_tag:${e}`))]}(),d=o.searchParameters?.facetFilters??[],p=t?function(e,t){const n=e=>"string"==typeof e?[e]:e;return[...n(e),...n(t)]}(c,d):d,f={...o.searchParameters,facetFilters:p},g=(0,s.k6)(),h=(0,r.useRef)(null),m=(0,r.useRef)(null),[b,y]=(0,r.useState)(!1),[v,w]=(0,r.useState)(void 0),k=(0,r.useCallback)((()=>Le?Promise.resolve():Promise.all([n.e(1426).then(n.bind(n,61426)),Promise.all([n.e(532),n.e(6945)]).then(n.bind(n,46945)),Promise.all([n.e(532),n.e(8894)]).then(n.bind(n,18894))]).then((e=>{let[{DocSearchModal:t}]=e;Le=t}))),[]),x=(0,r.useCallback)((()=>{k().then((()=>{h.current=document.createElement("div"),document.body.insertBefore(h.current,document.body.firstChild),y(!0)}))}),[k,y]),S=(0,r.useCallback)((()=>{y(!1),h.current?.remove()}),[y]),_=(0,r.useCallback)((e=>{k().then((()=>{y(!0),w(e.key)}))}),[k,y,w]),E=(0,r.useRef)({navigate(e){let{itemUrl:t}=e;(0,ee.F)(a,t)?window.location.href=t:g.push(t)}}).current,C=(0,r.useRef)((e=>o.transformItems?o.transformItems(e):e.map((e=>({...e,url:l(e.url)}))))).current,T=(0,r.useMemo)((()=>e=>(0,u.jsx)(Re,{...e,onClose:S})),[S]),A=(0,r.useCallback)((e=>(e.addAlgoliaAgent("docusaurus",i.docusaurusVersion),e)),[i.docusaurusVersion]);return function(e){var t=e.isOpen,n=e.onOpen,a=e.onClose,o=e.onInput,i=e.searchButtonRef;r.useEffect((function(){function e(e){var r;(27===e.keyCode&&t||"k"===(null===(r=e.key)||void 0===r?void 0:r.toLowerCase())&&(e.metaKey||e.ctrlKey)||!function(e){var t=e.target,n=t.tagName;return t.isContentEditable||"INPUT"===n||"SELECT"===n||"TEXTAREA"===n}(e)&&"/"===e.key&&!t)&&(e.preventDefault(),t?a():document.body.classList.contains("DocSearch--active")||document.body.classList.contains("DocSearch--active")||n()),i&&i.current===document.activeElement&&o&&/[a-zA-Z0-9]/.test(String.fromCharCode(e.keyCode))&&o(e)}return window.addEventListener("keydown",e),function(){window.removeEventListener("keydown",e)}}),[t,n,a,o,i])}({isOpen:b,onOpen:x,onClose:S,onInput:_,searchButtonRef:m}),(0,u.jsxs)(u.Fragment,{children:[(0,u.jsx)(Ee.Z,{children:(0,u.jsx)("link",{rel:"preconnect",href:`https://${o.appId}-dsn.algolia.net`,crossOrigin:"anonymous"})}),(0,u.jsx)(_e,{onTouchStart:k,onFocus:k,onMouseOver:k,onClick:x,ref:m,translations:Ne.button}),b&&Le&&h.current&&(0,je.createPortal)((0,u.jsx)(Le,{onClose:S,initialScrollY:window.scrollY,initialQuery:v,navigator:E,transformItems:C,hitComponent:Pe,transformSearchClient:A,...o.searchPagePath&&{resultsFooterComponent:T},...o,searchParameters:f,placeholder:Ne.placeholder,translations:Ne.modal}),h.current)]})}function Ie(){const{siteConfig:e}=(0,le.Z)();return(0,u.jsx)(Oe,{...e.themeConfig.algolia})}const Fe={navbarSearchContainer:"navbarSearchContainer_Bca1"};function Me(e){let{children:t,className:n}=e;return(0,u.jsx)("div",{className:(0,a.Z)(n,Fe.navbarSearchContainer),children:t})}var De=n(80143),Be=n(53438);var ze=n(60373);const $e=e=>e.docs.find((t=>t.id===e.mainDocId));const Ue={default:oe,localeDropdown:function(e){let{mobile:t,dropdownItemsBefore:n,dropdownItemsAfter:r,queryString:a="",...o}=e;const{i18n:{currentLocale:i,locales:c,localeConfigs:d}}=(0,le.Z)(),p=(0,fe.l)(),{search:f,hash:g}=(0,s.TH)(),h=[...n,...c.map((e=>{const n=`${`pathname://${p.createUrl({locale:e,fullyQualified:!1})}`}${f}${g}${a}`;return{label:d[e].label,lang:d[e].htmlLang,to:n,target:"_self",autoAddBaseUrl:!1,className:e===i?t?"menu__link--active":"dropdown__link--active":""}})),...r],m=t?(0,l.I)({message:"Languages",id:"theme.navbar.mobileLanguageDropdown.label",description:"The label for the mobile language switcher dropdown"}):d[i].label;return(0,u.jsx)(pe,{...o,mobile:t,label:(0,u.jsxs)(u.Fragment,{children:[(0,u.jsx)(ge,{className:he}),m]}),items:h})},search:function(e){let{mobile:t,className:n}=e;return t?null:(0,u.jsx)(Me,{className:n,children:(0,u.jsx)(Ie,{})})},dropdown:pe,html:function(e){let{value:t,className:n,mobile:r=!1,isDropdownItem:o=!1}=e;const i=o?"li":"div";return(0,u.jsx)(i,{className:(0,a.Z)({navbar__item:!r&&!o,"menu__list-item":r},n),dangerouslySetInnerHTML:{__html:t}})},doc:function(e){let{docId:t,label:n,docsPluginId:r,...a}=e;const{activeDoc:o}=(0,De.Iw)(r),i=(0,Be.vY)(t,r),s=o?.path===i?.path;return null===i||i.unlisted&&!s?null:(0,u.jsx)(oe,{exact:!0,...a,isActive:()=>s||!!o?.sidebar&&o.sidebar===i.sidebar,label:n??i.id,to:i.path})},docSidebar:function(e){let{sidebarId:t,label:n,docsPluginId:r,...a}=e;const{activeDoc:o}=(0,De.Iw)(r),i=(0,Be.oz)(t,r).link;if(!i)throw new Error(`DocSidebarNavbarItem: Sidebar with ID "${t}" doesn't have anything to be linked to.`);return(0,u.jsx)(oe,{exact:!0,...a,isActive:()=>o?.sidebar===t,label:n??i.label,to:i.path})},docsVersion:function(e){let{label:t,to:n,docsPluginId:r,...a}=e;const o=(0,Be.lO)(r)[0],i=t??o.label,s=n??(e=>e.docs.find((t=>t.id===e.mainDocId)))(o).path;return(0,u.jsx)(oe,{...a,label:i,to:s})},docsVersionDropdown:function(e){let{mobile:t,docsPluginId:n,dropdownActiveClassDisabled:r,dropdownItemsBefore:a,dropdownItemsAfter:o,...i}=e;const{search:c,hash:d}=(0,s.TH)(),p=(0,De.Iw)(n),f=(0,De.gB)(n),{savePreferredVersionName:g}=(0,ze.J)(n),h=[...a,...f.map((e=>{const t=p.alternateDocVersions[e.name]??$e(e);return{label:e.label,to:`${t.path}${c}${d}`,isActive:()=>e===p.activeVersion,onClick:()=>g(e.name)}})),...o],m=(0,Be.lO)(n)[0],b=t&&h.length>1?(0,l.I)({id:"theme.navbar.mobileVersionsDropdown.label",message:"Versions",description:"The label for the navbar versions dropdown on mobile view"}):m.label,y=t&&h.length>1?void 0:$e(m).path;return h.length<=1?(0,u.jsx)(oe,{...i,mobile:t,label:b,to:y,isActive:r?()=>!1:void 0}):(0,u.jsx)(pe,{...i,mobile:t,label:b,to:y,items:h,isActive:r?()=>!1:void 0})}};function Ze(e){let{type:t,...n}=e;const r=function(e,t){return e&&"default"!==e?e:"items"in t?"dropdown":"default"}(t,n),a=Ue[r];if(!a)throw new Error(`No NavbarItem component found for type "${t}".`);return(0,u.jsx)(a,{...n})}function He(){const e=(0,j.e)(),t=(0,w.L)().navbar.items;return(0,u.jsx)("ul",{className:"menu__list",children:t.map(((t,n)=>(0,r.createElement)(Ze,{mobile:!0,...t,onClick:()=>e.toggle(),key:n})))})}function Ve(e){return(0,u.jsx)("button",{...e,type:"button",className:"clean-btn navbar-sidebar__back",children:(0,u.jsx)(l.Z,{id:"theme.navbar.mobileSidebarSecondaryMenu.backButtonLabel",description:"The label of the back button to return to main menu, inside the mobile navbar sidebar secondary menu (notably used to display the docs sidebar)",children:"\u2190 Back to main menu"})})}function We(){const e=0===(0,w.L)().navbar.items.length,t=F();return(0,u.jsxs)(u.Fragment,{children:[!e&&(0,u.jsx)(Ve,{onClick:()=>t.hide()}),t.content]})}function Ge(){const e=(0,j.e)();var t;return void 0===(t=e.shown)&&(t=!0),(0,r.useEffect)((()=>(document.body.style.overflow=t?"hidden":"visible",()=>{document.body.style.overflow="visible"})),[t]),e.shouldRender?(0,u.jsx)(M,{header:(0,u.jsx)(Y,{}),primaryMenu:(0,u.jsx)(He,{}),secondaryMenu:(0,u.jsx)(We,{})}):null}const qe={navbarHideable:"navbarHideable_m1mJ",navbarHidden:"navbarHidden_jGov"};function Ke(e){return(0,u.jsx)("div",{role:"presentation",...e,className:(0,a.Z)("navbar-sidebar__backdrop",e.className)})}function Ye(e){let{children:t}=e;const{navbar:{hideOnScroll:n,style:o}}=(0,w.L)(),i=(0,j.e)(),{navbarRef:s,isNavbarVisible:d}=function(e){const[t,n]=(0,r.useState)(e),a=(0,r.useRef)(!1),o=(0,r.useRef)(0),i=(0,r.useCallback)((e=>{null!==e&&(o.current=e.getBoundingClientRect().height)}),[]);return(0,N.RF)(((t,r)=>{let{scrollY:i}=t;if(!e)return;if(i=s?n(!1):i+c{if(!e)return;const r=t.location.hash;if(r?document.getElementById(r.substring(1)):void 0)return a.current=!0,void n(!1);n(!0)})),{navbarRef:i,isNavbarVisible:t}}(n);return(0,u.jsxs)("nav",{ref:s,"aria-label":(0,l.I)({id:"theme.NavBar.navAriaLabel",message:"Main",description:"The ARIA label for the main navigation"}),className:(0,a.Z)("navbar","navbar--fixed-top",n&&[qe.navbarHideable,!d&&qe.navbarHidden],{"navbar--dark":"dark"===o,"navbar--primary":"primary"===o,"navbar-sidebar--show":i.shown}),children:[t,(0,u.jsx)(Ke,{onClick:i.toggle}),(0,u.jsx)(Ge,{})]})}var Qe=n(69690);const Xe="right";function Je(e){let{width:t=30,height:n=30,className:r,...a}=e;return(0,u.jsx)("svg",{className:r,width:t,height:n,viewBox:"0 0 30 30","aria-hidden":"true",...a,children:(0,u.jsx)("path",{stroke:"currentColor",strokeLinecap:"round",strokeMiterlimit:"10",strokeWidth:"2",d:"M4 7h22M4 15h22M4 23h22"})})}function et(){const{toggle:e,shown:t}=(0,j.e)();return(0,u.jsx)("button",{onClick:e,"aria-label":(0,l.I)({id:"theme.docs.sidebar.toggleSidebarButtonAriaLabel",message:"Toggle navigation bar",description:"The ARIA label for hamburger menu button of mobile navigation"}),"aria-expanded":t,className:"navbar__toggle clean-btn",type:"button",children:(0,u.jsx)(Je,{})})}const tt={colorModeToggle:"colorModeToggle_DEke"};function nt(e){let{items:t}=e;return(0,u.jsx)(u.Fragment,{children:t.map(((e,t)=>(0,u.jsx)(Qe.QW,{onError:t=>new Error(`A theme navbar item failed to render.\nPlease double-check the following navbar item (themeConfig.navbar.items) of your Docusaurus config:\n${JSON.stringify(e,null,2)}`,{cause:t}),children:(0,u.jsx)(Ze,{...e})},t)))})}function rt(e){let{left:t,right:n}=e;return(0,u.jsxs)("div",{className:"navbar__inner",children:[(0,u.jsx)("div",{className:"navbar__items",children:t}),(0,u.jsx)("div",{className:"navbar__items navbar__items--right",children:n})]})}function at(){const e=(0,j.e)(),t=(0,w.L)().navbar.items,[n,r]=function(e){function t(e){return"left"===(e.position??Xe)}return[e.filter(t),e.filter((e=>!t(e)))]}(t),a=t.find((e=>"search"===e.type));return(0,u.jsx)(rt,{left:(0,u.jsxs)(u.Fragment,{children:[!e.disabled&&(0,u.jsx)(et,{}),(0,u.jsx)(q,{}),(0,u.jsx)(nt,{items:n})]}),right:(0,u.jsxs)(u.Fragment,{children:[(0,u.jsx)(nt,{items:r}),(0,u.jsx)(W,{className:tt.colorModeToggle}),!a&&(0,u.jsx)(Me,{children:(0,u.jsx)(Ie,{})})]})})}function ot(){return(0,u.jsx)(Ye,{children:(0,u.jsx)(at,{})})}function it(e){let{item:t}=e;const{to:n,href:r,label:a,prependBaseUrlToHref:o,...i}=t,s=(0,X.Z)(n),l=(0,X.Z)(r,{forcePrependBaseUrl:!0});return(0,u.jsxs)(Q.Z,{className:"footer__link-item",...r?{href:o?l:r}:{to:s},...i,children:[a,r&&!(0,J.Z)(r)&&(0,u.jsx)(te.Z,{})]})}function st(e){let{item:t}=e;return t.html?(0,u.jsx)("li",{className:"footer__item",dangerouslySetInnerHTML:{__html:t.html}}):(0,u.jsx)("li",{className:"footer__item",children:(0,u.jsx)(it,{item:t})},t.href??t.to)}function lt(e){let{column:t}=e;return(0,u.jsxs)("div",{className:"col footer__col",children:[(0,u.jsx)("div",{className:"footer__title",children:t.title}),(0,u.jsx)("ul",{className:"footer__items clean-list",children:t.items.map(((e,t)=>(0,u.jsx)(st,{item:e},t)))})]})}function ct(e){let{columns:t}=e;return(0,u.jsx)("div",{className:"row footer__links",children:t.map(((e,t)=>(0,u.jsx)(lt,{column:e},t)))})}function ut(){return(0,u.jsx)("span",{className:"footer__link-separator",children:"\xb7"})}function dt(e){let{item:t}=e;return t.html?(0,u.jsx)("span",{className:"footer__link-item",dangerouslySetInnerHTML:{__html:t.html}}):(0,u.jsx)(it,{item:t})}function pt(e){let{links:t}=e;return(0,u.jsx)("div",{className:"footer__links text--center",children:(0,u.jsx)("div",{className:"footer__links",children:t.map(((e,n)=>(0,u.jsxs)(r.Fragment,{children:[(0,u.jsx)(dt,{item:e}),t.length!==n+1&&(0,u.jsx)(ut,{})]},n)))})})}function ft(e){let{links:t}=e;return function(e){return"title"in e[0]}(t)?(0,u.jsx)(ct,{columns:t}):(0,u.jsx)(pt,{links:t})}var gt=n(19965);const ht={footerLogoLink:"footerLogoLink_BH7S"};function mt(e){let{logo:t}=e;const{withBaseUrl:n}=(0,X.C)(),r={light:n(t.src),dark:n(t.srcDark??t.src)};return(0,u.jsx)(gt.Z,{className:(0,a.Z)("footer__logo",t.className),alt:t.alt,sources:r,width:t.width,height:t.height,style:t.style})}function bt(e){let{logo:t}=e;return t.href?(0,u.jsx)(Q.Z,{href:t.href,className:ht.footerLogoLink,target:t.target,children:(0,u.jsx)(mt,{logo:t})}):(0,u.jsx)(mt,{logo:t})}function yt(e){let{copyright:t}=e;return(0,u.jsx)("div",{className:"footer__copyright",dangerouslySetInnerHTML:{__html:t}})}function vt(e){let{style:t,links:n,logo:r,copyright:o}=e;return(0,u.jsx)("footer",{className:(0,a.Z)("footer",{"footer--dark":"dark"===t}),children:(0,u.jsxs)("div",{className:"container container-fluid",children:[n,(r||o)&&(0,u.jsxs)("div",{className:"footer__bottom text--center",children:[r&&(0,u.jsx)("div",{className:"margin-bottom--sm",children:r}),o]})]})})}function wt(){const{footer:e}=(0,w.L)();if(!e)return null;const{copyright:t,links:n,logo:r,style:a}=e;return(0,u.jsx)(vt,{style:a,links:n&&n.length>0&&(0,u.jsx)(ft,{links:n}),logo:r&&(0,u.jsx)(bt,{logo:r}),copyright:t&&(0,u.jsx)(yt,{copyright:t})})}const kt=r.memo(wt),xt=(0,L.Qc)([D.S,k.pl,N.OC,ze.L5,i.VC,function(e){let{children:t}=e;return(0,u.jsx)(P.n2,{children:(0,u.jsx)(j.M,{children:(0,u.jsx)(O,{children:t})})})}]);function St(e){let{children:t}=e;return(0,u.jsx)(xt,{children:t})}var _t=n(92503);function Et(e){let{error:t,tryAgain:n}=e;return(0,u.jsx)("main",{className:"container margin-vert--xl",children:(0,u.jsx)("div",{className:"row",children:(0,u.jsxs)("div",{className:"col col--6 col--offset-3",children:[(0,u.jsx)(_t.Z,{as:"h1",className:"hero__title",children:(0,u.jsx)(l.Z,{id:"theme.ErrorPageContent.title",description:"The title of the fallback page when the page crashed",children:"This page crashed."})}),(0,u.jsx)("div",{className:"margin-vert--lg",children:(0,u.jsx)(Qe.Cw,{onClick:n,className:"button button--primary shadow--lw"})}),(0,u.jsx)("hr",{}),(0,u.jsx)("div",{className:"margin-vert--md",children:(0,u.jsx)(Qe.aG,{error:t})})]})})})}const Ct={mainWrapper:"mainWrapper_z2l0"};function Tt(e){const{children:t,noFooter:n,wrapperClassName:r,title:s,description:l}=e;return(0,b.t)(),(0,u.jsxs)(St,{children:[(0,u.jsx)(i.d,{title:s,description:l}),(0,u.jsx)(v,{}),(0,u.jsx)(A,{}),(0,u.jsx)(ot,{}),(0,u.jsx)("div",{id:d,className:(0,a.Z)(m.k.wrapper.main,Ct.mainWrapper,r),children:(0,u.jsx)(o.Z,{fallback:e=>(0,u.jsx)(Et,{...e}),children:t})}),!n&&(0,u.jsx)(kt,{})]})}},21327:(e,t,n)=>{"use strict";n.d(t,{Z:()=>u});n(67294);var r=n(39960),a=n(44996),o=n(52263),i=n(86668),s=n(19965),l=n(85893);function c(e){let{logo:t,alt:n,imageClassName:r}=e;const o={light:(0,a.Z)(t.src),dark:(0,a.Z)(t.srcDark||t.src)},i=(0,l.jsx)(s.Z,{className:t.className,sources:o,height:t.height,width:t.width,alt:n,style:t.style});return r?(0,l.jsx)("div",{className:r,children:i}):i}function u(e){const{siteConfig:{title:t}}=(0,o.Z)(),{navbar:{title:n,logo:s}}=(0,i.L)(),{imageClassName:u,titleClassName:d,...p}=e,f=(0,a.Z)(s?.href||"/"),g=n?"":t,h=s?.alt??g;return(0,l.jsxs)(r.Z,{to:f,...p,...s?.target&&{target:s.target},children:[s&&(0,l.jsx)(c,{logo:s,alt:h,imageClassName:u}),null!=n&&(0,l.jsx)("b",{className:d,children:n})]})}},90197:(e,t,n)=>{"use strict";n.d(t,{Z:()=>o});n(67294);var r=n(35742),a=n(85893);function o(e){let{locale:t,version:n,tag:o}=e;const i=t;return(0,a.jsxs)(r.Z,{children:[t&&(0,a.jsx)("meta",{name:"docusaurus_locale",content:t}),n&&(0,a.jsx)("meta",{name:"docusaurus_version",content:n}),o&&(0,a.jsx)("meta",{name:"docusaurus_tag",content:o}),i&&(0,a.jsx)("meta",{name:"docsearch:language",content:i}),n&&(0,a.jsx)("meta",{name:"docsearch:version",content:n}),o&&(0,a.jsx)("meta",{name:"docsearch:docusaurus_tag",content:o})]})}},19965:(e,t,n)=>{"use strict";n.d(t,{Z:()=>u});var r=n(67294),a=n(86010),o=n(72389),i=n(92949);const s={themedComponent:"themedComponent_mlkZ","themedComponent--light":"themedComponent--light_NVdE","themedComponent--dark":"themedComponent--dark_xIcU"};var l=n(85893);function c(e){let{className:t,children:n}=e;const c=(0,o.Z)(),{colorMode:u}=(0,i.I)();return(0,l.jsx)(l.Fragment,{children:(c?"dark"===u?["dark"]:["light"]:["light","dark"]).map((e=>{const o=n({theme:e,className:(0,a.Z)(t,s.themedComponent,s[`themedComponent--${e}`])});return(0,l.jsx)(r.Fragment,{children:o},e)}))})}function u(e){const{sources:t,className:n,alt:r,...a}=e;return(0,l.jsx)(c,{className:n,children:e=>{let{theme:n,className:o}=e;return(0,l.jsx)("img",{src:t[n],alt:r,className:o,...a})}})}},86043:(e,t,n)=>{"use strict";n.d(t,{u:()=>c,z:()=>b});var r=n(67294),a=n(10412),o=n(20469),i=n(91442),s=n(85893);const l="ease-in-out";function c(e){let{initialState:t}=e;const[n,a]=(0,r.useState)(t??!1),o=(0,r.useCallback)((()=>{a((e=>!e))}),[]);return{collapsed:n,setCollapsed:a,toggleCollapsed:o}}const u={display:"none",overflow:"hidden",height:"0px"},d={display:"block",overflow:"visible",height:"auto"};function p(e,t){const n=t?u:d;e.style.display=n.display,e.style.overflow=n.overflow,e.style.height=n.height}function f(e){let{collapsibleRef:t,collapsed:n,animation:a}=e;const o=(0,r.useRef)(!1);(0,r.useEffect)((()=>{const e=t.current;function r(){const t=e.scrollHeight,n=a?.duration??function(e){if((0,i.n)())return 1;const t=e/36;return Math.round(10*(4+15*t**.25+t/5))}(t);return{transition:`height ${n}ms ${a?.easing??l}`,height:`${t}px`}}function s(){const t=r();e.style.transition=t.transition,e.style.height=t.height}if(!o.current)return p(e,n),void(o.current=!0);return e.style.willChange="height",function(){const t=requestAnimationFrame((()=>{n?(s(),requestAnimationFrame((()=>{e.style.height=u.height,e.style.overflow=u.overflow}))):(e.style.display="block",requestAnimationFrame((()=>{s()})))}));return()=>cancelAnimationFrame(t)}()}),[t,n,a])}function g(e){if(!a.Z.canUseDOM)return e?u:d}function h(e){let{as:t="div",collapsed:n,children:a,animation:o,onCollapseTransitionEnd:i,className:l,disableSSRStyle:c}=e;const u=(0,r.useRef)(null);return f({collapsibleRef:u,collapsed:n,animation:o}),(0,s.jsx)(t,{ref:u,style:c?void 0:g(n),onTransitionEnd:e=>{"height"===e.propertyName&&(p(u.current,n),i?.(n))},className:l,children:a})}function m(e){let{collapsed:t,...n}=e;const[a,i]=(0,r.useState)(!t),[l,c]=(0,r.useState)(t);return(0,o.Z)((()=>{t||i(!0)}),[t]),(0,o.Z)((()=>{a&&c(t)}),[a,t]),a?(0,s.jsx)(h,{...n,collapsed:l}):null}function b(e){let{lazy:t,...n}=e;const r=t?m:h;return(0,s.jsx)(r,{...n})}},59689:(e,t,n)=>{"use strict";n.d(t,{nT:()=>h,pl:()=>g});var r=n(67294),a=n(72389),o=n(50012),i=n(902),s=n(86668),l=n(85893);const c=(0,o.WA)("docusaurus.announcement.dismiss"),u=(0,o.WA)("docusaurus.announcement.id"),d=()=>"true"===c.get(),p=e=>c.set(String(e)),f=r.createContext(null);function g(e){let{children:t}=e;const n=function(){const{announcementBar:e}=(0,s.L)(),t=(0,a.Z)(),[n,o]=(0,r.useState)((()=>!!t&&d()));(0,r.useEffect)((()=>{o(d())}),[]);const i=(0,r.useCallback)((()=>{p(!0),o(!0)}),[]);return(0,r.useEffect)((()=>{if(!e)return;const{id:t}=e;let n=u.get();"annoucement-bar"===n&&(n="announcement-bar");const r=t!==n;u.set(t),r&&p(!1),!r&&d()||o(!1)}),[e]),(0,r.useMemo)((()=>({isActive:!!e&&!n,close:i})),[e,n,i])}();return(0,l.jsx)(f.Provider,{value:n,children:t})}function h(){const e=(0,r.useContext)(f);if(!e)throw new i.i6("AnnouncementBarProvider");return e}},92949:(e,t,n)=>{"use strict";n.d(t,{I:()=>b,S:()=>m});var r=n(67294),a=n(10412),o=n(902),i=n(50012),s=n(86668),l=n(85893);const c=r.createContext(void 0),u="theme",d=(0,i.WA)(u),p={light:"light",dark:"dark"},f=e=>e===p.dark?p.dark:p.light,g=e=>a.Z.canUseDOM?f(document.documentElement.getAttribute("data-theme")):f(e),h=e=>{d.set(f(e))};function m(e){let{children:t}=e;const n=function(){const{colorMode:{defaultMode:e,disableSwitch:t,respectPrefersColorScheme:n}}=(0,s.L)(),[a,o]=(0,r.useState)(g(e));(0,r.useEffect)((()=>{t&&d.del()}),[t]);const i=(0,r.useCallback)((function(t,r){void 0===r&&(r={});const{persist:a=!0}=r;t?(o(t),a&&h(t)):(o(n?window.matchMedia("(prefers-color-scheme: dark)").matches?p.dark:p.light:e),d.del())}),[n,e]);(0,r.useEffect)((()=>{document.documentElement.setAttribute("data-theme",f(a))}),[a]),(0,r.useEffect)((()=>{if(t)return;const e=e=>{if(e.key!==u)return;const t=d.get();null!==t&&i(f(t))};return window.addEventListener("storage",e),()=>window.removeEventListener("storage",e)}),[t,i]);const l=(0,r.useRef)(!1);return(0,r.useEffect)((()=>{if(t&&!n)return;const e=window.matchMedia("(prefers-color-scheme: dark)"),r=()=>{window.matchMedia("print").matches||l.current?l.current=window.matchMedia("print").matches:i(null)};return e.addListener(r),()=>e.removeListener(r)}),[i,t,n]),(0,r.useMemo)((()=>({colorMode:a,setColorMode:i,get isDarkTheme(){return a===p.dark},setLightTheme(){i(p.light)},setDarkTheme(){i(p.dark)}})),[a,i])}();return(0,l.jsx)(c.Provider,{value:n,children:t})}function b(){const e=(0,r.useContext)(c);if(null==e)throw new o.i6("ColorModeProvider","Please see https://docusaurus.io/docs/api/themes/configuration#use-color-mode.");return e}},60373:(e,t,n)=>{"use strict";n.d(t,{J:()=>v,L5:()=>b,Oh:()=>w});var r=n(67294),a=n(80143),o=n(29935),i=n(86668),s=n(53438),l=n(902),c=n(50012),u=n(85893);const d=e=>`docs-preferred-version-${e}`,p={save:(e,t,n)=>{(0,c.WA)(d(e),{persistence:t}).set(n)},read:(e,t)=>(0,c.WA)(d(e),{persistence:t}).get(),clear:(e,t)=>{(0,c.WA)(d(e),{persistence:t}).del()}},f=e=>Object.fromEntries(e.map((e=>[e,{preferredVersionName:null}])));const g=r.createContext(null);function h(){const e=(0,a._r)(),t=(0,i.L)().docs.versionPersistence,n=(0,r.useMemo)((()=>Object.keys(e)),[e]),[o,s]=(0,r.useState)((()=>f(n)));(0,r.useEffect)((()=>{s(function(e){let{pluginIds:t,versionPersistence:n,allDocsData:r}=e;function a(e){const t=p.read(e,n);return r[e].versions.some((e=>e.name===t))?{preferredVersionName:t}:(p.clear(e,n),{preferredVersionName:null})}return Object.fromEntries(t.map((e=>[e,a(e)])))}({allDocsData:e,versionPersistence:t,pluginIds:n}))}),[e,t,n]);return[o,(0,r.useMemo)((()=>({savePreferredVersion:function(e,n){p.save(e,t,n),s((t=>({...t,[e]:{preferredVersionName:n}})))}})),[t])]}function m(e){let{children:t}=e;const n=h();return(0,u.jsx)(g.Provider,{value:n,children:t})}function b(e){let{children:t}=e;return s.cE?(0,u.jsx)(m,{children:t}):(0,u.jsx)(u.Fragment,{children:t})}function y(){const e=(0,r.useContext)(g);if(!e)throw new l.i6("DocsPreferredVersionContextProvider");return e}function v(e){void 0===e&&(e=o.m);const t=(0,a.zh)(e),[n,i]=y(),{preferredVersionName:s}=n[e];return{preferredVersion:t.versions.find((e=>e.name===s))??null,savePreferredVersionName:(0,r.useCallback)((t=>{i.savePreferredVersion(e,t)}),[i,e])}}function w(){const e=(0,a._r)(),[t]=y();function n(n){const r=e[n],{preferredVersionName:a}=t[n];return r.versions.find((e=>e.name===a))??null}const r=Object.keys(e);return Object.fromEntries(r.map((e=>[e,n(e)])))}},1116:(e,t,n)=>{"use strict";n.d(t,{V:()=>c,b:()=>l});var r=n(67294),a=n(902),o=n(85893);const i=Symbol("EmptyContext"),s=r.createContext(i);function l(e){let{children:t,name:n,items:a}=e;const i=(0,r.useMemo)((()=>n&&a?{name:n,items:a}:null),[n,a]);return(0,o.jsx)(s.Provider,{value:i,children:t})}function c(){const e=(0,r.useContext)(s);if(e===i)throw new a.i6("DocsSidebarProvider");return e}},74477:(e,t,n)=>{"use strict";n.d(t,{E:()=>l,q:()=>s});var r=n(67294),a=n(902),o=n(85893);const i=r.createContext(null);function s(e){let{children:t,version:n}=e;return(0,o.jsx)(i.Provider,{value:n,children:t})}function l(){const e=(0,r.useContext)(i);if(null===e)throw new a.i6("DocsVersionProvider");return e}},93163:(e,t,n)=>{"use strict";n.d(t,{M:()=>p,e:()=>f});var r=n(67294),a=n(13102),o=n(87524),i=n(91980),s=n(86668),l=n(902),c=n(85893);const u=r.createContext(void 0);function d(){const e=function(){const e=(0,a.HY)(),{items:t}=(0,s.L)().navbar;return 0===t.length&&!e.component}(),t=(0,o.i)(),n=!e&&"mobile"===t,[l,c]=(0,r.useState)(!1);(0,i.Rb)((()=>{if(l)return c(!1),!1}));const u=(0,r.useCallback)((()=>{c((e=>!e))}),[]);return(0,r.useEffect)((()=>{"desktop"===t&&c(!1)}),[t]),(0,r.useMemo)((()=>({disabled:e,shouldRender:n,toggle:u,shown:l})),[e,n,u,l])}function p(e){let{children:t}=e;const n=d();return(0,c.jsx)(u.Provider,{value:n,children:t})}function f(){const e=r.useContext(u);if(void 0===e)throw new l.i6("NavbarMobileSidebarProvider");return e}},13102:(e,t,n)=>{"use strict";n.d(t,{HY:()=>l,Zo:()=>c,n2:()=>s});var r=n(67294),a=n(902),o=n(85893);const i=r.createContext(null);function s(e){let{children:t}=e;const n=(0,r.useState)({component:null,props:null});return(0,o.jsx)(i.Provider,{value:n,children:t})}function l(){const e=(0,r.useContext)(i);if(!e)throw new a.i6("NavbarSecondaryMenuContentProvider");return e[0]}function c(e){let{component:t,props:n}=e;const o=(0,r.useContext)(i);if(!o)throw new a.i6("NavbarSecondaryMenuContentProvider");const[,s]=o,l=(0,a.Ql)(n);return(0,r.useEffect)((()=>{s({component:t,props:l})}),[s,t,l]),(0,r.useEffect)((()=>()=>s({component:null,props:null})),[s]),null}},19727:(e,t,n)=>{"use strict";n.d(t,{h:()=>a,t:()=>o});var r=n(67294);const a="navigation-with-keyboard";function o(){(0,r.useEffect)((()=>{function e(e){"keydown"===e.type&&"Tab"===e.key&&document.body.classList.add(a),"mousedown"===e.type&&document.body.classList.remove(a)}return document.addEventListener("keydown",e),document.addEventListener("mousedown",e),()=>{document.body.classList.remove(a),document.removeEventListener("keydown",e),document.removeEventListener("mousedown",e)}}),[])}},66177:(e,t,n)=>{"use strict";n.d(t,{K:()=>s,M:()=>l});var r=n(67294),a=n(52263),o=n(91980);const i="q";function s(){return(0,o.Nc)(i)}function l(){const{siteConfig:{baseUrl:e,themeConfig:t}}=(0,a.Z)(),{algolia:{searchPagePath:n}}=t;return(0,r.useCallback)((t=>`${e}${n}?${i}=${encodeURIComponent(t)}`),[e,n])}},87524:(e,t,n)=>{"use strict";n.d(t,{i:()=>s});var r=n(67294),a=n(10412);const o={desktop:"desktop",mobile:"mobile",ssr:"ssr"},i=996;function s(){const[e,t]=(0,r.useState)((()=>"ssr"));return(0,r.useEffect)((()=>{function e(){t(function(){if(!a.Z.canUseDOM)throw new Error("getWindowSize() should only be called after React hydration");return window.innerWidth>i?o.desktop:o.mobile}())}return e(),window.addEventListener("resize",e),()=>{window.removeEventListener("resize",e)}}),[]),e}},35281:(e,t,n)=>{"use strict";n.d(t,{k:()=>r});const r={page:{blogListPage:"blog-list-page",blogPostPage:"blog-post-page",blogTagsListPage:"blog-tags-list-page",blogTagPostListPage:"blog-tags-post-list-page",docsDocPage:"docs-doc-page",docsTagsListPage:"docs-tags-list-page",docsTagDocListPage:"docs-tags-doc-list-page",mdxPage:"mdx-page"},wrapper:{main:"main-wrapper",blogPages:"blog-wrapper",docsPages:"docs-wrapper",mdxPages:"mdx-wrapper"},common:{editThisPage:"theme-edit-this-page",lastUpdated:"theme-last-updated",backToTopButton:"theme-back-to-top-button",codeBlock:"theme-code-block",admonition:"theme-admonition",unlistedBanner:"theme-unlisted-banner",admonitionType:e=>`theme-admonition-${e}`},layout:{},docs:{docVersionBanner:"theme-doc-version-banner",docVersionBadge:"theme-doc-version-badge",docBreadcrumbs:"theme-doc-breadcrumbs",docMarkdown:"theme-doc-markdown",docTocMobile:"theme-doc-toc-mobile",docTocDesktop:"theme-doc-toc-desktop",docFooter:"theme-doc-footer",docFooterTagsRow:"theme-doc-footer-tags-row",docFooterEditMetaRow:"theme-doc-footer-edit-meta-row",docSidebarContainer:"theme-doc-sidebar-container",docSidebarMenu:"theme-doc-sidebar-menu",docSidebarItemCategory:"theme-doc-sidebar-item-category",docSidebarItemLink:"theme-doc-sidebar-item-link",docSidebarItemCategoryLevel:e=>`theme-doc-sidebar-item-category-level-${e}`,docSidebarItemLinkLevel:e=>`theme-doc-sidebar-item-link-level-${e}`},blog:{}}},91442:(e,t,n)=>{"use strict";function r(){return window.matchMedia("(prefers-reduced-motion: reduce)").matches}n.d(t,{n:()=>r})},53438:(e,t,n)=>{"use strict";n.d(t,{LM:()=>g,MN:()=>T,SN:()=>C,_F:()=>y,cE:()=>p,f:()=>w,jA:()=>h,lO:()=>S,oz:()=>_,s1:()=>x,vY:()=>E,xz:()=>f});var r=n(67294),a=n(16550),o=n(18790),i=n(80143),s=n(60373),l=n(74477),c=n(1116),u=n(67392),d=n(48596);const p=!!i._r;function f(e){const t=(0,l.E)();if(!e)return;const n=t.docs[e];if(!n)throw new Error(`no version doc found by id=${e}`);return n}function g(e){return"link"!==e.type||e.unlisted?"category"===e.type?function(e){if(e.href&&!e.linkUnlisted)return e.href;for(const t of e.items){const e=g(t);if(e)return e}}(e):void 0:e.href}function h(){const{pathname:e}=(0,a.TH)(),t=(0,c.V)();if(!t)throw new Error("Unexpected: cant find current sidebar in context");const n=k({sidebarItems:t.items,pathname:e,onlyCategories:!0}).slice(-1)[0];if(!n)throw new Error(`${e} is not associated with a category. useCurrentSidebarCategory() should only be used on category index pages.`);return n}const m=(e,t)=>void 0!==e&&(0,d.Mg)(e,t),b=(e,t)=>e.some((e=>y(e,t)));function y(e,t){return"link"===e.type?m(e.href,t):"category"===e.type&&(m(e.href,t)||b(e.items,t))}function v(e,t){switch(e.type){case"category":return y(e,t)||e.items.some((e=>v(e,t)));case"link":return!e.unlisted||y(e,t);default:return!1}}function w(e,t){return(0,r.useMemo)((()=>e.filter((e=>v(e,t)))),[e,t])}function k(e){let{sidebarItems:t,pathname:n,onlyCategories:r=!1}=e;const a=[];return function e(t){for(const o of t)if("category"===o.type&&((0,d.Mg)(o.href,n)||e(o.items))||"link"===o.type&&(0,d.Mg)(o.href,n)){return r&&"category"!==o.type||a.unshift(o),!0}return!1}(t),a}function x(){const e=(0,c.V)(),{pathname:t}=(0,a.TH)(),n=(0,i.gA)()?.pluginData.breadcrumbs;return!1!==n&&e?k({sidebarItems:e.items,pathname:t}):null}function S(e){const{activeVersion:t}=(0,i.Iw)(e),{preferredVersion:n}=(0,s.J)(e),a=(0,i.yW)(e);return(0,r.useMemo)((()=>(0,u.j)([t,n,a].filter(Boolean))),[t,n,a])}function _(e,t){const n=S(t);return(0,r.useMemo)((()=>{const t=n.flatMap((e=>e.sidebars?Object.entries(e.sidebars):[])),r=t.find((t=>t[0]===e));if(!r)throw new Error(`Can't find any sidebar with id "${e}" in version${n.length>1?"s":""} ${n.map((e=>e.name)).join(", ")}".\nAvailable sidebar ids are:\n- ${t.map((e=>e[0])).join("\n- ")}`);return r[1]}),[e,n])}function E(e,t){const n=S(t);return(0,r.useMemo)((()=>{const t=n.flatMap((e=>e.docs)),r=t.find((t=>t.id===e));if(!r){if(n.flatMap((e=>e.draftIds)).includes(e))return null;throw new Error(`Couldn't find any doc with id "${e}" in version${n.length>1?"s":""} "${n.map((e=>e.name)).join(", ")}".\nAvailable doc ids are:\n- ${(0,u.j)(t.map((e=>e.id))).join("\n- ")}`)}return r}),[e,n])}function C(e){let{route:t}=e;const n=(0,a.TH)(),r=(0,l.E)(),i=t.routes,s=i.find((e=>(0,a.LX)(n.pathname,e)));if(!s)return null;const c=s.sidebar,u=c?r.docsSidebars[c]:void 0;return{docElement:(0,o.H)(i),sidebarName:c,sidebarItems:u}}function T(e){return e.filter((e=>!("category"===e.type||"link"===e.type)||!!g(e)))}},69690:(e,t,n)=>{"use strict";n.d(t,{aG:()=>u,Ac:()=>c,Cw:()=>l,QW:()=>d});var r=n(67294),a=n(95999),o=n(18780);const i={errorBoundaryError:"errorBoundaryError_a6uf",errorBoundaryFallback:"errorBoundaryFallback_VBag"};var s=n(85893);function l(e){return(0,s.jsx)("button",{type:"button",...e,children:(0,s.jsx)(a.Z,{id:"theme.ErrorPageContent.tryAgain",description:"The label of the button to try again rendering when the React error boundary captures an error",children:"Try again"})})}function c(e){let{error:t,tryAgain:n}=e;return(0,s.jsxs)("div",{className:i.errorBoundaryFallback,children:[(0,s.jsx)("p",{children:t.message}),(0,s.jsx)(l,{onClick:n})]})}function u(e){let{error:t}=e;const n=(0,o.getErrorCausalChain)(t).map((e=>e.message)).join("\n\nCause:\n");return(0,s.jsx)("p",{className:i.errorBoundaryError,children:n})}class d extends r.Component{componentDidCatch(e,t){throw this.props.onError(e,t)}render(){return this.props.children}}},82128:(e,t,n)=>{"use strict";n.d(t,{p:()=>a});var r=n(52263);function a(e){const{siteConfig:t}=(0,r.Z)(),{title:n,titleDelimiter:a}=t;return e?.trim().length?`${e.trim()} ${a} ${n}`:n}},91980:(e,t,n)=>{"use strict";n.d(t,{Nc:()=>l,Rb:()=>i,_X:()=>s});var r=n(67294),a=n(16550),o=n(902);function i(e){!function(e){const t=(0,a.k6)(),n=(0,o.zX)(e);(0,r.useEffect)((()=>t.block(((e,t)=>n(e,t)))),[t,n])}(((t,n)=>{if("POP"===n)return e(t,n)}))}function s(e){return function(e){const t=(0,a.k6)();return(0,r.useSyncExternalStore)(t.listen,(()=>e(t)),(()=>e(t)))}((t=>null===e?null:new URLSearchParams(t.location.search).get(e)))}function l(e){const t=s(e)??"",n=function(){const e=(0,a.k6)();return(0,r.useCallback)(((t,n,r)=>{const a=new URLSearchParams(e.location.search);n?a.set(t,n):a.delete(t),(r?.push?e.push:e.replace)({search:a.toString()})}),[e])}();return[t,(0,r.useCallback)(((t,r)=>{n(e,t,r)}),[n,e])]}},67392:(e,t,n)=>{"use strict";function r(e,t){return void 0===t&&(t=(e,t)=>e===t),e.filter(((n,r)=>e.findIndex((e=>t(e,n)))!==r))}function a(e){return Array.from(new Set(e))}n.d(t,{j:()=>a,l:()=>r})},10833:(e,t,n)=>{"use strict";n.d(t,{FG:()=>f,d:()=>d,VC:()=>g});var r=n(67294),a=n(86010),o=n(35742),i=n(30226);function s(){const e=r.useContext(i._);if(!e)throw new Error("Unexpected: no Docusaurus route context found");return e}var l=n(44996),c=n(82128),u=n(85893);function d(e){let{title:t,description:n,keywords:r,image:a,children:i}=e;const s=(0,c.p)(t),{withBaseUrl:d}=(0,l.C)(),p=a?d(a,{absolute:!0}):void 0;return(0,u.jsxs)(o.Z,{children:[t&&(0,u.jsx)("title",{children:s}),t&&(0,u.jsx)("meta",{property:"og:title",content:s}),n&&(0,u.jsx)("meta",{name:"description",content:n}),n&&(0,u.jsx)("meta",{property:"og:description",content:n}),r&&(0,u.jsx)("meta",{name:"keywords",content:Array.isArray(r)?r.join(","):r}),p&&(0,u.jsx)("meta",{property:"og:image",content:p}),p&&(0,u.jsx)("meta",{name:"twitter:image",content:p}),i]})}const p=r.createContext(void 0);function f(e){let{className:t,children:n}=e;const i=r.useContext(p),s=(0,a.Z)(i,t);return(0,u.jsxs)(p.Provider,{value:s,children:[(0,u.jsx)(o.Z,{children:(0,u.jsx)("html",{className:s})}),n]})}function g(e){let{children:t}=e;const n=s(),r=`plugin-${n.plugin.name.replace(/docusaurus-(?:plugin|theme)-(?:content-)?/gi,"")}`;const o=`plugin-id-${n.plugin.id}`;return(0,u.jsx)(f,{className:(0,a.Z)(r,o),children:t})}},902:(e,t,n)=>{"use strict";n.d(t,{D9:()=>s,Qc:()=>u,Ql:()=>c,i6:()=>l,zX:()=>i});var r=n(67294),a=n(20469),o=n(85893);function i(e){const t=(0,r.useRef)(e);return(0,a.Z)((()=>{t.current=e}),[e]),(0,r.useCallback)((function(){return t.current(...arguments)}),[])}function s(e){const t=(0,r.useRef)();return(0,a.Z)((()=>{t.current=e})),t.current}class l extends Error{constructor(e,t){super(),this.name="ReactContextError",this.message=`Hook ${this.stack?.split("\n")[1]?.match(/at (?:\w+\.)?(?\w+)/)?.groups.name??""} is called outside the <${e}>. ${t??""}`}}function c(e){const t=Object.entries(e);return t.sort(((e,t)=>e[0].localeCompare(t[0]))),(0,r.useMemo)((()=>e),t.flat())}function u(e){return t=>{let{children:n}=t;return(0,o.jsx)(o.Fragment,{children:e.reduceRight(((e,t)=>(0,o.jsx)(t,{children:e})),n)})}}},98022:(e,t,n)=>{"use strict";function r(e,t){return void 0!==e&&void 0!==t&&new RegExp(e,"gi").test(t)}n.d(t,{F:()=>r})},48596:(e,t,n)=>{"use strict";n.d(t,{Mg:()=>i,Ns:()=>s});var r=n(67294),a=n(723),o=n(52263);function i(e,t){const n=e=>(!e||e.endsWith("/")?e:`${e}/`)?.toLowerCase();return n(e)===n(t)}function s(){const{baseUrl:e}=(0,o.Z)().siteConfig;return(0,r.useMemo)((()=>function(e){let{baseUrl:t,routes:n}=e;function r(e){return e.path===t&&!0===e.exact}function a(e){return e.path===t&&!e.exact}return function e(t){if(0===t.length)return;return t.find(r)||e(t.filter(a).flatMap((e=>e.routes??[])))}(n)}({routes:a.Z,baseUrl:e})),[e])}},12466:(e,t,n)=>{"use strict";n.d(t,{Ct:()=>h,OC:()=>u,RF:()=>f,o5:()=>g});var r=n(67294),a=n(10412),o=n(72389),i=n(20469),s=n(902),l=n(85893);const c=r.createContext(void 0);function u(e){let{children:t}=e;const n=function(){const e=(0,r.useRef)(!0);return(0,r.useMemo)((()=>({scrollEventsEnabledRef:e,enableScrollEvents:()=>{e.current=!0},disableScrollEvents:()=>{e.current=!1}})),[])}();return(0,l.jsx)(c.Provider,{value:n,children:t})}function d(){const e=(0,r.useContext)(c);if(null==e)throw new s.i6("ScrollControllerProvider");return e}const p=()=>a.Z.canUseDOM?{scrollX:window.pageXOffset,scrollY:window.pageYOffset}:null;function f(e,t){void 0===t&&(t=[]);const{scrollEventsEnabledRef:n}=d(),a=(0,r.useRef)(p()),o=(0,s.zX)(e);(0,r.useEffect)((()=>{const e=()=>{if(!n.current)return;const e=p();o(e,a.current),a.current=e},t={passive:!0};return e(),window.addEventListener("scroll",e,t),()=>window.removeEventListener("scroll",e,t)}),[o,n,...t])}function g(){const e=d(),t=function(){const e=(0,r.useRef)({elem:null,top:0}),t=(0,r.useCallback)((t=>{e.current={elem:t,top:t.getBoundingClientRect().top}}),[]),n=(0,r.useCallback)((()=>{const{current:{elem:t,top:n}}=e;if(!t)return{restored:!1};const r=t.getBoundingClientRect().top-n;return r&&window.scrollBy({left:0,top:r}),e.current={elem:null,top:0},{restored:0!==r}}),[]);return(0,r.useMemo)((()=>({save:t,restore:n})),[n,t])}(),n=(0,r.useRef)(void 0),a=(0,r.useCallback)((r=>{t.save(r),e.disableScrollEvents(),n.current=()=>{const{restored:r}=t.restore();if(n.current=void 0,r){const t=()=>{e.enableScrollEvents(),window.removeEventListener("scroll",t)};window.addEventListener("scroll",t)}else e.enableScrollEvents()}}),[e,t]);return(0,i.Z)((()=>{queueMicrotask((()=>n.current?.()))})),{blockElementScrollPositionUntilNextRender:a}}function h(){const e=(0,r.useRef)(null),t=(0,o.Z)()&&"smooth"===getComputedStyle(document.documentElement).scrollBehavior;return{startScroll:n=>{e.current=t?function(e){return window.scrollTo({top:e,behavior:"smooth"}),()=>{}}(n):function(e){let t=null;const n=document.documentElement.scrollTop>e;return function r(){const a=document.documentElement.scrollTop;(n&&a>e||!n&&at&&cancelAnimationFrame(t)}(n)},cancelScroll:()=>e.current?.()}}},43320:(e,t,n)=>{"use strict";n.d(t,{HX:()=>i,_q:()=>l,os:()=>s});var r=n(80143),a=n(52263),o=n(60373);const i="default";function s(e,t){return`docs-${e}-${t}`}function l(){const{i18n:e}=(0,a.Z)(),t=(0,r._r)(),n=(0,r.WS)(),l=(0,o.Oh)();const c=[i,...Object.keys(t).map((function(e){const r=n?.activePlugin.pluginId===e?n.activeVersion:void 0,a=l[e],o=t[e].versions.find((e=>e.isLast));return s(e,(r??a??o).name)}))];return{locale:e.currentLocale,tags:c}}},50012:(e,t,n)=>{"use strict";n.d(t,{Nk:()=>u,WA:()=>c});var r=n(67294);const a="localStorage";function o(e){let{key:t,oldValue:n,newValue:r,storage:a}=e;if(n===r)return;const o=document.createEvent("StorageEvent");o.initStorageEvent("storage",!1,!1,t,n,r,window.location.href,a),window.dispatchEvent(o)}function i(e){if(void 0===e&&(e=a),"undefined"==typeof window)throw new Error("Browser storage is not available on Node.js/Docusaurus SSR process.");if("none"===e)return null;try{return window[e]}catch(n){return t=n,s||(console.warn("Docusaurus browser storage is not available.\nPossible reasons: running Docusaurus in an iframe, in an incognito browser session, or using too strict browser privacy settings.",t),s=!0),null}var t}let s=!1;const l={get:()=>null,set:()=>{},del:()=>{},listen:()=>()=>{}};function c(e,t){if("undefined"==typeof window)return function(e){function t(){throw new Error(`Illegal storage API usage for storage key "${e}".\nDocusaurus storage APIs are not supposed to be called on the server-rendering process.\nPlease only call storage APIs in effects and event handlers.`)}return{get:t,set:t,del:t,listen:t}}(e);const n=i(t?.persistence);return null===n?l:{get:()=>{try{return n.getItem(e)}catch(t){return console.error(`Docusaurus storage error, can't get key=${e}`,t),null}},set:t=>{try{const r=n.getItem(e);n.setItem(e,t),o({key:e,oldValue:r,newValue:t,storage:n})}catch(r){console.error(`Docusaurus storage error, can't set ${e}=${t}`,r)}},del:()=>{try{const t=n.getItem(e);n.removeItem(e),o({key:e,oldValue:t,newValue:null,storage:n})}catch(t){console.error(`Docusaurus storage error, can't delete key=${e}`,t)}},listen:t=>{try{const r=r=>{r.storageArea===n&&r.key===e&&t(r)};return window.addEventListener("storage",r),()=>window.removeEventListener("storage",r)}catch(r){return console.error(`Docusaurus storage error, can't listen for changes of key=${e}`,r),()=>{}}}}}function u(e,t){const n=(0,r.useRef)((()=>null===e?l:c(e,t))).current(),a=(0,r.useCallback)((e=>"undefined"==typeof window?()=>{}:n.listen(e)),[n]);return[(0,r.useSyncExternalStore)(a,(()=>"undefined"==typeof window?null:n.get()),(()=>null)),n]}},94711:(e,t,n)=>{"use strict";n.d(t,{l:()=>i});var r=n(52263),a=n(16550),o=n(18780);function i(){const{siteConfig:{baseUrl:e,url:t,trailingSlash:n},i18n:{defaultLocale:i,currentLocale:s}}=(0,r.Z)(),{pathname:l}=(0,a.TH)(),c=(0,o.applyTrailingSlash)(l,{trailingSlash:n,baseUrl:e}),u=s===i?e:e.replace(`/${s}/`,"/"),d=c.replace(e,"");return{createUrl:function(e){let{locale:n,fullyQualified:r}=e;return`${r?t:""}${function(e){return e===i?`${u}`:`${u}${e}/`}(n)}${d}`}}}},85936:(e,t,n)=>{"use strict";n.d(t,{S:()=>i});var r=n(67294),a=n(16550),o=n(902);function i(e){const t=(0,a.TH)(),n=(0,o.D9)(t),i=(0,o.zX)(e);(0,r.useEffect)((()=>{n&&t!==n&&i({location:t,previousLocation:n})}),[i,t,n])}},86668:(e,t,n)=>{"use strict";n.d(t,{L:()=>a});var r=n(52263);function a(){return(0,r.Z)().siteConfig.themeConfig}},6278:(e,t,n)=>{"use strict";n.d(t,{L:()=>a});var r=n(52263);function a(){const{siteConfig:{themeConfig:e}}=(0,r.Z)();return e}},239:(e,t,n)=>{"use strict";n.d(t,{l:()=>s});var r=n(67294),a=n(98022),o=n(44996),i=n(6278);function s(){const{withBaseUrl:e}=(0,o.C)(),{algolia:{externalUrlRegex:t,replaceSearchResultPathname:n}}=(0,i.L)();return(0,r.useCallback)((r=>{const o=new URL(r);if((0,a.F)(t,o.href))return r;const i=`${o.pathname+o.hash}`;return e(function(e,t){return t?e.replaceAll(new RegExp(t.from,"g"),t.to):e}(i,n))}),[e,t,n])}},8802:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.default=function(e,t){const{trailingSlash:n,baseUrl:r}=t;if(e.startsWith("#"))return e;if(void 0===n)return e;const[a]=e.split(/[#?]/),o="/"===a||a===r?a:(i=a,n?function(e){return e.endsWith("/")?e:`${e}/`}(i):function(e){return e.endsWith("/")?e.slice(0,-1):e}(i));var i;return e.replace(a,o)}},54143:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.getErrorCausalChain=void 0,t.getErrorCausalChain=function e(t){return t.cause?[t,...e(t.cause)]:[t]}},18780:function(e,t,n){"use strict";var r=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,"__esModule",{value:!0}),t.getErrorCausalChain=t.applyTrailingSlash=t.blogPostContainerID=void 0,t.blogPostContainerID="__blog-post-container";var a=n(8802);Object.defineProperty(t,"applyTrailingSlash",{enumerable:!0,get:function(){return r(a).default}});var o=n(54143);Object.defineProperty(t,"getErrorCausalChain",{enumerable:!0,get:function(){return o.getErrorCausalChain}})},86010:(e,t,n)=>{"use strict";function r(e){var t,n,a="";if("string"==typeof e||"number"==typeof e)a+=e;else if("object"==typeof e)if(Array.isArray(e))for(t=0;ta});const a=function(){for(var e,t,n=0,a="";n{"use strict";n.d(t,{lX:()=>w,q_:()=>C,ob:()=>f,PP:()=>A,Ep:()=>p});var r=n(87462);function a(e){return"/"===e.charAt(0)}function o(e,t){for(var n=t,r=n+1,a=e.length;r=0;p--){var f=i[p];"."===f?o(i,p):".."===f?(o(i,p),d++):d&&(o(i,p),d--)}if(!c)for(;d--;d)i.unshift("..");!c||""===i[0]||i[0]&&a(i[0])||i.unshift("");var g=i.join("/");return n&&"/"!==g.substr(-1)&&(g+="/"),g};var s=n(38776);function l(e){return"/"===e.charAt(0)?e:"/"+e}function c(e){return"/"===e.charAt(0)?e.substr(1):e}function u(e,t){return function(e,t){return 0===e.toLowerCase().indexOf(t.toLowerCase())&&-1!=="/?#".indexOf(e.charAt(t.length))}(e,t)?e.substr(t.length):e}function d(e){return"/"===e.charAt(e.length-1)?e.slice(0,-1):e}function p(e){var t=e.pathname,n=e.search,r=e.hash,a=t||"/";return n&&"?"!==n&&(a+="?"===n.charAt(0)?n:"?"+n),r&&"#"!==r&&(a+="#"===r.charAt(0)?r:"#"+r),a}function f(e,t,n,a){var o;"string"==typeof e?(o=function(e){var t=e||"/",n="",r="",a=t.indexOf("#");-1!==a&&(r=t.substr(a),t=t.substr(0,a));var o=t.indexOf("?");return-1!==o&&(n=t.substr(o),t=t.substr(0,o)),{pathname:t,search:"?"===n?"":n,hash:"#"===r?"":r}}(e),o.state=t):(void 0===(o=(0,r.Z)({},e)).pathname&&(o.pathname=""),o.search?"?"!==o.search.charAt(0)&&(o.search="?"+o.search):o.search="",o.hash?"#"!==o.hash.charAt(0)&&(o.hash="#"+o.hash):o.hash="",void 0!==t&&void 0===o.state&&(o.state=t));try{o.pathname=decodeURI(o.pathname)}catch(s){throw s instanceof URIError?new URIError('Pathname "'+o.pathname+'" could not be decoded. This is likely caused by an invalid percent-encoding.'):s}return n&&(o.key=n),a?o.pathname?"/"!==o.pathname.charAt(0)&&(o.pathname=i(o.pathname,a.pathname)):o.pathname=a.pathname:o.pathname||(o.pathname="/"),o}function g(){var e=null;var t=[];return{setPrompt:function(t){return e=t,function(){e===t&&(e=null)}},confirmTransitionTo:function(t,n,r,a){if(null!=e){var o="function"==typeof e?e(t,n):e;"string"==typeof o?"function"==typeof r?r(o,a):a(!0):a(!1!==o)}else a(!0)},appendListener:function(e){var n=!0;function r(){n&&e.apply(void 0,arguments)}return t.push(r),function(){n=!1,t=t.filter((function(e){return e!==r}))}},notifyListeners:function(){for(var e=arguments.length,n=new Array(e),r=0;rt?n.splice(t,n.length-t,a):n.push(a),d({action:r,location:a,index:t,entries:n})}}))},replace:function(e,t){var r="REPLACE",a=f(e,t,h(),w.location);u.confirmTransitionTo(a,r,n,(function(e){e&&(w.entries[w.index]=a,d({action:r,location:a}))}))},go:v,goBack:function(){v(-1)},goForward:function(){v(1)},canGo:function(e){var t=w.index+e;return t>=0&&t{"use strict";var r=n(59864),a={childContextTypes:!0,contextType:!0,contextTypes:!0,defaultProps:!0,displayName:!0,getDefaultProps:!0,getDerivedStateFromError:!0,getDerivedStateFromProps:!0,mixins:!0,propTypes:!0,type:!0},o={name:!0,length:!0,prototype:!0,caller:!0,callee:!0,arguments:!0,arity:!0},i={$$typeof:!0,compare:!0,defaultProps:!0,displayName:!0,propTypes:!0,type:!0},s={};function l(e){return r.isMemo(e)?i:s[e.$$typeof]||a}s[r.ForwardRef]={$$typeof:!0,render:!0,defaultProps:!0,displayName:!0,propTypes:!0},s[r.Memo]=i;var c=Object.defineProperty,u=Object.getOwnPropertyNames,d=Object.getOwnPropertySymbols,p=Object.getOwnPropertyDescriptor,f=Object.getPrototypeOf,g=Object.prototype;e.exports=function e(t,n,r){if("string"!=typeof n){if(g){var a=f(n);a&&a!==g&&e(t,a,r)}var i=u(n);d&&(i=i.concat(d(n)));for(var s=l(t),h=l(n),m=0;m{"use strict";e.exports=function(e,t,n,r,a,o,i,s){if(!e){var l;if(void 0===t)l=new Error("Minified exception occurred; use the non-minified dev environment for the full error message and additional helpful warnings.");else{var c=[n,r,a,o,i,s],u=0;(l=new Error(t.replace(/%s/g,(function(){return c[u++]})))).name="Invariant Violation"}throw l.framesToPop=1,l}}},5826:e=>{e.exports=Array.isArray||function(e){return"[object Array]"==Object.prototype.toString.call(e)}},7439:(e,t,n)=>{"use strict";n.r(t)},32497:(e,t,n)=>{"use strict";n.r(t)},29268:(e,t,n)=>{"use strict";n.r(t)},74865:function(e,t,n){var r,a;r=function(){var e,t,n={version:"0.2.0"},r=n.settings={minimum:.08,easing:"ease",positionUsing:"",speed:200,trickle:!0,trickleRate:.02,trickleSpeed:800,showSpinner:!0,barSelector:'[role="bar"]',spinnerSelector:'[role="spinner"]',parent:"body",template:'
    '};function a(e,t,n){return en?n:e}function o(e){return 100*(-1+e)}function i(e,t,n){var a;return(a="translate3d"===r.positionUsing?{transform:"translate3d("+o(e)+"%,0,0)"}:"translate"===r.positionUsing?{transform:"translate("+o(e)+"%,0)"}:{"margin-left":o(e)+"%"}).transition="all "+t+"ms "+n,a}n.configure=function(e){var t,n;for(t in e)void 0!==(n=e[t])&&e.hasOwnProperty(t)&&(r[t]=n);return this},n.status=null,n.set=function(e){var t=n.isStarted();e=a(e,r.minimum,1),n.status=1===e?null:e;var o=n.render(!t),c=o.querySelector(r.barSelector),u=r.speed,d=r.easing;return o.offsetWidth,s((function(t){""===r.positionUsing&&(r.positionUsing=n.getPositioningCSS()),l(c,i(e,u,d)),1===e?(l(o,{transition:"none",opacity:1}),o.offsetWidth,setTimeout((function(){l(o,{transition:"all "+u+"ms linear",opacity:0}),setTimeout((function(){n.remove(),t()}),u)}),u)):setTimeout(t,u)})),this},n.isStarted=function(){return"number"==typeof n.status},n.start=function(){n.status||n.set(0);var e=function(){setTimeout((function(){n.status&&(n.trickle(),e())}),r.trickleSpeed)};return r.trickle&&e(),this},n.done=function(e){return e||n.status?n.inc(.3+.5*Math.random()).set(1):this},n.inc=function(e){var t=n.status;return t?("number"!=typeof e&&(e=(1-t)*a(Math.random()*t,.1,.95)),t=a(t+e,0,.994),n.set(t)):n.start()},n.trickle=function(){return n.inc(Math.random()*r.trickleRate)},e=0,t=0,n.promise=function(r){return r&&"resolved"!==r.state()?(0===t&&n.start(),e++,t++,r.always((function(){0==--t?(e=0,n.done()):n.set((e-t)/e)})),this):this},n.render=function(e){if(n.isRendered())return document.getElementById("nprogress");u(document.documentElement,"nprogress-busy");var t=document.createElement("div");t.id="nprogress",t.innerHTML=r.template;var a,i=t.querySelector(r.barSelector),s=e?"-100":o(n.status||0),c=document.querySelector(r.parent);return l(i,{transition:"all 0 linear",transform:"translate3d("+s+"%,0,0)"}),r.showSpinner||(a=t.querySelector(r.spinnerSelector))&&f(a),c!=document.body&&u(c,"nprogress-custom-parent"),c.appendChild(t),t},n.remove=function(){d(document.documentElement,"nprogress-busy"),d(document.querySelector(r.parent),"nprogress-custom-parent");var e=document.getElementById("nprogress");e&&f(e)},n.isRendered=function(){return!!document.getElementById("nprogress")},n.getPositioningCSS=function(){var e=document.body.style,t="WebkitTransform"in e?"Webkit":"MozTransform"in e?"Moz":"msTransform"in e?"ms":"OTransform"in e?"O":"";return t+"Perspective"in e?"translate3d":t+"Transform"in e?"translate":"margin"};var s=function(){var e=[];function t(){var n=e.shift();n&&n(t)}return function(n){e.push(n),1==e.length&&t()}}(),l=function(){var e=["Webkit","O","Moz","ms"],t={};function n(e){return e.replace(/^-ms-/,"ms-").replace(/-([\da-z])/gi,(function(e,t){return t.toUpperCase()}))}function r(t){var n=document.body.style;if(t in n)return t;for(var r,a=e.length,o=t.charAt(0).toUpperCase()+t.slice(1);a--;)if((r=e[a]+o)in n)return r;return t}function a(e){return e=n(e),t[e]||(t[e]=r(e))}function o(e,t,n){t=a(t),e.style[t]=n}return function(e,t){var n,r,a=arguments;if(2==a.length)for(n in t)void 0!==(r=t[n])&&t.hasOwnProperty(n)&&o(e,n,r);else o(e,a[1],a[2])}}();function c(e,t){return("string"==typeof e?e:p(e)).indexOf(" "+t+" ")>=0}function u(e,t){var n=p(e),r=n+t;c(n,t)||(e.className=r.substring(1))}function d(e,t){var n,r=p(e);c(e,t)&&(n=r.replace(" "+t+" "," "),e.className=n.substring(1,n.length-1))}function p(e){return(" "+(e.className||"")+" ").replace(/\s+/gi," ")}function f(e){e&&e.parentNode&&e.parentNode.removeChild(e)}return n},void 0===(a="function"==typeof r?r.call(t,n,t,e):r)||(e.exports=a)},85795:()=>{Prism.languages.ada={comment:/--.*/,string:/"(?:""|[^"\r\f\n])*"/,number:[{pattern:/\b\d(?:_?\d)*#[\dA-F](?:_?[\dA-F])*(?:\.[\dA-F](?:_?[\dA-F])*)?#(?:E[+-]?\d(?:_?\d)*)?/i},{pattern:/\b\d(?:_?\d)*(?:\.\d(?:_?\d)*)?(?:E[+-]?\d(?:_?\d)*)?\b/i}],attribute:{pattern:/\b'\w+/,alias:"attr-name"},keyword:/\b(?:abort|abs|abstract|accept|access|aliased|all|and|array|at|begin|body|case|constant|declare|delay|delta|digits|do|else|elsif|end|entry|exception|exit|for|function|generic|goto|if|in|interface|is|limited|loop|mod|new|not|null|of|or|others|out|overriding|package|pragma|private|procedure|protected|raise|range|record|rem|renames|requeue|return|reverse|select|separate|some|subtype|synchronized|tagged|task|terminate|then|type|until|use|when|while|with|xor)\b/i,boolean:/\b(?:false|true)\b/i,operator:/<[=>]?|>=?|=>?|:=|\/=?|\*\*?|[&+-]/,punctuation:/\.\.?|[,;():]/,char:/'.'/,variable:/\b[a-z](?:\w)*\b/i}},57874:()=>{!function(e){var t="\\b(?:BASH|BASHOPTS|BASH_ALIASES|BASH_ARGC|BASH_ARGV|BASH_CMDS|BASH_COMPLETION_COMPAT_DIR|BASH_LINENO|BASH_REMATCH|BASH_SOURCE|BASH_VERSINFO|BASH_VERSION|COLORTERM|COLUMNS|COMP_WORDBREAKS|DBUS_SESSION_BUS_ADDRESS|DEFAULTS_PATH|DESKTOP_SESSION|DIRSTACK|DISPLAY|EUID|GDMSESSION|GDM_LANG|GNOME_KEYRING_CONTROL|GNOME_KEYRING_PID|GPG_AGENT_INFO|GROUPS|HISTCONTROL|HISTFILE|HISTFILESIZE|HISTSIZE|HOME|HOSTNAME|HOSTTYPE|IFS|INSTANCE|JOB|LANG|LANGUAGE|LC_ADDRESS|LC_ALL|LC_IDENTIFICATION|LC_MEASUREMENT|LC_MONETARY|LC_NAME|LC_NUMERIC|LC_PAPER|LC_TELEPHONE|LC_TIME|LESSCLOSE|LESSOPEN|LINES|LOGNAME|LS_COLORS|MACHTYPE|MAILCHECK|MANDATORY_PATH|NO_AT_BRIDGE|OLDPWD|OPTERR|OPTIND|ORBIT_SOCKETDIR|OSTYPE|PAPERSIZE|PATH|PIPESTATUS|PPID|PS1|PS2|PS3|PS4|PWD|RANDOM|REPLY|SECONDS|SELINUX_INIT|SESSION|SESSIONTYPE|SESSION_MANAGER|SHELL|SHELLOPTS|SHLVL|SSH_AUTH_SOCK|TERM|UID|UPSTART_EVENTS|UPSTART_INSTANCE|UPSTART_JOB|UPSTART_SESSION|USER|WINDOWID|XAUTHORITY|XDG_CONFIG_DIRS|XDG_CURRENT_DESKTOP|XDG_DATA_DIRS|XDG_GREETER_DATA_DIR|XDG_MENU_PREFIX|XDG_RUNTIME_DIR|XDG_SEAT|XDG_SEAT_PATH|XDG_SESSION_DESKTOP|XDG_SESSION_ID|XDG_SESSION_PATH|XDG_SESSION_TYPE|XDG_VTNR|XMODIFIERS)\\b",n={pattern:/(^(["']?)\w+\2)[ \t]+\S.*/,lookbehind:!0,alias:"punctuation",inside:null},r={bash:n,environment:{pattern:RegExp("\\$"+t),alias:"constant"},variable:[{pattern:/\$?\(\([\s\S]+?\)\)/,greedy:!0,inside:{variable:[{pattern:/(^\$\(\([\s\S]+)\)\)/,lookbehind:!0},/^\$\(\(/],number:/\b0x[\dA-Fa-f]+\b|(?:\b\d+(?:\.\d*)?|\B\.\d+)(?:[Ee]-?\d+)?/,operator:/--|\+\+|\*\*=?|<<=?|>>=?|&&|\|\||[=!+\-*/%<>^&|]=?|[?~:]/,punctuation:/\(\(?|\)\)?|,|;/}},{pattern:/\$\((?:\([^)]+\)|[^()])+\)|`[^`]+`/,greedy:!0,inside:{variable:/^\$\(|^`|\)$|`$/}},{pattern:/\$\{[^}]+\}/,greedy:!0,inside:{operator:/:[-=?+]?|[!\/]|##?|%%?|\^\^?|,,?/,punctuation:/[\[\]]/,environment:{pattern:RegExp("(\\{)"+t),lookbehind:!0,alias:"constant"}}},/\$(?:\w+|[#?*!@$])/],entity:/\\(?:[abceEfnrtv\\"]|O?[0-7]{1,3}|U[0-9a-fA-F]{8}|u[0-9a-fA-F]{4}|x[0-9a-fA-F]{1,2})/};e.languages.bash={shebang:{pattern:/^#!\s*\/.*/,alias:"important"},comment:{pattern:/(^|[^"{\\$])#.*/,lookbehind:!0},"function-name":[{pattern:/(\bfunction\s+)[\w-]+(?=(?:\s*\(?:\s*\))?\s*\{)/,lookbehind:!0,alias:"function"},{pattern:/\b[\w-]+(?=\s*\(\s*\)\s*\{)/,alias:"function"}],"for-or-select":{pattern:/(\b(?:for|select)\s+)\w+(?=\s+in\s)/,alias:"variable",lookbehind:!0},"assign-left":{pattern:/(^|[\s;|&]|[<>]\()\w+(?:\.\w+)*(?=\+?=)/,inside:{environment:{pattern:RegExp("(^|[\\s;|&]|[<>]\\()"+t),lookbehind:!0,alias:"constant"}},alias:"variable",lookbehind:!0},parameter:{pattern:/(^|\s)-{1,2}(?:\w+:[+-]?)?\w+(?:\.\w+)*(?=[=\s]|$)/,alias:"variable",lookbehind:!0},string:[{pattern:/((?:^|[^<])<<-?\s*)(\w+)\s[\s\S]*?(?:\r?\n|\r)\2/,lookbehind:!0,greedy:!0,inside:r},{pattern:/((?:^|[^<])<<-?\s*)(["'])(\w+)\2\s[\s\S]*?(?:\r?\n|\r)\3/,lookbehind:!0,greedy:!0,inside:{bash:n}},{pattern:/(^|[^\\](?:\\\\)*)"(?:\\[\s\S]|\$\([^)]+\)|\$(?!\()|`[^`]+`|[^"\\`$])*"/,lookbehind:!0,greedy:!0,inside:r},{pattern:/(^|[^$\\])'[^']*'/,lookbehind:!0,greedy:!0},{pattern:/\$'(?:[^'\\]|\\[\s\S])*'/,greedy:!0,inside:{entity:r.entity}}],environment:{pattern:RegExp("\\$?"+t),alias:"constant"},variable:r.variable,function:{pattern:/(^|[\s;|&]|[<>]\()(?:add|apropos|apt|apt-cache|apt-get|aptitude|aspell|automysqlbackup|awk|basename|bash|bc|bconsole|bg|bzip2|cal|cargo|cat|cfdisk|chgrp|chkconfig|chmod|chown|chroot|cksum|clear|cmp|column|comm|composer|cp|cron|crontab|csplit|curl|cut|date|dc|dd|ddrescue|debootstrap|df|diff|diff3|dig|dir|dircolors|dirname|dirs|dmesg|docker|docker-compose|du|egrep|eject|env|ethtool|expand|expect|expr|fdformat|fdisk|fg|fgrep|file|find|fmt|fold|format|free|fsck|ftp|fuser|gawk|git|gparted|grep|groupadd|groupdel|groupmod|groups|grub-mkconfig|gzip|halt|head|hg|history|host|hostname|htop|iconv|id|ifconfig|ifdown|ifup|import|install|ip|java|jobs|join|kill|killall|less|link|ln|locate|logname|logrotate|look|lpc|lpr|lprint|lprintd|lprintq|lprm|ls|lsof|lynx|make|man|mc|mdadm|mkconfig|mkdir|mke2fs|mkfifo|mkfs|mkisofs|mknod|mkswap|mmv|more|most|mount|mtools|mtr|mutt|mv|nano|nc|netstat|nice|nl|node|nohup|notify-send|npm|nslookup|op|open|parted|passwd|paste|pathchk|ping|pkill|pnpm|podman|podman-compose|popd|pr|printcap|printenv|ps|pushd|pv|quota|quotacheck|quotactl|ram|rar|rcp|reboot|remsync|rename|renice|rev|rm|rmdir|rpm|rsync|scp|screen|sdiff|sed|sendmail|seq|service|sftp|sh|shellcheck|shuf|shutdown|sleep|slocate|sort|split|ssh|stat|strace|su|sudo|sum|suspend|swapon|sync|sysctl|tac|tail|tar|tee|time|timeout|top|touch|tr|traceroute|tsort|tty|umount|uname|unexpand|uniq|units|unrar|unshar|unzip|update-grub|uptime|useradd|userdel|usermod|users|uudecode|uuencode|v|vcpkg|vdir|vi|vim|virsh|vmstat|wait|watch|wc|wget|whereis|which|who|whoami|write|xargs|xdg-open|yarn|yes|zenity|zip|zsh|zypper)(?=$|[)\s;|&])/,lookbehind:!0},keyword:{pattern:/(^|[\s;|&]|[<>]\()(?:case|do|done|elif|else|esac|fi|for|function|if|in|select|then|until|while)(?=$|[)\s;|&])/,lookbehind:!0},builtin:{pattern:/(^|[\s;|&]|[<>]\()(?:\.|:|alias|bind|break|builtin|caller|cd|command|continue|declare|echo|enable|eval|exec|exit|export|getopts|hash|help|let|local|logout|mapfile|printf|pwd|read|readarray|readonly|return|set|shift|shopt|source|test|times|trap|type|typeset|ulimit|umask|unalias|unset)(?=$|[)\s;|&])/,lookbehind:!0,alias:"class-name"},boolean:{pattern:/(^|[\s;|&]|[<>]\()(?:false|true)(?=$|[)\s;|&])/,lookbehind:!0},"file-descriptor":{pattern:/\B&\d\b/,alias:"important"},operator:{pattern:/\d?<>|>\||\+=|=[=~]?|!=?|<<[<-]?|[&\d]?>>|\d[<>]&?|[<>][&=]?|&[>&]?|\|[&|]?/,inside:{"file-descriptor":{pattern:/^\d/,alias:"important"}}},punctuation:/\$?\(\(?|\)\)?|\.\.|[{}[\];\\]/,number:{pattern:/(^|\s)(?:[1-9]\d*|0)(?:[.,]\d+)?\b/,lookbehind:!0}},n.inside=e.languages.bash;for(var a=["comment","function-name","for-or-select","assign-left","parameter","string","environment","function","keyword","builtin","boolean","file-descriptor","operator","punctuation","number"],o=r.variable[1].inside,i=0;i{!function(e){function t(e,t){return e.replace(/<<(\d+)>>/g,(function(e,n){return"(?:"+t[+n]+")"}))}function n(e,n,r){return RegExp(t(e,n),r||"")}function r(e,t){for(var n=0;n>/g,(function(){return"(?:"+e+")"}));return e.replace(/<>/g,"[^\\s\\S]")}var a="bool byte char decimal double dynamic float int long object sbyte short string uint ulong ushort var void",o="class enum interface record struct",i="add alias and ascending async await by descending from(?=\\s*(?:\\w|$)) get global group into init(?=\\s*;) join let nameof not notnull on or orderby partial remove select set unmanaged value when where with(?=\\s*{)",s="abstract as base break case catch checked const continue default delegate do else event explicit extern finally fixed for foreach goto if implicit in internal is lock namespace new null operator out override params private protected public readonly ref return sealed sizeof stackalloc static switch this throw try typeof unchecked unsafe using virtual volatile while yield";function l(e){return"\\b(?:"+e.trim().replace(/ /g,"|")+")\\b"}var c=l(o),u=RegExp(l(a+" "+o+" "+i+" "+s)),d=l(o+" "+i+" "+s),p=l(a+" "+o+" "+s),f=r(/<(?:[^<>;=+\-*/%&|^]|<>)*>/.source,2),g=r(/\((?:[^()]|<>)*\)/.source,2),h=/@?\b[A-Za-z_]\w*\b/.source,m=t(/<<0>>(?:\s*<<1>>)?/.source,[h,f]),b=t(/(?!<<0>>)<<1>>(?:\s*\.\s*<<1>>)*/.source,[d,m]),y=/\[\s*(?:,\s*)*\]/.source,v=t(/<<0>>(?:\s*(?:\?\s*)?<<1>>)*(?:\s*\?)?/.source,[b,y]),w=t(/[^,()<>[\];=+\-*/%&|^]|<<0>>|<<1>>|<<2>>/.source,[f,g,y]),k=t(/\(<<0>>+(?:,<<0>>+)+\)/.source,[w]),x=t(/(?:<<0>>|<<1>>)(?:\s*(?:\?\s*)?<<2>>)*(?:\s*\?)?/.source,[k,b,y]),S={keyword:u,punctuation:/[<>()?,.:[\]]/},_=/'(?:[^\r\n'\\]|\\.|\\[Uux][\da-fA-F]{1,8})'/.source,E=/"(?:\\.|[^\\"\r\n])*"/.source,C=/@"(?:""|\\[\s\S]|[^\\"])*"(?!")/.source;e.languages.csharp=e.languages.extend("clike",{string:[{pattern:n(/(^|[^$\\])<<0>>/.source,[C]),lookbehind:!0,greedy:!0},{pattern:n(/(^|[^@$\\])<<0>>/.source,[E]),lookbehind:!0,greedy:!0}],"class-name":[{pattern:n(/(\busing\s+static\s+)<<0>>(?=\s*;)/.source,[b]),lookbehind:!0,inside:S},{pattern:n(/(\busing\s+<<0>>\s*=\s*)<<1>>(?=\s*;)/.source,[h,x]),lookbehind:!0,inside:S},{pattern:n(/(\busing\s+)<<0>>(?=\s*=)/.source,[h]),lookbehind:!0},{pattern:n(/(\b<<0>>\s+)<<1>>/.source,[c,m]),lookbehind:!0,inside:S},{pattern:n(/(\bcatch\s*\(\s*)<<0>>/.source,[b]),lookbehind:!0,inside:S},{pattern:n(/(\bwhere\s+)<<0>>/.source,[h]),lookbehind:!0},{pattern:n(/(\b(?:is(?:\s+not)?|as)\s+)<<0>>/.source,[v]),lookbehind:!0,inside:S},{pattern:n(/\b<<0>>(?=\s+(?!<<1>>|with\s*\{)<<2>>(?:\s*[=,;:{)\]]|\s+(?:in|when)\b))/.source,[x,p,h]),inside:S}],keyword:u,number:/(?:\b0(?:x[\da-f_]*[\da-f]|b[01_]*[01])|(?:\B\.\d+(?:_+\d+)*|\b\d+(?:_+\d+)*(?:\.\d+(?:_+\d+)*)?)(?:e[-+]?\d+(?:_+\d+)*)?)(?:[dflmu]|lu|ul)?\b/i,operator:/>>=?|<<=?|[-=]>|([-+&|])\1|~|\?\?=?|[-+*/%&|^!=<>]=?/,punctuation:/\?\.?|::|[{}[\];(),.:]/}),e.languages.insertBefore("csharp","number",{range:{pattern:/\.\./,alias:"operator"}}),e.languages.insertBefore("csharp","punctuation",{"named-parameter":{pattern:n(/([(,]\s*)<<0>>(?=\s*:)/.source,[h]),lookbehind:!0,alias:"punctuation"}}),e.languages.insertBefore("csharp","class-name",{namespace:{pattern:n(/(\b(?:namespace|using)\s+)<<0>>(?:\s*\.\s*<<0>>)*(?=\s*[;{])/.source,[h]),lookbehind:!0,inside:{punctuation:/\./}},"type-expression":{pattern:n(/(\b(?:default|sizeof|typeof)\s*\(\s*(?!\s))(?:[^()\s]|\s(?!\s)|<<0>>)*(?=\s*\))/.source,[g]),lookbehind:!0,alias:"class-name",inside:S},"return-type":{pattern:n(/<<0>>(?=\s+(?:<<1>>\s*(?:=>|[({]|\.\s*this\s*\[)|this\s*\[))/.source,[x,b]),inside:S,alias:"class-name"},"constructor-invocation":{pattern:n(/(\bnew\s+)<<0>>(?=\s*[[({])/.source,[x]),lookbehind:!0,inside:S,alias:"class-name"},"generic-method":{pattern:n(/<<0>>\s*<<1>>(?=\s*\()/.source,[h,f]),inside:{function:n(/^<<0>>/.source,[h]),generic:{pattern:RegExp(f),alias:"class-name",inside:S}}},"type-list":{pattern:n(/\b((?:<<0>>\s+<<1>>|record\s+<<1>>\s*<<5>>|where\s+<<2>>)\s*:\s*)(?:<<3>>|<<4>>|<<1>>\s*<<5>>|<<6>>)(?:\s*,\s*(?:<<3>>|<<4>>|<<6>>))*(?=\s*(?:where|[{;]|=>|$))/.source,[c,m,h,x,u.source,g,/\bnew\s*\(\s*\)/.source]),lookbehind:!0,inside:{"record-arguments":{pattern:n(/(^(?!new\s*\()<<0>>\s*)<<1>>/.source,[m,g]),lookbehind:!0,greedy:!0,inside:e.languages.csharp},keyword:u,"class-name":{pattern:RegExp(x),greedy:!0,inside:S},punctuation:/[,()]/}},preprocessor:{pattern:/(^[\t ]*)#.*/m,lookbehind:!0,alias:"property",inside:{directive:{pattern:/(#)\b(?:define|elif|else|endif|endregion|error|if|line|nullable|pragma|region|undef|warning)\b/,lookbehind:!0,alias:"keyword"}}}});var T=E+"|"+_,A=t(/\/(?![*/])|\/\/[^\r\n]*[\r\n]|\/\*(?:[^*]|\*(?!\/))*\*\/|<<0>>/.source,[T]),j=r(t(/[^"'/()]|<<0>>|\(<>*\)/.source,[A]),2),N=/\b(?:assembly|event|field|method|module|param|property|return|type)\b/.source,L=t(/<<0>>(?:\s*\(<<1>>*\))?/.source,[b,j]);e.languages.insertBefore("csharp","class-name",{attribute:{pattern:n(/((?:^|[^\s\w>)?])\s*\[\s*)(?:<<0>>\s*:\s*)?<<1>>(?:\s*,\s*<<1>>)*(?=\s*\])/.source,[N,L]),lookbehind:!0,greedy:!0,inside:{target:{pattern:n(/^<<0>>(?=\s*:)/.source,[N]),alias:"keyword"},"attribute-arguments":{pattern:n(/\(<<0>>*\)/.source,[j]),inside:e.languages.csharp},"class-name":{pattern:RegExp(b),inside:{punctuation:/\./}},punctuation:/[:,]/}}});var P=/:[^}\r\n]+/.source,R=r(t(/[^"'/()]|<<0>>|\(<>*\)/.source,[A]),2),O=t(/\{(?!\{)(?:(?![}:])<<0>>)*<<1>>?\}/.source,[R,P]),I=r(t(/[^"'/()]|\/(?!\*)|\/\*(?:[^*]|\*(?!\/))*\*\/|<<0>>|\(<>*\)/.source,[T]),2),F=t(/\{(?!\{)(?:(?![}:])<<0>>)*<<1>>?\}/.source,[I,P]);function M(t,r){return{interpolation:{pattern:n(/((?:^|[^{])(?:\{\{)*)<<0>>/.source,[t]),lookbehind:!0,inside:{"format-string":{pattern:n(/(^\{(?:(?![}:])<<0>>)*)<<1>>(?=\}$)/.source,[r,P]),lookbehind:!0,inside:{punctuation:/^:/}},punctuation:/^\{|\}$/,expression:{pattern:/[\s\S]+/,alias:"language-csharp",inside:e.languages.csharp}}},string:/[\s\S]+/}}e.languages.insertBefore("csharp","string",{"interpolation-string":[{pattern:n(/(^|[^\\])(?:\$@|@\$)"(?:""|\\[\s\S]|\{\{|<<0>>|[^\\{"])*"/.source,[O]),lookbehind:!0,greedy:!0,inside:M(O,R)},{pattern:n(/(^|[^@\\])\$"(?:\\.|\{\{|<<0>>|[^\\"{])*"/.source,[F]),lookbehind:!0,greedy:!0,inside:M(F,I)}],char:{pattern:RegExp(_),greedy:!0}}),e.languages.dotnet=e.languages.cs=e.languages.csharp}(Prism)},60397:()=>{!function(e){var t="(?:"+[/[a-zA-Z_\x80-\uFFFF][\w\x80-\uFFFF]*/.source,/-?(?:\.\d+|\d+(?:\.\d*)?)/.source,/"[^"\\]*(?:\\[\s\S][^"\\]*)*"/.source,/<(?:[^<>]|(?!)*>/.source].join("|")+")",n={markup:{pattern:/(^<)[\s\S]+(?=>$)/,lookbehind:!0,alias:["language-markup","language-html","language-xml"],inside:e.languages.markup}};function r(e,n){return RegExp(e.replace(//g,(function(){return t})),n)}e.languages.dot={comment:{pattern:/\/\/.*|\/\*[\s\S]*?\*\/|^#.*/m,greedy:!0},"graph-name":{pattern:r(/(\b(?:digraph|graph|subgraph)[ \t\r\n]+)/.source,"i"),lookbehind:!0,greedy:!0,alias:"class-name",inside:n},"attr-value":{pattern:r(/(=[ \t\r\n]*)/.source),lookbehind:!0,greedy:!0,inside:n},"attr-name":{pattern:r(/([\[;, \t\r\n])(?=[ \t\r\n]*=)/.source),lookbehind:!0,greedy:!0,inside:n},keyword:/\b(?:digraph|edge|graph|node|strict|subgraph)\b/i,"compass-point":{pattern:/(:[ \t\r\n]*)(?:[ewc_]|[ns][ew]?)(?![\w\x80-\uFFFF])/,lookbehind:!0,alias:"builtin"},node:{pattern:r(/(^|[^-.\w\x80-\uFFFF\\])/.source),lookbehind:!0,greedy:!0,inside:n},operator:/[=:]|-[->]/,punctuation:/[\[\]{};,]/},e.languages.gv=e.languages.dot}(Prism)},81295:()=>{Prism.languages.haskell={comment:{pattern:/(^|[^-!#$%*+=?&@|~.:<>^\\\/])(?:--(?:(?=.)[^-!#$%*+=?&@|~.:<>^\\\/].*|$)|\{-[\s\S]*?-\})/m,lookbehind:!0},char:{pattern:/'(?:[^\\']|\\(?:[abfnrtv\\"'&]|\^[A-Z@[\]^_]|ACK|BEL|BS|CAN|CR|DC1|DC2|DC3|DC4|DEL|DLE|EM|ENQ|EOT|ESC|ETB|ETX|FF|FS|GS|HT|LF|NAK|NUL|RS|SI|SO|SOH|SP|STX|SUB|SYN|US|VT|\d+|o[0-7]+|x[0-9a-fA-F]+))'/,alias:"string"},string:{pattern:/"(?:[^\\"]|\\(?:\S|\s+\\))*"/,greedy:!0},keyword:/\b(?:case|class|data|deriving|do|else|if|in|infixl|infixr|instance|let|module|newtype|of|primitive|then|type|where)\b/,"import-statement":{pattern:/(^[\t ]*)import\s+(?:qualified\s+)?(?:[A-Z][\w']*)(?:\.[A-Z][\w']*)*(?:\s+as\s+(?:[A-Z][\w']*)(?:\.[A-Z][\w']*)*)?(?:\s+hiding\b)?/m,lookbehind:!0,inside:{keyword:/\b(?:as|hiding|import|qualified)\b/,punctuation:/\./}},builtin:/\b(?:abs|acos|acosh|all|and|any|appendFile|approxRational|asTypeOf|asin|asinh|atan|atan2|atanh|basicIORun|break|catch|ceiling|chr|compare|concat|concatMap|const|cos|cosh|curry|cycle|decodeFloat|denominator|digitToInt|div|divMod|drop|dropWhile|either|elem|encodeFloat|enumFrom|enumFromThen|enumFromThenTo|enumFromTo|error|even|exp|exponent|fail|filter|flip|floatDigits|floatRadix|floatRange|floor|fmap|foldl|foldl1|foldr|foldr1|fromDouble|fromEnum|fromInt|fromInteger|fromIntegral|fromRational|fst|gcd|getChar|getContents|getLine|group|head|id|inRange|index|init|intToDigit|interact|ioError|isAlpha|isAlphaNum|isAscii|isControl|isDenormalized|isDigit|isHexDigit|isIEEE|isInfinite|isLower|isNaN|isNegativeZero|isOctDigit|isPrint|isSpace|isUpper|iterate|last|lcm|length|lex|lexDigits|lexLitChar|lines|log|logBase|lookup|map|mapM|mapM_|max|maxBound|maximum|maybe|min|minBound|minimum|mod|negate|not|notElem|null|numerator|odd|or|ord|otherwise|pack|pi|pred|primExitWith|print|product|properFraction|putChar|putStr|putStrLn|quot|quotRem|range|rangeSize|read|readDec|readFile|readFloat|readHex|readIO|readInt|readList|readLitChar|readLn|readOct|readParen|readSigned|reads|readsPrec|realToFrac|recip|rem|repeat|replicate|return|reverse|round|scaleFloat|scanl|scanl1|scanr|scanr1|seq|sequence|sequence_|show|showChar|showInt|showList|showLitChar|showParen|showSigned|showString|shows|showsPrec|significand|signum|sin|sinh|snd|sort|span|splitAt|sqrt|subtract|succ|sum|tail|take|takeWhile|tan|tanh|threadToIOResult|toEnum|toInt|toInteger|toLower|toRational|toUpper|truncate|uncurry|undefined|unlines|until|unwords|unzip|unzip3|userError|words|writeFile|zip|zip3|zipWith|zipWith3)\b/,number:/\b(?:\d+(?:\.\d+)?(?:e[+-]?\d+)?|0o[0-7]+|0x[0-9a-f]+)\b/i,operator:[{pattern:/`(?:[A-Z][\w']*\.)*[_a-z][\w']*`/,greedy:!0},{pattern:/(\s)\.(?=\s)/,lookbehind:!0},/[-!#$%*+=?&@|~:<>^\\\/][-!#$%*+=?&@|~.:<>^\\\/]*|\.[-!#$%*+=?&@|~.:<>^\\\/]+/],hvariable:{pattern:/\b(?:[A-Z][\w']*\.)*[_a-z][\w']*/,inside:{punctuation:/\./}},constant:{pattern:/\b(?:[A-Z][\w']*\.)*[A-Z][\w']*/,inside:{punctuation:/\./}},punctuation:/[{}[\];(),.:]/},Prism.languages.hs=Prism.languages.haskell},52503:()=>{!function(e){var t=/\b(?:abstract|assert|boolean|break|byte|case|catch|char|class|const|continue|default|do|double|else|enum|exports|extends|final|finally|float|for|goto|if|implements|import|instanceof|int|interface|long|module|native|new|non-sealed|null|open|opens|package|permits|private|protected|provides|public|record(?!\s*[(){}[\]<>=%~.:,;?+\-*/&|^])|requires|return|sealed|short|static|strictfp|super|switch|synchronized|this|throw|throws|to|transient|transitive|try|uses|var|void|volatile|while|with|yield)\b/,n=/(?:[a-z]\w*\s*\.\s*)*(?:[A-Z]\w*\s*\.\s*)*/.source,r={pattern:RegExp(/(^|[^\w.])/.source+n+/[A-Z](?:[\d_A-Z]*[a-z]\w*)?\b/.source),lookbehind:!0,inside:{namespace:{pattern:/^[a-z]\w*(?:\s*\.\s*[a-z]\w*)*(?:\s*\.)?/,inside:{punctuation:/\./}},punctuation:/\./}};e.languages.java=e.languages.extend("clike",{string:{pattern:/(^|[^\\])"(?:\\.|[^"\\\r\n])*"/,lookbehind:!0,greedy:!0},"class-name":[r,{pattern:RegExp(/(^|[^\w.])/.source+n+/[A-Z]\w*(?=\s+\w+\s*[;,=()]|\s*(?:\[[\s,]*\]\s*)?::\s*new\b)/.source),lookbehind:!0,inside:r.inside},{pattern:RegExp(/(\b(?:class|enum|extends|implements|instanceof|interface|new|record|throws)\s+)/.source+n+/[A-Z]\w*\b/.source),lookbehind:!0,inside:r.inside}],keyword:t,function:[e.languages.clike.function,{pattern:/(::\s*)[a-z_]\w*/,lookbehind:!0}],number:/\b0b[01][01_]*L?\b|\b0x(?:\.[\da-f_p+-]+|[\da-f_]+(?:\.[\da-f_p+-]+)?)\b|(?:\b\d[\d_]*(?:\.[\d_]*)?|\B\.\d[\d_]*)(?:e[+-]?\d[\d_]*)?[dfl]?/i,operator:{pattern:/(^|[^.])(?:<<=?|>>>?=?|->|--|\+\+|&&|\|\||::|[?:~]|[-+*/%&|^!=<>]=?)/m,lookbehind:!0},constant:/\b[A-Z][A-Z_\d]+\b/}),e.languages.insertBefore("java","string",{"triple-quoted-string":{pattern:/"""[ \t]*[\r\n](?:(?:"|"")?(?:\\.|[^"\\]))*"""/,greedy:!0,alias:"string"},char:{pattern:/'(?:\\.|[^'\\\r\n]){1,6}'/,greedy:!0}}),e.languages.insertBefore("java","class-name",{annotation:{pattern:/(^|[^.])@\w+(?:\s*\.\s*\w+)*/,lookbehind:!0,alias:"punctuation"},generics:{pattern:/<(?:[\w\s,.?]|&(?!&)|<(?:[\w\s,.?]|&(?!&)|<(?:[\w\s,.?]|&(?!&)|<(?:[\w\s,.?]|&(?!&))*>)*>)*>)*>/,inside:{"class-name":r,keyword:t,punctuation:/[<>(),.:]/,operator:/[?&|]/}},import:[{pattern:RegExp(/(\bimport\s+)/.source+n+/(?:[A-Z]\w*|\*)(?=\s*;)/.source),lookbehind:!0,inside:{namespace:r.inside.namespace,punctuation:/\./,operator:/\*/,"class-name":/\w+/}},{pattern:RegExp(/(\bimport\s+static\s+)/.source+n+/(?:\w+|\*)(?=\s*;)/.source),lookbehind:!0,alias:"static",inside:{namespace:r.inside.namespace,static:/\b\w+$/,punctuation:/\./,operator:/\*/,"class-name":/\w+/}}],namespace:{pattern:RegExp(/(\b(?:exports|import(?:\s+static)?|module|open|opens|package|provides|requires|to|transitive|uses|with)\s+)(?!)[a-z]\w*(?:\.[a-z]\w*)*\.?/.source.replace(//g,(function(){return t.source}))),lookbehind:!0,inside:{punctuation:/\./}}})}(Prism)},96854:()=>{!function(e){function t(e,t){return"___"+e.toUpperCase()+t+"___"}Object.defineProperties(e.languages["markup-templating"]={},{buildPlaceholders:{value:function(n,r,a,o){if(n.language===r){var i=n.tokenStack=[];n.code=n.code.replace(a,(function(e){if("function"==typeof o&&!o(e))return e;for(var a,s=i.length;-1!==n.code.indexOf(a=t(r,s));)++s;return i[s]=e,a})),n.grammar=e.languages.markup}}},tokenizePlaceholders:{value:function(n,r){if(n.language===r&&n.tokenStack){n.grammar=e.languages[r];var a=0,o=Object.keys(n.tokenStack);!function i(s){for(var l=0;l=o.length);l++){var c=s[l];if("string"==typeof c||c.content&&"string"==typeof c.content){var u=o[a],d=n.tokenStack[u],p="string"==typeof c?c:c.content,f=t(r,u),g=p.indexOf(f);if(g>-1){++a;var h=p.substring(0,g),m=new e.Token(r,e.tokenize(d,n.grammar),"language-"+r,d),b=p.substring(g+f.length),y=[];h&&y.push.apply(y,i([h])),y.push(m),b&&y.push.apply(y,i([b])),"string"==typeof c?s.splice.apply(s,[l,1].concat(y)):c.content=y}}else c.content&&i(c.content)}return s}(n.tokens)}}}})}(Prism)},58704:()=>{Prism.languages.nix={comment:{pattern:/\/\*[\s\S]*?\*\/|#.*/,greedy:!0},string:{pattern:/"(?:[^"\\]|\\[\s\S])*"|''(?:(?!'')[\s\S]|''(?:'|\\|\$\{))*''/,greedy:!0,inside:{interpolation:{pattern:/(^|(?:^|(?!'').)[^\\])\$\{(?:[^{}]|\{[^}]*\})*\}/,lookbehind:!0,inside:null}}},url:[/\b(?:[a-z]{3,7}:\/\/)[\w\-+%~\/.:#=?&]+/,{pattern:/([^\/])(?:[\w\-+%~.:#=?&]*(?!\/\/)[\w\-+%~\/.:#=?&])?(?!\/\/)\/[\w\-+%~\/.:#=?&]*/,lookbehind:!0}],antiquotation:{pattern:/\$(?=\{)/,alias:"important"},number:/\b\d+\b/,keyword:/\b(?:assert|builtins|else|if|in|inherit|let|null|or|then|with)\b/,function:/\b(?:abort|add|all|any|attrNames|attrValues|baseNameOf|compareVersions|concatLists|currentSystem|deepSeq|derivation|dirOf|div|elem(?:At)?|fetch(?:Tarball|url)|filter(?:Source)?|fromJSON|genList|getAttr|getEnv|hasAttr|hashString|head|import|intersectAttrs|is(?:Attrs|Bool|Function|Int|List|Null|String)|length|lessThan|listToAttrs|map|mul|parseDrvName|pathExists|read(?:Dir|File)|removeAttrs|replaceStrings|seq|sort|stringLength|sub(?:string)?|tail|throw|to(?:File|JSON|Path|String|XML)|trace|typeOf)\b|\bfoldl'\B/,boolean:/\b(?:false|true)\b/,operator:/[=!<>]=?|\+\+?|\|\||&&|\/\/|->?|[?@]/,punctuation:/[{}()[\].,:;]/},Prism.languages.nix.string.inside.interpolation.inside=Prism.languages.nix},13210:()=>{Prism.languages.pascal={directive:{pattern:/\{\$[\s\S]*?\}/,greedy:!0,alias:["marco","property"]},comment:{pattern:/\(\*[\s\S]*?\*\)|\{[\s\S]*?\}|\/\/.*/,greedy:!0},string:{pattern:/(?:'(?:''|[^'\r\n])*'(?!')|#[&$%]?[a-f\d]+)+|\^[a-z]/i,greedy:!0},asm:{pattern:/(\basm\b)[\s\S]+?(?=\bend\s*[;[])/i,lookbehind:!0,greedy:!0,inside:null},keyword:[{pattern:/(^|[^&])\b(?:absolute|array|asm|begin|case|const|constructor|destructor|do|downto|else|end|file|for|function|goto|if|implementation|inherited|inline|interface|label|nil|object|of|operator|packed|procedure|program|record|reintroduce|repeat|self|set|string|then|to|type|unit|until|uses|var|while|with)\b/i,lookbehind:!0},{pattern:/(^|[^&])\b(?:dispose|exit|false|new|true)\b/i,lookbehind:!0},{pattern:/(^|[^&])\b(?:class|dispinterface|except|exports|finalization|finally|initialization|inline|library|on|out|packed|property|raise|resourcestring|threadvar|try)\b/i,lookbehind:!0},{pattern:/(^|[^&])\b(?:absolute|abstract|alias|assembler|bitpacked|break|cdecl|continue|cppdecl|cvar|default|deprecated|dynamic|enumerator|experimental|export|external|far|far16|forward|generic|helper|implements|index|interrupt|iochecks|local|message|name|near|nodefault|noreturn|nostackframe|oldfpccall|otherwise|overload|override|pascal|platform|private|protected|public|published|read|register|reintroduce|result|safecall|saveregisters|softfloat|specialize|static|stdcall|stored|strict|unaligned|unimplemented|varargs|virtual|write)\b/i,lookbehind:!0}],number:[/(?:[&%]\d+|\$[a-f\d]+)/i,/\b\d+(?:\.\d+)?(?:e[+-]?\d+)?/i],operator:[/\.\.|\*\*|:=|<[<=>]?|>[>=]?|[+\-*\/]=?|[@^=]/,{pattern:/(^|[^&])\b(?:and|as|div|exclude|in|include|is|mod|not|or|shl|shr|xor)\b/,lookbehind:!0}],punctuation:/\(\.|\.\)|[()\[\]:;,.]/},Prism.languages.pascal.asm.inside=Prism.languages.extend("pascal",{asm:void 0,keyword:void 0,operator:void 0}),Prism.languages.objectpascal=Prism.languages.pascal},80366:()=>{Prism.languages.python={comment:{pattern:/(^|[^\\])#.*/,lookbehind:!0,greedy:!0},"string-interpolation":{pattern:/(?:f|fr|rf)(?:("""|''')[\s\S]*?\1|("|')(?:\\.|(?!\2)[^\\\r\n])*\2)/i,greedy:!0,inside:{interpolation:{pattern:/((?:^|[^{])(?:\{\{)*)\{(?!\{)(?:[^{}]|\{(?!\{)(?:[^{}]|\{(?!\{)(?:[^{}])+\})+\})+\}/,lookbehind:!0,inside:{"format-spec":{pattern:/(:)[^:(){}]+(?=\}$)/,lookbehind:!0},"conversion-option":{pattern:/![sra](?=[:}]$)/,alias:"punctuation"},rest:null}},string:/[\s\S]+/}},"triple-quoted-string":{pattern:/(?:[rub]|br|rb)?("""|''')[\s\S]*?\1/i,greedy:!0,alias:"string"},string:{pattern:/(?:[rub]|br|rb)?("|')(?:\\.|(?!\1)[^\\\r\n])*\1/i,greedy:!0},function:{pattern:/((?:^|\s)def[ \t]+)[a-zA-Z_]\w*(?=\s*\()/g,lookbehind:!0},"class-name":{pattern:/(\bclass\s+)\w+/i,lookbehind:!0},decorator:{pattern:/(^[\t ]*)@\w+(?:\.\w+)*/m,lookbehind:!0,alias:["annotation","punctuation"],inside:{punctuation:/\./}},keyword:/\b(?:_(?=\s*:)|and|as|assert|async|await|break|case|class|continue|def|del|elif|else|except|exec|finally|for|from|global|if|import|in|is|lambda|match|nonlocal|not|or|pass|print|raise|return|try|while|with|yield)\b/,builtin:/\b(?:__import__|abs|all|any|apply|ascii|basestring|bin|bool|buffer|bytearray|bytes|callable|chr|classmethod|cmp|coerce|compile|complex|delattr|dict|dir|divmod|enumerate|eval|execfile|file|filter|float|format|frozenset|getattr|globals|hasattr|hash|help|hex|id|input|int|intern|isinstance|issubclass|iter|len|list|locals|long|map|max|memoryview|min|next|object|oct|open|ord|pow|property|range|raw_input|reduce|reload|repr|reversed|round|set|setattr|slice|sorted|staticmethod|str|sum|super|tuple|type|unichr|unicode|vars|xrange|zip)\b/,boolean:/\b(?:False|None|True)\b/,number:/\b0(?:b(?:_?[01])+|o(?:_?[0-7])+|x(?:_?[a-f0-9])+)\b|(?:\b\d+(?:_\d+)*(?:\.(?:\d+(?:_\d+)*)?)?|\B\.\d+(?:_\d+)*)(?:e[+-]?\d+(?:_\d+)*)?j?(?!\w)/i,operator:/[-+%=]=?|!=|:=|\*\*?=?|\/\/?=?|<[<=>]?|>[=>]?|[&|^~]/,punctuation:/[{}[\];(),.:]/},Prism.languages.python["string-interpolation"].inside.interpolation.inside.rest=Prism.languages.python,Prism.languages.py=Prism.languages.python},59385:()=>{!function(e){e.languages.ruby=e.languages.extend("clike",{comment:{pattern:/#.*|^=begin\s[\s\S]*?^=end/m,greedy:!0},"class-name":{pattern:/(\b(?:class|module)\s+|\bcatch\s+\()[\w.\\]+|\b[A-Z_]\w*(?=\s*\.\s*new\b)/,lookbehind:!0,inside:{punctuation:/[.\\]/}},keyword:/\b(?:BEGIN|END|alias|and|begin|break|case|class|def|define_method|defined|do|each|else|elsif|end|ensure|extend|for|if|in|include|module|new|next|nil|not|or|prepend|private|protected|public|raise|redo|require|rescue|retry|return|self|super|then|throw|undef|unless|until|when|while|yield)\b/,operator:/\.{2,3}|&\.|===||[!=]?~|(?:&&|\|\||<<|>>|\*\*|[+\-*/%<>!^&|=])=?|[?:]/,punctuation:/[(){}[\].,;]/}),e.languages.insertBefore("ruby","operator",{"double-colon":{pattern:/::/,alias:"punctuation"}});var t={pattern:/((?:^|[^\\])(?:\\{2})*)#\{(?:[^{}]|\{[^{}]*\})*\}/,lookbehind:!0,inside:{content:{pattern:/^(#\{)[\s\S]+(?=\}$)/,lookbehind:!0,inside:e.languages.ruby},delimiter:{pattern:/^#\{|\}$/,alias:"punctuation"}}};delete e.languages.ruby.function;var n="(?:"+[/([^a-zA-Z0-9\s{(\[<=])(?:(?!\1)[^\\]|\\[\s\S])*\1/.source,/\((?:[^()\\]|\\[\s\S]|\((?:[^()\\]|\\[\s\S])*\))*\)/.source,/\{(?:[^{}\\]|\\[\s\S]|\{(?:[^{}\\]|\\[\s\S])*\})*\}/.source,/\[(?:[^\[\]\\]|\\[\s\S]|\[(?:[^\[\]\\]|\\[\s\S])*\])*\]/.source,/<(?:[^<>\\]|\\[\s\S]|<(?:[^<>\\]|\\[\s\S])*>)*>/.source].join("|")+")",r=/(?:"(?:\\.|[^"\\\r\n])*"|(?:\b[a-zA-Z_]\w*|[^\s\0-\x7F]+)[?!]?|\$.)/.source;e.languages.insertBefore("ruby","keyword",{"regex-literal":[{pattern:RegExp(/%r/.source+n+/[egimnosux]{0,6}/.source),greedy:!0,inside:{interpolation:t,regex:/[\s\S]+/}},{pattern:/(^|[^/])\/(?!\/)(?:\[[^\r\n\]]+\]|\\.|[^[/\\\r\n])+\/[egimnosux]{0,6}(?=\s*(?:$|[\r\n,.;})#]))/,lookbehind:!0,greedy:!0,inside:{interpolation:t,regex:/[\s\S]+/}}],variable:/[@$]+[a-zA-Z_]\w*(?:[?!]|\b)/,symbol:[{pattern:RegExp(/(^|[^:]):/.source+r),lookbehind:!0,greedy:!0},{pattern:RegExp(/([\r\n{(,][ \t]*)/.source+r+/(?=:(?!:))/.source),lookbehind:!0,greedy:!0}],"method-definition":{pattern:/(\bdef\s+)\w+(?:\s*\.\s*\w+)?/,lookbehind:!0,inside:{function:/\b\w+$/,keyword:/^self\b/,"class-name":/^\w+/,punctuation:/\./}}}),e.languages.insertBefore("ruby","string",{"string-literal":[{pattern:RegExp(/%[qQiIwWs]?/.source+n),greedy:!0,inside:{interpolation:t,string:/[\s\S]+/}},{pattern:/("|')(?:#\{[^}]+\}|#(?!\{)|\\(?:\r\n|[\s\S])|(?!\1)[^\\#\r\n])*\1/,greedy:!0,inside:{interpolation:t,string:/[\s\S]+/}},{pattern:/<<[-~]?([a-z_]\w*)[\r\n](?:.*[\r\n])*?[\t ]*\1/i,alias:"heredoc-string",greedy:!0,inside:{delimiter:{pattern:/^<<[-~]?[a-z_]\w*|\b[a-z_]\w*$/i,inside:{symbol:/\b\w+/,punctuation:/^<<[-~]?/}},interpolation:t,string:/[\s\S]+/}},{pattern:/<<[-~]?'([a-z_]\w*)'[\r\n](?:.*[\r\n])*?[\t ]*\1/i,alias:"heredoc-string",greedy:!0,inside:{delimiter:{pattern:/^<<[-~]?'[a-z_]\w*'|\b[a-z_]\w*$/i,inside:{symbol:/\b\w+/,punctuation:/^<<[-~]?'|'$/}},string:/[\s\S]+/}}],"command-literal":[{pattern:RegExp(/%x/.source+n),greedy:!0,inside:{interpolation:t,command:{pattern:/[\s\S]+/,alias:"string"}}},{pattern:/`(?:#\{[^}]+\}|#(?!\{)|\\(?:\r\n|[\s\S])|[^\\`#\r\n])*`/,greedy:!0,inside:{interpolation:t,command:{pattern:/[\s\S]+/,alias:"string"}}}]}),delete e.languages.ruby.string,e.languages.insertBefore("ruby","number",{builtin:/\b(?:Array|Bignum|Binding|Class|Continuation|Dir|Exception|FalseClass|File|Fixnum|Float|Hash|IO|Integer|MatchData|Method|Module|NilClass|Numeric|Object|Proc|Range|Regexp|Stat|String|Struct|Symbol|TMS|Thread|ThreadGroup|Time|TrueClass)\b/,constant:/\b[A-Z][A-Z0-9_]*(?:[?!]|\b)/}),e.languages.rb=e.languages.ruby}(Prism)},70767:()=>{!function(e){for(var t=/\/\*(?:[^*/]|\*(?!\/)|\/(?!\*)|)*\*\//.source,n=0;n<2;n++)t=t.replace(//g,(function(){return t}));t=t.replace(//g,(function(){return/[^\s\S]/.source})),e.languages.rust={comment:[{pattern:RegExp(/(^|[^\\])/.source+t),lookbehind:!0,greedy:!0},{pattern:/(^|[^\\:])\/\/.*/,lookbehind:!0,greedy:!0}],string:{pattern:/b?"(?:\\[\s\S]|[^\\"])*"|b?r(#*)"(?:[^"]|"(?!\1))*"\1/,greedy:!0},char:{pattern:/b?'(?:\\(?:x[0-7][\da-fA-F]|u\{(?:[\da-fA-F]_*){1,6}\}|.)|[^\\\r\n\t'])'/,greedy:!0},attribute:{pattern:/#!?\[(?:[^\[\]"]|"(?:\\[\s\S]|[^\\"])*")*\]/,greedy:!0,alias:"attr-name",inside:{string:null}},"closure-params":{pattern:/([=(,:]\s*|\bmove\s*)\|[^|]*\||\|[^|]*\|(?=\s*(?:\{|->))/,lookbehind:!0,greedy:!0,inside:{"closure-punctuation":{pattern:/^\||\|$/,alias:"punctuation"},rest:null}},"lifetime-annotation":{pattern:/'\w+/,alias:"symbol"},"fragment-specifier":{pattern:/(\$\w+:)[a-z]+/,lookbehind:!0,alias:"punctuation"},variable:/\$\w+/,"function-definition":{pattern:/(\bfn\s+)\w+/,lookbehind:!0,alias:"function"},"type-definition":{pattern:/(\b(?:enum|struct|trait|type|union)\s+)\w+/,lookbehind:!0,alias:"class-name"},"module-declaration":[{pattern:/(\b(?:crate|mod)\s+)[a-z][a-z_\d]*/,lookbehind:!0,alias:"namespace"},{pattern:/(\b(?:crate|self|super)\s*)::\s*[a-z][a-z_\d]*\b(?:\s*::(?:\s*[a-z][a-z_\d]*\s*::)*)?/,lookbehind:!0,alias:"namespace",inside:{punctuation:/::/}}],keyword:[/\b(?:Self|abstract|as|async|await|become|box|break|const|continue|crate|do|dyn|else|enum|extern|final|fn|for|if|impl|in|let|loop|macro|match|mod|move|mut|override|priv|pub|ref|return|self|static|struct|super|trait|try|type|typeof|union|unsafe|unsized|use|virtual|where|while|yield)\b/,/\b(?:bool|char|f(?:32|64)|[ui](?:8|16|32|64|128|size)|str)\b/],function:/\b[a-z_]\w*(?=\s*(?:::\s*<|\())/,macro:{pattern:/\b\w+!/,alias:"property"},constant:/\b[A-Z_][A-Z_\d]+\b/,"class-name":/\b[A-Z]\w*\b/,namespace:{pattern:/(?:\b[a-z][a-z_\d]*\s*::\s*)*\b[a-z][a-z_\d]*\s*::(?!\s*<)/,inside:{punctuation:/::/}},number:/\b(?:0x[\dA-Fa-f](?:_?[\dA-Fa-f])*|0o[0-7](?:_?[0-7])*|0b[01](?:_?[01])*|(?:(?:\d(?:_?\d)*)?\.)?\d(?:_?\d)*(?:[Ee][+-]?\d+)?)(?:_?(?:f32|f64|[iu](?:8|16|32|64|size)?))?\b/,boolean:/\b(?:false|true)\b/,punctuation:/->|\.\.=|\.{1,3}|::|[{}[\];(),:]/,operator:/[-+*\/%!^]=?|=[=>]?|&[&=]?|\|[|=]?|<>?=?|[@?]/},e.languages.rust["closure-params"].inside.rest=e.languages.rust,e.languages.rust.attribute.inside.string=e.languages.rust.string}(Prism)},30218:(e,t,n)=>{var r={"./prism-ada":85795,"./prism-bash":57874,"./prism-csharp":79016,"./prism-dot":60397,"./prism-haskell":81295,"./prism-java":52503,"./prism-nix":58704,"./prism-pascal":13210,"./prism-python":80366,"./prism-ruby":59385,"./prism-rust":70767};function a(e){var t=o(e);return n(t)}function o(e){if(!n.o(r,e)){var t=new Error("Cannot find module '"+e+"'");throw t.code="MODULE_NOT_FOUND",t}return r[e]}a.keys=function(){return Object.keys(r)},a.resolve=o,e.exports=a,a.id=30218},92703:(e,t,n)=>{"use strict";var r=n(50414);function a(){}function o(){}o.resetWarningCache=a,e.exports=function(){function e(e,t,n,a,o,i){if(i!==r){var s=new Error("Calling PropTypes validators directly is not supported by the `prop-types` package. Use PropTypes.checkPropTypes() to call them. Read more at http://fb.me/use-check-prop-types");throw s.name="Invariant Violation",s}}function t(){return e}e.isRequired=e;var n={array:e,bigint:e,bool:e,func:e,number:e,object:e,string:e,symbol:e,any:e,arrayOf:t,element:e,elementType:e,instanceOf:t,node:e,objectOf:t,oneOf:t,oneOfType:t,shape:t,exact:t,checkPropTypes:o,resetWarningCache:a};return n.PropTypes=n,n}},45697:(e,t,n)=>{e.exports=n(92703)()},50414:e=>{"use strict";e.exports="SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED"},64448:(e,t,n)=>{"use strict";var r=n(67294),a=n(63840);function o(e){for(var t="https://reactjs.org/docs/error-decoder.html?invariant="+e,n=1;n

Submitting

In case you have any questions, feel free to reach out to me.

-
+
\ No newline at end of file diff --git a/c/category/bonuses/index.html b/c/category/bonuses/index.html index 334edda..52b2c6b 100644 --- a/c/category/bonuses/index.html +++ b/c/category/bonuses/index.html @@ -16,8 +16,8 @@ - - + +

Bonuses

Bonus assignments for Kontr Coins. diff --git a/c/category/practice-exams/index.html b/c/category/practice-exams/index.html index e0f8a88..5b99153 100644 --- a/c/category/practice-exams/index.html +++ b/c/category/practice-exams/index.html @@ -16,8 +16,8 @@ - - + +

Practice Exams

Practice exams for training for the final exam. diff --git a/c/index.html b/c/index.html index 98d1934..246df49 100644 --- a/c/index.html +++ b/c/index.html @@ -14,10 +14,10 @@ - - + + -

+ \ No newline at end of file diff --git a/c/mr/index.html b/c/mr/index.html index 2983018..f330b0a 100644 --- a/c/mr/index.html +++ b/c/mr/index.html @@ -14,8 +14,8 @@ - - + +

Submitting merge requests for review

@@ -87,6 +87,6 @@ For the sake of safety, do not continue without clean repository. Then with comm be main or trunk.

aisa$ git status
# Check if repository is clean

# If you know, what is your default branch, you can skip next command.
aisa$ git branch
# Find the default branch in the list; should be one of the `master`, `main` or
# `trunk` and you should not have more than one of those.
# In case the list clears the terminal and you cannot see shell prompt, you can
# press `q` to quit the pager.

aisa$ git checkout master

-

Adapted from: https://www.fi.muni.cz/~xlacko1/pb071/mr.html

+

Adapted from: https://www.fi.muni.cz/~xlacko1/pb071/mr.html

\ No newline at end of file diff --git a/c/pexam/cams/index.html b/c/pexam/cams/index.html index 5791cdb..8da5362 100644 --- a/c/pexam/cams/index.html +++ b/c/pexam/cams/index.html @@ -16,8 +16,8 @@ - - + +

Watching Cams

diff --git a/c/pexam/garbage_collect/index.html b/c/pexam/garbage_collect/index.html index 6e1c9eb..5cc0e28 100644 --- a/c/pexam/garbage_collect/index.html +++ b/c/pexam/garbage_collect/index.html @@ -16,8 +16,8 @@ - - + +

Garbage Collection

diff --git a/contributions/index.html b/contributions/index.html index 62f4a80..49aa973 100644 --- a/contributions/index.html +++ b/contributions/index.html @@ -14,8 +14,8 @@ - - + +

Contributions

Many of my contributions to open-source projects.

centpkg

Description

A tool for working with CentOS dist-git.

Contribution

I have fixed a bug that caused centpkg-sig to be unable to clone the dist-git repos from SIGs.

Fedora Messaging

Description

A library for sending AMQP messages with JSON schema in Fedora infrastructure.

Contribution

I contributed a small packaging fix that has been introduced by a new feature.

flexmock

Description

Flexmock is a testing library for Python that makes it easy to create mocks, stubs, and fakes.

Contribution

I've converted the interception for pytest after they've changed their internal design to use pytest's hook system.

tmt

Description

The tmt tool provides a user-friendly way to work with tests. You can comfortably create new tests, safely and easily run tests across different environments, review test results, debug test code and enable tests in the CI using a consistent and concise config.

Contribution

Just a smallish contribution to the docs related to the changes implemented on the Packit side.

Fedora Infrastructure Ansible

Description

Collection of Ansible playbooks that powers the Fedora Infrastructure.

Contribution

I have adjusted the groups in the Bodhi playbooks after Packit has been granted the privileges to propose updates without restrictions.

Bodhi

Description

Bodhi is a web-system that facilitates the process of publishing updates for a Fedora-based software distribution.

Contribution

I have adjusted the client, so that it doesn't show secrets in terminal when you log in to the Bodhi via browser.

Gluetool Modules Collection

Description

Modules for gluetool — a command line centric framework usable for glueing modules into a pipeline.

Contribution
  • I have proposed a possible implementation of git merging that was later on extended.
  • I have tried to help out with Copr module after they deprecated older version of their API.

Pagure

Description

Pagure is a git-centered forge, python based using pygit2.

Contribution

I have added an API endpoint for reopening pull requests.

Copr

Description

RPM build system - upstream for Copr.

Contribution
  • Supporting external repositories for custom SRPM build method.
  • Allowing admins of Copr repositories to build without the need to ask for explicit builder permissions.

python-gitlab

Description

A python wrapper for the GitLab API.

Contribution

I have contributed support for the merge_ref on merge requests that hasn't been supported, yet it was present in the GitLab API.

PatternFly React

Description

A set of React components for the PatternFly project.

Contribution

When working on Packit Dashboard, I have spotted smaller bugs that were present in this project and fixed them upstream to provide better experience for our users.

Fira Code

Description

Free monospaced font with programming ligatures.

Contribution

I have set up a GitHub Action for building the font on each push to the default branch allowing users to install bleeding edge version of the font.

nixpkgs

Description

Nixpkgs is a collection of over 80,000 software packages that can be installed with the Nix package manager. It also implements NixOS, a purely-functional Linux distribution.

Contribution

When I was trying out the nixpkgs, I have tried to bump .NET Core to the latest version. My changes haven't been accepted as they required bumping of multiple more packages that depended upon the .NET Core.

Darcula

Description

A theme for Visual Studio Code based on Darcula theme from Jetbrains IDEs.

Contribution

I have contributed support for diff files, though the project doesn't seem to be live anymore, so it hasn't been accepted as of now.

Packit

Description

An open source project aiming to ease the integration of your project with Fedora Linux, CentOS Stream and other distributions.

Contribution

Have a look at my pull requests.

Snitch

Description

Language agnostic tool that collects TODOs in the source code and reports them as Issues.

Contribution
  • Environment variable support for self-hosted GitLab instances
  • GitLab support

Karel the Robot

Description

Karel the robot is in general an educational programming language for beginners, created by Richard E. Pattis. This is implementation of Karel the Robot for C programming language.

This project is used for educational purposes at TUKE.

Contribution

I have contributed some refactoring tips to the author of the library.

diff --git a/cpp/category/exceptions-and-raii/index.html b/cpp/category/exceptions-and-raii/index.html index b225c58..53ab215 100644 --- a/cpp/category/exceptions-and-raii/index.html +++ b/cpp/category/exceptions-and-raii/index.html @@ -16,8 +16,8 @@ - - + +

Exceptions and RAII

Materials related to the exceptions or RAII in C++. diff --git a/cpp/environment/index.html b/cpp/environment/index.html index 4c81205..45f5161 100644 --- a/cpp/environment/index.html +++ b/cpp/environment/index.html @@ -16,8 +16,8 @@ - - + +

Environment

Required tools per OS

diff --git a/cpp/exceptions-and-raii/placeholders/index.html b/cpp/exceptions-and-raii/placeholders/index.html index 9663a59..86373b1 100644 --- a/cpp/exceptions-and-raii/placeholders/index.html +++ b/cpp/exceptions-and-raii/placeholders/index.html @@ -16,8 +16,8 @@ - - + +

Placeholders

Here we will try to implement some placeholders that you can find in other diff --git a/cpp/index.html b/cpp/index.html index d2b1691..8da37d8 100644 --- a/cpp/index.html +++ b/cpp/index.html @@ -14,10 +14,10 @@ - - + + -

+ \ No newline at end of file diff --git a/files/algorithms/graphs/iterative-and-iterators.tar.bz2 b/files/algorithms/graphs/iterative-and-iterators.tar.bz2 index 51876341131cc60771420ba538df07df34209027..6bd469cdd92cc936880ebcaff2ffe10dbf2602fa 100644 GIT binary patch delta 1835 zcmV+`2h{kH50MWJLRx4!F+o`-Q&~5;>0gl!D1VFq)f5T<005xi$TVmJCYXkr41*BD z27u9th|mB4(^EjEnhBAUMvVZ|KxhB}000bt4h(}vfHG-_X`sk43?OI?7?_O!00~c0 zO$ub%qej$e>KbGK4FJ)Q00xaTWM}~3$TVmJCYXkr41*BD27u9th|mB4i9rG;g!IrL z!abQbrbebdPjI$Nrk z*h>k5S_Yvwamu-o@f88&lLrAve_}utHwgg&Dgq~f2kr5(3;m@j><{6ZXk_I0te;QP z{Z!a)aK^EonIzrfRQl~pUUd?4w|>`Su!3UqFw!mTl0*A>{Vp=r>|seq!Uyvi`D3kZV4;b$-hEYcn>HX>}r zNHgu3-@5WFCu3qsvv4RFe<0mCh_vU1jy#EoB`~DKWEPB;oLqvt83YazzEE5&q+A@@ z!5KEVTA^U}G_8V!2wM*dY?@Y5(3u(0%WDkcg4t_cqCikAs98L~B4n~dL^bV=hr$tC z{7yQ*1E>cFEgb4>3deI&hT?|M;ineDxDAH9xyW8CL4G{U_W*Sqf5BSga`gA3Di(P# zz%jivz%bsrRl4VkSDh*Jph9XR{r4gu*#VwKQ#QHEK;Jp$3)NOlA5UvPn5(%9te%?ZBbyGnxtiVZqXlfH0 z;c}VSOI%7;(wC$Ye++02gWmC7#TT3%Lg1jb=Pk%R@0)JW z4NU;PEtBGKOupS^Q590$jq`cnGzdYkUL+gCyqX*>izUemly6!c$~7?Z>9ryit~t%S zb1Q>{B}%d%G3-{g;uxlEGn|@H3j+vd5((^xm332R3#m332Zk*MCIW;R1|n)f+<7_H zs#?ku)K_F(f9;yabPp##%y>gUql5$7O|O*qP|Pz3YA_#QwNPj#z)!tACmn>y1KY7` zVvKjlJOcwo17ffb#5j;OACe`Jfl$|QiBvq{P(HCZ!*Ji79fbfO$C;s+y)+ttL4 z4l|FQEC~eGW)%*5OuK`=HXyj8&V|Lu-bC}2N_8pt4(E+nJm)`bIo|$*;0TofExueb z@Da}Hf9F+vnCKi~$Q&Gn5h)lDLW%tVsQw^XI>4-924oQrgQNq6*|HvP0qHUuhX?uK z9ckxE+Tvgdi0d9i!h=vU|J%L4NALXUN%~Xgtu{Xxx+A_X8{FvWqf3+%x4Qy~LK@#d z7Y?70@1Le|>N5%;b^&Bvn#!vXlAu*6$_^uBf3O~nfLVzw$QXTLhz1~+?+I}7?pJ)@ zFaXd?4K);QCjzxbYT8p414X2{VF83P?82L(sq9=D#v!4eU^5HH|FLnW4=Ze5yc}O?ITR zXcX0m9RTHV3$OB{gbwJsl8sWURDd5V0HR`?!t+Ikknj!P*`g^4dSWI=sL`MR0000000STcgCNnM44PsZXfg~#2pR)MCL=%q0#nqJ zLYX$G(X|?ShM52ZKs00k0i#VB8UQ#l4H^K+rXi+-AjB|%pfqA)Gyni1P(YG-4KxTa zrcz81shCYPPf6-x89hU4X`@XtH2$J~zjO9PGv?>$fq`sLr5K}3gaqloZk;_nR??W% zN(pqd4xuN^lL!Gwf8ihsn}mRXl>rmH1NQjX zh5pi%_J{DzG%|90R!^tteyVFXIAd7POp=NhFeCf>=3duSXK#{e#n?3A^vR_Rol z22?3n2GU9{gGwkN0!}uo*|AFcehRnMM^s zVGvk+Eam{^nnT6L#7&r~27R+T_g+PW>}*LkZUqALe;Y?F7PR4`j~3YkrWII>g4B~K z#mFo%kU-%pQcTq5DLF zXG}XcQ$|?A71V}eZ(t<3dZ}9pOcb^0SwS$cf0n2@Wye@o9Nkz!MpT3P(JE$U0#@MmLriDdm1zwIga> ze}TS*s2Gq8NhN4X>%MKfKs7W1__j}p!7}@Gl|)rbayQNAfY2cZ!FZ5w4&rEVHY}GU zE>XQ`cBs_D%cj(bR=DRj?aZzY5S1#(eCM@V*N9@7u+DO6L@W#;m`EqKB30E*d=8}6 zU>*3h7?=tWWEhF52XW-*TB&O&Pf=Zwe|NTP8PGhO|2f|c0*(+5bvC|J-$O9WA*jH8 zqSZm5n!!Hw@0@lMAP;u6sfsb!LEjh}C>qs(ej&txsQi&Ej0%SJ!X;4ig+Thm;|;@p zbaj*fgC1svV)W2z0R|EGB5Pl1)`4V!2h4rKavf(Gw~B&p8ix&DrFbx*5Uhi2e_CN4 zVQyy$d@55;b5U*)xV}XcagnxEJJeAcfiiIVT#X+LI=qX{LI)+ZAB*n|Ky+owC!9`P zm4qP$-yR{jN529Pks!tr5aT%c;=qti<1nam+GW}ugJKJcJm_3pj>0FLs#B>?z;`@q z!RI;qA9D%>cQ4*1X1Sp@-3XkFildKBH5N1IT z_)tA?LP~*DqbN9yf0Dp@HGyU% zvmjyhh9DS%U$`a1%eh^K!vGBgu+w;&CRZvH2r;h^(&_VV6R&(eCOH-Sk!mi0ls2A= z9KDV<5RfETL?|9JFtEN*FykEx8&k%1M`q(dza;S#ixR2_Q&iwaqkwXh9XVtpuV%;0NJO)MaHpTZ zj-#0#kgPaGhi8DhfQD{@PzoR#dW5hB)W{pVL(CN94sG0)2ttKIQK^3EVPIQGCtGI2 z?>0Beq#gY?g5lWmqo^twQG<}2{N$b#=&3q~*cY^)mc2wy#L+hgf2`qOVF+J~C=}gV z5N>g4VXzV*p%USnfh4(-cqw5TDFcaKARPj_Atx^Dbm<1CQ<`>3ea|M0`cYxucK%>K8r-RyF$LspgPKc}j#oUoj6eJ|~Ufh7=Yde_$ diff --git a/files/algorithms/graphs/iterative-and-iterators.tar.gz b/files/algorithms/graphs/iterative-and-iterators.tar.gz index 4240e9ca311427d85f03905ade6726e98e05db36..f40c007e7fbfb89630e44234622a0191003842c8 100644 GIT binary patch literal 1938 zcmV;D2W|KtiwFP!000001MON{bJ{o*&NDOp4_am)%#=D10?ZUbr%6b)eTHqIkGk#(5 zPcHFxuZS_9db;V&iTmfy-Oym@?C-~a#P!?>)!z?CI=fXJ zJgYpbAOvD_Oz85Ixc+x?QW;NgWB6Npa?(t{x8b^Df9r=0`9uThVy@~*-7WW+iI)x|6bsGmUD&9 zmmbA4{m8X#c92@GG>?vQUf8q%=R~G*1b*BSz|y2-V6g zJ!Cpy;W|sqBE7mbL7G@(M3$$RUK+NKVKLXIXu-A?A3P!M?4p*QyEc#yb1N4q`&R|_ zeQ{kIy)nEWY9GPWCr;eVBiEsZ<#-ZXE0UQL!}f4dn136xZ6nTIC>dtsFkDQQ?(I7S zE3Qq@N;wtCGhU_-XLGvb#gwmT6>RyHVrY*HMg9Ny#F{L zAK2Xg^P0Wr+^j~*_U(0(=W61OGZ3&Gil{Zi*|wc*!Ax$zZh5B5S|1(<%{nV1BLEUj zCzfM*(>v+moM(W}DGbTf2mu*gU;)&Ukx3ugbZU7zA7QG4*yVSVAR&MFj+RlxV#`!C zddVYw;u36_Q=~!jSa6!b+!ib8A%T%~66i$Su@4hX%&Vb;1L3RAX`gHsfLX`eo0wG> zJu=mJqP`(<77(-|2v50y1RWJNJgp1%K(Gf?3{m1|jD>K_4LS|UAZ66Gud!q%8+I+3 z)-W(!v&{b}3kAMuQF(vj_I|F5>Iy!wKqKw>bI=tOmktCw6+*CHKl8n*rUg!mq$Vf^ zAF0*SKHN+#8zYUYIC6cqH3z66^9RDDv9o|)2Fdh%lNF4|x(HY)Y{2+B6QwXxzeE%C zcg*Ma_?Bu?>Js_n&eJ?)9l3Bje~N5c2QPL@5<&iOBCA4#S$QVPJ!bNePY8Bs+0ut_ zIm|<01~Ve7N)jjTS*#`^4Qt%SI2a^C7OR#zgr^a2Vv(M3x8!LF$MbZEr~PnS zNLBFi&%vwUherkqrl2Pg7Bh`}F98GPELI6X!OG1`+fDy*nTGR4G2twh5? zSJp;p{t8k4>SI5wh~MG=)O%+Dm(hm~{~OS4IoTGH8`-wc78Ih#SSXcIYgP@S62e10 ztga-d^J~4eM2vp-iumh-sanq|Caq9fGB&VCvVoH21`v5(6y-RMb-wwG^(X%`dXAd; z(}F7Cll&at0LkR0-w20TN%lqNmT=6E9OKU;W!}a<5>ov%Xfx0M$jv3qd_0ftj$Q?o zkwHFVytDE`#Pis%{zx%*HfBhY&fT^#0{{tZm ziYB(JgTqIVAdeEJe}Ik{RiSuzYs}_0=0h1e6SA1t*Sl}o_6${IT>NVCbdfapke9*g2@f(oH-~*K3V4@j$I+L&QWlju^4D|tx1Pe^ zMKv`iCB)<5l@YorBSbd{1(7cybh|-lDY98CM9M5jM81oK7G*+kQzn?VWi$naSS<9d zOq~362xJX1|Cu7#n*59YcZTI?qPRbOMh3aclx%!I$o8*f`-~^vh#0J{J;M$koEV!A z_mFrV()q(ougq@R{48_C&MMc&`bWZ=*;~uO+OO5`LcvNKzeL~TCh3XSXuO4ZUiiT_kVT%W+Ztw-?tuk7#t_Bwl=?hb0+hjBl7|9=GE|4Z`U-fOluV0*kxL`v6b?0PT|6=Kufz literal 1937 zcmV;C2X6QuiwFP!000001MOPfa@sf)&NVZA2Q9M~W=b6(0cHxJ(*Ss$3f1>E0L42`E(fRoLp!&`-iR-x&s=ptObZDv$ zo>iVz5Mp9;Oz7g2xc+>=nxOH6Pv<@zE#`PIyv6<9#C<3+GRPICC&ZZH8<$)U98BAK zqraPN7qh^C_r7f#Uu-onyoK-)eTU@$c?+)cJoe@IA}9Lgx#Q z;+cNr+BO`dmg{)>DF$~~X0MWxcxyRddzFd<=e9RDOpF9iK;QZ4jU9i6K#5Dj28NGQ z$f`PmWLnhGp>3GgylYwEKc;PX9^#qS9}UpW6cda_=p}Mo>cG*TP&6l2U{H+CT|)8r z98)$RfMQ^o*h2@%!8fTst=7vKdu;JV8f4KQ)l*{z2#>Ea+6tuE6!9GX7uzz^=3PeS z#miuT+J_Ee<6}FQYw7~m8l%_aG1G)^wGr}b8D)_c9i%irv1lF=wj9w@mw2dFX6hm6 zU=!CNFhO>9Yl1W}$%rgYF}*ZwAG66^pP~S^7VkVE?(CwL9lJ7+cXKO)jQz_3`@XoY zjoujE54DeA>Jukv=8@}A!*V={trf}0iD7%V$j!eEVcUpvm!%BYIE*Hfg?sx8Vl%Ex z&`K>Tlm}j>4`*|_;K`J)Xc=z#rDAB03`O<-_~d*G)qi9C-)}YcGWEaH-EXS;e;?Rf z|MQBysN9evW$X5;$a6Kx!Wjx!4n@?O;q|heF2Nu-fF{p$q4eQ#SghA&WCTE>>BMp@ zZ+a&^obwFOIb~fkH9|l}7r=p9+B4Zhn@%lH=RKf0^j&^62?O$n?`Ug^z_*~H(Muoc z6PIAaoFa`CkATw*Shko+j|hyclCVm|7xrPIiE%Y_a3I#IbJ`~x#Q@gv@+L;rMUBi9 zp15vE7RwNpBIcfQ4hbtN+win5*aN{Hqhg2>f6Z9tj=4dn5gDXFUHcjYGhMK2>99tQ z;hJUZkE2kqHZ4x?Pu$+mb&*}+9XJ|k&!010VRGq=U}s#&tk=(cZ>nkGqD4?s6odEF zYS}g1Of4HDjjK3veb|}<)R3)*xk-bwfL?~d^n4Q%#)B%ttQ0n2e7)wS$Wy<>1N3*W z=J)uPYEtSFugRTfdCJOj(RTh6+q80CqDkUG{%|78LWChbQ|X>C`N$^(JG5--Gj}<# zLSY6Nv93zuC%&>oPQ)5kYfChh%Z{{1d6vXFq^S~j*J@ket>M86=?Di7x@0`~13AVM z!?$VwqK+;HTH;LQ4QOH;S6&@mFz$be#zL4A;#ww|S$VpM%af${Qd+ziSm60gd5oKN z7IAIXpZ8dk5KG!$bfU338Rx=lDxMM!1}T>%vZc=4(?}MvSWmQD^0Y+#c{;??ezYy5 zDtLPG@yYGcQ;!6X0Y&`(@P7FJ9^?F3{@-pW{(m31EB`;-BLA1Od}=tRoK%N)eAc8SJw^u!+LJaa%BWZ}!^B0d#NA<4 z)<#+W%Dnv5$9|L%zq7wH@0}UAj6QVuZ%DW0WLrpXWZOPWC`6C3P%5L=kPRXeqC-8( zt~96fYrU03f`0dk_-g>FR%41uD@!dI8wk>Dpk%r+h&TsDF-~F?Z$4sm=YK}eQ8Ry7 zm<4>0pR+cGba1n8gd;2^`(mw0EXZ|e{!UWB%;(0^TLcar|*t%Azty{%Q>W>M7P6 zR5N2TLfju-8KIjpLUe;r==l;tw;O~OBAUfQq|9_g#JgB1DC2^gGS0j$qbW?pVxezk z{N%4(AS;mh&lKU-_1ND%ZyPM*_v{t>s|t*XnnnV5yB?qVGwQ^wev#aQiLmXp)sn zye5mJYT1}1|5ZU;pTN7VNAUk&>;M1P>g+X|JE(ad#{J~={}Fuum&Cu_YIQfne_O_> z_&@afUwQoZHpG8h#;N!}^z)x2{@qryy&?YFGVUjjzk-5-f`WpAf`WpAf`WpAf`WpA Xf`WpAf`Wp={|Em90Si*J08jt`AdcHq diff --git a/files/algorithms/paths/bf-to-astar.tar.bz2 b/files/algorithms/paths/bf-to-astar.tar.bz2 index 19ed026f586878a8dcb4994a8133c617312b12d7..8ca28a3eeddcb119546e338338b4ffe84b00e6ef 100644 GIT binary patch delta 3162 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 Aa{vGU delta 3146 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 diff --git a/files/algorithms/paths/bf-to-astar.tar.gz b/files/algorithms/paths/bf-to-astar.tar.gz index be818778bfe4a943854f02eb38538959997d8682..eb5ccecf9e8e5366c93467043d1917e2e77f1041 100644 GIT binary patch literal 2994 zcmV;j3r+MNiwFP!000001MOSsa@)ue*5Bn*Or%5xX^|pzR!E5{`H=0zv0bvWt13ms zg2*9>2*gmpfFh$+)xOr|XC7srB;7p&U;rKxE!p19V(cQpIeU8g___zW=$54@+kv$G zP5P|#hr^Y}EmbIcJ3IJY+uyCx@7n%8eM8xK4$o`;dRJQFP;J!4gx}n#Wj__>PtQEuQx==cMSo zQ8-r%1v`|2k+fQE;RTXW<2vhYF!g%`#PD%TuCqXdew#=2IB=cyiv05)az=o z1M}JOWV6X`pxfpq8`zhe1)I!FJt28O z1Yhu;<9UwPW7mD|t4*{89IX?uDxL$1##t~1_Ds&%p+5fxw8XqTgBIw4tyNlkcop)H zwyd3ot+AYPDPXOm&4-rH}2@)D=FnOa(jZ z0Bs#0uFhV(IeGc~)0_A2J|@!>`6E1>G=s;$U>rHY?@6&?cBeBw1o_7YE8JkCqF!Bz zbr<*Ewmmiwuzwgpg27#v*}wruJ_$f{q~!hv^SNt}|NApkQd>Ce*pf41zn&0TLks@l zaHcx3^>st|6Twovd8&v#FdJw`&`LWrIL+pFg5A!Zxe<>YhCx3oL0PrT@Ob`mDBPnW zGB)P?ZG8T>$ZMa=(DxFm8U?6c<6Z~&wOKO!1uJb9zO`e^%e~5lf&VVLUjY2A+=>78 zceb`O_-}h}cQ?m>U!%nM@7Zx0{OR9|L7oHV2<+nEVQ>ykKss$@=UeSQZ(p_)fXkx0 z1&CuIj#^J_)&?LTz=w;bLd3%q8NzcXV22e@LBL3DXuRpc84P`JHv{g;mU6YaZv<&V zZ)mqK71E*|fdLnO2Z0TtKcod07_m(j1EYp+7*oTa%my`UaOn(V{}yP+2M~#oiz+Dp zmGvEmvt3!_inMLl)N6weYxU5R`XcQ0X+;mg-vuC_Ai`SV3_lJooOZDsFjxu}+yM$c z8xq9O=)V5{A>N1^PG?$cmhC;h~6Omb@lQWc~b9Z}RuV_>1n6fmc#*0Q)!$ zLutR65d;jtIKvsSYlt@;PvL(gm;F9L*x;9K9(>p25ljX$rW^I=Z zS}(e>A$HV(X$wUjf$T_hAgq*FT~=nb2DCSE_pDqV8TvbehO`3%#V}kC4E^!P+1uCZ z7lnvZebk|65%`&L>Xm?lu652+bzR2~LwlUL+S7oxrcxZIm}vMHSIxz0INRYpK&^l~z%Ni$ zzjIH`S}q6qIJ%U}elGi2*-w~2qiAV`^m}j$;L=?ohC$(BG$GJkNYw`6&|R74QD;GFN8)r{nzV65@IL zv9myT-Tzhhb~E{(-6}Na`Jb;);{4BxH-G)x$4@6m=`2vH_Sbj|7|HAx@w)lVUw-pP zH-GtUUw+%C%dhOV@80)&54qSgy}<7dA^m?B6aU4|^^w=O1OM%A)w1`0JKK9(IsW?^ zCB}cRPL4jjPJ_Rs$^>}>a49BAbDe=BgA}}5?ou!e(5XjAEpilS%@7OGgZ(t9L+V<7)hlLdhj%jIVqi!Nw0AwZMFzi+d05TzvGP)}u zgN=MJloRj~e_>UadDi%|>Ulf`yCHjPUU;TmO_V{6O!7b8oxD7H{`%&Qr6ZRU7H)5UC=bfaeiC`7&MU^ z5f_n~$X=5z!cNAiN6PMn1MY(zRj!3BDPr8QdN%?D`tSIU|^r-h;_3XW)9*zHS8rPUQVSlQ=*F|I0JuCxduZAuJ%gJVKvx++ z!w{n$SgE&JRM6SGF}X32hNdf@<$5pr<&y&Q`Ii zS4ju?2B1q1{a)zTi;bb_Ab;-ASCsRHCK?sp$#fm?(i%C(iD8H(#6Z7rA|*V!ybHKg z_+UDtH2fA~(}39*g5Hxb^ZCi!XT2$?2T1SF(*O`^_lw18n$M1D9`@|`oIOwWtWxpO zMx)ge@(dc{H)_Um|5R4_0g!}&aS?xTvy18(CQMtsTFZ7ttT2TFcasQ>@~ literal 2995 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 T1v-K#zx-Xv6yZWZ8=bD?st%7J diff --git a/files/algorithms/recursion/karel-1.tar.gz b/files/algorithms/recursion/karel-1.tar.gz index 80bdb4a4a9ff3b06215a5ef6f27037a898e06376..f384b2ec49a85c8ccb938a33b623a1ce570bf861 100644 GIT binary patch delta 6220 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

*az9Hu&X9CEK6u~Tn4iD2cHV0 z7GudAEeuZZlE3BFvT4{_h^36iseJpljglr@?&o)qy#L&9_2Cp>yl_%?Ijhb(Q_Mr& z{zu~NVU5Scjxc0bl$1HJQ##vSxEm^x4iv3n9j3e@+PP9)@JPh|q_ZWofn_wXT6CM+ zXhsfDUI9f9M_%gpI0>DHk3VL7$g}#vyVoj+<@c_RN9yZiWDVPzntxeEqmNVYxbpE` zh^hZ-Ge@OqV=>s4ewQJ4(=?g;CX4~w6a>FqgJxHQQ=mc?*g~UuVeWBtweHHcWQ>7N c$!l0;(G?2$Uxx>;6%d_`kZu%>8XfI_02I?(`v3p{ delta 6168 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 ViuTcBq1kS;z0dfzOeuR delta 1477 zcmV;$1v>hS43`WJLRx4!F+o`-Q(6A=RveKIB{2X101g@%G|Q5ELjlw6TT>_DN>u? zl_^DD@+@4iwTh)$rKxKb4$}oKb|+n|m2%j{RatuxVu>iCKjZk;Z4G3I+EhqRVv!Ot zB1nJxe;-hM?B83u4D3XdKQAHFYiV7%7D2gbQQ7HBf7Z-JK@$UP-9Wl$FKa=$grZTg3 zj^oa9w@wF|oUC)!TYs%BTnD|R*ZP*9CoO*}T30Qm1vQ2toZj4JH?d99Qd+levhylc zSz|3vE-kYe<=vk78f#WB*>!w+I=1pdijr^+=cUp*PZQQy!Pa2N`cI^>ne8a{n+iQ| zZ)jLpP@J9%bdGF%Xv5iSDI=#fp@vMZsJ@>#@${SQ($nViZ}Pgl)ZMekZZBPX7iE9y zHZ;>c6_Gje*BaZKmJ`R6?&a0Tf({9XY1CZfEOs4*j?r?C(<29IV+MvsWf_{97BVQK zL%7h?u(4w!BQqmma|ULEGK(3QH85%}SXjBKgEL`~V#Uo$EM{PoSj@Swv4ZBNrbdFs z3N{xoQK_l0*l1YP$fH7x%|*_3>A8P7<(zXIS3KOqBImQCDOAzU&#_*7cHeVsDBo_$ z@eZ)hdt>#ivBq;biDxlWww-5`@|HS{Pch~)G8;tq9}kDs@W9BTjWjn~h~b}mh_isC zu|`Hk9)nWF78pY;tTvQQr3Dr&KBA;(ahjGkn+%MKEN?e1ZJ@mciVcNnyOMt{QF6x7 zV#ecfb7{ETDA1!(g65>X2kucAFlJoZYFKS3W>CRHOzce5EK!1qVueP96j7vf*2WD@=4Rt)!LZn7W^X9DgJ8L0;YAF}BWXhh zr4}Ye!!u#9%-CpcG&UOz3mbn7!DCXzjfO^s49X;CW>|lxe0X{7;o)e#MDMFVlGdy8 z*uFdP-MH3y{n!0sr?QJmynGf(;I9vTl5=)G`FGcQe=A#qhM_8?`{nZflG1f}&67hD z`O4D&LcY&-M;!WJK$t$j{li(N-S*3G^q%+q&i-G(w45}G3Ww8*UZj6t=ByWb{b%sE zMg8#?UYe@c^<^`)!`GgLRHxfK=gB;NvHV9l%cC}FBfP=sJjWqniHRQ+*)*RIkbY7o z*!Nd!-5#U%;RqhWYB$nP86k$Eab9cL;?yhC>Ss*lB+v~~V# z90g~I72RgPg6zfYRWiyL8o}j*S1FT>;vRb! zW$=|k$zhjl;&&c{q9nWR zw9*bCEux;)bv{W_l@<3o1IR=2B;hJg;OaS^gTPek^2+wrZV!)wyZ^>UHnfdmlz;d4 z{TQ32O02vsBGvu_jM%m4tW{XY?@1m>o#zKx{ocvB$Xb;vGthPih;X=-PB}|QJynXW zxEK286NvSC_tbg!9P<)fX9w&zoRv9wNze{c5;lgx`!`2Qgwsq=WF{mkNm5X7Nj6GU zj6G0fHn^VR{B6O~9=4raM!@|H^$wQ`Q-QF=8=_Jqw^cKr&hdB6pH;T9l#(=@fuRnv fL-UIk?>h%z?3Iyn!on6LfB3tSDZ+$@_nNTaK0na@ diff --git a/files/algorithms/recursion/pyramid-slide-down.tar.gz b/files/algorithms/recursion/pyramid-slide-down.tar.gz index 9cd1501e64da729b1fe2696f428534aa76b88ccf..5e031e8008c1a68ccf9e9607294698e9c6d8e7f5 100644 GIT binary patch delta 1413 zcmV;01$z393y%ws8-I#nvruifRkdofTQ%9fM5yw@gt#@fWt$`@oB!T37lW^mL~PoX z&L@xu&$-Wx`Nnp4! zqa*`9)V*cq2fepR;;qut!^3#_Iq;`24ZJjkd``gqAs|#AmM+7CA7&6l;hd$}IiE&9 z;VkOl$;-**1Y$YCx=NEH?@Dvw6h;uTThXE9djSjQ*)@t`D7oTBp&|w+U`)`648Avw z;?>8ij*@AT)qmDDb8Hb-?QS8Gt0)1UBCODBO~pLL^Wzcdr*LwzDyF_pACl;{HQ?1m zgH5}^eJO-H5T5Sf4L7Q!PvQ9ZuIgENhh;cp32GJUxq@TN^zshN-K3F4fB5t340Z0f zAiApQD#tbTDt>5kD-JtVU&H$_V{?}D&fb6c>(95peSiA79xm1Z(}3d$(9p1G8b*p%@zWC20G*;S z7mc}G8g1gC@3y2jQ?K%W(=>?xzXVDwUyl5P;@u-lUO=am&~#i0OD#RDaq^Ouu}oi3%SuZagmp;Nm7aI8A2hYD@d!&EQ;eR@c z6aRYwl=z<*`L9g>#x?qfJd87zH=yUuGKpK?0Bz=8TW$$fIO5k~pIf-v`UYg}vVZnS za#+6}K7sxb|0DiaO_2B>@jv2!#Q)Z4;C~lU%r7SUV}LvOpJN!c=l_=L5dV7#)Smxe zB#fPTarFfNH7V4;O2Vd5GK1fv)X)4#Foz29L%RW6urN#EU9^b3#QPkuH@U*N@b9GD zNKG!uE}~8@2ubbfxgv6}Mv(Nd(SP)eyTS}_ykN;bUU9WqH&Yh^I!s#xu2$x&k49c1cd6t(q(uE!VKn7IAdvc&Zp5& zIEy-X@^XARhFDIpuF~YlyV6`Zg&~COR&*%&-kgQA>>9-|lw5J6P!WR@Fve&^2H%@R z@#^DMN69qFYJY2+IkpI^cDE48Rg?fv5mxB6redDr`Oy&cQ#d(U6;ofQ4@q>}8t`hY z!KU5dz7)b82v2wLh8tDVr*M3HSM{vC!!n$*1hoqFT){DBdU=QCZqmr2KZ4nHhB|j# z5M9-DmE)Rv6+bk&6^EUwui<@|u^CHxXYW7!_2=8)K7ajO4;O2IX~6Li&iw4UxA5;e zB3~^}qFdH^D3`Su9G_BXZX;iiO<1-}!lJl7#*dU$a^+=m69rRP_(9k?&ypaV;Uw^r zSy~*V^HrL$MK4-ry%T1}#b17=H%;nkeVsw~y9sl<(_O&uW=LLJwVd zCYO=fTDeMr-nj@!SB76vcSOHB-3Us@ViGFah3&NQ<$K5{J@x@WhpMj>|iaQI(S62c22 zuJiw262_*hy|MqD{NJ)oy~_Vh%Od{&5-72JIr7iu_?nPH!Xz7$XkKFdSI`lpw}CJl zRi>)gRZfCYZ+waN#*I{rTgFa7Oh?0_(tlQB`sGVaRQP~V<9X3|Y@8@utJbVVtqN0X=V)N!z+xU>`TOS7JcNT@S3ZdQM zj7yiCm2dVnI8%o7BFij@J%YfMW3RCDQl}c_^?+!3{3Dq7lWSI%UXMns8kM&>)XNNc zZ?E*sTuq5$KmI(eQ}b_dXHd*|d|Aw|{Z92OQDBq_Go-`muWZ#>m$l(lk$ue@1~7cq zhC+^~c)w=7UQ3&dC+#wJS(7`D%0!nL$IEP;sn)n(TBo}8uDG-|V;gJx-0AFE8R}J~ zTx`@S#JY2r)KopObE2&iZJlWAL|Z4?IuQs20)apv5C{YUfj}S-2m}IwKp+qZ1OkCT SAP@+IN8?}Sv!w(8Pyhf-64qe= diff --git a/files/algorithms/time-complexity/extend.tar.bz2 b/files/algorithms/time-complexity/extend.tar.bz2 index 3c0718bbb0c92bd683bf143dee202e79bf2629d3..d315625defc51e22d1f42c8de6cba9cb129956f1 100644 GIT binary patch literal 4074 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 diff --git a/files/algorithms/time-complexity/extend.tar.gz b/files/algorithms/time-complexity/extend.tar.gz index aa30c695b40ce5f23b81c6f458abf672803583d5..badee3a847eae18e339d9c31f9f6a256c61e8d7f 100644 GIT binary patch literal 3913 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 XQ=j_Or#|&*-_!pAVo)(w0H6Q>5zo0w literal 3915 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 ZOJDlZm%j9+FMZkf@_!br`mX?>008mAnQ;IB diff --git a/files/c/bonuses/03.tar.bz2 b/files/c/bonuses/03.tar.bz2 index 6b39418d86686b98311472e15e9f052ff1e84d39..725c49f7a73f1ce47fa6b00ecbaa647c87698523 100644 GIT binary patch delta 2623 zcmV-F3c&T#6wnkrLRx4!F+o`-Q(1!z(&spR- zS6YWjGk~NOA}pw?LVPC2-2Q(GzxUPYp-O#)DM^#osJf@rrhikbTpx05s-;tY?i!2I zl`yKjy5&_=#I@52g32CjUrYDBuTq?*=Y#2D{O|l=`EC7}-Tj$0a{R?PM=51G(vs?2 zrVA-PP}L$|1mVBuf^K$x_CXyEPq+A^kTDnful%{g*p?dzY2J`@nte` zEZL?C(>AkmV5(+sdh~FAwmvT|g`c^Ns>@k|+Y+2OVp`5la07U-Ur zLlfR|=PoXx-7nb2c20jDFa5FfJXJ4m@ zxMM|>^|70s4HQ$e4BMLO&79_yHN4VvibXe-B8gCjj;@h|7j$sLF%1)`tdB_d42JYO zh+S`G;&0+kX~8=jc6jid&kCj!CRSy%=9;w3Q^q~_M@Rd=p~D^pCw@PN{d8k7^;LE* z*nXKoxk_2*e2{;CbxC5rrH`Dcnw2S9DbS9TqIM3oQCUyD{2#^o%rN(je3MDDftODK zYgzd3<-;QkHwwb5!G-d}M|0+TFmUHpuNAqNV7$Fo?tHH7JeKaYd`_744rytdw{vIT z!PzNj=*5wSGO}EykI1`?|4SO|A6icmM5ESGMJW`zlH|C5d}~GFP?#yhDykEVdB+ON zwmyN+(^XwOPoYWN_PwvE|8K4JzQ%}h8#Y|oM$MLB*|TQO#O-o2@@uKpKSP-46llZn z4yf+jdZ$3)IGjU5f(}P~o#UbuQA0u|(#O5A)Qxf{sfi;RzPxgr1lD3z?ZUj_cobspJnEknVNHIS#iZ;#%`z)$A>;$TSr4P zOf`l#F1vxLj&~u*bn@!h=HFAHp?4**W48!*JwBg*Tsni0K{% zy(&GK*p+KOHA%A#uVT@FSmchuL%0;3YAOU!)KEsA^a!*R9nL=*7DaoZ(eu1T&y7Ar zAa_E$;#k^h|4Mr|vqSb2lBB1&{iy%32Z0W5E%e6A83NONxyJL*Ax;>CqXARYP^BgYp`qSu-$xR->XJ^yd)ab83%5 zVCxyYxk(OG>70`TXxS3gRmqJDdTGYSlFk(08cQw7H_L9aCd?kh*sWrVz9kbvlOl1a zl%j=6y}zV*p();yQhd%7i>1H3?&7NRrE{Lc`;z%r^u?nEaF^4G4h6aRbq@@&g hC|M@-iNzs#72`z*d3B2x6%hXd?ntK!5)jpSx5@qdK;xB(D<|NsAg=l=fx|KIum0sshL z4Ssy300001Qb;19KmZj$PynECG}BE6hK7blfMfxopfu5t00Rk#4GspHX`s;1(8$mX zfHX7)nlbJ1vFff_Ofnx2WEG}=uvG;dKdf4;09zhr1Mag_y&5C=<_W#AHZ8ahE;I2%^f0D%G& zNf40&4zOGw(|1^puD+}VDfbkmCXbm>g-_6?zoFT?C-qJ0s#SkD@a3q*DN`z}OfXed zOv}P$GFpd*Z?W<+oe~Sf5u$9BJLkZm*p~5Go5h92`vC>uUM)`4q{5gflGL9-Zb+EP zI+_nGn74AHa-{LJTe_nWRTW9ZjajLQLN;YG4Fu2xS5bvj3<`^wLZbjkY@42E-O`?k z>E1V_OD;R7TBm=WdYT2Av{O2jF52QxLncp2O`F}tCe*dqeqY`EcXv4*F3I^G$-Tkf zUu7_pnNEWPS5lA6(V?WKFD4!IlUgcJ>T~md4#Dn4KZ@4YcImV(je7JRJmqA|5_x8( z>F6&Fcg&I}y#E)C->dtc$y1PXtbFP2I2c;qcFxv%^E7`>hZkg0xfsQ@W|ci$jm8fl z$mVM$$E(?i@SG{Ho719U!gxK4S^Vbjt zgZG(>7;k@arns5L@#k9ygrvH7nmRORJnbGOJd-A!w(#GT{SM}COY5GuTQl2q>o72( z-!a_IcTX3aIIS3-Ig?4Xc&CqNpQpx_^S&zT-J5rY9FH5F$kgUDoxZ+j0i717%+7Fi zwoy*(wQz3S)vW53H)3r&1tOeEkwmLoX}i6fJf?rsIc-qdJUA|QzJ`gFCoD3KEj*4q z$<;Y0bDrL8r&GeIl+mTM-#Vt|+KPFHyzA@#C-OOCz@+qN@qV3|%>FvA<{QV^C^#ug zdY?oe*-}|wYR{yps+B2QDb|j}qIV9}QCd%H_rHVu%(C{)-g&g%q@+hf52uoDiCgdB&hF*P%Z7aOGWau3_5O(-sRXtrzvCYQk11aiR^Bh=O4QhY^J9q>fD;v$5w?2w@53qZw3qw0>auh zu+XB;=1j;cZdSOQ42IIuZU(@)hNVu7i5mJmtw7QqaQb9w>fxuw^GZW*-&+ZcFV>^y z*2!0Il~QkIzZhcWj5(8$A@P+S?J9rEkldo>PpZO80RgYv^&vD@U^Dk!QiqK)p&-}@ z?};G7+<9Q?<`#%;1PcoX=r;uX8%SjLm2$Om%07ws5pA6RwX5jp`bz8Aqih8N+MUS2N)1HjRwXCY;;j`ZDEc>W^1+))PwRA zUr{t<6;~GVt;dj+KyZmS&5nNwU)DOVS-xh2#Uf0Kl#hfuM3p2$K*C=59s^=|jD5on z0vt*i#}|Mk$<~XBCW+Y{>xM$3tNI1J8T4BW1vQ_F=jZ%a9TTNTL$Q<}in7ggscNpL zj8E4(;YBl>`=zG%G-VrQEh;jUf{hzAA9S86(FSE)!qW_vmvi=iMW%mBjz~zb4$>5J z0~@9WALGYDm(UXlg@gFw44hnThdU@)iT#YH2Yg3EzFKHhMn<2s1z zbd@IAO^i%GJ;a=oDZV2{1xCW5?bC$ojYTSxg}t#5rACk?km*jz(K0v2^h;RCo#&l@yOd@Epzrp8lFi(r!Jf3>hZl#M#Q)kAfW6 zJ`wrUC7abEOJPzLK3a`KfSy`M-XoEj+tV%_fZs9>(XjYa(mj6$`JyO%A2Y47RT7k_ zcx??=xieE{)0L$8+*o2wmMygOJoHu7DPJ2VM*}3KOeIH5g`{*k&ChX@nHtB>Gg5gO zxVB0@f|5q2`QwQ1j?0zT#lJsXRn)0FQQ&d!B9M*Rf6|uEyxDwF{gH#AhRu~|GVzi5lDwLB2CCM8ok(N+w>P$|r zGI^CMenpYy-0hRbZ%H^N??68?9$tq_gxw_dN`j{$!c%_>DGzz=jd#t2bwMQWsi7dg){lw?a+BJh%P+nl~|=;>yv ztFM8W=RJQ8f=?5{)0%Tk7QCMl~doXW)K zxuRz#j9sv-Wz}*YNt~;b4`SRLvXwW?+uZZh7GUgED-v~@HJZKFl1)m7OUgZLBi^az zO;nam$l~mZM-)}^N+nIi+wsY<%GO1@X2h=RRos88St)Db!P6L0a*~o-=1W+p*;t<% z*(i+ctEo{$(iYaI8?{uri```|;{43mGFq-g!f@7g$wcT4Y~Jsdp5S z;!8l^EmGqf6DG*=u+Ai@62p%Hs+1~9lUF%4jmhOyUpz7?7}em|GPas~_S8oRG)>q1 z<{wg{G-^SRat+1hM}|;&OI&olZZiqSExCzBB_8Csw&7*OmZ?v5g{qAFQrzujvr0s% kQA#N8P_&#5}^{1cYmh&eA`?x8;G{K0_GFSlt9EnD*#vtBF`hiVm!yUZKOPS5wPK*Ac_D;8Fhalz z0&B{kNBVw%U!DV2KO_M#KM0Z1fXK7`(TE_0MTUa-4wRd>Q!txQWsKl665o zwgPJeF6oDG=2MT0gc65C0(}~=P_fgI13DPaU^8O-IH@`4d@N}59~_>ej>yOlrr_h0 zVsr?t8^SozMt|wnrw%ZjPDQ-cxM&8*cQLXdICewvsFwaI0Rk$$bNcd>Gx(6#&1(_@ z^&B$c0`%x$K+<_(hmc8_N0)jW21^y9CNo25`w{jYiQgC}G0CFAGAh#bvWNg(WsGBt z_*dwoghRA8We_pqaB&@CQ*=u|a0vIyydaWQK*A{S7=N57-Efq=ex$$f9>q+WDYn7L zn$S@+ifx5TOROXGkg=74(+QzcX zEQslM`SicA$0fd{-0Jcz`dHS#-t+!9hyOl#bMdBfh_b*MG^%NT`||Kiv>WigI^#<- zJ~QJbQl&(OeQx{#37FI_HYY1L@T0*H1_U>JYJbC6x(U+_G|4+p%nT+v)^ripG#gG# zpnYW7YQfZi{rGF2e;kpqvj8E&F|l>EDucvoTK;7ObxY!`{GD{N(Rm2_#pD>d;n8;Z1~I9|87 zf;F?t(=0Yul)1S9*2Fk_C4q;z0#xGRDSu*`dwkQ0^^N-uey*)mK@P=1rZp8VUPT_9 z#UNGKN8)PCm4lFItrZWZTBSsp<`3M*R%st|kZb~y^{=ylE5?gPJ-*=kfj`0=XV!?) z`<~p%vW6aW*}Ac86)tB@U}o*CEVfMNGx`>+`;{_0bIOJsA5WCkRCTMwb7(&wD1Xl* zOu_sSp0+K9Qigco#^lUPc2t=xE_7L(jl`&EJK=vY;pE$XKfr7gHH%pvnqVs98<2@L z8oL;pd0y($8{x@dTa08fRU}de5oxMB8V+H^Q&wDWxVM^#(hWd^ETBfE@#VGvI~6CzxZ3^h>?5xu$LybZn@hZPwdB0+_S|W+;+97|IkD-fg zG?NZQZD6NCr@Snf9C6{ECX$4KOT0`Z+0$Jf#|_D7EPq`jRZ6;Qkb!59 zrEVj9=J4qu9}9D|hx2KHy?~Eh z<@X#9WW=>HPasPQ^l(O8qInwXNew-mk-cDQc4lfH^ji;HJAavrj}o^xFY}6wUdxc) z5-N@!B75{1iBCkrcSHc}Sq}8b(7L656d2-E0zNLUyMXc)ETgA7Nr+=el7TYxMb@8+ ziwAXtf?DmQR*U(|5qBAWjd(Q3-15$M-@RO)I(F&pne$le&3a+sOIKXKE-+>Nzw7dQ zjwkw80L$zD=6`l`tC_3+Hyh2JqW=Fm;NJTGcT?(r>f*j$rx!PB^0raD$}7ijyfFVM zi{nBoGZ)K6mHTU~a?hzWep?Ts-Y;Q6s44+lv0#ZzLrwTH&!iqL_y?xy?-Sr68^`5$p3FJ#d68hjj=rc zH=9i}m;Y}zx3-J?|8v06QEOn^rK4AW9lmb2>X_ZP>=!SferdTb{$es7So|3TxX$aB zW8&auPVG{O2a4U&Pd`_Vj;esafD?VZgPv(ebu-dX|k31vzkVxbiPtOSwgkzg^NBs>c3}>(zv3;D>9CSVwwD}JX&rwHY3Ug2fUYve zF-H6=^ijegTAMP67;(6`4zVe^r5`wi`(<7b$toaW6n}UOPLysqN?t$GUwDsVCe0Mv zU}R0`C>q7KLZv0v5qikj%E0M_P^od@s}*z?97fU^pnp|0qntFAA|C_^qpS-zvQ#nLgU=148w7-3McqZBncwe3I zr5T@@@e-+0BEvp6{(uBbY8RW6l^gicU12y2=R zCnnH7vTU_rYQTQ{wa-5eOz@E~xTB23Q6#iN6p9M(3A=XUBpG8(veuf;3HsWCYRp+s z8CBUs9K+^HfZh}i+earSaBH~{S*nwS>K?76c%McuoZrVPhSR{LD<%aksKrF0xmJbA zUVn-;U5GW^)3vI&)fL5~wanv$g=}xJ3j=^y_McJn2fF6>@727L^D8jHG%>+MHvt|H z$AL8%ah(pR??LCd-D&4dGbHv6pLo2hFmdoC&JVVW#MTwIvbjpSwBMDQc$y7GT2dUZ zTU^1K+2v^#n=8uP+yHB0oV}93!(0I>@qh3XG0i=`>BRcReFs0+)~X; z56)tcD(oY1HRj4eNVL|92UD$5qD=D#?qjR8k2y#-0m=H;S-=(JMWY^H@cqCaVU9Cv zMCpA`?qpd*kGX8!Shfn6vnDXJc2*W!rt=wn3)cNg8J;<1LynIp%4({*RpL3cpMMXO z=Mko0{s>Ro7DFjRJaA)j<|R9-OcocqEY3z^RJ5J&KbUaxZNDF2wuzd>tPf2vmGKS8 z#2SrV49z?*b?J@pWUwtpGMOq8se_0#)g29oFybjIt~cCU%|z)2AU{rTIqxI1pGX2_ zS{a{T#7nG6HGWr`u?5eij<_{c-+#O7cMbCz`%?Y>1NDXh&rJiL__K+BoA_6LoAANN zV4AY48Dk0(Nt?w)mYaxXz!vr!ux-GO0lyjW!r&9kF-3Ajt|N9G(d&p`M}j(1)RCnA zLX49ol49ilpg#z&h*zOKU$4Ahu~{vVM0V|vKg-9^ z#Wr%M#)r=1P``S4^fY2-SDv(1ejfS#<>TifgGk0%&JNpcOi@L^81rcFtgG>7j$@0W zjJ&I2>u~5YU#{@%X)I0hXMbXkI1_2XN8L?fn$vBc{C$iI@2LV(EcTp`lpZzj3raA; zv|O|zHol9K#9lQUvgAg7Pv8=JwidaR0F>8$~mNL#*V&c6;GSAuU<{yl;G+l|p&zKgE+$bnM#Iewp zFR^>}|2^vd}Sy7G% zNN))hM-P!b`i#UUBH=qC0QM{gdSqzbQa=g|aVh~Hm)BiD`3jcNQ=KHlF(k=A8TumY zPsPQ9IzmCMc2cXw{N;$d48KM^8f0#H=ezG-u1_7i^!ChoEcRx-u<)fTu3s0Jvi{$7 z`8~%I{VRaw^?!eJySdfO)&H9fL@Vn5p8@Wz|9>~7{--YP>vei@qb6?~#jCt>{KgCO zpRzbEv@&zCTvWNg#wz!mO7kZ&-xn$we_Q3D)6l1CIozJJ$Sf+FF69Ekk?22(7TJlz<} z^MAA1G;{g?W^>yt^8e2PM@OxJZI_N-{dM@d-Kt}D-?Cr4fcmB7y7-I9cwq5o5a2qm zUyg}`n>n>hB_1etOF#WwIXbEW{t5b`iBX!3Gt0kXPzQY7-bR1!;jS2XGE xKiyjHAP(Rq%XM*aHPaB|eQCWGll}-7lMo37lMo374F!B|_#eo#KH>mS0037aNJ#(y diff --git a/files/c/bonuses/04.tar.bz2 b/files/c/bonuses/04.tar.bz2 index 916d071fac81b127e2944f0a06fd267492cbe92e..2ad2387121e7f71bc8da069d01db8adcbfc7e07b 100644 GIT binary patch delta 2513 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 X1*wpA$1af||BJaIoG3_JK>hWP!zE_Wr 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 K3j>+}PyhgwxiH@V diff --git a/files/c/bonuses/05-06.tar.bz2 b/files/c/bonuses/05-06.tar.bz2 index 2871683a4ceae5871d93752f5c55d396a0c5c28f..a5547c33c6a97c7d60c4f6167bdd31f7885ef234 100644 GIT binary patch literal 3647 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

aAMR{>6(cRtQlTYDEb4JwU@0Xd0x3vgYizWG zT(DmTNdGeGF|mw>Q$%S!ql^!$tt9u3K6u$r_77oHixpYOrWVC}+R|EYdUJ^!&RtNL z)Ne=ATv`1WXVj@Am~xA3bA%S2{8>BO>9KXw1(WmHn*w+f5@%87WtMoV@6*+0!CJOs z{8rlxn`%Ph+6$^uJa5~$Z%I2{&o=^lSv#pD+{jpVsAaNYI8CUWaw1tIX&Zh2BMgSR z$S_@Km`P8B+~q37qK5KL`wiYNY`bHX=Pa15VX7`Hqfs-F)Nd_hHsdBzq@twVWR@yW zrkihu2{n>6YAqyQY%Lr7t#w8%TakdGSxPD!p=DT>TN)QiQ53-qRv(=j^;lc!t4OLv zcc_%jN=huU%27wTCQ@B>DN1g6rcjb|^_FqVc;Imy*d@|ZN*K|}C6p{nDQ47Q(FH4+ zCtjp{N<~Eq!z9~A7+oZ|!TGgo@6$yS;BY6uug!Kgo=2t<|dO? zWKh8b=2+cxvDJ4r1Ymw}9gI9VBGE>q=n>kA2Xvx^ZB(tlKyJ2OAu6BLkkGCRK zBPv2Ul?omLhofTU#t7^ex-Sx0(UKS{<2Gc2nsS45?5crCfA&kul#-Bpct5RXNPnQm RyiiZ|7ji{7P>>q~q~cMV+sgm| literal 3643 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 NF64@Ep&^B3ry!z((wYDO diff --git a/files/c/bonuses/05-06.tar.gz b/files/c/bonuses/05-06.tar.gz index abe7751d47fbeec3f029018c0f6e2cf586064dcf..58ce0ead822b8f9cafb97a4d6a1e77a0161992d5 100644 GIT binary patch delta 3446 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 Y1r=0KK?N05(6>YX2Ua(IcK~<*0J446kN^Mx delta 3445 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 XsGx!hDyX1>z8(5M;rhbb0C)fZk~+}< diff --git a/files/c/bonuses/08.tar.bz2 b/files/c/bonuses/08.tar.bz2 index d5f59fc9a63db73d04a89265c300a6ab07b00eae..757b9ac83919de025b35d23e87235f7dd0d6a88f 100644 GIT binary patch literal 75693 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 literal 75742 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
@nzR|TZV<>m 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 diff --git a/files/c/bonuses/08.tar.gz b/files/c/bonuses/08.tar.gz index 1da4aeede498151b9067a72a2855ea16f95cae28..2ea70eb3fdf000ec622871e0d1b67c44865f7c5f 100644 GIT binary patch delta 79694 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

mV|^fg7L1$UA?&vzJ`w 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 delta 79694 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

l3J#qKfv{ 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

c!L190tY_nnQh2R}!-L62yvLN-(8kawS_S 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 z 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